def check_emulatorpin(params, test): """ Check emulator affinity :params: the parameter dictionary """ dicts = {} vm = params.get("vm") vm_name = params.get("main_vm") cpu_list = params.get("cpu_list") cgconfig = params.get("cgconfig", "on") options = params.get("emulatorpin_options") result = virsh.emulatorpin(vm_name, debug=True) cmd_output = result.stdout.strip().splitlines() logging.debug(cmd_output) # Parsing command output and putting them into python dictionary. for l in cmd_output[2:]: k, v = l.split(':') dicts[k.strip()] = v.strip() logging.debug(dicts) emulator_from_cmd = dicts['*'] emulatorpin_from_xml = "" # To change a running guest with 'config' option, which will affect # next boot, if don't shutdown the guest, we need to run virsh dumpxml # with 'inactive' option to get guest XML changes. if options == "config" and vm and not vm.is_alive(): emulatorpin_from_xml = \ vm_xml.VMXML().new_from_dumpxml(vm_name, "--inactive").cputune.emulatorpin else: emulatorpin_from_xml = \ vm_xml.VMXML().new_from_dumpxml(vm_name).cputune.emulatorpin # To get guest corresponding emulator/cpuset.cpus value # from cpuset controller of the cgroup. if cgconfig == "on" and vm and vm.is_alive(): emulatorpin_from_cgroup = get_emulatorpin_from_cgroup(params, test) logging.debug("The emulatorpin value from " "cgroup: %s", emulatorpin_from_cgroup) # To check specified cpulist value with virsh command output # and/or cpuset.cpus from cpuset controller of the cgroup. if cpu_list: if vm and vm.is_alive() and options != "config": if (cpu_list != cpus_parser(emulator_from_cmd)) or \ (cpu_list != cpus_parser(emulatorpin_from_cgroup)): logging.error("To expect emulatorpin %s: %s", cpu_list, emulator_from_cmd) return False else: if cpu_list != cpus_parser(emulatorpin_from_xml): logging.error("To expect emulatorpin %s: %s", cpu_list, emulatorpin_from_xml) return False return True
def container_xml_generator(): """ Generate container xml """ vmxml = vm_xml.VMXML(dom_type) vmxml.vm_name = vm_name vmxml.max_mem = max_mem vmxml.current_mem = cur_mem vmxml.vcpu = vcpu osxml = vmxml.os osxml.type = os_type osxml.arch = os_arch osxml.init = os_init vmxml.os = osxml # Generate emulator emulator = Emulator() emulator.path = emulator_path # Generate console console = Console() # Add emulator and console in devices devices = vm_xml.VMXMLDevices() devices.append(emulator) devices.append(console) logging.debug("device is %s", devices) vmxml.set_devices(devices) return vmxml
def run(test, params, env): """ Test domiftune tuning 1) Positive testing 1.1) get the current domiftune parameters for a running guest 1.2) set the current domiftune parameters for a running guest 2) Negative testing 2.1) get domiftune parameters 2.2) set domiftune parameters """ # Run test case vm_name = params.get("main_vm") vm = env.get_vm(vm_name) status_error = params.get("status_error", "no") start_vm = params.get("start_vm", "yes") change_parameters = params.get("change_parameters", "no") interface_ref = params.get("interface_ref", "name") interface = [] if vm and not vm.is_alive(): vm.start() if vm and vm.is_alive(): virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) interface = virt_xml_obj.get_iface_dev(vm_name) if_mac = interface[0] # Get interface name vmxml = virt_xml_obj.new_from_dumpxml(vm_name) if_node = vmxml.get_iface_all().get(if_mac) if_name = if_node.find('target').get('dev') if interface_ref == "name": interface = if_name if interface_ref == "mac": interface = if_mac logging.debug("the interface is %s", interface) test_dict = dict(params) test_dict['vm'] = vm if interface: test_dict['iface_dev'] = interface if start_vm == "no" and vm and vm.is_alive(): vm.destroy() # positive and negative testing ######### libvirtd = utils_libvirtd.Libvirtd() if change_parameters == "no": get_domiftune_parameter(test_dict, test, libvirtd) else: set_domiftune_parameter(test_dict, test, libvirtd) if change_parameters != "no": ret = virsh.domiftune(vm_name, interface, 'current', '0', '0', debug=True) libvirt.check_exit_status(ret)
def check_domiftune(params, test_clear): """ Compare inbound and outbound value with guest XML configuration and virsh command output. :params: the parameter dictionary """ vm_name = params.get("main_vm") vm = params.get("vm") interface = params.get("iface_dev") options = params.get("options") inbound = params.get("inbound", "") outbound = params.get("outbound", "") inbound_from_cmd_output = None outbound_from_cmd_output = None peak_in_from_cmd_output = None peak_out_from_cmd_output = None burst_in_from_cmd_output = None burst_out_from_cmd_output = None domiftune_params = {} logging.debug("Checking inbound=%s outbound=%s", inbound, outbound) if vm and vm.is_alive(): result = virsh.domiftune(vm_name, interface, options=options) dicts = {} o = result.stdout.strip().split("\n") for l in o: if l and l.find(':'): k, v = l.split(':') dicts[k.strip()] = v.strip() logging.debug(dicts) inbound_from_cmd_output = dicts['inbound.average'] outbound_from_cmd_output = dicts['outbound.average'] logging.debug( "inbound_from_cmd_output=%s, outbound_from_cmd_output=%s", inbound_from_cmd_output, outbound_from_cmd_output) peak_in_from_cmd_output = dicts['inbound.peak'] peak_out_from_cmd_output = dicts['outbound.peak'] burst_in_from_cmd_output = dicts['inbound.peak'] burst_out_from_cmd_output = dicts['outbound.peak'] virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) if options == "config" and vm and vm.is_alive(): domiftune_params = virt_xml_obj.get_iftune_params( vm_name, "--inactive") elif vm and not vm.is_alive(): logging.debug("The guest %s isn't running!", vm_name) return True else: domiftune_params = virt_xml_obj.get_iftune_params(vm_name) try: inbound_from_xml = domiftune_params.get("inbound").get("average") outbound_from_xml = domiftune_params.get("outbound").get("average") except AttributeError, details: logging.error("Error in get inbound/outbound average: %s", details)
def lxc_hook(): """ Check the lxc hooks. """ if platform.platform().count('el8'): test.cancel("lxc is not supported in rhel8") test_xml = vm_xml.VMXML("lxc") root_dir = data_dir.get_root_dir() lxc_xml_related_path_file = params.get("lxc_xml_file") lxc_xml_path_file = os.path.join(root_dir, lxc_xml_related_path_file) with open(lxc_xml_path_file, 'r') as fd: test_xml.xml = fd.read() uri = "lxc:///" vm_name = "lxc_test_vm1" hook_para = "%s %s" % (hook_file, vm_name) prepare_hook_file(hook_script % hook_log) exit1 = params.get("exit1", "no") output = virsh.create(test_xml.xml, options="--console", uri=uri) if output.exit_status: logging.debug("output.stderr1: %s", output.stderr.lower()) if (exit1 == "yes" and "hook script execution failed" in output.stderr.lower()): return True else: test.fail("Create %s domain failed:%s" % ("lxc", output.stderr)) logging.info("Domain %s created, will check with console", vm_name) hook_str = hook_para + " prepare begin -" if not check_hooks(hook_str): test.fail("Failed to check lxc hook string: %s" % hook_str) hook_str = hook_para + " start begin -" if not check_hooks(hook_str): test.fail("Failed to check lxc hook string: %s" % hook_str) virsh.destroy(vm_name, options="", uri=uri) hook_str = hook_para + " stopped end -" if not check_hooks(hook_str): test.fail("Failed to check lxc hook string: %s" % hook_str) hook_str = hook_para + " release end -" if not check_hooks(hook_str): test.fail("Failed to check lxc hook string: %s" % hook_str)
def run(test, params, env): """ Test domiftune tuning 1) Positive testing 1.1) get the current domiftune parameters for a running guest 1.2) set the current domiftune parameters for a running guest 2) Negative testing 2.1) get domiftune parameters 2.2) set domiftune parameters """ # Run test case vm_name = params.get("vms") vm = env.get_vm(vm_name) status_error = params.get("status_error", "no") start_vm = params.get("start_vm", "yes") change_parameters = params.get("change_parameters", "no") interface = [] if vm and vm.is_alive(): virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) interface = virt_xml_obj.get_iface_dev(vm_name) test_dict = dict(params) test_dict['vm'] = vm if interface: test_dict['iface_dev'] = interface[0] if start_vm == "no" and vm and vm.is_alive(): vm.destroy() # positive and negative testing ######### if status_error == "no": if change_parameters == "no": get_domiftune_parameter(test_dict) else: set_domiftune_parameter(test_dict) if status_error == "yes": if change_parameters == "no": get_domiftune_parameter(test_dict) else: set_domiftune_parameter(test_dict)
def set_emulatorpin_parameter(params): """ Set the emulatorpin parameters :params: the parameter dictionary """ vm_name = params.get("main_vm") vm = params.get("vm") cpulist = params.get("emulatorpin_cpulist") options = params.get("emulatorpin_options") start_vm = params.get("start_vm", "yes") if start_vm == "no" and vm and vm.is_alive(): vm.destroy() result = virsh.emulatorpin(vm_name, cpulist, options) status = result.exit_status # Check status_error status_error = params.get("status_error") # Changing affinity for emulator thread dynamically is # not allowed when CPU placement is 'auto' placement = vm_xml.VMXML().new_from_dumpxml(vm_name).placement if placement == "auto": status_error = "yes" if status_error == "yes": if status or not check_emulatorpin(params): logging.info("It's an expected : %s", result.stderr) else: raise error.TestFail("%d not a expected command " "return value", status) elif status_error == "no": if status: raise error.TestFail(result.stderr) else: if check_emulatorpin(params): logging.info(result.stdout) else: raise error.TestFail("The 'cpulist' is inconsistent with" " 'cpulist' emulatorpin XML or/and is" " different from emulator/cpuset.cpus" " value from cgroup cpuset controller")
def run(test, params, env): """ Test domiftune tuning 1) Positive testing 1.1) get the current domiftune parameters for a running guest 1.2) set the current domiftune parameters for a running guest 2) Negative testing 2.1) get domiftune parameters 2.2) set domiftune parameters """ # Run test case vm_name = params.get("main_vm") vm = env.get_vm(vm_name) status_error = params.get("status_error", "no") start_vm = params.get("start_vm", "yes") change_parameters = params.get("change_parameters", "no") interface = [] if vm and not vm.is_alive(): vm.start() if vm and vm.is_alive(): virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) interface = virt_xml_obj.get_iface_dev(vm_name) logging.debug("the interface is %s" % interface[0]) test_dict = dict(params) test_dict['vm'] = vm if interface: test_dict['iface_dev'] = interface[0] if start_vm == "no" and vm and vm.is_alive(): vm.destroy() # positive and negative testing ######### if change_parameters == "no": get_domiftune_parameter(test_dict, test) else: set_domiftune_parameter(test_dict, test) ret = virsh.domiftune(vm_name, interface[0], 'current', '0', '0') libvirt.check_exit_status(ret)
def generate_container_xml(): """ Generate container xml """ vmxml = vm_xml.VMXML(dom_type) vmxml.vm_name = vm_name vmxml.max_mem = max_mem vmxml.current_mem = current_mem vmxml.vcpu = vcpu # Generate os vm_os = vm_xml.VMOSXML() vm_os.type = os_type vm_os.arch = os_arch vm_os.init = os_init vmxml.os = vm_os # Generate emulator emulator = Emulator() emulator.path = emulator_path # Generate console console = Console() filesystem = Filesystem() filesystem.accessmode = fs_accessmode filesystem.source = {'dir': install_root} filesystem.target = {'dir': fs_target} # Add emulator and console in devices devices = vm_xml.VMXMLDevices() devices.append(emulator) devices.append(console) devices.append(filesystem) # Add network device network = Interface(type_name=interface_type) network.mac_address = utils_net.generate_mac_address_simple() network.source = {interface_type: net_name} devices.append(network) vmxml.set_devices(devices) return vmxml
def check_domiftune(params): """ Compare inbound and outbound value with guest XML configuration and virsh command output. :params: the parameter dictionary """ vm_name = params.get("vms") vm = params.get("vm") interface = params.get("iface_dev") options = params.get("options") inbound = params.get("inbound", "") outbound = params.get("outbound", "") inbound_from_cmd_output = None outbound_from_cmd_output = None domiftune_params = {} if vm and vm.is_alive(): result = virsh.domiftune(vm_name, interface, options=options) dicts = {} o = result.stdout.strip().split("\n") for l in o: if l and l.find(':'): k, v = l.split(':') dicts[k.strip()] = v.strip() logging.debug(dicts) inbound_from_cmd_output = dicts['inbound.average'] outbound_from_cmd_output = dicts['outbound.average'] virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) if options == "config" and vm and vm.is_alive(): domiftune_params = virt_xml_obj.get_iftune_params( vm_name, "--inactive") elif vm and not vm.is_alive(): logging.debug("The guest %s isn't running!", vm_name) return True else: domiftune_params = virt_xml_obj.get_iftune_params(vm_name) inbound_from_xml = domiftune_params.get("inbound") outbound_from_xml = domiftune_params.get("outbound") if vm and vm.is_alive() and options != "config": if inbound and inbound != inbound_from_cmd_output: logging.error("To expect inbound %s: %s", inbound, inbound_from_cmd_output) return False if outbound and outbound != outbound_from_cmd_output: logging.error("To expect inbound %s: %s", outbound, outbound_from_cmd_output) return False if inbound and inbound_from_xml and inbound != inbound_from_xml: logging.error("To expect outbound %s: %s", inbound, inbound_from_xml) return False if outbound and outbound_from_xml and outbound != outbound_from_xml: logging.error("To expect outbound %s: %s", outbound, outbound_from_xml) return False return True
def _from_scratch(self): vmxml = vm_xml.VMXML('test1', virsh_instance=self.dummy_virsh) vmxml.vm_name = 'test2' vmxml.uuid = 'test3' vmxml.vcpu = 4 return vmxml
def run(test, params, env): """ Test interface with unprivileged user """ def create_bridge(br_name, iface_name): """ Create bridge attached to physical interface """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge utils_package.package_install('tmux') cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \ ' ip link set {1} master {0}; ip link set {0} up; pkill dhclient; ' \ 'sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name) process.run(cmd, shell=True, verbose=True) def check_ping(dest_ip, ping_count, timeout, src_ip=None, session=None, expect_success=True): """ Check if ping result meets expectation """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session, force_ipv4=True) success = True if status == 0 else False if success != expect_success: test.fail('Ping result not met expectation, ' 'actual result is {}'.format(success)) if not libvirt_version.version_compare(5, 6, 0): test.cancel('Libvirt version is too low for this test.') vm_name = params.get('main_vm') rand_id = '_' + utils_misc.generate_random_string(3) upu_vm_name = 'upu_vm' + rand_id user_vm_name = params.get('user_vm_name', 'non_root_vm') bridge_name = params.get('bridge_name', 'test_br0') + rand_id device_type = params.get('device_type', '') iface_name = utils_net.get_net_if(state="UP")[0] tap_name = params.get('tap_name', 'mytap0') + rand_id macvtap_name = params.get('macvtap_name', 'mymacvtap0') + rand_id remote_ip = params.get('remote_ip') up_user = params.get('up_user', 'test_upu') + rand_id case = params.get('case', '') # Create unprivileged user logging.info('Create unprivileged user %s', up_user) process.run('useradd %s' % up_user, shell=True, verbose=True) root_vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) upu_args = { 'unprivileged_user': up_user, 'ignore_status': False, 'debug': True, } try: # Create vm as unprivileged user logging.info('Create vm as unprivileged user') upu_vmxml = root_vmxml.copy() # Prepare vm for unprivileged user xml_devices = upu_vmxml.devices disks = xml_devices.by_device_tag("disk") for disk in disks: ori_path = disk.source['attrs'].get('file') if not ori_path: continue file_name = ori_path.split('/')[-1] new_disk_path = '/home/{}/{}'.format(up_user, file_name) logging.debug('New disk path:{}'.format(new_disk_path)) # Copy disk image file and chown to make sure that # unprivileged user has access shutil.copyfile(ori_path, new_disk_path) shutil.chown(new_disk_path, up_user, up_user) # Modify xml to set new path of disk disk_index = xml_devices.index(disk) source = xml_devices[disk_index].source new_attrs = source.attrs new_attrs['file'] = new_disk_path source.attrs = new_attrs xml_devices[disk_index].source = source logging.debug(xml_devices[disk_index].source) upu_vmxml.devices = xml_devices new_xml_path = '/home/{}/upu.xml'.format(up_user) shutil.copyfile(upu_vmxml.xml, new_xml_path) # Define vm for unprivileged user virsh.define(new_xml_path, **upu_args) virsh.domrename(vm_name, upu_vm_name, **upu_args) logging.debug(virsh.dumpxml(upu_vm_name, **upu_args)) upu_vmxml = vm_xml.VMXML() upu_vmxml.xml = virsh.dumpxml(upu_vm_name, **upu_args).stdout_text if case == 'precreated': if device_type == 'tap': # Create bridge create_bridge(bridge_name, iface_name) # Create tap device tap_cmd = 'ip tuntap add mode tap user {user} group {user} ' \ 'name {tap};ip link set {tap} up;ip link set {tap} ' \ 'master {br}'.format(tap=tap_name, user=up_user, br=bridge_name) # Execute command as root process.run(tap_cmd, shell=True, verbose=True) if device_type == 'macvtap': # Create macvtap device mac_addr = utils_net.generate_mac_address_simple() macvtap_cmd = 'ip link add link {iface} name {macvtap} address' \ ' {mac} type macvtap mode bridge;' \ 'ip link set {macvtap} up'.format( iface=iface_name, macvtap=macvtap_name, mac=mac_addr) process.run(macvtap_cmd, shell=True, verbose=True) cmd_get_tap = 'ip link show {} | head -1 | cut -d: -f1'.format(macvtap_name) tap_index = process.run(cmd_get_tap, shell=True, verbose=True).stdout_text.strip() device_path = '/dev/tap{}'.format(tap_index) logging.debug('device_path: {}'.format(device_path)) # Change owner and group for device process.run('chown {user} {path};chgrp {user} {path}'.format( user=up_user, path=device_path), shell=True, verbose=True) # Check if device owner is changed to unprivileged user process.run('ls -l %s' % device_path, shell=True, verbose=True) # Modify interface all_devices = upu_vmxml.devices iface_list = all_devices.by_device_tag('interface') if not iface_list: test.error('No iface to modify') iface = iface_list[0] # Remove other interfaces for ifc in iface_list[1:]: all_devices.remove(ifc) if device_type == 'tap': dev_name = tap_name elif device_type == 'macvtap': dev_name = macvtap_name else: test.error('Invalid device type: {}'.format(device_type)) if_index = all_devices.index(iface) iface = all_devices[if_index] iface.type_name = 'ethernet' iface.target = { 'dev': dev_name, 'managed': 'no' } if device_type == 'macvtap': iface.mac_address = mac_addr logging.debug(iface) upu_vmxml.devices = all_devices logging.debug(upu_vmxml) # Define updated xml shutil.copyfile(upu_vmxml.xml, new_xml_path) upu_vmxml.xml = new_xml_path virsh.define(new_xml_path, **upu_args) # Switch to unprivileged user and modify vm's interface # Start vm as unprivileged user and test network virsh.start(upu_vm_name, debug=True, ignore_status=False, unprivileged_user=up_user) cmd = ("su - %s -c 'virsh console %s'" % (up_user, upu_vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), r"[\#\$]\s*$", 60) logging.debug(session.cmd_output('ifconfig')) check_ping(remote_ip, 5, 10, session=session) session.close() finally: if 'upu_virsh' in locals(): virsh.destroy(upu_vm_name, unprivileged_user=up_user) virsh.undefine(upu_vm_name, unprivileged_user=up_user) if case == 'precreated': try: if device_type == 'tap': process.run('ip tuntap del mode tap {}'.format(tap_name), shell=True, verbose=True) elif device_type == 'macvtap': process.run('ip l del {}'.format(macvtap_name), shell=True, verbose=True) except Exception: pass finally: cmd = 'tmux -c "ip link set {1} nomaster; ip link delete {0};' \ 'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name) process.run(cmd, shell=True, verbose=True, ignore_status=True) process.run('pkill -u {0};userdel -f -r {0}'.format(up_user), shell=True, verbose=True, ignore_status=True)
def check_cpu(xml, cpu_match): """ Check the dumpxml result for --update-cpu option Note, function custom_cpu() hard code these features and policy, so after run virsh dumpxml --update-cpu: 1. For match='minimum', all host support features will added, and match='exact' 2. policy='optional' features(support by host) will update to policy='require' 3. policy='optional' features(unsupport by host) will update to policy='disable' 4. Other policy='disable|force|forbid|require' with keep the original values """ vmxml = vm_xml.VMXML() vmxml['xml'] = xml vmcpu_xml = vmxml['cpu'] check_pass = True require_count = 0 expect_require_features = 0 cpu_feature_list = vmcpu_xml.get_feature_list() host_capa = capability_xml.CapabilityXML() for i in range(len(cpu_feature_list)): f_name = vmcpu_xml.get_feature_name(i) f_policy = vmcpu_xml.get_feature_policy(i) err_msg = "Policy of '%s' is not expected: %s" % (f_name, f_policy) expect_policy = "disable" if f_name in ["xtpr", "vme", "ia64"]: # Check if feature is support on the host if host_capa.check_feature_name(f_name): expect_policy = "require" if f_policy != expect_policy: logging.error(err_msg) check_pass = False if f_name == "tm2": if f_policy != "disable": logging.error(err_msg) check_pass = False if f_name == "est": if f_policy != "force": logging.error(err_msg) check_pass = False if f_name == "vmx": if f_policy != "forbid": logging.error(err_msg) check_pass = False # Count expect require features if expect_policy == "require": expect_require_features += 1 # Count actual require features if f_policy == "require": require_count += 1 # Check if cpu_match == "minimum": expect_match = "exact" # For different host, the support require features are different, # so just check the actual require features greater than the # expect number if require_count < expect_require_features: logging.error("Find %d require features, but expect >=%s", require_count, expect_require_features) check_pass = False else: expect_match = cpu_match if require_count != expect_require_features: logging.error("Find %d require features, but expect %s", require_count, expect_require_features) check_pass = False match = vmcpu_xml['match'] if match != expect_match: logging.error("CPU match '%s' is not expected", match) check_pass = False if vmcpu_xml['model'] != 'Penryn': logging.error("CPU model %s is not expected", vmcpu_xml['model']) check_pass = False if vmcpu_xml['vendor'] != "Intel": logging.error("CPU vendor %s is not expected", vmcpu_xml['vendor']) check_pass = False return check_pass
def check_domiftune(params, test_clear): """ Compare inbound and outbound value with guest XML configuration and virsh command output. :params: the parameter dictionary """ vm_name = params.get("main_vm") vm = params.get("vm") interface = params.get("iface_dev") options = params.get("options") inbound = params.get("inbound", "") outbound = params.get("outbound", "") inbound_from_cmd_output = None outbound_from_cmd_output = None peak_in_from_cmd_output = None peak_out_from_cmd_output = None burst_in_from_cmd_output = None burst_out_from_cmd_output = None domiftune_params = {} logging.debug("Checking inbound=%s outbound=%s", inbound, outbound) if vm and vm.is_alive(): result = virsh.domiftune(vm_name, interface, options=options) dicts = {} o = result.stdout.strip().split("\n") for l in o: if l and l.find(':'): k, v = l.split(':') dicts[k.strip()] = v.strip() logging.debug(dicts) inbound_from_cmd_output = dicts['inbound.average'] outbound_from_cmd_output = dicts['outbound.average'] logging.debug( "inbound_from_cmd_output=%s, outbound_from_cmd_output=%s", inbound_from_cmd_output, outbound_from_cmd_output) peak_in_from_cmd_output = dicts['inbound.peak'] peak_out_from_cmd_output = dicts['outbound.peak'] burst_in_from_cmd_output = dicts['inbound.peak'] burst_out_from_cmd_output = dicts['outbound.peak'] virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) if options == "config" and vm and vm.is_alive(): domiftune_params = virt_xml_obj.get_iftune_params( vm_name, "--inactive") elif vm and not vm.is_alive(): logging.debug("The guest %s isn't running!", vm_name) return True else: domiftune_params = virt_xml_obj.get_iftune_params(vm_name) inbound_from_xml = domiftune_params.get("inbound") outbound_from_xml = domiftune_params.get("outbound") logging.debug("inbound_from_xml=%s, outbound_from_xml=%s", inbound_from_xml, outbound_from_cmd_output) if vm and vm.is_alive() and options != "config": if test_clear and inbound: if inbound_from_xml is not None or \ inbound_from_cmd_output is not "0" or \ peak_in_from_cmd_output is not "0" or \ burst_in_from_cmd_output is not "0": logging.error( "Inbound was not cleared, xml=%s " "avg=%s peak=%s burst=%s", inbound_from_xml, inbound_from_cmd_output, peak_in_from_cmd_output, burst_in_from_cmd_output) return False if test_clear and outbound: if outbound_from_xml is not None or \ outbound_from_cmd_output is not "0" or \ peak_out_from_cmd_output is not "0" or \ burst_out_from_cmd_output is not "0": logging.error( "Outbound was not cleared, xml=%s " "avg=%s peak=%s burst=%s", outbound_from_xml, outbound_from_cmd_output, peak_out_from_cmd_output, burst_out_from_cmd_output) if test_clear: return True if inbound and inbound != inbound_from_cmd_output: logging.error("To expect inbound %s: %s", inbound, inbound_from_cmd_output) return False if outbound and outbound != outbound_from_cmd_output: logging.error("To expect inbound %s: %s", outbound, outbound_from_cmd_output) return False if inbound and inbound_from_xml and inbound != inbound_from_xml: logging.error("To expect outbound %s: %s", inbound, inbound_from_xml) return False if outbound and outbound_from_xml and outbound != outbound_from_xml: logging.error("To expect outbound %s: %s", outbound, outbound_from_xml) return False return True
def _from_scratch(self): vmxml = vm_xml.VMXML(self.dummy_virsh, 'test1') vmxml.vm_name = 'test2' vmxml.uuid = 'test3' vmxml.vcpu = 4 return vmxml
def check_cpu(xml, cpu_match, arch, model, policies): """ Check the dumpxml result for --update-cpu option Note, function custom_cpu() hard code these features and policy, so after run virsh dumpxml --update-cpu: 1. For match='minimum', all host support features will added, and match change to 'exact'. Since libvirt-3.0, cpu update is reworked, and the custom CPU with minimum match is converted similarly to host-model. 2. policy='optional' features(support by host) will update to policy='require' 3. policy='optional' features(unsupported by host) will update to policy='disable' 4. Other policy='disable|force|forbid|require' with keep the original values """ vmxml = vm_xml.VMXML() vmxml['xml'] = xml vmcpu_xml = vmxml['cpu'] check_pass = True require_count = 0 expect_require_features = 0 cpu_feature_list = vmcpu_xml.get_feature_list() dom_capa = domcapability_xml.DomCapabilityXML() is_supported_on_hypervisor = is_supported_on_hypervisor_func(dom_capa) for i in range(len(cpu_feature_list)): f_name = vmcpu_xml.get_feature_name(i) f_policy = vmcpu_xml.get_feature_policy(i) err_msg = "Policy of '%s' is not expected: %s" % (f_name, f_policy) expect_policy = "disable" if f_name in policies: if policies[f_name] == "optional" and arch != "s390x": if is_supported_on_hypervisor(f_name): expect_policy = "require" else: expect_policy = policies[f_name] if f_policy != expect_policy: logging.error(err_msg) check_pass = False # Count expect require features if expect_policy == "require": expect_require_features += 1 # Count actual require features if f_policy == "require": require_count += 1 # Check optional feature is changed to require/disable expect_model = model if cpu_match == "minimum": # libvirt commit 3b6be3c0 change the behavior of update-cpu # Check model is changed to host cpu-model given in domcapabilities if libvirt_version.version_compare(3, 0, 0): expect_model = dom_capa.get_hostmodel_name() expect_match = "exact" # For different host, the support require features are different, # so just check the actual require features greater than the # expect number if require_count < expect_require_features: logging.error("Found %d require features, but expect >=%s", require_count, expect_require_features) check_pass = False else: expect_match = cpu_match if require_count != expect_require_features: logging.error("Found %d require features, but expect %s", require_count, expect_require_features) check_pass = False logging.debug("Expect 'match' value is: %s", expect_match) match = vmcpu_xml['match'] if match != expect_match: logging.error("CPU match '%s' is not expected", match) check_pass = False logging.debug("Expect 'model' value is: %s", expect_model) if vmcpu_xml['model'] != expect_model: logging.error("CPU model %s is not expected", vmcpu_xml['model']) check_pass = False return check_pass
def get_vmxml(): vmxml = vm_xml.VMXML() vmxml['xml'] = XML.strip() return vmxml
def check_cpu(xml, cpu_match, arch): """ Check the dumpxml result for --update-cpu option Note, function custom_cpu() hard code these features and policy, so after run virsh dumpxml --update-cpu: 1. For match='minimum', all host support features will added, and match change to 'exact'. Since libvirt-3.0, cpu update is reworked, and the custom CPU with minimum match is converted similarly to host-model. 2. policy='optional' features(support by host) will update to policy='require' 3. policy='optional' features(unsupport by host) will update to policy='disable' 4. Other policy='disable|force|forbid|require' with keep the original values """ vmxml = vm_xml.VMXML() vmxml['xml'] = xml vmcpu_xml = vmxml['cpu'] check_pass = True require_count = 0 expect_require_features = 0 if arch == 's390x': # on s390x custom is left as-is pass else: cpu_feature_list = vmcpu_xml.get_feature_list() host_capa = capability_xml.CapabilityXML() for i in range(len(cpu_feature_list)): f_name = vmcpu_xml.get_feature_name(i) f_policy = vmcpu_xml.get_feature_policy(i) err_msg = "Policy of '%s' is not expected: %s" % (f_name, f_policy) expect_policy = "disable" if f_name in ["xtpr", "vme", "ia64"]: # Check if feature is support on the host # Since libvirt3.9, libvirt query qemu/kvm to get one feature support or not if libvirt_version.version_compare(3, 9, 0): if f_name in get_cpu_features(): expect_policy = "require" else: if host_capa.check_feature_name(f_name): expect_policy = "require" if f_policy != expect_policy: logging.error(err_msg) check_pass = False if f_name == "tm2": if f_policy != "disable": logging.error(err_msg) check_pass = False if f_name == "est": if f_policy != "force": logging.error(err_msg) check_pass = False if f_name == "vmx": if f_policy != "forbid": logging.error(err_msg) check_pass = False # Count expect require features if expect_policy == "require": expect_require_features += 1 # Count actual require features if f_policy == "require": require_count += 1 # Check optional feature is changed to require/disable expect_model = 'Penryn' if cpu_match == "minimum": # libvirt commit 3b6be3c0 change the behavior of update-cpu # Check model is changed to host cpu-model given in domcapabilities if libvirt_version.version_compare(3, 0, 0): expect_model = host_capa.model expect_match = "exact" # For different host, the support require features are different, # so just check the actual require features greater than the # expect number if require_count < expect_require_features: logging.error("Found %d require features, but expect >=%s", require_count, expect_require_features) check_pass = False else: expect_match = cpu_match if require_count != expect_require_features: logging.error("Found %d require features, but expect %s", require_count, expect_require_features) check_pass = False logging.debug("Expect 'match' value is: %s", expect_match) match = vmcpu_xml['match'] if match != expect_match: logging.error("CPU match '%s' is not expected", match) check_pass = False logging.debug("Expect 'model' value is: %s", expect_model) if vmcpu_xml['model'] != expect_model: logging.error("CPU model %s is not expected", vmcpu_xml['model']) check_pass = False return check_pass
def check_domiftune(params, test_clear): """ Compare inbound and outbound value with guest XML configuration and virsh command output. :params: the parameter dictionary """ vm_name = params.get("main_vm") vm = params.get("vm") interface = params.get("iface_dev") options = params.get("options") inbound = params.get("inbound", "") outbound = params.get("outbound", "") set_clear = "yes" == params.get("set_clear", "no") test_outbound = "yes" == params.get("test_outbound", "no") test_inbound = "yes" == params.get("test_inbound", "no") status_error = 'yes' == params.get("status_error", "no") later_start = 'yes' == params.get("later_start", "no") average_inbound_from_cmd_output = None average_outbound_from_cmd_output = None peak_inbound_from_cmd_output = None peak_outbound_from_cmd_output = None burst_inbound_from_cmd_output = None burst_outbound_from_cmd_output = None floor_inbound_from_cmd_output = None average_inbound_from_xml = None average_outbound_from_xml = None peak_inbound_from_xml = None peak_outbound_from_xml = None burst_inbound_from_xml = None burst_outbound_from_xml = None floor_inbound_from_xml = None netfloor = params.get("netfloor") logging.debug("Checking inbound=%s outbound= %s", inbound, outbound) # get inbound and outbound parameters from virsh cmd setting if not status_error and test_inbound: in_list = re.findall(r'[0-9]+', inbound) inbound_average = int(in_list[0]) if len(in_list) >= 3: inbound_peak = int(in_list[1]) inbound_burst = int(in_list[2]) if netfloor: inbound_floor = int(in_list[3]) if not status_error and test_outbound: out_list = re.findall(r'[0-9]+', outbound) outbound_average = int(out_list[0]) if len(out_list) == 3: outbound_peak = int(out_list[1]) outbound_burst = int(out_list[2]) # --config affect next boot if options == "config": vm.destroy() vm.start() # setting for shutoff guest need start to check if later_start: vm.start() # get inbound and outbound parameters from virsh cmd output if vm and vm.is_alive(): result = virsh.domiftune(vm_name, interface, options=options) dicts = {} bws = result.stdout.strip().split("\n") for bw in bws: if bw and bw.find(':'): k, v = bw.split(':') dicts[k.strip()] = v.strip() logging.debug(dicts) average_inbound_from_cmd_output = int(dicts['inbound.average']) average_outbound_from_cmd_output = int(dicts['outbound.average']) peak_inbound_from_cmd_output = int(dicts['inbound.peak']) peak_outbound_from_cmd_output = int(dicts['outbound.peak']) burst_inbound_from_cmd_output = int(dicts['inbound.burst']) burst_outbound_from_cmd_output = int(dicts['outbound.burst']) floor_inbound_from_cmd_output = int(dicts['inbound.floor']) logging.debug("inbound and outbound from cmd output:") logging.debug("inbound: %s,%s,%s; outbound: %s,%s,%s", average_inbound_from_cmd_output, peak_inbound_from_cmd_output, burst_inbound_from_cmd_output, average_outbound_from_cmd_output, peak_outbound_from_cmd_output, burst_outbound_from_cmd_output) if netfloor: logging.debug("inbound floor: %s", floor_inbound_from_cmd_output) # get inbound and outbound parameters from vm xml virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) if options == "config" and vm and vm.is_alive(): domiftune_params = virt_xml_obj.get_iftune_params( vm_name, "--inactive") elif vm and not vm.is_alive(): logging.debug("The guest %s isn't running!", vm_name) return True else: domiftune_params = virt_xml_obj.get_iftune_params(vm_name) try: logging.debug("test inbound is %s, test outbound is %s", test_inbound, test_outbound) if test_inbound: average_inbound_from_xml = int(domiftune_params.get("inbound").get("average")) peak_inbound_from_xml = int(domiftune_params.get("inbound").get("peak")) burst_inbound_from_xml = int(domiftune_params.get("inbound").get("burst")) logging.debug("inbound from xml:") logging.debug("%s, %s, %s", average_inbound_from_xml, peak_inbound_from_xml, burst_inbound_from_xml) if netfloor: floor_inbound_from_xml = int(domiftune_params.get("inbound").get("floor")) logging.debug("inbound floor from xml: %s", floor_inbound_from_xml) if test_outbound: average_outbound_from_xml = int(domiftune_params.get("outbound").get("average")) peak_outbound_from_xml = int(domiftune_params.get("outbound").get("peak")) burst_outbound_from_xml = int(domiftune_params.get("outbound").get("burst")) logging.debug("outbound from xml:") logging.debug("%s, %s, %s", average_outbound_from_xml, peak_outbound_from_xml, burst_outbound_from_xml) except AttributeError as details: logging.error("Error in get inbound/outbound average: %s", details) logging.debug("average_inbound_from_xml=%s, average_outbound_from_xml=%s", average_inbound_from_xml, average_outbound_from_xml) if vm and vm.is_alive(): if test_clear and set_clear and test_inbound: if average_inbound_from_xml is not None or \ average_inbound_from_cmd_output != 0 or \ peak_inbound_from_cmd_output != 0 or \ burst_inbound_from_cmd_output != 0: logging.error("Inbound was not cleared, xml=%s " "avg=%s peak=%s burst=%s", average_inbound_from_xml, average_inbound_from_cmd_output, peak_inbound_from_cmd_output, burst_inbound_from_cmd_output) return False else: return True if test_clear and set_clear and test_outbound: if average_outbound_from_xml is not None or \ average_outbound_from_cmd_output != 0 or \ peak_outbound_from_cmd_output != 0 or \ burst_outbound_from_cmd_output != 0: logging.error("Outbound was not cleared, xml=%s " "avg=%s peak=%s burst=%s", average_outbound_from_xml, average_outbound_from_cmd_output, peak_outbound_from_cmd_output, burst_outbound_from_cmd_output) return False else: return True if test_inbound and (inbound_average != average_inbound_from_cmd_output or inbound_peak != peak_inbound_from_cmd_output or inbound_burst != burst_inbound_from_cmd_output): logging.error("To expect inbound %s: but got {average: %s, peak:" " %s, burst: %s} from cmd output", inbound, average_inbound_from_cmd_output, peak_inbound_from_cmd_output, burst_inbound_from_cmd_output) return False if netfloor and inbound_floor != floor_inbound_from_cmd_output: logging.error("To expect inbound floor %s, but got %s from cmd output", inbound_floor, floor_inbound_from_cmd_output) return False if test_inbound and (inbound_average != average_inbound_from_xml or inbound_peak != peak_inbound_from_xml or inbound_burst != burst_inbound_from_xml): logging.error("To expect inbound %s: but got {average: %s, peak:" " %s, burst: %s} from xml", inbound, average_inbound_from_xml, peak_inbound_from_xml, burst_inbound_from_xml) return False if netfloor and inbound_floor != floor_inbound_from_xml: logging.error("To expect inbound floor %s, but got %s from xml", inbound_floor, floor_inbound_from_xml) return False if test_outbound and (outbound_average != average_outbound_from_cmd_output or outbound_peak != peak_outbound_from_cmd_output or outbound_burst != burst_outbound_from_cmd_output): logging.error("To expect outbound %s: but got {average: %s, peak:" " %s, burst: %s} from cmd output", outbound, average_outbound_from_cmd_output, peak_outbound_from_cmd_output, burst_outbound_from_cmd_output) return False if test_outbound and (outbound_average != average_outbound_from_xml or outbound_peak != peak_outbound_from_xml or outbound_burst != burst_outbound_from_xml): logging.error("To expect outbound %s: but got {average: %s, peak:" " %s, burst: %s} from xml", outbound, average_outbound_from_xml, peak_outbound_from_xml, burst_outbound_from_xml) return False return True