def create_network_interface(name): """ Create network type interface xml. """ new_iface = Interface('network') new_iface.source = {'network': name} new_iface.model = "virtio" new_iface.mac_address = utils_net.generate_mac_address_simple() return new_iface
def create_iface_xml(): """ Create interface xml file """ iface = Interface("bridge") iface.source = eval("{'bridge':'virbr0'}") iface.model = "virtio" logging.debug("Create new interface xml: %s", iface) return iface
def create_interface(): """ Call different function to create interface according to the type """ new_iface = Interface('network') if vf_type == "vf": new_iface = create_hostdev_interface(vf_addr, managed, model) if vf_type == "vf_pool": netxml = create_hostdev_network() virsh.net_define(netxml.xml, ignore_status=True) if not inactive_pool: virsh.net_start(netxml.name) new_iface = create_network_interface(netxml.name) if vf_type == "macvtap": new_iface = Interface('direct') new_iface.source = {"dev": vf_name, "mode": "passthrough"} new_iface.mac_address = utils_net.generate_mac_address_simple() new_iface.model = "virtio" if vlan_id: new_iface.vlan = new_iface.new_vlan(**vlan_id) if vf_type == "macvtap_network": netxml = create_macvtap_network() result = virsh.net_define(netxml.xml, ignore_status=True) virsh.net_start(netxml.name) new_iface = create_network_interface(netxml.name) return new_iface
def create_iface_xml(mac): """ Create interface xml file :param mac: The mac address of nic device """ iface = Interface(type_name='network') iface.source = iface_source iface.model = iface_model iface.mac_address = mac logging.debug("Create new interface xml: %s", iface) return iface
def create_iface_xml(mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) iface.source = iface_source iface.model = iface_model if iface_model else "virtio" if iface_target: iface.target = {'dev': iface_target} iface.mac_address = mac logging.debug("Create new interface xml: %s", iface) return iface
def create_iface(iface_model, iface_source, **kwargs): """ Create an interface to be attached to vm :param iface_model: model of the interface device :param iface_source: source of the interface device :param kwargs: other k-w args that needed to create device :return: the newly created interface object """ iface = Interface('network') iface.model = iface_model iface.source = eval(iface_source) if 'mac' in kwargs: iface.mac_address = kwargs['mac'] else: mac = utils_net.generate_mac_address_simple() iface.mac_address = mac if 'address' in kwargs: iface.address = iface.new_iface_address( attrs=eval(kwargs['address'])) logging.debug('iface: %s', iface) return iface
def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if test_target: iface.target = {"dev": target_dev} logging.debug("Create new interface xml: %s", iface) return iface
def create_hostdev_interface(pci_id, managed, model): """ Create hostdev type interface xml. """ attrs = create_address_dict(pci_id) new_iface = Interface('hostdev') new_iface.managed = managed if model != "": new_iface.model = model new_iface.mac_address = utils_net.generate_mac_address_simple() new_iface.hostdev_address = new_iface.new_iface_address( **{"attrs": attrs}) chars = string.ascii_letters + string.digits + '-_' alias_name = 'ua-' + ''.join( random.choice(chars) for _ in list(range(64))) new_iface.alias = {'name': alias_name} if vlan_id: new_iface.vlan = new_iface.new_vlan(**vlan_id) return new_iface
def create_interface(): """ Call different function to create interface according to the type """ new_iface = Interface('network') if vf_type == "vf": new_iface = create_hostdev_interface(vf_addr, managed, model) if vf_type == "vf_pool": netxml = create_hostdev_network() virsh.net_define(netxml.xml, ignore_status=True) if not inactive_pool: virsh.net_start(netxml.name) new_iface = create_network_interface(netxml.name) if vf_type == "macvtap": new_iface = Interface('direct') new_iface.source = {"dev": vf_name, "mode": "passthrough"} new_iface.mac_address = utils_net.generate_mac_address_simple() if vf_type == "macvtap_network": netxml = create_macvtap_network() result = virsh.net_define(netxml.xml, ignore_status=True) virsh.net_start(netxml.name) new_iface = create_network_interface(netxml.name) return new_iface
def create_hostdev_interface(pci_id, managed, model): """ Create hostdev type interface xml. """ attrs = create_address_dict(pci_id) new_iface = Interface('hostdev') new_iface.managed = managed if model != "": new_iface.model = model new_iface.mac_address = utils_net.generate_mac_address_simple() new_iface.hostdev_address = new_iface.new_iface_address( **{"attrs": attrs}) return new_iface
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 create_iface(iface_type, **kwargs): """ Create a interface to be attached to vm """ m_iface = Interface(iface_type) m_iface.mac_address = utils_net.generate_mac_address_simple() if 'base_if' in kwargs: m_iface.source = {'dev': kwargs['base_if'], 'mode': 'vepa'} if 'source_net' in kwargs: m_iface.source = {'network': kwargs['source_net']} if 'mtu' in kwargs: m_iface.mtu = {'size': kwargs['mtu']} if 'model_net' in kwargs: m_iface.model = kwargs['model_net'] logging.debug(m_iface.get_xml()) logging.debug(m_iface) return m_iface
def create_iface_xml(mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) iface.source = iface_source iface.model = iface_model if iface_model else "virtio" if iface_target: iface.target = {'dev': iface_target} iface.mac_address = mac if iface_rom: iface.rom = eval(iface_rom) logging.debug("Create new interface xml: %s", iface) return iface
def create_hostdev_interface(pci_id, managed, model): """ Create hostdev type interface xml. """ attrs = create_address_dict(pci_id) new_iface = Interface('hostdev') new_iface.managed = managed if model != "": new_iface.model = model new_iface.mac_address = utils_net.generate_mac_address_simple() new_iface.hostdev_address = new_iface.new_iface_address(**{"attrs": attrs}) chars = string.ascii_letters + string.digits + '-_' alias_name = 'ua-' + ''.join(random.choice(chars) for _ in list(range(64))) new_iface.alias = {'name': alias_name} return new_iface
def prepare_iface_xml(iface_bus, iface_slot): """ Create interface xml file """ iface_xml = Interface(type_name='bridge') iface_xml.source = {'bridge': 'virbr0'} iface_xml.model = "virtio" addr_dict = { 'bus': iface_bus, 'slot': iface_slot, 'domain': '0x0000', 'function': '0x0' } iface_xml.address = iface_xml.new_iface_address(type_name='pci', **{"attrs": addr_dict}) return iface_xml
def modify_iface_xml(br_name, nwfilter, vm_name): """ Modify interface xml with the new bridge and the nwfilter :param br_name: bridge name :param nwfilter: nwfilter name :param vm_name: vm name """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) iface_xml = Interface(type_name='bridge') iface_xml.source = {'bridge': br_name} iface_xml.model = 'virtio' iface_xml.filterref = iface_xml.new_filterref(name=nwfilter) logging.debug("new interface xml is: %s" % iface_xml) vmxml.add_device(iface_xml) vmxml.sync()
def create_iface(iface_model, iface_source, **kwargs): """ Create an interface to be attached to vm :param iface_model: model of the interface device :param iface_source: source of the interface device :param kwargs: other k-w args that needed to create device :return: the newly created interface object """ iface = Interface('network') iface.model = iface_model iface.source = eval(iface_source) if 'mac' in kwargs: iface.mac_address = kwargs['mac'] else: mac = utils_net.generate_mac_address_simple() iface.mac_address = mac if 'address' in kwargs: iface.address = iface.new_iface_address(attrs=eval(kwargs['address'])) logging.debug('iface: %s', iface) return iface
def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) logging.debug("Create new interface xml: %s", iface) return iface
def modify_iface_xml(): """ Modify interface xml options Two methods to modify domain interfae: 1. modify guest xml, define it 2. attach one interface for running guest :return: 0 for successful negative case test.fail is fail for positive/negative case None for successful positive case """ if hotplug_iface: iface = Interface(iface_type) else: vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) xml_devices = vmxml.devices iface_index = xml_devices.index( xml_devices.by_device_tag("interface")[0]) iface = xml_devices[iface_index] if iface_type == 'network': iface.type_name = iface_type source = {iface_type: net_name} elif iface_type == 'bridge' and bridge_name: iface.type_name = iface_type source = {iface_type: bridge_name} elif iface_type == 'direct': iface.type_name = iface_type source = {'dev': interface, 'mode': 'bridge'} if source: del iface.source iface.source = source iface_model = params.get("iface_model", "virtio") iface.model = iface_model iface.coalesce = {'max': coalesce_value} if network_type == "ovsbridge" and iface_type == "bridge": iface.virtualport_type = "openvswitch" if not hotplug_iface: vmxml.devices = xml_devices vmxml.xmltreefile.write() try: vmxml.sync() except xcepts.LibvirtXMLError as details: if status_error: # Expect error for negetive test return 0 else: test.fail("Define guest: FAIL") else: if not vm.is_alive(): vm.start() # Wait guest boot completely time.sleep(2) try: ret = virsh.attach_device(vm_name, iface.xml, ignore_status=False, debug=True) except process.CmdError as error: if status_error: # Expect error for negetive test return 0 else: test.fail("Define guest: FAIL")
def run(test, params, env): """ cpu, memory, network, disk limit test: 1) prepare the guest with given topology, memory and if any devices 2) Start and login to the guest 3) Check if the guest functional 4) if given run some stress test :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. TODO: 1. Add multiple pci-bridge and pci devices respectively. 2. Get no. VM interfaces at test start and use for validation. """ failures = { "Failed to allocate KVM HPT of order": "Host does no have enough cma to boot, try increasing \ kvm_cma_resv_ratio in host boot", "unable to map backing store for guest RAM": "Not enough memory in the host to boot the guest" } vm_name = params.get("main_vm") max_vcpu = current_vcpu = int(params.get("max_vcpu", 240)) vm_cores = int(params.get("limit_vcpu_cores", 240)) vm_threads = int(params.get("limit_vcpu_threads", 1)) vm_sockets = int(params.get("limit_vcpu_sockets", 1)) usermaxmem = params.get("usermaxmem", '') default_mem = int(params.get("default_mem", 8)) maxmem = params.get("maxmem", "no") == "yes" swap_setup = params.get("swap_setup", "yes") == "yes" blk_partition = params.get("blk_part", '') graphic = params.get("graphics", "no") == "yes" vm = env.get_vm(vm_name) guestmemory = None max_network = params.get("max_network", "no") == "yes" max_disk = params.get("max_disk", "no") == "yes" num_network = int(params.get("num_network", 16)) num_disk = int(params.get("num_disk", 16)) drive_format = params.get("drive_format", "scsi") disk_format = params.get("disk_format", "qcow2") netdst = params.get("netdst", "virbr0") memunit = params.get("memunit", 'G') failed = False vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) org_xml = vmxml.copy() # Destroy the vm vm.destroy() try: # Setup swap if swap_setup: if not blk_partition: test.cancel("block partition is not given") # Check if valid partition or raise cmd = "blkid /dev/%s|awk -F" " '{print $2}'" % blk_partition output = process.system_output(cmd, shell=True) if "UUID" not in output: test.cancel("Not a valid partition given for swap creation") # Create swap partition cmd = "mkswap /dev/%s" % blk_partition process.system(cmd, shell=True) cmd = "swapon /dev/%s" % blk_partition process.system(cmd, shell=True) # Check for host memory and cpu levels and validate against # requested limits, allow to max of 10X for CPU and 2.5X for memory host_memory = int(memory.rounded_memtotal()) if maxmem: if usermaxmem: guestmemory = usermaxmem else: # Normalize to GB guestmemory = int(2.5 * host_memory / (1024 * 1024)) else: pass if not guestmemory: # assign default memory guestmemory = default_mem # Set the current and max memory params vmxml.current_mem_unit = memunit vmxml.max_mem_unit = memunit vmxml.current_mem = int(guestmemory) vmxml.max_mem = int(guestmemory) vmxml.sync() # Set vcpu and topology libvirt_xml.VMXML.set_vm_vcpus(vm_name, max_vcpu, current_vcpu, vm_sockets, vm_cores, vm_threads) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Set vnc display as needed graphics = vmxml.get_device_class('graphics')() if graphic: if not vmxml.get_graphics_devices("vnc"): graphics.add_graphic(vm_name, graphic="vnc") else: if vmxml.get_graphics_devices("vnc"): graphics.del_graphic(vm_name) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) network_str = None disk_str = None # Set network devices if max_network: network_str = "ip link|grep ^[1-9]|wc -l" for idx in range(num_network): network = Interface(type_name="bridge") network.mac_address = utils_net.generate_mac_address_simple() network.source = {"bridge": netdst} vmxml.add_device(network) # Set disk devices if max_disk: for idx in range(num_disk): disk_str = "lsblk|grep ^[s,v]|grep 1G|wc -l" disk = Disk() disk_path = os.path.join(data_dir.get_data_dir(), "images", "%s.qcow2" % idx) if "scsi" in drive_format: drive_format = "scsi" disk_target = "sd%s" % letters[(idx % 51) + 1] else: drive_format = "virtio" disk_target = "vd%s" % letters[(idx % 51) + 1] disk_source = libvirt.create_local_disk( "file", disk_path, '1', "qcow2") disk.device = "disk" disk.source = disk.new_disk_source( **{"attrs": { 'file': disk_source }}) disk.target = {"dev": disk_target, "bus": drive_format} disk.driver = {"name": "qemu", 'type': disk_format} vmxml.add_device(disk) vmxml.sync() # Start VM logging.debug("VM XML: \n%s", vmxml) try: vm.start() except virt_vm.VMStartError, detail: for msg in failures.items(): if msg[0] in detail: test.cancel("%s", msg[1]) test.fail("%s" % detail) # Check the memory and vcpu inside guest memtotal = vm.get_totalmem_sys() cpucount = vm.get_cpu_count() session = vm.wait_for_login() if network_str: guestnetworks = int(session.cmd_output(network_str)) logging.debug("guestnet: %d", guestnetworks) if (guestnetworks - 2) != num_network: failed = True logging.error( "mismatch in guest network devices: \n" "Expected: %d\nActual: %d", num_network, guestnetworks) if disk_str: guestdisks = int(session.cmd_output(disk_str)) logging.debug("guestdisk: %d", guestdisks) if guestdisks != num_disk: failed = True logging.error( "mismatch in guest disk devices: \n" "Expected: %d\nActual: %s", num_disk, guestdisks) session.close() guestmem = utils_misc.normalize_data_size("%s G" % guestmemory) # TODO:512 MB threshold deviation value, need to normalize if int(float(guestmem) - memtotal) > 512: failed = True logging.error( "mismatch in guest memory: \nExpected: " "%s\nActual: %s", float(guestmem), memtotal) if cpucount != current_vcpu: failed = True logging.error( "mismatch in guest vcpu:\nExpected: %d\nActual: " "%d", current_vcpu, cpucount) if failed: test.fail("Consult previous failures")
def run(test, params, env): """ cpu, memory, network, disk limit test: 1) prepare the guest with given topology, memory and if any devices 2) Start and login to the guest 3) Check if the guest functional 4) if given run some stress test :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. TODO: 1. Add multiple pci-bridge and pci devices respectively. 2. Get no. VM interfaces at test start and use for validation. """ failures = {"Failed to allocate KVM HPT of order": "Host does no have enough cma to boot, try increasing \ kvm_cma_resv_ratio in host boot", "unable to map backing store for guest RAM": "Not enough memory in the host to boot the guest"} vm_name = params.get("main_vm") max_vcpu = current_vcpu = int(params.get("max_vcpu", 240)) vm_cores = int(params.get("limit_vcpu_cores", 240)) vm_threads = int(params.get("limit_vcpu_threads", 1)) vm_sockets = int(params.get("limit_vcpu_sockets", 1)) usermaxmem = params.get("usermaxmem", '') default_mem = int(params.get("default_mem", 8)) maxmem = params.get("maxmem", "no") == "yes" swap_setup = params.get("swap_setup", "yes") == "yes" blk_partition = params.get("blk_part", '') graphic = params.get("graphics", "no") == "yes" vm = env.get_vm(vm_name) guestmemory = None max_network = params.get("max_network", "no") == "yes" max_disk = params.get("max_disk", "no") == "yes" num_network = int(params.get("num_network", 16)) num_disk = int(params.get("num_disk", 16)) drive_format = params.get("drive_format", "scsi") disk_format = params.get("disk_format", "qcow2") netdst = params.get("netdst", "virbr0") memunit = params.get("memunit", 'G') failed = False vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) org_xml = vmxml.copy() # Destroy the vm vm.destroy() try: # Setup swap if swap_setup: if not blk_partition: test.cancel("block partition is not given") # Check if valid partition or raise cmd = "blkid /dev/%s|awk -F" " '{print $2}'" % blk_partition output = process.system_output(cmd, shell=True) if "UUID" not in output: test.cancel("Not a valid partition given for swap creation") # Create swap partition cmd = "mkswap /dev/%s" % blk_partition process.system(cmd, shell=True) cmd = "swapon /dev/%s" % blk_partition process.system(cmd, shell=True) # Check for host memory and cpu levels and validate against # requested limits, allow to max of 10X for CPU and 2.5X for memory host_memory = int(memory.rounded_memtotal()) if maxmem: if usermaxmem: guestmemory = usermaxmem else: # Normalize to GB guestmemory = int(2.5 * host_memory/(1024 * 1024)) else: pass if not guestmemory: # assign default memory guestmemory = default_mem # Set the current and max memory params vmxml.current_mem_unit = memunit vmxml.max_mem_unit = memunit vmxml.current_mem = int(guestmemory) vmxml.max_mem = int(guestmemory) vmxml.sync() # Set vcpu and topology libvirt_xml.VMXML.set_vm_vcpus(vm_name, max_vcpu, current_vcpu, vm_sockets, vm_cores, vm_threads) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Set vnc display as needed graphics = vmxml.get_device_class('graphics')() if graphic: if not vmxml.get_graphics_devices("vnc"): graphics.add_graphic(vm_name, graphic="vnc") else: if vmxml.get_graphics_devices("vnc"): graphics.del_graphic(vm_name) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) network_str = None disk_str = None # Set network devices if max_network: network_str = "ip link|grep ^[1-9]|wc -l" for idx in range(num_network): network = Interface(type_name="bridge") network.mac_address = utils_net.generate_mac_address_simple() network.source = {"bridge": netdst} vmxml.add_device(network) # Set disk devices if max_disk: for idx in range(num_disk): disk_str = "lsblk|grep ^[s,v]|grep 1G|wc -l" disk = Disk() disk_path = os.path.join(data_dir.get_data_dir(), "images", "%s.qcow2" % idx) if "scsi" in drive_format: drive_format = "scsi" disk_target = "sd%s" % letters[(idx % 51)+1] else: drive_format = "virtio" disk_target = "vd%s" % letters[(idx % 51)+1] disk_source = libvirt.create_local_disk("file", disk_path, '1', "qcow2") disk.device = "disk" disk.source = disk.new_disk_source(**{"attrs": {'file': disk_source}}) disk.target = {"dev": disk_target, "bus": drive_format} disk.driver = {"name": "qemu", 'type': disk_format} vmxml.add_device(disk) vmxml.sync() # Start VM logging.debug("VM XML: \n%s", vmxml) try: vm.start() except virt_vm.VMStartError, detail: for msg in failures.items(): if msg[0] in detail: test.cancel("%s", msg[1]) test.fail("%s" % detail) # Check the memory and vcpu inside guest memtotal = vm.get_totalmem_sys() cpucount = vm.get_cpu_count() session = vm.wait_for_login() if network_str: guestnetworks = int(session.cmd_output(network_str)) logging.debug("guestnet: %d", guestnetworks) if (guestnetworks - 2) != num_network: failed = True logging.error("mismatch in guest network devices: \n" "Expected: %d\nActual: %d", num_network, guestnetworks) if disk_str: guestdisks = int(session.cmd_output(disk_str)) logging.debug("guestdisk: %d", guestdisks) if guestdisks != num_disk: failed = True logging.error("mismatch in guest disk devices: \n" "Expected: %d\nActual: %s", num_disk, guestdisks) session.close() guestmem = utils_misc.normalize_data_size("%s G" % guestmemory) # TODO:512 MB threshold deviation value, need to normalize if int(float(guestmem) - memtotal) > 512: failed = True logging.error("mismatch in guest memory: \nExpected: " "%s\nActual: %s", float(guestmem), memtotal) if cpucount != current_vcpu: failed = True logging.error("mismatch in guest vcpu:\nExpected: %d\nActual: " "%d", current_vcpu, cpucount) if failed: test.fail("Consult previous failures")
def run(test, params, env): """ Test virsh {at|de}tach-interface command. 1) Prepare test environment and its parameters 2) Attach the required interface 3) According test type(only attach or both attach and detach): a.Go on to test detach(if attaching is correct) b.Return GOOD or raise TestFail(if attaching is wrong) 4) Check if attached interface is correct: a.Try to catch it in vm's XML file b.Try to catch it in vm 5) Detach the attached interface 6) Check result """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Test parameters uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri", "default")) vm_ref = params.get("at_detach_iface_vm_ref", "domname") options_suffix = params.get("at_detach_iface_options_suffix", "") status_error = "yes" == params.get("status_error", "no") start_vm = params.get("start_vm") # Should attach must be pass for detach test. correct_attach = "yes" == params.get("correct_attach", "no") readonly = ("yes" == params.get("readonly", "no")) # Interface specific attributes. iface_type = params.get("at_detach_iface_type", "network") iface_source = params.get("at_detach_iface_source", "default") iface_mode = params.get("at_detach_iface_mode", "vepa") iface_mac = params.get("at_detach_iface_mac", "created") iface_target = params.get("at_detach_iface_target") iface_model = params.get("at_detach_iface_model") iface_inbound = params.get("at_detach_iface_inbound") iface_outbound = params.get("at_detach_iface_outbound") iface_rom = params.get("at_detach_rom_bar") iface_link = params.get("at_detach_link_state") iface_boot = params.get("at_detach_boot_order") iface_driver = params.get("at_detach_iface_driver") iface_driver_host = params.get("at_detach_driver_host") iface_driver_guest = params.get("at_detach_driver_guest") iface_backend = params.get("at_detach_iface_backend") save_restore = params.get("save_restore", "no") restart_libvirtd = params.get("restart_libvirtd", "no") attach_cmd = params.get("attach_cmd", "attach-interface") virsh_dargs = {'ignore_status': True, 'debug': True, 'uri': uri} validate_xml_result = "yes" == params.get("check_xml_result", "no") paused_after_vm_start = "yes" == params.get("paused_after_vm_start", "no") machine_type = params.get("machine_type") # Get iface name if iface_type is direct if iface_type == "direct": iface_source = utils_net.get_net_if(state="UP")[0] # Get a bridge name for test if iface_type is bridge. # If there is no bridge other than virbr0, try to create one # or fail test if iface_type == "bridge": host_bridge = utils_net.Bridge() bridge_list = host_bridge.list_br() try: bridge_list.remove("virbr0") except AttributeError: pass # If no virbr0, just pass is ok logging.debug("Useful bridges:%s", bridge_list) if len(bridge_list): iface_source = bridge_list[0] else: process.run('ip link add name br0 type bridge', ignore_status=False) iface_source = 'br0' logging.debug("Added bridge br0") # Test both detach and attach, So collect info # both of them for result check. # When something wrong with interface, set it to 1 fail_flag = 0 result_info = [] # Get a mac address if iface_mac is 'created'. if iface_mac == "created" or correct_attach: iface_mac = utils_net.generate_mac_address_simple() names = locals() iface_format = get_formatted_iface_dict(names, params.get("vm_arch_name")) # for rtl8139 model, need to add pcie bridge if iface_model == "rtl8139" and machine_type == "q35": add_pcie_controller(vm_name) if start_vm == "yes" and not vm.is_alive(): vm.start() try: # Generate xml file if using attach-device command if attach_cmd == "attach-device": # Change boot order to disk libvirt.change_boot_order(vm_name, "disk", "1") vm.destroy() vm.start() # Generate attached xml new_iface = Interface(type_name=iface_type) xml_file_tmp = libvirt.modify_vm_iface(vm_name, "get_xml", iface_format) new_iface.xml = xml_file_tmp new_iface.del_address() xml_file = new_iface.xml # To confirm vm's state and make sure os fully started if start_vm == "no": if vm.is_alive(): vm.destroy() else: vm.wait_for_login().close() if paused_after_vm_start: vm.pause() # Set attach-interface domain dom_uuid = vm.get_uuid() dom_id = vm.get_id() if vm_ref == "domname": vm_ref = vm_name elif vm_ref == "domid": vm_ref = dom_id elif vm_ref == "domuuid": vm_ref = dom_uuid elif vm_ref == "hexdomid" and dom_id is not None: vm_ref = hex(int(dom_id)) # Set attach-interface options and Start attach-interface test if correct_attach: options = set_options("network", "default", iface_mac, "", "attach", None, iface_model) if readonly: virsh_dargs.update({'readonly': True, 'debug': True}) attach_result = virsh.attach_interface(vm_name, options, **virsh_dargs) else: if attach_cmd == "attach-interface": options = set_options(iface_type, iface_source, iface_mac, options_suffix, "attach", iface_target, iface_model, iface_inbound, iface_outbound) attach_result = virsh.attach_interface(vm_ref, options, **virsh_dargs) elif attach_cmd == "attach-device": attach_result = virsh.attach_device(vm_name, xml_file, ignore_status=True, debug=True) attach_status = attach_result.exit_status logging.debug(attach_result) # If attach interface failed. if attach_status: if not status_error: fail_flag = 1 result_info.append("Attach Failed: %s" % attach_result.stderr) elif status_error: # Here we just use it to exit, do not mean test failed fail_flag = 1 # If attach interface succeeded. else: if status_error and not correct_attach: fail_flag = 1 result_info.append("Attach Success with wrong command.") if fail_flag and start_vm == "yes": vm.destroy() if len(result_info): test.fail(result_info) else: # Exit because it is error_test for attach-interface. return if "print-xml" in options_suffix: iface_obj = Interface(type_name=iface_type) iface_obj.xml = attach_result.stdout.strip() if (iface_obj.type_name == iface_type and iface_obj.source['dev'] == iface_source and iface_obj.target['dev'] == iface_target and iface_obj.model == iface_model and iface_obj.bandwidth.inbound == eval( iface_format['inbound']) and iface_obj.bandwidth.outbound == eval( iface_format['outbound'])): logging.info("Print ml all element check pass") else: test.fail("Print xml do not show as expected") # Check dumpxml file whether the interface is added successfully. status, ret = check_dumpxml_iface(vm_name, iface_format) if "print-xml" not in options_suffix: # Check validate_xml_result flag to determine whether apply check_interface_xml. if validate_xml_result: # If options_suffix contains config, it need dump inactive xml. is_active = True if options_suffix.count("config"): is_active = False # Check dumping VM xml value. if not check_interface_xml(vm_name, iface_type, iface_source, iface_mac, is_active): test.fail( "Failed to find matched interface values in VM interface xml" ) if status: fail_flag = 1 result_info.append(ret) else: if status == 0: test.fail( "Attach interface effect in xml with print-xml option") else: return # Login to domain to check new interface. if not vm.is_alive(): vm.start() elif vm.state() == "paused": vm.resume() vm.wait_for_login().close() status, ret = login_to_check(vm, iface_mac) if status: fail_flag = 1 result_info.append(ret) # Check on host for direct type if iface_type == 'direct': cmd_result = process.run( "ip -d link show test").stdout_text.strip() logging.info("cmd output is %s", cmd_result) check_patten = ( "%s@%s.*\n.*%s.*\n.*macvtap.*mode.*%s" % (iface_target, iface_source, iface_mac, iface_mode)) logging.info("check patten is %s", check_patten) if not re.search(check_patten, cmd_result): logging.error("Can not find %s in ip link" % check_patten) fail_flag = 1 result_info.append(cmd_result) # Do operation and check again if restart_libvirtd == "yes": libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() if save_restore == "yes": check_save_restore(vm_name) status, ret = check_dumpxml_iface(vm_name, iface_format) if status: fail_flag = 1 result_info.append(ret) # Set detach-interface options options = set_options(iface_type, None, iface_mac, options_suffix, "detach") # Start detach-interface test if save_restore == "yes" and vm_ref == dom_id: vm_ref = vm_name detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs) detach_status = detach_result.exit_status detach_msg = detach_result.stderr.strip() logging.debug(detach_result) if detach_status == 0 and status_error == 0: # If command with --config parameter, ignore below checking. if options_suffix.count("config"): return # Check the xml after detach and clean up if needed. time.sleep(5) status, _ = check_dumpxml_iface(vm_name, iface_format) if status == 0: detach_status = 1 detach_msg = "xml still exist after detach" cleanup_options = "--type %s --mac %s" % (iface_type, iface_mac) virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs) else: logging.info("After detach, the interface xml disappeared") # Check results. if status_error: if detach_status == 0: test.fail("Detach Success with wrong command.") else: if detach_status != 0: test.fail("Detach Failed: %s" % detach_msg) else: if fail_flag: test.fail("Attach-Detach Success but " "something wrong with its " "functional use:%s" % result_info) finally: if vm.is_alive(): vm.destroy() backup_xml.sync()
def run(test, params, env): """ Test pci/pcie-to-pci bridge Hotplug interface to pci/pcie-to-pci bridge, then check xml and inside vm. Hotunplug interface, then check xml and inside vm """ vm_name = params.get('main_vm') pci_model = params.get('pci_model', 'pci') hotplug = 'yes' == params.get('hotplug', 'no') pci_model_name = params.get('pci_model_name') pci_br_has_device = 'yes' == params.get('pci_br_has_device', 'no') sound_dev_model_type = params.get('sound_dev_model_type', '') sound_dev_address = params.get('sound_dev_address', '') iface_model = params.get('iface_model', '') iface_source = params.get('iface_source', '') vmxml = VMXML.new_from_inactive_dumpxml(vm_name) bkxml = vmxml.copy() vm = env.get_vm(vm_name) try: # Check if there is a pci/pcie-to-pci bridge, if so, # just use the existing pci/pcie-to-pci-bridge to test ori_pci_br = [ dev for dev in vmxml.get_devices('controller') if dev.type == 'pci' and dev.model == pci_model ] # If there is not a pci/pcie-to-pci bridge to test, # create one and add to vm if not ori_pci_br: logging.info('No %s on vm, create one', pci_model) pci_bridge = Controller('pci') pci_bridge.model = pci_model pci_bridge.model_name = {'name': pci_model_name} vmxml.add_device(pci_bridge) vmxml.sync() logging.debug(virsh.dumpxml(vm_name)) # Check if pci/pcie-to-pci bridge is successfully added vmxml = VMXML.new_from_inactive_dumpxml(vm_name) cur_pci_br = [ dev for dev in vmxml.get_devices('controller') if dev.type == 'pci' and dev.model == pci_model ] if not cur_pci_br: test.error('Failed to add %s controller to vm xml' % pci_model) pci_br = cur_pci_br[0] logging.debug(pci_br) pci_br_index = pci_br.index # If test scenario requires another pci device on pci/pcie-to-pci # bridge before hotplug, add a sound device and make sure # the 'bus' is same with pci bridge index if pci_br_has_device: sound_dev = Sound() sound_dev.model_type = sound_dev_model_type sound_dev.address = eval(sound_dev_address % pci_br_index) logging.debug(sound_dev.address) vmxml.add_device(sound_dev) vmxml.sync() # Test hotplug scenario if hotplug: vm.start() vm.wait_for_login().close() # Create interface to be hotplugged logging.info('Create interface to be hotplugged') iface = Interface('network') iface.model = iface_model iface.source = eval(iface_source) mac = utils_net.generate_mac_address_simple() iface.mac_address = mac logging.debug(iface) result = virsh.attach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(result) xml_after_attach = VMXML.new_from_dumpxml(vm_name) logging.debug(virsh.dumpxml(vm_name)) # Check if the iface with given mac address is successfully attached iface_list = [ iface for iface in xml_after_attach.get_devices('interface') if iface.mac_address == mac ] logging.debug('iface list after attach: %s', iface_list) if not iface_list: test.error('Failed to attach interface %s' % iface) # Check inside vm def check_inside_vm(session, expect=True): ip_output = session.cmd('ip a') logging.debug(ip_output) return expect if mac in ip_output else not expect session = vm.wait_for_serial_login() if not utils_misc.wait_for(lambda: check_inside_vm(session, True), timeout=60, step=5): test.fail('Check interface inside vm failed,' 'interface not successfully attached:' 'not found mac address %s' % mac) session.close() # Test hotunplug result = virsh.detach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(result) logging.debug(virsh.dumpxml(vm_name)) # Check if the iface with given mac address has been # successfully detached xml_after_detach = VMXML.new_from_dumpxml(vm_name) iface_list_after_detach = [ iface for iface in xml_after_detach.get_devices('interface') if iface.mac_address == mac ] logging.debug('iface list after detach: %s', iface_list_after_detach) if iface_list_after_detach: test.fail('Failed to detach device: %s', iface) # Check again inside vm session = vm.wait_for_serial_login() if not utils_misc.wait_for(lambda: check_inside_vm(session, False), timeout=60, step=5): test.fail('Check interface inside vm failed,' 'interface not successfully detached:' 'found mac address %s' % mac) session.close() finally: bkxml.sync()
def run(test, params, env): """ Test virsh {at|de}tach-interface command. 1) Prepare test environment and its parameters 2) Attach the required interface 3) According test type(only attach or both attach and detach): a.Go on to test detach(if attaching is correct) b.Return GOOD or raise TestFail(if attaching is wrong) 4) Check if attached interface is correct: a.Try to catch it in vm's XML file b.Try to catch it in vm 5) Detach the attached interface 6) Check result """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Test parameters uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri", "default")) vm_ref = params.get("at_detach_iface_vm_ref", "domname") options_suffix = params.get("at_detach_iface_options_suffix", "") status_error = "yes" == params.get("status_error", "no") start_vm = params.get("start_vm") # Should attach must be pass for detach test. correct_attach = "yes" == params.get("correct_attach", "no") readonly = ("yes" == params.get("readonly", "no")) # Interface specific attributes. iface_type = params.get("at_detach_iface_type", "network") if iface_type == "bridge": try: utils_path.find_command("brctl") except utils_path.CmdNotFoundError: test.cancel("Command 'brctl' is missing. You must " "install it.") iface_source = params.get("at_detach_iface_source", "default") iface_mode = params.get("at_detach_iface_mode", "vepa") iface_mac = params.get("at_detach_iface_mac", "created") iface_target = params.get("at_detach_iface_target") iface_model = params.get("at_detach_iface_model") iface_inbound = params.get("at_detach_iface_inbound") iface_outbound = params.get("at_detach_iface_outbound") iface_rom = params.get("at_detach_rom_bar") iface_link = params.get("at_detach_link_state") iface_boot = params.get("at_detach_boot_order") iface_driver = params.get("at_detach_iface_driver") iface_driver_host = params.get("at_detach_driver_host") iface_driver_guest = params.get("at_detach_driver_guest") iface_backend = params.get("at_detach_iface_backend") save_restore = params.get("save_restore", "no") restart_libvirtd = params.get("restart_libvirtd", "no") attach_cmd = params.get("attach_cmd", "attach-interface") virsh_dargs = {'ignore_status': True, 'debug': True, 'uri': uri} # Get iface name if iface_type is direct if iface_type == "direct": iface_source = utils_net.get_net_if(state="UP")[0] # Get a bridge name for test if iface_type is bridge. # If there is no bridge other than virbr0, raise TestCancel if iface_type == "bridge": host_bridge = utils_net.Bridge() bridge_list = host_bridge.list_br() try: bridge_list.remove("virbr0") except AttributeError: pass # If no virbr0, just pass is ok logging.debug("Useful bridges:%s", bridge_list) # just choosing one bridge on host. if len(bridge_list): iface_source = bridge_list[0] else: test.cancel("No useful bridge on host " "other than 'virbr0'.") # Test both detach and attach, So collect info # both of them for result check. # When something wrong with interface, set it to 1 fail_flag = 0 result_info = [] # Get a mac address if iface_mac is 'created'. if iface_mac == "created" or correct_attach: iface_mac = utils_net.generate_mac_address_simple() # Record all iface parameters in iface_dict iface_dict = {} update_list = [ "driver", "driver_host", "driver_guest", "model", "rom", "inbound", "outbound", "link", "target", "mac", "source", "boot", "backend", "type", "mode" ] names = locals() for update_item in update_list: if names["iface_"+update_item]: iface_dict.update({update_item: names["iface_"+update_item]}) else: iface_dict.update({update_item: None}) logging.info("iface_dict is %s", iface_dict) # Format the params iface_format = format_param(iface_dict) logging.info("iface_format is %s", iface_format) try: # Generate xml file if using attach-device command if attach_cmd == "attach-device": # Change boot order to disk libvirt.change_boot_order(vm_name, "disk", "1") vm.destroy() vm.start() # Generate attached xml xml_file_tmp = libvirt.modify_vm_iface(vm_name, "get_xml", iface_format) new_iface = Interface(type_name=iface_type) new_iface.xml = xml_file_tmp new_iface.del_address() xml_file = new_iface.xml # To confirm vm's state and make sure os fully started if start_vm == "no": if vm.is_alive(): vm.destroy() else: vm.wait_for_login().close() # Set attach-interface domain dom_uuid = vm.get_uuid() dom_id = vm.get_id() if vm_ref == "domname": vm_ref = vm_name elif vm_ref == "domid": vm_ref = dom_id elif vm_ref == "domuuid": vm_ref = dom_uuid elif vm_ref == "hexdomid" and dom_id is not None: vm_ref = hex(int(dom_id)) # Set attach-interface options and Start attach-interface test if correct_attach: options = set_options("network", "default", iface_mac, "", "attach") if readonly: virsh_dargs.update({'readonly': True, 'debug': True}) attach_result = virsh.attach_interface(vm_name, options, **virsh_dargs) else: if attach_cmd == "attach-interface": options = set_options(iface_type, iface_source, iface_mac, options_suffix, "attach", iface_target, iface_model, iface_inbound, iface_outbound) attach_result = virsh.attach_interface(vm_ref, options, **virsh_dargs) elif attach_cmd == "attach-device": attach_result = virsh.attach_device(vm_name, xml_file, ignore_status=True, debug=True) attach_status = attach_result.exit_status logging.debug(attach_result) # If attach interface failed. if attach_status: if not status_error: fail_flag = 1 result_info.append("Attach Failed: %s" % attach_result.stderr) elif status_error: # Here we just use it to exit, do not mean test failed fail_flag = 1 # If attach interface succeeded. else: if status_error and not correct_attach: fail_flag = 1 result_info.append("Attach Success with wrong command.") if fail_flag and start_vm == "yes": vm.destroy() if len(result_info): test.fail(result_info) else: # Exit because it is error_test for attach-interface. return if "print-xml" in options_suffix: iface_obj = Interface(type_name=iface_type) iface_obj.xml = attach_result.stdout.strip() if (iface_obj.type_name == iface_type and iface_obj.source['dev'] == iface_source and iface_obj.target['dev'] == iface_target and iface_obj.model == iface_model and iface_obj.bandwidth.inbound == eval(iface_format['inbound']) and iface_obj.bandwidth.outbound == eval(iface_format['outbound'])): logging.info("Print ml all element check pass") else: test.fail("Print xml do not show as expected") # Check dumpxml file whether the interface is added successfully. status, ret = check_dumpxml_iface(vm_name, iface_format) if "print-xml" not in options_suffix: if status: fail_flag = 1 result_info.append(ret) else: if status == 0: test.fail("Attach interface effect in xml with print-xml option") else: return # Login to domain to check new interface. if not vm.is_alive(): vm.start() elif vm.state() == "paused": vm.resume() status, ret = login_to_check(vm, iface_mac) if status: fail_flag = 1 result_info.append(ret) # Check on host for direct type if iface_type == 'direct': cmd_result = process.run("ip -d link show test").stdout_text.strip() logging.info("cmd output is %s", cmd_result) check_patten = ("%s@%s.*\n.*%s.*\n.*macvtap.*mode.*%s" % (iface_target, iface_source, iface_mac, iface_mode)) logging.info("check patten is %s", check_patten) if not re.search(check_patten, cmd_result): logging.error("Can not find %s in ip link" % check_patten) fail_flag = 1 result_info.append(cmd_result) # Do operation and check again if restart_libvirtd == "yes": libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() if save_restore == "yes": check_save_restore(vm_name) status, ret = check_dumpxml_iface(vm_name, iface_format) if status: fail_flag = 1 result_info.append(ret) # Set detach-interface options options = set_options(iface_type, None, iface_mac, options_suffix, "detach") # Start detach-interface test if save_restore == "yes" and vm_ref == dom_id: vm_ref = vm_name detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs) detach_status = detach_result.exit_status detach_msg = detach_result.stderr.strip() logging.debug(detach_result) if detach_status == 0 and status_error == 0: # Check the xml after detach and clean up if needed. time.sleep(5) status, _ = check_dumpxml_iface(vm_name, iface_format) if status == 0: detach_status = 1 detach_msg = "xml still exist after detach" cleanup_options = "--type %s --mac %s" % (iface_type, iface_mac) virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs) else: logging.info("After detach, the interface xml disappeared") # Check results. if status_error: if detach_status == 0: test.fail("Detach Success with wrong command.") else: if detach_status != 0: test.fail("Detach Failed: %s" % detach_msg) else: if fail_flag: test.fail("Attach-Detach Success but " "something wrong with its " "functional use:%s" % result_info) finally: if vm.is_alive(): vm.destroy() backup_xml.sync()