def verify_info(self, params=None): """ verify option is applied to image file correctly """ error_context.context("verify option of converted image", logging.info) image_filename = storage.get_image_filename(params, self.data_dir) info = utils_test.get_image_info(image_filename) avalue = evalue = "" for option in params.objects("option_verified"): avalue = info.get(option) if option == "format": evalue = params.get("image_format") elif option == "lcounts": if params.get("lazy_refcounts") == "on": evalue = "true" elif params.get("lazy_refcounts") == "off": evalue = "false" elif option == "csize": csize = params.get("image_cluster_size") evalue = int(float(utils_misc.normalize_data_size(csize, "B"))) elif option == "sparse_size": if info.get("dsize") < info.get("vsize"): avalue = info.get("dsize") evalue = info.get("vsize") elif option == "compat": evalue = params.get("qcow2_compatible") else: evalue = params.get(option) if avalue is not None and avalue != evalue: msg = "Get wrong %s from image %s!" % (option, image_filename) msg += "Expect: %s, actual: %s" % (evalue, avalue) self.test.fail(msg)
def verify_info(self, params=None): """ verify option is applied to image file correctly """ error_context.context("verify option of converted image", logging.info) image_filename = storage.get_image_filename(params, self.data_dir) info = utils_test.get_image_info(image_filename) avalue = evalue = "" for option in params.objects("option_verified"): avalue = info.get(option) if option == "format": evalue = params.get("image_format") elif option == "lcounts": if params.get("lazy_refcounts") == "on": evalue = "true" elif params.get("lazy_refcounts") == "off": evalue = "false" elif option == "csize": csize = params.get("cluster_size") evalue = int(float(utils_misc.normalize_data_size(csize, "B"))) elif option == "sparse_size": if info.get("dsize") < info.get("vsize"): avalue = info.get("dsize") evalue = info.get("vsize") else: evalue = params.get(option) if avalue is not None and avalue != evalue: msg = "Get wrong %s from image %s!" % (option, image_filename) msg += "Expect: %s, actual: %s" % (evalue, avalue) self.test.fail(msg)
def modify_source(vm_name, target, dst_image): """ Modify domain's configuration to change its disk source """ try: virsh.detach_disk(vm_name, target, extra="--config", ignore_status=False) dst_image_format = utils_test.get_image_info(dst_image)['format'] options = "--config --subdriver %s" % dst_image_format virsh.attach_disk(vm_name, dst_image, target, extra=options, ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError), detail: raise error.TestFail("Modify guest source failed: %s" % detail)
def modify_source(vm_name, target, dst_image): """ Modify domain's configuration to change its disk source """ try: virsh.detach_disk(vm_name, target, extra="--config", ignore_status=False) dst_image_format = utils_test.get_image_info(dst_image)['format'] options = "--config --subdriver %s" % dst_image_format virsh.attach_disk(vm_name, dst_image, target, extra=options, ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError, error.CmdError), detail: raise error.TestFail("Modify guest source failed: %s" % detail)
def run(test, params, env): """ Test qemu-monitor-command blockjobs by migrating with option --copy-storage-all or --copy-storage-inc. """ if not libvirt_version.version_compare(1, 0, 1): raise error.TestNAError("Blockjob functions - " "complete,pause,resume are" "not supported in current libvirt version.") vm = env.get_vm(params.get("main_vm")) cpu_size = int(params.get("cpu_size", "1")) memory_size = int(params.get("memory_size", "1048576")) primary_target = vm.get_first_disk_devices()["target"] file_path, file_size = vm.get_device_size(primary_target) # Convert to Gib file_size = int(file_size) / 1073741824 image_format = utils_test.get_image_info(file_path)["format"] remote_host = params.get("migrate_dest_host", "REMOTE.EXAMPLE") remote_user = params.get("remote_user", "root") remote_passwd = params.get("migrate_dest_pwd", "PASSWORD.EXAMPLE") if remote_host.count("EXAMPLE"): raise error.TestNAError("Config remote or local host first.") # Config ssh autologin for it ssh_key.setup_ssh_key(remote_host, remote_user, remote_passwd, port=22) # Define a new vm with modified cpu/memory new_vm_name = "%s_blockjob" % vm.name if vm.is_alive(): vm.destroy() utlv.define_new_vm(vm.name, new_vm_name) try: set_cpu_memory(new_vm_name, cpu_size, memory_size) vm = libvirt_vm.VM(new_vm_name, vm.params, vm.root_dir, vm.address_cache) except: # Make sure created vm is cleaned up virsh.remove_domain(new_vm_name) raise rdm_params = {"remote_ip": remote_host, "remote_user": remote_user, "remote_pwd": remote_passwd} rdm = utils_test.RemoteDiskManager(rdm_params) try: vm = libvirt_vm.VM(new_vm_name, vm.params, vm.root_dir, vm.address_cache) vm.start() rdm.create_image("file", file_path, file_size, None, None, img_frmt=image_format) logging.debug("Start migration...") copied_migration(vm, params, params.get("qmp_blockjob_type"), primary_target) finally: # Recover created vm if vm.is_alive(): vm.destroy() if vm.name == new_vm_name: vm.undefine() rdm.remove_path("file", file_path) rdm.runner.session.close()
os.remove(clone_image) except error.CmdError, detail: raise error.TestFail("Clean clone guest failed!:%s" % detail) sysprep_type = params.get("sysprep_type", 'clone') sysprep_target = params.get("sysprep_target", 'guest') sysprep_hostname = params.get("sysprep_hostname", 'sysprep_test') vm_name = params.get("main_vm", "virt-tests-vm1") file_system = params.get("sysprep_file_system", "ext3") vm = env.get_vm(vm_name) disks = vm.get_disk_devices() if len(disks): disk = disks.values()[0] image = disk['source'] target = disks.keys()[0] image_info_dict = utils_test.get_image_info(image) if sysprep_type == "sparsify" and image_info_dict['format'] != 'qcow2': raise error.TestNAError("This test case needs qcow2 format image.") else: raise error.TestError("Can not get disk of %s" % vm_name) vt = utils_test.libguestfs.VirtTools(vm, params) fs_type = vt.get_primary_disk_fs_type() if fs_type != file_system: raise error.TestNAError("This test case gets wrong disk file system." "get: %s, expected: %s" % (fs_type, file_system)) # Do some prepare action vm_clone_name = "%s_clone" % vm_name clone_image = "%s_clone.img" % image vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
def run(test, params, env): """ Test migration of multi vms. """ vm_names = params.get("migrate_vms").split() if len(vm_names) < 2: raise exceptions.TestSkipError("No multi vms provided.") # Prepare parameters method = params.get("virsh_migrate_method") jobabort = "yes" == params.get("virsh_migrate_jobabort", "no") options = params.get("virsh_migrate_options", "") status_error = "yes" == params.get("status_error", "no") remote_host = params.get("remote_host", "DEST_HOSTNAME.EXAMPLE.COM") local_host = params.get("local_host", "SOURCE_HOSTNAME.EXAMPLE.COM") host_user = params.get("host_user", "root") host_passwd = params.get("host_password", "PASSWORD") nfs_shared_disk = params.get("nfs_shared_disk", True) migration_type = params.get("virsh_migration_type", "simultaneous") migrate_timeout = int(params.get("virsh_migrate_thread_timeout", 900)) migration_time = int(params.get("virsh_migrate_timeout", 60)) # Params for NFS and SSH setup params["server_ip"] = params.get("migrate_dest_host") params["server_user"] = "******" params["server_pwd"] = params.get("migrate_dest_pwd") params["client_ip"] = params.get("migrate_source_host") params["client_user"] = "******" params["client_pwd"] = params.get("migrate_source_pwd") params["nfs_client_ip"] = params.get("migrate_dest_host") params["nfs_server_ip"] = params.get("migrate_source_host") desturi = libvirt_vm.get_uri_with_transport(transport="ssh", dest_ip=remote_host) srcuri = libvirt_vm.get_uri_with_transport(transport="ssh", dest_ip=local_host) # Don't allow the defaults. if srcuri.count('///') or srcuri.count('EXAMPLE'): raise exceptions.TestSkipError("The srcuri '%s' is invalid" % srcuri) if desturi.count('///') or desturi.count('EXAMPLE'): raise exceptions.TestSkipError("The desturi '%s' is invalid" % desturi) # Config ssh autologin for remote host ssh_key.setup_remote_ssh_key(remote_host, host_user, host_passwd, port=22, public_key="rsa") # Prepare local session and remote session localrunner = remote.RemoteRunner(host=remote_host, username=host_user, password=host_passwd) remoterunner = remote.RemoteRunner(host=remote_host, username=host_user, password=host_passwd) # Configure NFS in remote host if nfs_shared_disk: nfs_client = nfs.NFSClient(params) nfs_client.setup() # Prepare MigrationHelper instance vms = [] for vm_name in vm_names: vm = env.get_vm(vm_name) vms.append(vm) try: option = make_migration_options(method, options, migration_time) # make sure cache=none if "unsafe" not in options: device_target = params.get("virsh_device_target", "sda") for vm in vms: if vm.is_alive(): vm.destroy() for each_vm in vm_names: logging.info("configure cache=none") vmxml = vm_xml.VMXML.new_from_dumpxml(each_vm) device_source = str(vmxml.get_disk_attr(each_vm, device_target, 'source', 'file')) ret_detach = virsh.detach_disk(each_vm, device_target, "--config") status = ret_detach.exit_status output = ret_detach.stdout.strip() logging.info("Status:%s", status) logging.info("Output:\n%s", output) if not ret_detach: raise exceptions.TestError("Detach disks fails") subdriver = utils_test.get_image_info(device_source)['format'] ret_attach = virsh.attach_disk(each_vm, device_source, device_target, "--driver qemu " "--config --cache none " "--subdriver %s" % subdriver) status = ret_attach.exit_status output = ret_attach.stdout.strip() logging.info("Status:%s", status) logging.info("Output:\n%s", output) if not ret_attach: raise exceptions.TestError("Attach disks fails") for vm in vms: if vm.is_dead(): vm.start() vm.wait_for_login() multi_migration(vms, srcuri, desturi, option, migration_type, migrate_timeout, jobabort, lrunner=localrunner, rrunner=remoterunner) except Exception, info: logging.error("Test failed: %s" % info) flag_migration = False
def run(test, params, env): """ Test qemu-monitor-command blockjobs by migrating with option --copy-storage-all or --copy-storage-inc. """ if not libvirt_version.version_compare(1, 0, 1): raise error.TestNAError("Blockjob functions - " "complete,pause,resume are" "not supported in current libvirt version.") vm = env.get_vm(params.get("main_vm")) cpu_size = int(params.get("cpu_size", "1")) memory_size = int(params.get("memory_size", "1048576")) primary_target = vm.get_first_disk_devices()["target"] file_path, file_size = vm.get_device_size(primary_target) # Convert to Gib file_size = int(file_size) / 1073741824 image_format = utils_test.get_image_info(file_path)["format"] remote_host = params.get("migrate_dest_host", "REMOTE.EXAMPLE") remote_user = params.get("remote_user", "root") remote_passwd = params.get("migrate_dest_pwd", "PASSWORD.EXAMPLE") if remote_host.count("EXAMPLE"): raise error.TestNAError("Config remote or local host first.") # Config ssh autologin for it ssh_key.setup_ssh_key(remote_host, remote_user, remote_passwd, port=22) # Define a new vm with modified cpu/memory new_vm_name = "%s_blockjob" % vm.name if vm.is_alive(): vm.destroy() utlv.define_new_vm(vm.name, new_vm_name) try: set_cpu_memory(new_vm_name, cpu_size, memory_size) vm = libvirt_vm.VM(new_vm_name, vm.params, vm.root_dir, vm.address_cache) except: # Make sure created vm is cleaned up virsh.remove_domain(new_vm_name) raise rdm_params = { "remote_ip": remote_host, "remote_user": remote_user, "remote_pwd": remote_passwd } rdm = utils_test.RemoteDiskManager(rdm_params) try: vm = libvirt_vm.VM(new_vm_name, vm.params, vm.root_dir, vm.address_cache) vm.start() rdm.create_image("file", file_path, file_size, None, None, img_frmt=image_format) logging.debug("Start migration...") copied_migration(vm, params, params.get("qmp_blockjob_type"), primary_target) finally: # Recover created vm if vm.is_alive(): vm.destroy() if vm.name == new_vm_name: vm.undefine() rdm.remove_path("file", file_path) rdm.runner.session.close()
exception = False try: # Change the disk of the vm to shared disk if vm.is_alive(): vm.destroy(gracefully=False) devices = vm.get_blk_devices() for device in devices: s_detach = virsh.detach_disk(vm_name, device, "--config", debug=True) if not s_detach: logging.error("Detach vda failed before test.") subdriver = utils_test.get_image_info(shared_storage)['format'] extra_attach = ("--config --driver qemu --subdriver %s --cache %s" % (subdriver, disk_cache)) s_attach = virsh.attach_disk(vm_name, shared_storage, "vda", extra_attach, debug=True) if s_attach.exit_status != 0: logging.error("Attach vda failed before test.") vm.start() vm.wait_for_login() # Confirm VM can be accessed through network. time.sleep(delay)
if options.count("unsafe") and disk_cache != "none": unsafe_test = True exception = False try: # Change the disk of the vm to shared disk if vm.is_alive(): vm.destroy(gracefully=False) devices = vm.get_blk_devices() for device in devices: s_detach = virsh.detach_disk(vm_name, device, "--config", debug=True) if not s_detach: logging.error("Detach vda failed before test.") subdriver = utils_test.get_image_info(shared_storage)['format'] extra_attach = ("--config --driver qemu --subdriver %s --cache %s" % (subdriver, disk_cache)) s_attach = virsh.attach_disk(vm_name, shared_storage, "vda", extra_attach, debug=True) if s_attach.exit_status != 0: logging.error("Attach vda failed before test.") # Attach a scsi device for special testcases if attach_scsi_disk: shared_dir = os.path.dirname(shared_storage) scsi_disk = "%s/scsi_test.img" % shared_dir utils.run("qemu-img create -f qcow2 %s 100M" % scsi_disk) s_attach = virsh.attach_disk(vm_name, scsi_disk, "sdb", extra_attach, debug=True) if s_attach.exit_status != 0:
def run(test, params, env): """ Test migration of multi vms. """ vm_names = params.get("migrate_vms").split() if len(vm_names) < 2: raise exceptions.TestSkipError("No multi vms provided.") # Prepare parameters method = params.get("virsh_migrate_method") jobabort = "yes" == params.get("virsh_migrate_jobabort", "no") options = params.get("virsh_migrate_options", "") status_error = "yes" == params.get("status_error", "no") remote_host = params.get("remote_host", "DEST_HOSTNAME.EXAMPLE.COM") local_host = params.get("local_host", "SOURCE_HOSTNAME.EXAMPLE.COM") host_user = params.get("host_user", "root") host_passwd = params.get("host_password", "PASSWORD") nfs_shared_disk = params.get("nfs_shared_disk", True) migration_type = params.get("virsh_migration_type", "simultaneous") migrate_timeout = int(params.get("virsh_migrate_thread_timeout", 900)) migration_time = int(params.get("virsh_migrate_timeout", 60)) # Params for NFS and SSH setup params["server_ip"] = params.get("migrate_dest_host") params["server_user"] = "******" params["server_pwd"] = params.get("migrate_dest_pwd") params["client_ip"] = params.get("migrate_source_host") params["client_user"] = "******" params["client_pwd"] = params.get("migrate_source_pwd") params["nfs_client_ip"] = params.get("migrate_dest_host") params["nfs_server_ip"] = params.get("migrate_source_host") desturi = libvirt_vm.get_uri_with_transport(transport="ssh", dest_ip=remote_host) srcuri = libvirt_vm.get_uri_with_transport(transport="ssh", dest_ip=local_host) # Don't allow the defaults. if srcuri.count('///') or srcuri.count('EXAMPLE'): raise exceptions.TestSkipError("The srcuri '%s' is invalid" % srcuri) if desturi.count('///') or desturi.count('EXAMPLE'): raise exceptions.TestSkipError("The desturi '%s' is invalid" % desturi) # Config ssh autologin for remote host ssh_key.setup_remote_ssh_key(remote_host, host_user, host_passwd, port=22, public_key="rsa") # Prepare local session and remote session localrunner = remote.RemoteRunner(host=remote_host, username=host_user, password=host_passwd) remoterunner = remote.RemoteRunner(host=remote_host, username=host_user, password=host_passwd) # Configure NFS in remote host if nfs_shared_disk: nfs_client = nfs.NFSClient(params) nfs_client.setup() # Prepare MigrationHelper instance vms = [] for vm_name in vm_names: vm = env.get_vm(vm_name) vms.append(vm) try: option = make_migration_options(method, options, migration_time) # make sure cache=none if "unsafe" not in options: device_target = params.get("virsh_device_target", "sda") for vm in vms: if vm.is_alive(): vm.destroy() for each_vm in vm_names: logging.info("configure cache=none") vmxml = vm_xml.VMXML.new_from_dumpxml(each_vm) device_source = str( vmxml.get_disk_attr(each_vm, device_target, 'source', 'file')) ret_detach = virsh.detach_disk(each_vm, device_target, "--config") status = ret_detach.exit_status output = ret_detach.stdout.strip() logging.info("Status:%s", status) logging.info("Output:\n%s", output) if not ret_detach: raise exceptions.TestError("Detach disks fails") subdriver = utils_test.get_image_info(device_source)['format'] ret_attach = virsh.attach_disk( each_vm, device_source, device_target, "--driver qemu " "--config --cache none " "--subdriver %s" % subdriver) status = ret_attach.exit_status output = ret_attach.stdout.strip() logging.info("Status:%s", status) logging.info("Output:\n%s", output) if not ret_attach: raise exceptions.TestError("Attach disks fails") for vm in vms: if vm.is_dead(): vm.start() vm.wait_for_login() multi_migration(vms, srcuri, desturi, option, migration_type, migrate_timeout, jobabort, lrunner=localrunner, rrunner=remoterunner, status_error=status_error) except Exception as info: logging.error("Test failed: %s" % info) flag_migration = False # NFS cleanup if nfs_shared_disk: logging.info("NFS cleanup") nfs_client.cleanup(ssh_auto_recover=False) localrunner.session.close() remoterunner.session.close() if not (ret_migration or flag_migration): if not status_error: raise exceptions.TestFail("Migration test failed") if not ret_jobabort: if not status_error: raise exceptions.TestFail("Abort migration failed") if not ret_downtime_tolerable: raise exceptions.TestFail("Downtime during migration is intolerable")
def run(test, params, env): """ Test the command virt-sysprep """ def prepare_action(vm): """ Do some actions before testing: Touch new file in "/var/log" and "/var/mail/" etc. """ global o_ssh if vm.is_dead(): vm.start() try: session = vm.wait_for_login() # Create tmp file and modify hostname session.cmd("touch /var/log/tmp.log") session.cmd("touch /var/mail/tmp") tmp_hostname = "%stmp" % sysprep_hostname session.cmd("hostname %s" % tmp_hostname) o_ssh = session.cmd_output("cd /etc/ssh && cat ssh_host_key.pub") # Confirm the file/hostname has been created/modified log_out = session.cmd_output("cd /var/log/ && ls | grep tmp.log") mail_out = session.cmd_output("cd /var/mail && ls | grep tmp") hname_out = session.cmd_output("hostname") if (not log_out.strip() or not mail_out.strip() or hname_out.strip() != tmp_hostname): logging.debug("log:%s\nmail:%s\nhostname:%s" % (log_out, mail_out, hname_out)) test.fail("Prepare action failed!") session.close() vm.destroy() except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: if "session" in dir(): session.close() test.fail("Prepare action failed: %s" % detail) def sysprep_action(vm_name, image_name, sysprep_target, hostname): """ Execute "virt-sysprep" command """ options = "" if hostname: options = "--hostname %s " % hostname if sysprep_target == "guest": disk_or_domain = vm_name else: disk_or_domain = image_name lgf.virt_sysprep_cmd(disk_or_domain, options, ignore_status=False) def modify_source(vm_name, target, dst_image): """ Modify domain's configuration to change its disk source """ try: virsh.detach_disk(vm_name, target, extra="--config", ignore_status=False) dst_image_format = utils_test.get_image_info(dst_image)['format'] options = "--config --subdriver %s" % dst_image_format virsh.attach_disk(vm_name, dst_image, target, extra=options, ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError, process.CmdError) as detail: test.fail("Modify guest source failed: %s" % detail) def modify_network(vm_name, first_nic): """ Modify domain's interface to make sure domain can be login. """ iface_type = first_nic.type_name iface_source = first_nic.source.get('bridge') mac_address = first_nic.mac_address try: virsh.detach_interface(vm_name, "--type=%s --config" % iface_type, ignore_status=False) virsh.attach_interface(vm_name, "--type=%s --source %s --mac %s --config" % (iface_type, iface_source, mac_address), ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: test.fail("Modify network failed:%s" % detail) def result_confirm(vm): """ Confirm tmp file has been cleaned up, hostname has been changed, etc. """ global o_ssh try: if vm.is_dead(): vm.start() session = vm.wait_for_login(nic_index=0) log_out = session.cmd_output("cd /var/log/ && ls | grep tmp.log") mail_out = session.cmd_output("cd /var/mail && ls | grep tmp") hname_out = session.cmd_output("hostname") ssh_out = session.cmd_output("cd /etc/ssh && cat ssh_host_key.pub") session.close() vm.destroy() if (log_out.strip() or mail_out.strip() or hname_out.strip() != sysprep_hostname or ssh_out.strip() == o_ssh.strip()): logging.debug("log: %s\nmail:%s\nhostname:%s\nsshkey:%s" % (log_out, mail_out, hname_out, ssh_out)) return False return True except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: logging.error(str(detail)) if "session" in dir(): session.close() return False def clean_clone_vm(): """ Clean up cloned domain. """ try: if virsh.domain_exists(vm_clone_name): if virsh.is_alive(vm_clone_name): virsh.destroy(vm_clone_name, ignore_status=False) virsh.undefine(vm_clone_name, ignore_status=False) if os.path.exists(clone_image): os.remove(clone_image) except process.CmdError as detail: test.fail("Clean clone guest failed!:%s" % detail) sysprep_type = params.get("sysprep_type", 'clone') sysprep_target = params.get("sysprep_target", 'guest') sysprep_hostname = params.get("sysprep_hostname", 'sysprep_test') vm_name = params.get("main_vm", "avocado-vt-vm1") file_system = params.get("sysprep_file_system", "ext3") vm = env.get_vm(vm_name) disks = vm.get_disk_devices() if len(disks): disk = list(disks.values())[0] image = disk['source'] target = list(disks.keys())[0] image_info_dict = utils_test.get_image_info(image) if sysprep_type == "sparsify" and image_info_dict['format'] != 'qcow2': test.cancel("This test case needs qcow2 format image.") else: test.error("Can not get disk of %s" % vm_name) vt = utils_test.libguestfs.VirtTools(vm, params) fs_type = vt.get_primary_disk_fs_type() if fs_type != file_system: test.cancel("This test case gets wrong disk file system." "get: %s, expected: %s" % (fs_type, file_system)) # Do some prepare action vm_clone_name = "%s_clone" % vm_name clone_image = "%s_clone.img" % image vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) first_nic = vmxml.get_devices(device_type="interface")[0] clean_clone_vm() # Clone guest to guest_clone dargs = {} dargs['files'] = [clone_image] dargs['ignore_status'] = True clone_result = lgf.virt_clone_cmd(vm_name, newname=vm_clone_name, **dargs) if clone_result.exit_status: test.fail("virt-clone failed:%s" % clone_result.stderr.strip()) try: # Modify network to make sure the clone guest can be logging. modify_network(vm_clone_name, first_nic) new_vm = libvirt_vm.VM(vm_clone_name, params, vm.root_dir, vm.address_cache) prepare_action(new_vm) test_image = clone_image if sysprep_type == "resize": img_size = image_info_dict['vsize'] / 1024 / 1024 / 1024 resize_image = "%s_resize.img" % clone_image cmd = "qemu-img create -f raw %s %dG" % (resize_image, (img_size + 1)) process.run(cmd, shell=True) lgf.virt_resize_cmd(clone_image, resize_image, timeout=600, debug=True) modify_source(vm_clone_name, target, resize_image) test_image = resize_image elif sysprep_type == "sparsify": sparsify_image = "%s_sparsify.img" % clone_image lgf.virt_sparsify_cmd(clone_image, sparsify_image, compress=True, format=image_info_dict['format'], timeout=600) modify_source(vm_clone_name, target, sparsify_image) test_image = sparsify_image sysprep_action(vm_clone_name, test_image, sysprep_target, sysprep_hostname) if not result_confirm(new_vm): test.fail("Test Failed!") finally: clean_clone_vm() if "resize_image" in dir(): if os.path.exists(resize_image): os.remove(resize_image) if "sparsify_image" in dir(): if os.path.exists(sparsify_image): os.remove(sparsify_image)
def run(test, params, env): """ Test the command virt-sysprep """ def prepare_action(vm): """ Do some actions before testing: Touch new file in "/var/log" and "/var/mail/" etc. """ global o_ssh if vm.is_dead(): vm.start() try: session = vm.wait_for_login() # Create tmp file and modify hostname session.cmd("touch /var/log/tmp.log") session.cmd("touch /var/mail/tmp") tmp_hostname = "%stmp" % sysprep_hostname session.cmd("hostname %s" % tmp_hostname) o_ssh = session.cmd_output("cd /etc/ssh && cat ssh_host_key.pub") # Confirm the file/hostname has been created/modified log_out = session.cmd_output("cd /var/log/ && ls | grep tmp.log") mail_out = session.cmd_output("cd /var/mail && ls | grep tmp") hname_out = session.cmd_output("hostname") if (not log_out.strip() or not mail_out.strip() or hname_out.strip() != tmp_hostname): logging.debug("log:%s\nmail:%s\nhostname:%s" % (log_out, mail_out, hname_out)) test.fail("Prepare action failed!") session.close() vm.destroy() except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: if "session" in dir(): session.close() test.fail("Prepare action failed: %s" % detail) def sysprep_action(vm_name, image_name, sysprep_target, hostname): """ Execute "virt-sysprep" command """ options = "" if hostname: options = "--hostname %s " % hostname if sysprep_target == "guest": disk_or_domain = vm_name else: disk_or_domain = image_name lgf.virt_sysprep_cmd(disk_or_domain, options, ignore_status=False) def modify_source(vm_name, target, dst_image): """ Modify domain's configuration to change its disk source """ try: virsh.detach_disk(vm_name, target, extra="--config", ignore_status=False) dst_image_format = utils_test.get_image_info(dst_image)['format'] options = "--config --subdriver %s" % dst_image_format virsh.attach_disk(vm_name, dst_image, target, extra=options, ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError, process.CmdError) as detail: test.fail("Modify guest source failed: %s" % detail) def modify_network(vm_name, first_nic): """ Modify domain's interface to make sure domain can be login. """ iface_type = first_nic.type_name iface_source = first_nic.source.get('bridge') mac_address = first_nic.mac_address try: virsh.detach_interface(vm_name, "--type=%s --config" % iface_type, ignore_status=False) virsh.attach_interface(vm_name, "--type=%s --source %s --mac %s --config" % (iface_type, iface_source, mac_address), ignore_status=False) except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: test.fail("Modify network failed:%s" % detail) def result_confirm(vm): """ Confirm tmp file has been cleaned up, hostname has been changed, etc. """ global o_ssh try: if vm.is_dead(): vm.start() session = vm.wait_for_login(nic_index=0) log_out = session.cmd_output("cd /var/log/ && ls | grep tmp.log") mail_out = session.cmd_output("cd /var/mail && ls | grep tmp") hname_out = session.cmd_output("hostname") ssh_out = session.cmd_output("cd /etc/ssh && cat ssh_host_key.pub") session.close() vm.destroy() if (log_out.strip() or mail_out.strip() or hname_out.strip() != sysprep_hostname or ssh_out.strip() == o_ssh.strip()): logging.debug("log: %s\nmail:%s\nhostname:%s\nsshkey:%s" % (log_out, mail_out, hname_out, ssh_out)) return False return True except (remote.LoginError, virt_vm.VMError, aexpect.ShellError) as detail: logging.error(str(detail)) if "session" in dir(): session.close() return False def clean_clone_vm(): """ Clean up cloned domain. """ try: if virsh.domain_exists(vm_clone_name): if virsh.is_alive(vm_clone_name): virsh.destroy(vm_clone_name, ignore_status=False) virsh.undefine(vm_clone_name, ignore_status=False) if os.path.exists(clone_image): os.remove(clone_image) except process.CmdError as detail: test.fail("Clean clone guest failed!:%s" % detail) sysprep_type = params.get("sysprep_type", 'clone') sysprep_target = params.get("sysprep_target", 'guest') sysprep_hostname = params.get("sysprep_hostname", 'sysprep_test') vm_name = params.get("main_vm", "avocado-vt-vm1") file_system = params.get("sysprep_file_system", "ext3") vm = env.get_vm(vm_name) disks = vm.get_disk_devices() if len(disks): disk = list(disks.values())[0] image = disk['source'] target = list(disks.keys())[0] image_info_dict = utils_test.get_image_info(image) if sysprep_type == "sparsify" and image_info_dict['format'] != 'qcow2': test.cancel("This test case needs qcow2 format image.") else: test.error("Can not get disk of %s" % vm_name) vt = utils_test.libguestfs.VirtTools(vm, params) fs_type = vt.get_primary_disk_fs_type() if fs_type != file_system: test.cancel("This test case gets wrong disk file system." "get: %s, expected: %s" % (fs_type, file_system)) # Do some prepare action vm_clone_name = "%s_clone" % vm_name clone_image = "%s_clone.img" % image vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) first_nic = vmxml.get_devices(device_type="interface")[0] clean_clone_vm() # Clone guest to guest_clone dargs = {} dargs['files'] = [clone_image] dargs['ignore_status'] = True clone_result = lgf.virt_clone_cmd(vm_name, newname=vm_clone_name, **dargs) if clone_result.exit_status: test.fail("virt-clone failed:%s" % clone_result.stderr.strip()) try: # Modify network to make sure the clone guest can be logging. modify_network(vm_clone_name, first_nic) new_vm = libvirt_vm.VM(vm_clone_name, params, vm.root_dir, vm.address_cache) prepare_action(new_vm) test_image = clone_image if sysprep_type == "resize": img_size = image_info_dict['vsize'] / 1024 / 1024 / 1024 resize_image = "%s_resize.img" % clone_image cmd = "qemu-img create -f raw %s %dG" % (resize_image, (img_size + 1)) process.run(cmd, shell=True) lgf.virt_resize_cmd(clone_image, resize_image, timeout=600, debug=True) modify_source(vm_clone_name, target, resize_image) test_image = resize_image elif sysprep_type == "sparsify": sparsify_image = "%s_sparsify.img" % clone_image lgf.virt_sparsify_cmd(clone_image, sparsify_image, compress=True, format=image_info_dict['format'], timeout=600) modify_source(vm_clone_name, target, sparsify_image) test_image = sparsify_image sysprep_action(vm_clone_name, test_image, sysprep_target, sysprep_hostname) if not result_confirm(new_vm): test.fail("Test Falied!") finally: clean_clone_vm() if "resize_image" in dir(): if os.path.exists(resize_image): os.remove(resize_image) if "sparsify_image" in dir(): if os.path.exists(sparsify_image): os.remove(sparsify_image)