def run(test, params, env): """ Convert a remote vm to local libvirt(KVM). """ for v in list(params.values()): if "V2V_EXAMPLE" in v: raise exceptions.TestSkipError("Please set real value for %s" % v) vm_name = params.get("main_vm") source_user = params.get("username", "root") xen_ip = params.get("xen_hostname") xen_pwd = params.get("xen_pwd") vpx_ip = params.get("vpx_hostname") vpx_pwd = params.get("vpx_pwd") vpx_pwd_file = params.get("vpx_passwd_file") vpx_dc = params.get("vpx_dc") esx_ip = params.get("esx_hostname") hypervisor = params.get("hypervisor") input_mode = params.get("input_mode") target = params.get("target") v2v_opts = params.get("v2v_opts") # Prepare step for different hypervisor if hypervisor == "esx": source_ip = vpx_ip source_pwd = vpx_pwd # Create password file to access ESX hypervisor with open(vpx_pwd_file, 'w') as f: f.write(vpx_pwd) elif hypervisor == "xen": source_ip = xen_ip source_pwd = xen_pwd # Set up ssh access using ssh-agent and authorized_keys ssh_key.setup_ssh_key(source_ip, source_user, source_pwd) try: utils_misc.add_identities_into_ssh_agent() except: process.run("ssh-agent -k") raise exceptions.TestError("Fail to setup ssh-agent") else: raise exceptions.TestSkipError("Unspported hypervisor: %s" % hypervisor) # Create libvirt URI for the source node v2v_uri = utils_v2v.Uri(hypervisor) remote_uri = v2v_uri.get_uri(source_ip, vpx_dc, esx_ip) logging.debug("Remote host uri for converting: %s", remote_uri) # Make sure the VM exist before convert virsh_dargs = { 'uri': remote_uri, 'remote_ip': source_ip, 'remote_user': source_user, 'remote_pwd': source_pwd, 'debug': True } remote_virsh = virsh.VirshPersistent(**virsh_dargs) try: if not remote_virsh.domain_exists(vm_name): raise exceptions.TestError("VM '%s' not exist" % vm_name) finally: remote_virsh.close_session() # Prepare libvirt storage pool pool_type = params.get("pool_type") pool_name = params.get("pool_name") pool_target = params.get("pool_target") libvirt_pool = utlv.PoolVolumeTest(test, params) libvirt_pool.pre_pool(pool_name, pool_type, pool_target, '') # Preapre libvirt virtual network network = params.get("network") net_kwargs = { 'net_name': network, 'address': params.get('network_addr'), 'dhcp_start': params.get('network_dhcp_start'), 'dhcp_end': params.get('network_dhcp_end') } libvirt_net = utlv.LibvirtNetwork('vnet', **net_kwargs) net_info = virsh.net_info(network).stdout.strip() bridge = re.search(r'Bridge:\s+(\S+)', net_info).group(1) params['netdst'] = bridge # Maintain a single params for v2v to avoid duplicate parameters v2v_params = { 'target': target, 'hypervisor': hypervisor, 'main_vm': vm_name, 'input_mode': input_mode, 'network': network, 'bridge': bridge, 'storage': pool_name, 'hostname': source_ip } if vpx_dc: v2v_params.update({"vpx_dc": vpx_dc}) if esx_ip: v2v_params.update({"esx_ip": esx_ip}) if v2v_opts: v2v_params.update({"v2v_opts": v2v_opts}) # Set libguestfs environment if hypervisor == 'xen': os.environ['LIBGUESTFS_BACKEND'] = 'direct' try: # Execute virt-v2v command ret = utils_v2v.v2v_cmd(v2v_params) logging.debug("virt-v2v verbose messages:\n%s", ret) if ret.exit_status != 0: raise exceptions.TestFail("Convert VM failed") logging.debug("XML info:\n%s", virsh.dumpxml(vm_name)) vm = env.create_vm("libvirt", "libvirt", vm_name, params, test.bindir) # Win10 is not supported by some cpu model, # need to modify to 'host-model' if params.get('os_version') in ['win10', 'win2016']: logging.info('Set cpu mode to "host-model" for win10 and win2016') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) cpu_xml = vm_xml.VMCPUXML() cpu_xml.mode = 'host-model' cpu_xml.fallback = 'allow' vmxml['cpu'] = cpu_xml vmxml.sync() vm.start() # Check all checkpoints after convert vmchecker = VMChecker(test, params, env) ret = vmchecker.run() if len(ret) == 0: logging.info("All checkpoints passed") else: raise exceptions.TestFail("%d checkpoints failed: %s" % (len(ret), ret)) finally: vmcheck = utils_v2v.VMCheck(test, params, env) vmcheck.cleanup() utils_v2v.cleanup_constant_files(params) if hypervisor == "xen": process.run("ssh-agent -k") # Clean libvirt VM virsh.remove_domain(vm_name) # Clean libvirt pool if libvirt_pool: libvirt_pool.cleanup_pool(pool_name, pool_type, pool_target, '') # Clean libvirt network if libvirt_net: libvirt_net.cleanup()
def run(test, params, env): """ Test command: virsh net-event 1. Prepare a new network. 2. Running virsh net-event with different options, and start/stop the network if needed, then check the output of net-event. 3. Clean the environment. """ prepare_net = "yes" == params.get("prepare_net", "yes") net_addr = params.get("net_addr") net_name = params.get("net_name") net_event_list = "yes" == params.get("net_event_list", "no") net_event_loop = "yes" == params.get("net_event_loop", "no") net_event_name = params.get("net_event_name") net_event_timeout = params.get("net_event_timeout") net_event_amount = int(params.get("net_event_amount", 1)) status_error = "yes" == params.get("status_error", "no") net_event_option = params.get("net_event_option", "") virsh_dargs = {'debug': True, 'ignore_status': True} net_event_interrupt = False libv_net = None expected_event_list = [] virsh_session = aexpect.ShellSession(virsh.VIRSH_EXEC, auto_close=True) def trigger_net_event(event_amount=1): """ Trigger network start/stop actions in event_number times """ i = event_amount // 2 event_list = [] try: while i > 0: virsh.net_start(net_name, **virsh_dargs) event_list.append("Started") virsh.net_destroy(net_name, **virsh_dargs) event_list.append("Stopped") i -= 1 if event_amount % 2: virsh.net_start(net_name, **virsh_dargs) event_list.append("Started") finally: return event_list def check_output(output, expected_event_list): """ Check received net-event in output. :param output: The virsh shell output, such as: Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands 'quit' to quit virsh # event 'lifecycle' for network virttest_net: Started events received: 1 virsh # : expected_event_list: A list of expected events ['Started', 'Stopped', ..] """ event_match_str = "event 'lifecycle' for network %s: %s" if net_event_interrupt: output = output.strip().splitlines()[5:] else: output = output.strip().splitlines()[5:-2] output = [o.replace("virsh #", "").strip() for o in output] # Both order and content should match index = 0 for event_str in expected_event_list: match_str = event_match_str % (net_name, event_str) logging.debug("Expected output: %s", match_str) logging.debug("Actual output: %s", output[index]) if not output[index].count(match_str): test.fail("Event received not match") index += 1 try: if prepare_net: libv_net = utlv.LibvirtNetwork("vnet", address=net_addr, net_name=net_name, persistent=True) # Destroy the network if virsh.net_state_dict()[net_name]['active']: virsh.net_destroy(net_name) logging.info("Defined network %s", net_name) if net_event_list: net_event_option += " --list" if net_event_loop: net_event_option += " --loop" if not status_error and not net_event_list: # Assemble the net-event command net_event_cmd = "net-event %s" % net_event_option if net_name: net_event_cmd += " --network %s" % net_name if net_event_name: net_event_cmd += " --event %s" % net_event_name if net_event_timeout: net_event_cmd += " --timeout %s" % net_event_timeout if not status_error: net_event_timeout = int(net_event_timeout) # Run the command in a new virsh session, then waiting for # 'lifecycle' events logging.info("Sending '%s' to virsh shell", net_event_cmd) virsh_session.sendline(net_event_cmd) else: result = virsh.net_event(network=net_name, event=net_event_name, event_timeout=net_event_timeout, options=net_event_option, **virsh_dargs) utlv.check_exit_status(result, status_error) if not status_error: # Verify 'lifecycle' events if not net_event_list and net_event_name == 'lifecycle': expected_event_list = trigger_net_event(net_event_amount) if net_event_timeout: # Make sure net-event will timeout on time time.sleep(net_event_timeout) elif net_event_loop: virsh_session.send_ctrl("^C") net_event_interrupt = True ret_output = virsh_session.get_stripped_output() check_output(ret_output, expected_event_list) finally: virsh_session.close() if libv_net: libv_net.cleanup()
def run(test, params, env): """ Convert a remote vm to local libvirt(KVM). """ for v in list(params.values()): if "V2V_EXAMPLE" in v: raise exceptions.TestSkipError("Please set real value for %s" % v) enable_legacy_policy = params_get(params, "enable_legacy_policy") == 'yes' vm_name = params.get("main_vm") source_user = params.get("username", "root") xen_ip = params.get("xen_hostname") xen_pwd = params.get("xen_pwd") vpx_ip = params.get("vpx_hostname") vpx_pwd = params.get("vpx_pwd") vpx_pwd_file = params.get("vpx_passwd_file") vpx_dc = params.get("vpx_dc") esx_ip = params.get("esx_hostname") hypervisor = params.get("hypervisor") input_mode = params.get("input_mode") target = params.get("target") v2v_opts = '-v -x' if params.get('v2v_debug', 'on') == 'on' else '' if params.get('v2v_opts'): # Add a blank by force v2v_opts += ' ' + params.get("v2v_opts") # For VDDK input_transport = params.get("input_transport") vddk_libdir = params.get('vddk_libdir') # nfs mount source vddk_libdir_src = params.get('vddk_libdir_src') vddk_thumbprint = params.get('vddk_thumbprint') source_pwd = None # Prepare step for different hypervisor if enable_legacy_policy: update_crypto_policy("LEGACY") if hypervisor == "esx": source_ip = vpx_ip source_pwd = vpx_pwd # Create password file to access ESX hypervisor with open(vpx_pwd_file, 'w') as f: f.write(vpx_pwd) elif hypervisor == "xen": source_ip = xen_ip source_pwd = xen_pwd # Set up ssh access using ssh-agent and authorized_keys xen_pubkey, xen_session = utils_v2v.v2v_setup_ssh_key(source_ip, source_user, source_pwd, auto_close=False) try: utils_misc.add_identities_into_ssh_agent() except Exception: process.run("ssh-agent -k") raise exceptions.TestError("Fail to setup ssh-agent") else: raise exceptions.TestSkipError("Unsupported hypervisor: %s" % hypervisor) # Create libvirt URI for the source node v2v_uri = utils_v2v.Uri(hypervisor) remote_uri = v2v_uri.get_uri(source_ip, vpx_dc, esx_ip) LOG.debug("Remote host uri for converting: %s", remote_uri) # Make sure the VM exist before convert virsh_dargs = { 'uri': remote_uri, 'remote_ip': source_ip, 'remote_user': source_user, 'remote_pwd': source_pwd, 'auto_close': True, 'debug': True } remote_virsh = virsh.VirshPersistent(**virsh_dargs) try: if not remote_virsh.domain_exists(vm_name): raise exceptions.TestError("VM '%s' not exist" % vm_name) finally: remote_virsh.close_session() # Prepare libvirt storage pool pool_type = params.get("pool_type") pool_name = params.get("pool_name") pool_target = params.get("pool_target") libvirt_pool = utlv.PoolVolumeTest(test, params) libvirt_pool.pre_pool(pool_name, pool_type, pool_target, '') # Prepare libvirt virtual network network = params.get("network") net_kwargs = { 'net_name': network, 'address': params.get('network_addr'), 'dhcp_start': params.get('network_dhcp_start'), 'dhcp_end': params.get('network_dhcp_end') } libvirt_net = utlv.LibvirtNetwork('vnet', **net_kwargs) net_info = virsh.net_info(network).stdout.strip() bridge = re.search(r'Bridge:\s+(\S+)', net_info).group(1) params['netdst'] = bridge # Maintain a single params for v2v to avoid duplicate parameters v2v_params = { 'target': target, 'hypervisor': hypervisor, 'main_vm': vm_name, 'input_mode': input_mode, 'network': network, 'bridge': bridge, 'os_pool': pool_name, 'hostname': source_ip, 'password': source_pwd, 'input_transport': input_transport, 'vcenter_host': vpx_ip, 'vcenter_password': vpx_pwd, 'vddk_thumbprint': vddk_thumbprint, 'vddk_libdir': vddk_libdir, 'vddk_libdir_src': vddk_libdir_src, 'params': params } if vpx_dc: v2v_params.update({"vpx_dc": vpx_dc}) if esx_ip: v2v_params.update({"esx_ip": esx_ip}) if v2v_opts: v2v_params.update({"v2v_opts": v2v_opts}) # Set libguestfs environment if hypervisor == 'xen': os.environ['LIBGUESTFS_BACKEND'] = 'direct' try: # Execute virt-v2v command ret = utils_v2v.v2v_cmd(v2v_params) if ret.exit_status != 0: raise exceptions.TestFail("Convert VM failed") LOG.debug("XML info:\n%s", virsh.dumpxml(vm_name)) vm = env.create_vm("libvirt", "libvirt", vm_name, params, test.bindir) # Win10 is not supported by some cpu model, # need to modify to 'host-model' unsupport_list = ['win10', 'win2016', 'win2019'] if params.get('os_version') in unsupport_list: LOG.info('Set cpu mode to "host-model" for %s.', unsupport_list) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) cpu_xml = vm_xml.VMCPUXML() cpu_xml.mode = 'host-model' cpu_xml.fallback = 'allow' vmxml['cpu'] = cpu_xml vmxml.sync() vm.start() # Check all checkpoints after convert vmchecker = VMChecker(test, params, env) # Cannot do "params['vmchecker'] = vmchecker" if vm was to_libvirt, # or exception 'Fatal Python error: Cannot recover from stack overflow' # will happen. Not sure how it happens now, if somebody knows about it, # Please help to fix it. # # The exception happens at: # avocado/utils/stacktrace.py, line 98 in analyze_unpickable_item # <FIXIT> in future. try: ret = vmchecker.run() finally: vmchecker.cleanup() if len(ret) == 0: LOG.info("All checkpoints passed") else: raise exceptions.TestFail("%d checkpoints failed: %s" % (len(ret), ret)) finally: utils_v2v.cleanup_constant_files(params) if enable_legacy_policy: update_crypto_policy() if hypervisor == "xen": utils_v2v.v2v_setup_ssh_key_cleanup(xen_session, xen_pubkey) process.run("ssh-agent -k") # Clean libvirt VM virsh.remove_domain(vm_name) # Clean libvirt pool if libvirt_pool: libvirt_pool.cleanup_pool(pool_name, pool_type, pool_target, '') # Clean libvirt network if libvirt_net: libvirt_net.cleanup()