def vm_acpi_shutdown(vm_name): logger.info('%s(): caller: %s()', log_utils.get_fname(1), log_utils.get_fname(2)) logger.info("Shutting down VM %s.", vm_name) vbm("controlvm", vm_name, "acpipowerbutton") # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_wait_for_shutdown(vm_name, timeout=None): logger.info('%s(): caller: %s()', log_utils.get_fname(1), log_utils.get_fname(2)) if conf.wbatch: wb.wbatch_wait_poweroff(vm_name) cs.conditional_sleep(1) if not conf.do_build: return logger.info("Waiting for shutdown of VM %s.", vm_name) sec = 0 while True: if vm_is_shut_down(vm_name): logger.info("Machine powered off.") break if timeout and sec > timeout: logger.info("Timeout reached, giving up.") break print('.', end='') sys.stdout.flush() delay = 1 sleep(delay) sec += delay
def vm_snapshot(vm_name, shot_name): logger.info('%s(): caller: %s()', log_utils.get_fname(1), log_utils.get_fname(2)) vbm("snapshot", vm_name, "take", shot_name) # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_detach_disk(vm_name, port=0): logger.info('%s(): caller: %s()', log_utils.get_fname(1), log_utils.get_fname(2)) logger.info("Detaching disk from VM %s.", vm_name) vbm("storageattach", vm_name, "--storagectl", "SATA", "--port", str(port), "--device", "0", "--type", "hdd", "--medium", "none") # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_detach_disk(vm_name, port=0): logger.info("Detaching disk from VM %s.", vm_name) vbm("storageattach", vm_name, "--storagectl", "SATA", "--port", str(port), "--device", "0", "--type", "hdd", "--medium", "none") # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def keyboard_send_string(vm_name, string): # This loop is inefficient enough that we don't overrun the keyboard input # buffer when pushing scancodes to the VM. for letter in string: scancode = kc.char2scancode(letter) kc.keyboard_push_scancode(vm_name, scancode) # Sleep occasionally to keep us from overruning the keyboard input # buffer keyboard_send_string.cnt += 1 if keyboard_send_string.cnt % 50 == 0: cs.conditional_sleep(1)
def keyboard_send_string(vm_name, string): # This loop is inefficient enough that we don't overrun the keyboard input # buffer when pushing scancodes to the VM. for letter in string: scancode = kc.char2scancode(letter) kc.keyboard_push_scancode(vm_name, scancode) # Inject sleep into the wbatch files because the Windows batch file # is sometimes _too_ efficient and overruns the keyboard input buffer if conf.wbatch: keyboard_send_string.cnt += 1 if keyboard_send_string.cnt % 50 == 0: cs.conditional_sleep(1)
def vm_power_off(vm_name): if vm_is_running(vm_name): logger.info("Powering off VM %s", vm_name) try: vbm("controlvm", vm_name, "poweroff") except EnvironmentError: logger.debug("vm_power_off got an error, hoping for the best.") # Give VirtualBox time to sort out whatever happened sleep(5) vm_wait_for_shutdown(vm_name, timeout=10) if vm_is_running(vm_name): logger.error("VM %s does not power off. Aborting.", vm_name) sys.exit(1) # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_delete(vm_name): logger.info("Asked to delete VM %s.", vm_name) if vm_exists(vm_name): logger.info("\tfound") vm_power_off(vm_name) # virt-install restarts VM after poweroff, we may need to power off # twice cs.conditional_sleep(1) vm_power_off(vm_name) # Take a break before undefining the VM cs.conditional_sleep(1) virsh("undefine", "--snapshots-metadata", "--remove-all-storage", vm_name) else: logger.info("\tnot found")
def distro_start_installer(config): """Boot the ISO image operating system installer""" preseed = PRESEED_URL[conf.vm_access] logger.debug("Using %s", preseed) boot_args = _BOOT_ARGS % preseed if conf.vm_proxy: boot_args += " mirror/http/proxy=%s http_proxy=%s" % (conf.vm_proxy, conf.vm_proxy) kc.keyboard_send_escape(config.vm_name) kc.keyboard_send_escape(config.vm_name) kc.keyboard_send_enter(config.vm_name) cs.conditional_sleep(1) logger.debug("Pushing boot command line: %s", boot_args) kc.keyboard_send_string(config.vm_name, boot_args) logger.info("Initiating boot sequence for %s.", config.vm_name) kc.keyboard_send_enter(config.vm_name)
def vm_wait_for_shutdown(vm_name, timeout=None): if conf.wbatch: wb.wbatch_wait_poweroff(vm_name) cs.conditional_sleep(1) if not conf.do_build: return logger.info("Waiting for shutdown of VM %s.", vm_name) sec = 0 while True: if vm_is_shut_down(vm_name): logger.info("Machine powered off.") break if timeout and sec > timeout: logger.info("Timeout reached, giving up.") break print('.', end='') sys.stdout.flush() delay = 1 sleep(delay) sec += delay
def vm_snapshot(vm_name, shot_name): vbm("snapshot", vm_name, "take", shot_name) # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_acpi_shutdown(vm_name): logger.info("Shutting down VM %s.", vm_name) vbm("controlvm", vm_name, "acpipowerbutton") # VirtualBox VM needs a break before taking new commands cs.conditional_sleep(1)
def vm_install_base(): vm_name = "base" conf.vm[vm_name] = conf.VMconfig(vm_name) base_disk_name = conf.get_base_disk_name() vm.vm_delete(vm_name) if base_disk_exists(): logger.info("Deleting existing basedisk.") base_disk_delete() vm_config = conf.vm[vm_name] if conf.do_build: install_iso = iso_image.find_install_iso() else: install_iso = os.path.join(conf.img_dir, conf.iso_image.name) logger.info("Install ISO:\n\t%s", install_iso) autostart.autostart_reset() autostart.autostart_queue("osbash/base_fixups.sh") autostart.autostart_from_config(conf.base_install_scripts) autostart.autostart_queue("zero_empty.sh", "shutdown.sh") base_disk_size = 10000 vm.disk_create(base_disk_name, base_disk_size) libvirt_connect_uri = "qemu:///system" virt_install_call = [ "sudo", "virt-install", "--connect={}".format(libvirt_connect_uri) ] call_args = virt_install_call call_args.extend(["--name", vm_name]) call_args.extend(["--ram", str(vm_config.vm_mem)]) call_args.extend(["--vcpus", str(1)]) call_args.extend(["--os-type", "linux"]) call_args.extend(["--cdrom", install_iso]) call_args.extend([ "--disk", "vol={}/{},cache=none".format(vm.kvm_vol_pool, base_disk_name) ]) if conf.vm_ui == "headless": call_args.extend(("--graphics", "none", "--noautoconsole")) elif conf.vm_ui == "vnc": call_args.extend(("--graphics", "vnc,listen=127.0.0.1")) # Default (no extra argument) is gui option: should open a console viewer call_args.append("--wait=-1") import subprocess errout = subprocess.STDOUT logger.debug("virt-install call: %s", ' '.join(call_args)) logger.debug("virt-install call: %s", call_args) vm.virsh_log(call_args) subprocess.Popen(call_args, stderr=errout) while True: if vm.vm_is_running(vm_name): break print('.', end='') time.sleep(1) delay = 5 logger.info("\nWaiting %d seconds for VM %s to come up.", delay, vm_name) cs.conditional_sleep(delay) logger.info("Booting into distribution installer.") distro_boot.distro_start_installer(vm_config) # Prevent "time stamp from the future" due to race between two sudos for # virt-install (background) above and virsh below time.sleep(1) logger.info("Waiting for VM %s to be defined.", vm_name) while True: if vm.vm_is_running(vm_name): break time.sleep(1) print(".") ssh_ip = vm.node_to_ip(vm_name) conf.vm[vm_name].ssh_ip = ssh_ip logger.info("Waiting for ping returning from %s.", ssh_ip) hf.wait_for_ping(ssh_ip) autostart.autostart_and_wait(vm_name) vm.vm_wait_for_shutdown(vm_name) logger.info("Compacting %s.", base_disk_name) vm.disk_compress(base_disk_name) vm.virsh("undefine", vm_name) del conf.vm[vm_name] logger.info("Base disk created.") logger.info("stacktrain base disk build ends.")
def vm_install_base(): vm_name = "base" conf.vm[vm_name] = conf.VMconfig(vm_name) base_disk_name = conf.get_base_disk_name() vm.vm_delete(vm_name) vm.disk_delete(base_disk_name) vm_config = conf.vm[vm_name] if conf.do_build: install_iso = iso_image.find_install_iso() else: install_iso = os.path.join(conf.img_dir, conf.iso_image.name) logger.info("Install ISO:\n\t%s", install_iso) autostart.autostart_reset() autostart.autostart_queue("osbash/base_fixups.sh") autostart.autostart_from_config(conf.base_install_scripts) autostart.autostart_queue("zero_empty.sh", "shutdown.sh") base_disk_size = 10000 vm.disk_create(base_disk_name, base_disk_size) libvirt_connect_uri = "qemu:///system" virt_install_call = ["sudo", "virt-install", "--connect={}".format(libvirt_connect_uri)] vm_base_mem = 512 call_args = virt_install_call call_args.extend(["--name", vm_name]) call_args.extend(["--ram", str(vm_base_mem)]) call_args.extend(["--vcpus", str(1)]) call_args.extend(["--os-type", "linux"]) call_args.extend(["--cdrom", install_iso]) call_args.extend(["--disk", "vol={}/{},cache=none".format(vm.kvm_vol_pool, base_disk_name)]) if conf.vm_ui == "headless": call_args.extend(("--graphics", "none", "--noautoconsole")) elif conf.vm_ui == "vnc": call_args.extend(("--graphics", "vnc,listen=127.0.0.1")) # Default (no extra argument) is gui option: should open a console viewer call_args.append("--wait=-1") import subprocess errout = subprocess.STDOUT logger.debug("virt-install call: %s", ' '.join(call_args)) logger.debug("virt-install call: %s", call_args) vm.virsh_log(call_args) subprocess.Popen(call_args, stderr=errout) while True: if vm.vm_is_running(vm_name): break print('.', end='') time.sleep(1) delay = 5 logger.info("\nWaiting %d seconds for VM %s to come up.", delay, vm_name) cs.conditional_sleep(delay) logger.info("Booting into distribution installer.") distro_boot.distro_start_installer(vm_config) # Prevent "time stamp from the future" due to race between two sudos for # virt-install (background) above and virsh below time.sleep(1) logger.info("Waiting for VM %s to be defined.", vm_name) while True: if vm.vm_is_running(vm_name): break time.sleep(1) print(".") ssh_ip = vm.node_to_ip(vm_name) conf.vm[vm_name].ssh_ip = ssh_ip logger.info("Waiting for ping returning from %s.", ssh_ip) hf.wait_for_ping(ssh_ip) autostart.autostart_and_wait(vm_name) vm.vm_wait_for_shutdown(vm_name) logger.info("Compacting %s.", base_disk_name) vm.disk_compress(base_disk_name) vm.virsh("undefine", vm_name) del conf.vm[vm_name] logger.info("Base disk created.") logger.info("stacktrain base disk build ends.")
def vm_install_base(): vm_name = "base" conf.vm[vm_name] = conf.VMconfig(vm_name) base_disk_path = cvb.get_base_disk_path() base_build_disk = os.path.join(conf.img_dir, "tmp-disk.vdi") logger.info("Creating\n\t%s.", base_disk_path) if conf.wbatch: wbatch.wbatch_begin_base() wbatch.wbatch_delete_disk(base_build_disk) if conf.do_build: if base_disk_exists(): logger.info("Deleting existing basedisk.") base_disk_delete() try: os.remove(base_build_disk) except OSError as err: if err.errno != errno.ENOENT: raise # File doesn't exist, that's fine. vm_config = conf.vm[vm_name] if conf.do_build: install_iso = iso_image.find_install_iso() else: install_iso = os.path.join(conf.img_dir, conf.iso_image.name) logger.info("Install ISO:\n\t%s", install_iso) vm.vm_create(vm_config) vm.vm_mem(vm_config) vm.vm_attach_dvd(vm_name, install_iso) if conf.wbatch: vm.vm_attach_guestadd_iso(vm_name) vm.create_vdi(base_build_disk, conf.base_disk_size) vm.vm_attach_disk(vm_name, base_build_disk) if conf.wbatch: # Automounted on /media/sf_bootstrap for first boot vm.vm_add_share_automount(vm_name, conf.share_dir, "bootstrap") # Mounted on /conf.share_name after first boot vm.vm_add_share(vm_name, conf.share_dir, conf.share_name) else: vm.vm_port(vm_name, "ssh", conf.vm[vm_name].ssh_port, 22) vm.vbm("modifyvm", vm_name, "--boot1", "dvd") vm.vbm("modifyvm", vm_name, "--boot2", "disk") autostart.autostart_reset() if conf.wbatch: autostart.autostart_queue("osbash/activate_autostart.sh") autostart.autostart_queue("osbash/base_fixups.sh") autostart.autostart_from_config(conf.base_install_scripts) autostart.autostart_queue("zero_empty.sh", "shutdown.sh") logger.info("Booting VM %s.", vm_name) vm.vm_boot(vm_name) # Note: It takes about 5 seconds for the installer in the VM to be ready # on a fairly typical laptop. If we don't wait long enough, the # installation will fail. Ideally, we would have a different method # of making sure the installer is ready. For now, we just have to # try and err on the side of caution. delay = 10 logger.info("Waiting %d seconds for VM %s to come up.", delay, vm_name) cs.conditional_sleep(delay) logger.info("Booting into distribution installer.") distro_boot.distro_start_installer(vm_config) autostart.autostart_and_wait(vm_name) vm.vm_wait_for_shutdown(vm_name) # Detach disk from VM now or it will be deleted by vm_unregister_del vm.vm_detach_disk(vm_name) vm.vm_unregister_del(vm_name) del conf.vm[vm_name] logger.info("Compacting %s.", base_build_disk) vm.vbm("modifyhd", base_build_disk, "--compact") # This disk will be moved to a new name, and this name will be used for # a new disk next time the script runs. vm.disk_unregister(base_build_disk) logger.info("Base disk created.") logger.info("Moving base disk to:\n\t%s", base_disk_path) if conf.do_build: import shutil shutil.move(base_build_disk, base_disk_path) if conf.wbatch: wbatch.wbatch_rename_disk(os.path.basename(base_build_disk), os.path.basename(base_disk_path)) wbatch.wbatch_end_file() logger.info("Base disk build ends.")