def set_env(): """ set two interface with different network filter and change interface type """ # Add enough PCI to attach interface libvirt_pcicontr.reset_pci_num(vm_name) virsh.attach_interface(vm_name, option, debug=True) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) logging.debug("Guest xml is {}".format(vmxml)) devices = vmxml.get_devices('interface') iface_xml = devices[0] iface_xml_2 = devices[1] vmxml.del_device(iface_xml) vmxml.del_device(iface_xml_2) new_iface_1 = interface.Interface('network') new_iface_2 = interface.Interface('network') new_iface_1.xml = iface_xml.xml new_iface_2.xml = iface_xml_2.xml new_iface_1.type_name = "network" new_iface_2.type_name = "network" new_iface_1.source = {'network': source_network} new_iface_2.source = {'network': source_network} new_iface_1.target = {'dev': 'new_net0'} new_iface_2.target = {'dev': 'new_net1'} new_filterref = new_iface_1.new_filterref(**filterref_dict_1) new_iface_1.filterref = new_filterref new_filterref = new_iface_2.new_filterref(**filterref_dict_2) new_iface_2.filterref = new_filterref logging.debug("new interface xml is: %s \n %s" % (new_iface_1, new_iface_2)) vmxml.add_device(new_iface_1) vmxml.add_device(new_iface_2) vmxml.sync() return new_iface_1, new_iface_2
def env_setting(filterref_dict_1, filterref_dict_2): ret = virsh.attach_interface(vm_name, option) utlv.check_exit_status(ret, status_error) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) devices = vmxml.get_devices('interface') iface_xml = devices[0] logging.debug("iface_xml : %s" % iface_xml) iface_xml_2 = devices[1] vmxml.del_device(iface_xml) vmxml.del_device(iface_xml_2) new_iface_1 = interface.Interface('network') logging.debug("new_iface_1 : %s" % new_iface_1) new_iface_2 = interface.Interface('network') new_iface_1.xml = iface_xml.xml new_iface_1.type_name = "network" logging.debug("new_iface_1 : %s" % new_iface_1) new_iface_2.xml = iface_xml_2.xml new_iface_1.source = {'network': "default"} new_filterref = new_iface_1.new_filterref(**filterref_dict_1) new_iface_1.filterref = new_filterref new_filterref = new_iface_2.new_filterref(**filterref_dict_2) new_iface_2.filterref = new_filterref logging.debug("new interface xml is: %s \n %s" % (new_iface_1, new_iface_2)) vmxml.add_device(new_iface_1) vmxml.add_device(new_iface_2) vmxml.sync() return new_iface_1, new_iface_2
def test_setup_iface_default(self): iface = interface.Interface() iface.setup_attrs(**iface_attrs) cmp_device = interface.Interface() cmp_device.xml = XML.strip() self.assertEqual(iface, cmp_device)
def test_hotplug_hostdev_iface_with_teaming(): logging.info("Attach the bridge and hostdev interfaces.") iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) hostdev_iface_xml = create_hostdev_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, hostdev_iface_xml, debug=True, ignore_status=False) check_ifaces(vm_name, expected_ifaces={"bridge", "hostdev"}) vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) logging.info("Detach the hostdev interface.") hostdev_iface = interface.Interface("network") for ifc in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface"): if ifc.type_name == "hostdev": ifc.del_address() hostdev_iface = ifc virsh.detach_device(vm_name, hostdev_iface.xml, wait_remove_event=True, debug=True, ignore_status=False) check_ifaces(vm_name, expected_ifaces={"hostdev"}, status_error=True) check_vm_network_accessed(vm_session, 2, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=False) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) logging.info("Re-attach the hostdev interface.") virsh.attach_device(vm_name, hostdev_iface.xml, debug=True, ignore_status=False) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True)
def set_env(): """ prepare the vm interface xml this xml can both use in two senario. but little different for two senario """ vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_iface.type_name = "network" iface_target = {'dev': target_dev} new_iface.target = iface_target source = {'network': source_network, 'bridge': source_bridge} new_iface.source = source filterrefs_dict = {} filterrefs_dict['name'] = filter_name filterrefs_dict['parameters'] = [] new_filterref = new_iface.new_filterref(**filterrefs_dict) new_iface.filterref = new_filterref alias_dict = {'name': alias_name} new_iface.alias = alias_dict vmxml.add_device(new_iface) logging.debug("new interface xml is: %s" % new_iface) vmxml.sync() return new_iface
def setup_save_restore_hostdev_iface_with_teaming(): logging.info("Create hostdev network.") net_hostdev_fwd = params.get("net_hostdev_fwd", '{"mode": "hostdev", "managed": "yes"}') net_hostdev_dict = { "net_name": net_hostdev_name, "net_forward": net_hostdev_fwd, "net_forward_pf": '{"dev": "%s"}' % pf_name } libvirt_network.create_or_del_network(net_hostdev_dict) libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) iface.xml = create_hostdev_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) vmxml.sync() logging.debug("VMXML after updating ifaces: %s.", vm_xml.VMXML.new_from_dumpxml(vm_name)) vm.start() vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True)
def test_vf_hotplug(): """ Hot-plug VF to VM """ logging.info("Preparing a running guest...") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vm.start() vm_session = vm.wait_for_serial_login(timeout=180) logging.info("Attaching VF to the guest...") mac_addr = utils_net.generate_mac_address_simple() iface_dict = eval( params.get('iface_dict', '{"hostdev_addr": "%s"}') % utils_sriov.pci_to_addr(vf_pci)) iface = interface.Interface("hostdev") iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", iface_dict) virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) logging.info("Checking VF in the guest...") vm_iface_types = [ iface.get_type_name() for iface in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface") ] if 'hostdev' not in vm_iface_types: test.fail('Unable to get hostdev interface!') if cmd_in_vm: if not utils_misc.wait_for( lambda: not vm_session.cmd_status(cmd_in_vm), 30, 10): test.fail("Can not get the Virtual Function info on vm!") vm_session.close()
def update_iface_xml(vmxml): """ Update interfaces for guest :param vmxml: vm_xml.VMXML object """ vmxml.remove_all_device_by_type('interface') vmxml.sync() iface_dict = {"type": "network", "source": "{'network': 'host-bridge'}", "mac": mac_addr, "model": "virtio", "teaming": '{"type":"persistent"}', "alias": '{"name": "ua-backup0"}', "inbound": '{"average":"5"}', "outbound": '{"average":"5"}'} iface_dict2 = {"type": "network", "source": "{'network': 'hostdev-net'}", "mac": mac_addr, "model": "virtio", "teaming": '{"type":"transient", "persistent": "ua-backup0"}'} iface = interface.Interface('network') for ifc in (iface_dict, iface_dict2): iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", ifc) vmxml.add_device(iface) vmxml.sync()
def attach_new_device(): newnet_iface = interface.Interface('network') newnet_iface.source = {'network': "default"} filterref_dict = {} filterref_list = [{'name': "CTRL_IP_LEARNING", 'value': "dhcp"}] filterref_dict['name'] = "clean-traffic" filterref_dict['parameters'] = filterref_list newnet_iface.filterref = newnet_iface.new_filterref(**filterref_dict) ret = virsh.attach_device(domainarg=vm_name, filearg=newnet_iface.xml, debug=True) utlv.check_exit_status(ret, status_error)
def create_iface(iface_dict): """ Create Interface device :param iface_dict: Dict, attrs of Interface :return: xml object of interface """ iface = interface.Interface("network") iface.setup_attrs(**iface_dict) logging.debug("Interface XML: %s", iface) return iface
def set_env(): vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() return new_iface
def set_env(): vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_iface.type_name = "network" new_iface.source = {'network': "default"} filter_dict = {} filter_dict['name'] = filter_name filter_dict['parameters'] = [] new_iface.filterref = new_iface.new_filterref(**filter_dict) logging.debug("new iface is %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync()
def update_iface_xml(vm_name, iface_dict): """ Update interfaces for guest :param vm_name: The name of VM :param iface_dict: The interface configurations params """ logging.debug("update iface xml") vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) vmxml.remove_all_device_by_type('interface') vmxml.sync() iface = interface.Interface('network') iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", iface_dict) libvirt.add_vm_device(vmxml, iface)
def setup_save_restore_hostdev_device_with_teaming(): logging.info("Start a VM with bridge iface and hostdev device.") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) hostdev_dev = libvirt.create_hostdev_xml(vf_pci, teaming=hostdev_teaming_dict) vmxml.add_device(hostdev_dev) vmxml.sync() vm.start() utils_sriov.set_vf_mac(pf_name, mac_addr) vm.wait_for_serial_login(timeout=240).close()
def detach_iface_device(vm_name, dev_type): """ Detach an interface from VM :param vm_name: VM's name :param dev_type: Interface device type """ iface = interface.Interface(dev_type) iface = vm_xml.VMXML.new_from_dumpxml(vm_name).devices.by_device_tag( "interface")[0] virsh.detach_device(vm_name, iface.xml, wait_for_event=True, debug=True, ignore_status=False) libvirt_vmxml.check_guest_xml(vm_name, dev_type, status_error=True)
def prepare_env(): vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_iface.type_name = "network" new_iface.source = {'network': "default", 'bridge': "virbr0"} alias_dict = {'name': "net0"} new_iface.alias = alias_dict target_dict = {'dev': "vnet0"} new_iface.target = target_dict logging.debug("new interface xml is : %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() return new_iface
def test_device_hotplug(): """ Hotplug/unplug VF with managed='no' 1) Prepare a running guest 2) Check the driver of vf on host 3) Prepare a xml with "managed=no"and attach to guest 4) Detach the device from host 5) Check the driver of vf on host 6) Attach the device to guest 7) Check the interface of the guest 8) Detach the device from guest and check the driver 9) Reattach the device to the host and check the driver """ libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') start_vm(vm) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) mac_addr = utils_net.generate_mac_address_simple() iface_dict = eval( params.get('iface_dict', '{"hostdev_addr": "%s"}') % utils_sriov.pci_to_addr(vf_pci)) iface = interface.Interface("hostdev") iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", iface_dict) res = virsh.attach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(res, True) virsh.nodedev_detach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci) virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) check_vm_iface_managed(vm_name, iface_dict) vm.wait_for_serial_login().close() virsh.detach_device(vm_name, iface.xml, wait_remove_event=True, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci) virsh.nodedev_reattach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True)
def update_iface_xml(vm_name, iface_dict, virsh_instance=virsh): """ Update interfaces for guest :param vm_name: The name of VM :param iface_dict: The interface configurations params :param virsh_instance: virsh instance object """ logging.debug("update iface xml") vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( vm_name, virsh_instance=virsh_instance) vmxml.remove_all_device_by_type('interface') vm_sync(vmxml, vm_name, virsh_instance=virsh_instance) iface = interface.Interface('network') iface.xml = libvirt.modify_vm_iface(vm_name, "get_xml", iface_dict, virsh_instance=virsh_instance) vmxml.add_device(iface) vmxml.xmltreefile.write() vm_sync(vmxml, vm_name, virsh_instance=virsh_instance) logging.debug("VM XML after updating interface: %s" % vmxml)
def run_invalid_interface(params, libvirtd, vm): """ Define a domain with an invalid interface device. """ vm_name = vm.name vm_xml = VMXML.new_from_inactive_dumpxml(vm_name) vm_xml_backup = vm_xml.copy() try: iface_xml = interface.Interface('bridge') iface_xml.set_target({'dev': 'vnet'}) devices = vm_xml.devices devices.append(iface_xml) vm_xml.devices = devices try: vm_xml.sync() except LibvirtXMLError: pass finally: vm_xml_backup.sync()
def setup_hotplug_hostdev_iface_with_teaming(): logging.info("Create hostdev network.") net_hostdev_fwd = params.get("net_hostdev_fwd", '{"mode": "hostdev", "managed": "yes"}') net_hostdev_dict = { "net_name": net_hostdev_name, "net_forward": net_hostdev_fwd, "net_forward_pf": '{"dev": "%s"}' % pf_name } libvirt_network.create_or_del_network(net_hostdev_dict) logging.info("Clear up VM interface.") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, iface.xml, flagstr='--persistent', debug=True, ignore_status=False) vm.start() vm.wait_for_serial_login(timeout=180).close()
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") attach_option = params.get("attach_option", "") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") attach_twice_invalid = "yes" == params.get("attach_twice_invalid", "no") status_error = "yes" == params.get("status_error", "no") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) # Prepare vm filterref parameters dict list filterref_dict = {} filterref_dict['name'] = filter_name # Prepare interface parameters iface_type = 'network' iface_source = {'network': 'default'} iface_target = params.get("iface_target", 'vnet1') # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() try: # Prepare interface xml for attach new_iface = interface.Interface(type_name=iface_type) new_iface.source = iface_source new_iface.target = {'dev': iface_target} new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref new_iface.model = "virtio" logging.debug("new interface xml is: %s" % new_iface) # Attach interface to vm ret = virsh.attach_device(vm_name, new_iface.xml, flagstr=attach_option, debug=True, ignore_status=True) utlv.check_exit_status(ret, status_error) if attach_twice_invalid: ret = virsh.attach_device(vm_name, new_iface.xml, flagstr=attach_option, debug=True, ignore_status=True) utlv.check_exit_status(ret, status_error) if not libvirtd.is_running(): test.fail("libvirtd not running after attach " "interface.") # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system(check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) out = astring.to_text(process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) finally: if attach_twice_invalid: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync()
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() device_name = None try: rule = params.get("rule") if rule: # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: pkg = "ipset" if not utils_package.package_install(pkg): test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) # This change anchors nwfilter_vm_start.possitive_test.new_filter.variable_notation case # The matched destination could be ip address or hostname if "iptables -L" in check_cmd and expect_match: # ip address that need to be replaced replace_param = params.get("parameter_value_2") #Get hostname by ip address. hostname_info = None try: hostname_info = socket.gethostbyaddr(replace_param) except socket.error as e: logging.info( "Failed to get hostname from ip address with error: %s", str(e)) if hostname_info: # String is used to replace ip address replace_with = "%s|%s" % (replace_param, hostname_info[0]) expect_match = r"%s" % expect_match.replace( replace_param, replace_with) logging.debug("final iptables match string:%s", expect_match) out = to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -s TERM `pidof libvirtd`" process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) # After libvirt 5.6.0, libvirtd is using systemd socket activation by default if not ret and not libvirt_version.version_compare(5, 6, 0): test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True)
def run(test, params, env): """ Test bridge support from network 1) create a linux bridge and connect a physical interface to it 2) define nwfilter with "vdsm-no-mac-spoofing" 3) redefine the vm with the new create bridge and filter 4) check if guest can get public ip after vm start 5) check if guest and host can ping each other 6) check if guest and host can ping outside 7) start another vm connected to the same bridge 8) check if the 2 guests can ping each other """ def create_bridge(br_name, iface_name): """ Create a linux bridge by virsh cmd: 1. Stop NetworkManager and Start network service 2. virsh iface-bridge <iface> <name> [--no-stp] :param br_name: bridge name :param iface_name: physical interface name :return: bridge created or raise exception """ # 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 create_bridge_network(br_name, net_name): """ Define and start the bridge type network """ # check if network with the same name already exists output_all = virsh.net_list("--all").stdout.strip() if re.search(net_name, output_all): test.cancel("Network with the same name already exists!") test_xml = network_xml.NetworkXML(network_name="%s" % net_name) test_xml.forward = {"mode": "bridge"} test_xml.bridge = {"name": br_name} test_xml.create() def define_nwfilter(filter_name): """ Define nwfilter vdsm-no-mac-spoofing with content like: <filter name='vdsm-no-mac-spoofing' chain='root'> <filterref filter='no-mac-spoofing'/> <filterref filter='no-arp-mac-spoofing'/> </filter> :param filter_name: the name of nwfilter :return: filter created or raise exception """ filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") filter_params = { "filter_name": "vdsm-no-mac-spoofing", "filter_chain": "root", "filter_uuid": filter_uuid, "filterref_name_1": "no-mac-spoofing", "filterref_name_2": "no-arp-mac-spoofing" } filter_xml = libvirt.create_nwfilter_xml(filter_params).xml # Run command result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True) if result.exit_status: test.fail("Failed to define nwfilter with %s" % filter_xml) def ping(src_ip, dest_ip, ping_count, timeout, session=None): """ Wrap of ping :param src_ip: source address :param dest_ip: destination address :param ping_count: count of icmp packet :param timeout: timeout for the ping command :param session: local execution or session to execute the ping command :return: ping succeed or raise exception """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session, force_ipv4=True) if status: test.fail("Fail to ping %s from %s" % (dest_ip, src_ip)) def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session, host_ip, remote_url, endpoint_ip): # make sure host network works well # host ping remote url ping(host_ip, remote_url, ping_count, ping_timeout) # host ping guest ping(host_ip, guest_ip, ping_count, ping_timeout) # guest ping host ping(guest_ip, host_ip, ping_count, ping_timeout, session=guest_session) # guest ping remote url ping(guest_ip, remote_url, ping_count, ping_timeout, session=guest_session) # guest ping endpoint ping(guest_ip, endpoint_ip, ping_count, ping_timeout, session=guest_session) # Get test params bridge_name = params.get("bridge_name", "test_br0") filter_name = params.get("filter_name", "vdsm-no-mac-spoofing") ping_count = params.get("ping_count", "5") ping_timeout = float(params.get("ping_timeout", "10")) iface_name = utils_net.get_net_if(state="UP")[0] bridge_script = NETWORK_SCRIPT + bridge_name iface_script = NETWORK_SCRIPT + iface_name iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name) attach_interface = "yes" == params.get("attach_interface", "no") iface_model = params.get("iface_model", "virtio") iface_source = eval(params.get("iface_source", "{'bridge':'test_br0'}")) iface_type = params.get("iface_type", None) iface_target = params.get("iface_target", "br_target") iface_alias = params.get("iface_alias", None) hotplug = "yes" == params.get("hotplug", "no") iface_driver = params.get("iface_driver", None) start_vm2 = "yes" == params.get("start_vm2", "no") create_network = "yes" == params.get("create_network", "no") update_device = "yes" == params.get("update_with_diff_type", "no") vms = params.get("vms").split() if len(vms) <= 1: test.cancel("Need two VMs to test") else: vm1_name = vms[0] vm2_name = vms[1] vm1 = env.get_vm(vm1_name) vm2 = env.get_vm(vm2_name) # Back up the interface script process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True, verbose=True) # Back up vm xml vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name) vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name) # Stop NetworkManager service NM_service = service.Factory.create_service("NetworkManager") NM_status = NM_service.status() if not NM_status: NM_service.start() mac = utils_net.generate_mac_address_simple() try: create_bridge(bridge_name, iface_name) define_nwfilter(filter_name) if hotplug: err_msgs = ("No more available PCI slots", "No more available PCI addresses") # delete the original interface on the vm before hot-plug if vm1.is_alive(): vm1.destroy() vmxml = vm_xml.VMXML.new_from_dumpxml(vm1_name) iface_xml = vmxml.get_devices('interface')[0] logging.debug("Delete the original interface") vmxml.del_device(iface_xml) vmxml.sync() vm1.start() # do hot-plug if attach_interface: logging.info("Try to hot-plug interface") options = ( "%s %s --model %s --mac %s" % (iface_type, iface_source['bridge'], iface_model, mac)) ret = virsh.attach_interface(vm1_name, options, ignore_status=True) else: logging.info("Try to hot-plug device") if create_network: create_bridge_network(bridge_name, iface_source["network"]) target = str({'dev': iface_target}) iface_alias = str({'name': iface_alias}) vm_iface_source = str(iface_source) iface_params = { "type": iface_type, "source": vm_iface_source, "filter": filter_name, "mac": mac, 'alias': iface_alias, 'target': target, 'model': iface_model, 'driver': iface_driver } attach_xml = interface.Interface(iface_params['type']) attach_xml.xml = libvirt.modify_vm_iface( vm1_name, 'get_xml', iface_params) ret = virsh.attach_device(vm1_name, attach_xml.xml, ignore_status=True, debug=True) if ret.exit_status: if any([msg in ret.stderr for msg in err_msgs]): test.error("No more pci slots, can't attach more devices") else: test.fail("Failed to attach-interface: %s" % ret.stderr.strip()) else: logging.debug("Hot-plug interface or device pass") if update_device: # As the interface type will change to actual type "bridge" in live xml, we need to ensure # the update with original "network" type will not fail. # Try to delete the nwfilter with original type in iface_params update_xml = interface.Interface(iface_type) iface_params_update = { "del_filter": "yes", "type": "network", "source": vm_iface_source } update_xml.xml = libvirt.modify_vm_iface( vm1_name, 'get_xml', iface_params_update) ret = virsh.update_device(vm1_name, update_xml.xml, ignore_status=True, debug=True) libvirt.check_exit_status(ret) else: vm_iface_source = str(iface_source) vm1_iface_params = { "type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac, 'driver': iface_driver, "iface_model": iface_model } libvirt.modify_vm_iface(vm1_name, "update_iface", vm1_iface_params) if vm1.is_alive(): vm1.destroy() vm1.start() # apply ip address as it may not be initialized session1 = session2 = None session1 = vm1.wait_for_serial_login() utils_net.restart_guest_network(session1) output = session1.cmd_output("ifconfig || ip a") logging.debug("guest1 ip info %s" % output) # Check guest's network function host_ip = utils_net.get_ip_address_by_interface(bridge_name) remote_url = params.get("remote_ip", "www.google.com") try: vm1_ip = utils_net.get_guest_ip_addr(session1, mac) except Exception as errs: test.fail("vm1 can't get IP with the new create bridge: %s" % errs) if hotplug: # reboot vm1 then check network function to ensure the interface still there and works fine logging.info("reboot the vm") virsh.reboot(vm1) if session1 is None: session1 = vm1.wait_for_serial_login() ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1) # restart libvirtd service then check the interface still works fine libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() vm1.cleanup_serial_console() vm1.create_serial_console() session1 = vm1.wait_for_serial_login() ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1) logging.info( "after reboot and restart libvirtd, the network works fine") if iface_driver: try: driver_dict = eval(iface_driver) if session1 is None: session1 = vm1.wait_for_serial_login() guest_iface_info = session1.cmd_output("ip l").strip() guest_iface_name = re.findall( r"^\d+: (\S+?)[@:].*state UP.*$", guest_iface_info, re.MULTILINE)[0] comb_size = driver_dict.get('queues') rx_size = driver_dict.get('rx_queue_size') session1.cmd_status("ethtool -L %s combined %s" % (guest_iface_name, comb_size)) ret, outp = session1.cmd_status_output("ethtool -l %s" % guest_iface_name) logging.debug("ethtool cmd output:%s" % outp) if not ret: pre_comb = re.search( "Pre-set maximums:[\s\S]*?Combined:.*?(\d+)", outp).group(1) cur_comb = re.search( "Current hardware settings:[\s\S]*?Combined:.*?(\d+)", outp).group(1) if int(pre_comb) != int(comb_size) or int( cur_comb) != int(comb_size): test.fail( "Fail to check the combined size: setting: %s," "Pre-set: %s, Current-set: %s" % (comb_size, pre_comb, cur_comb)) else: logging.info( "Getting correct Pre-set and Current set value" ) else: test.error("ethtool list fail: %s" % outp) # as tx_queue size is only supported for vhost-user interface, only check rx_queue size ret1, outp1 = session1.cmd_status_output("ethtool -g %s" % guest_iface_name) logging.debug("guest queue size setting is %s" % outp1) if not ret1: pre_set = re.search(r"Pre-set maximums:\s*RX:\s*(\d+)", outp1).group(1) cur_set = re.search( r"Current hardware settings:\s*RX:\s*(\d+)", outp1).group(1) if int(pre_set) != int(rx_size) or int(cur_set) != int( rx_size): test.fail("Fail to check the rx_queue_size!") except Exception as errs: test.fail("fail to get driver info") # hot-unplug interface/device if attach_interface: ret = virsh.detach_interface(vm1_name, "bridge", ignore_status=True) else: ret = virsh.detach_device(vm1_name, attach_xml.xml, ignore_status=True, debug=True) if ret.exit_status: test.fail("Hot-unplug interface/device fail") else: logging.info("hot-unplug interface/device succeed") else: if start_vm2: # Start vm2 connect to the same bridge mac2 = utils_net.generate_mac_address_simple() vm2_iface_params = { "type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac2 } libvirt.modify_vm_iface(vm2_name, "update_iface", vm2_iface_params) if vm2.is_alive(): vm2.destroy() vm2.start() # Check if vm1 and vm2 can ping each other try: utils_net.update_mac_ip_address(vm2, timeout=120) vm2_ip = vm2.get_address() except Exception as errs: test.fail( "vm2 can't get IP with the new create bridge: %s" % errs) session2 = vm2.wait_for_login() # make sure guest has got ip address utils_net.restart_guest_network(session2) output2 = session2.cmd_output("ifconfig || ip a") logging.debug("guest ip info %s" % output2) # check 2 guests' network functions check_net_functions(vm1_ip, ping_count, ping_timeout, session1, host_ip, remote_url, vm2_ip) check_net_functions(vm2_ip, ping_count, ping_timeout, session2, host_ip, remote_url, vm1_ip) finally: logging.debug("Start to restore") vm1_xml_bak.sync() vm2_xml_bak.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) if libvirt.check_iface(bridge_name, "exists", "--all"): virsh.iface_unbridge(bridge_name, timeout=60, debug=True) if os.path.exists(iface_script_bk): process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True, verbose=True) if os.path.exists(bridge_script): process.run("rm -rf %s" % bridge_script, shell=True, verbose=True) 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) # reload network configuration NM_service.restart() # recover NetworkManager if NM_status is True: NM_service.start() if 'network' in iface_source and iface_source[ "network"] in virsh.net_state_dict(): virsh.net_destroy(iface_source["network"], ignore_status=False)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") bug_url = params.get("bug_url", "") vm_name = params.get("main_vm") if not libvirt_version.version_compare(1, 2, 6): raise error.TestNAError("Bug %s not fixed on current build" % bug_url) vm = env.get_vm(vm_name) # Prepare vm filterref parameters dict list filterref_dict = {} filterref_dict['name'] = filter_name # backup vm and filter xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) backup_filter = libvirt_xml.NwfilterXML() filterxml = backup_filter.new_from_filter_dumpxml(filter_name) libvirtd = utils_libvirtd.LibvirtdSession() def nwfilter_sync_loop(filter_name, filerxml): """ Undefine filter and redefine filter from xml in loop """ for i in range(2400): virsh.nwfilter_undefine(filter_name, ignore_status=True) time.sleep(0.1) virsh.nwfilter_define(filterxml.xml, ignore_status=True) def vm_start_destory_loop(vm): """ Start and destroy vm in loop """ for i in range(2400): vm.start() time.sleep(0.1) vm.destroy(gracefully=False) try: libvirtd.start() # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() filter_thread = threading.Thread(target=nwfilter_sync_loop, args=(filter_name, filterxml)) vm_thread = threading.Thread(target=vm_start_destory_loop, args=(vm,)) filter_thread.start() time.sleep(0.3) vm_thread.start() ret = utils_misc.wait_for(lambda: not libvirtd.is_working(), timeout=240, step=1) filter_thread.join() vm_thread.join() if ret: raise error.TestFail("Libvirtd hang, %s" % bug_url) finally: libvirtd.exit() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm and filter. vmxml_backup.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) virsh.nwfilter_define(filterxml.xml, ignore_status=True)
def run(test, params, env): """ Test update filter rules when domain is running. 1) Prepare parameters. 2) Add filter to domain interface. 3) Start domain. 4) Update filter rule and check 5) Cleanup """ # Prepare parameters filter_name = params.get("filter_name", "testcase") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") check_vm_cmd = params.get("check_vm_cmd") vm_expect_match = params.get("vm_expect_match") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) filterref_dict = {} filterref_dict['name'] = filter_name # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_filter = libvirt_xml.NwfilterXML() filter_backup = new_filter.new_from_filter_dumpxml(filter_name) def clean_up_dirty_nwfilter_binding(): cmd_result = virsh.nwfilter_binding_list(debug=True) binding_list = cmd_result.stdout_text.strip().splitlines() binding_list = binding_list[2:] result = [] # If binding list is not empty. if binding_list: for line in binding_list: # Split on whitespace, assume 1 column linesplit = line.split(None, 1) result.append(linesplit[0]) logging.info("nwfilter binding list is: %s", result) for binding_uuid in result: try: virsh.nwfilter_binding_delete(binding_uuid) except Exception as e: logging.error( "Exception thrown while undefining nwfilter-binding: %s", str(e)) raise try: # Clean up dirty nwfilter binding if there are. clean_up_dirty_nwfilter_binding() # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() # Start vm vm.start() session = vm.wait_for_login() vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Update filter rule by nwfilter-define filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Check ebtables on host after filter update if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) out = astring.to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) # Check in vm if check_vm_cmd: output = session.cmd_output(check_vm_cmd) logging.debug("cmd output: %s", output) if vm_expect_match and not re.search(vm_expect_match, output): test.fail("'%s' not found in output: %s" % (vm_expect_match, output)) finally: # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Restore created filter virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filter_backup.xml, debug=True)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") need_vm2 = "yes" == params.get("need_vm2", "no") add_vm_name = params.get("add_vm_name", "vm2") vms = [vm] dst_outside = params.get("dst_outside", "www.google.com") ping_timeout = int(params.get("ping_timeout", "10")) # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] if params_dict['value'] == "MAC_of_virbr0": virbr0_info = process.run("ip a | grep virbr0: -A1", shell=True).stdout_text.strip() virbr0_mac = re.search( r'link/ether\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})', virbr0_info, re.M | re.I).group(1) params_dict['value'] = virbr0_mac logging.debug("params_dict['value'] is %s " % params_dict['value']) filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list params['filter_uuid'] = process.run("uuidgen", ignore_status=True, shell=True).stdout_text.strip() # get all the check commands and corresponding expected results form config file and make a dictionary cmd_list_ = params.get('check_cmd', '') if cmd_list_: cmd_list = cmd_list_.split(',') expect_res = params.get('expect_match', '').split(',') logging.debug("cmd_list is %s" % cmd_list) logging.debug("expect_res is %s" % expect_res) cmd_result_dict = dict(zip(cmd_list, expect_res)) logging.debug("the check dict is %s" % cmd_result_dict) # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd("virtqemud") device_name = None def check_nwfilter_rules(check_cmd, expect_match): """"check the nwfilter corresponding rule is added by iptables commands""" ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) # This change anchors nwfilter_vm_start.possitive_test.new_filter.variable_notation case # The matched destination could be ip address or hostname if "iptables -L" in check_cmd and expect_match and 'ACCEPT' in expect_match: # ip address that need to be replaced replace_param = params.get("parameter_value_2") # Get hostname by ip address. hostname_info = None try: hostname_info = socket.gethostbyaddr(replace_param) except socket.error as e: logging.info( "Failed to get hostname from ip address with error: %s", str(e)) if hostname_info: # String is used to replace ip address replace_with = "%s|%s" % (replace_param, hostname_info[0]) expect_match = r"%s" % expect_match.replace( replace_param, replace_with) logging.debug("final iptables match string:%s", expect_match) out = astring.to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) def clean_up_dirty_nwfilter_binding(): cmd_result = virsh.nwfilter_binding_list(debug=True) binding_list = cmd_result.stdout_text.strip().splitlines() binding_list = binding_list[2:] result = [] # If binding list is not empty. if binding_list: for line in binding_list: # Split on whitespace, assume 1 column linesplit = line.split(None, 1) result.append(linesplit[0]) logging.info("nwfilter binding list is: %s", result) for binding_uuid in result: try: virsh.nwfilter_binding_delete(binding_uuid) except Exception as e: logging.error( "Exception thrown while undefining nwfilter-binding: %s", str(e)) raise try: # Clean up dirty nwfilter binding if there are. clean_up_dirty_nwfilter_binding() rule = params.get("rule") if rule: # Add pre-check whether nwfilter exists or not since # utlv.create_nwfilter_xml will fail if there is no any nwfilter exists nwfilter_list = libvirt_nwfilter.get_nwfilter_list() if not nwfilter_list: test.error("There is no any nwfilter existed on the host") # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: pkg = "ipset" if not utils_package.package_install(pkg): test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] iface_mac = iface_xml.mac_address logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if need_vm2: # Clone more vm for testing result = virsh.dom_list('--inactive').stdout_text if add_vm_name in result: logging.debug("%s is already exists!" % add_vm_name) vms.append(env.get_vm(add_vm_name)) else: vm.destroy() ret_clone = utils_libguestfs.virt_clone_cmd(vm_name, add_vm_name, True, timeout=360) if ret_clone.exit_status: test.fail("Error when clone a second vm!") vms.append(vm.clone(add_vm_name)) vm.start() vm2 = vms[1] logging.debug("Now the vms is: %s", [dom.name for dom in vms]) # update the vm2 interface with the nwfilter logging.debug("filter_params_list is %s" % filter_param_list) iface_dict = { "filter": filter_name, "filter_parameters": filter_param_list, "del_mac": True } if vm2.is_alive(): vm2.destroy() utlv.modify_vm_iface(vm2.name, "update_iface", iface_dict) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm2.name) iface_xml = vmxml.get_devices('interface')[0] logging.debug("iface_xml for vm2 is %s" % iface_xml) vm2.start() vm2_session = vm2.wait_for_serial_login() vm2_mac = vm2.get_mac_address() vm2_ip = utils_net.get_guest_ip_addr(vm2_session, vm2_mac) vm.session = vm.wait_for_serial_login() # test network functions, the 2 vms can not access to each other gateway_ip = utils_net.get_ip_address_by_interface("virbr0") status1, output1 = utils_net.ping(dest=vm2_ip, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) status2, output2 = utils_net.ping(dest=gateway_ip, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) status3, output3 = utils_net.ping(dest=dst_outside, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) if not status1: test.fail( "vm with clean-traffic-gateway ping succeed to %s %s, but it is not expected!" % (vm2.name, vm2_ip)) if status2 or status3: test.fail("vm ping failed! check %s \n %s" % (output2, output3)) if cmd_list_: loop = 0 for check_cmd_, expect_match_ in cmd_result_dict.items(): check_cmd = check_cmd_.strip() expect_match = expect_match_.strip() if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) if "VMMAC" in expect_match: expect_match = expect_match.replace("VMMAC", iface_mac) logging.debug( "the check_cmd is %s, and expected result is %s" % (check_cmd, expect_match)) check_nwfilter_rules(check_cmd, expect_match) loop += 1 except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: daemon_name = libvirtd.service_name pid = process.run('pidof %s' % daemon_name, shell=True).stdout_text.strip() cmd = "kill -s TERM %s" % pid process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) # After libvirt 5.6.0, libvirtd is using systemd socket activation by default if not ret and not libvirt_version.version_compare(5, 6, 0): test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter except clean-traffic as it is built-in nwfilter if filter_name != exist_filter and filter_name != 'clean-traffic': virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True) # Remove additional vms if need_vm2: result = virsh.dom_list("--all").stdout_text if add_vm_name in result: virsh.remove_domain(add_vm_name, "--remove-all-storage")
def run(test, params, env): """ Test virsh nwfilter-binding-list 1)Prepare parameters 2)Run nwfilter_binding_list command 3)check result 4)Clean env """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) new_filter_1 = params.get("newfilter_1") new_filter_2 = params.get("newfilter_2") vmxml_backup = libvirt_xml.vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_net0_xml = os.path.join(data_dir.get_tmp_dir(), "new_net0.xml") new_net1_xml = os.path.join(data_dir.get_tmp_dir(), "new_net1.xml") option = params.get("option") status_error = "yes" == params.get("status_error") alias_name = params.get("alias_name") new_filter_name = params.get("new_filter_name") source_network = params.get("source_network") # prepare vm filterrfer parameters dict list filter_param_list_1 = [] params_key_1 = [] filter_param_list_2 = [] params_key_2 = [] for i in params.keys(): if 'parameters_name_' in i: params_key_1.append(i) params_key_1.sort() for i in range(len(params_key_1)): params_dict = {} params_dict['name'] = params[params_key_1[i]] params_dict['value'] = params['parameters_value_%s' % i] filter_param_list_1.append(params_dict) filterref_dict_1 = {} filterref_dict_1['name'] = new_filter_1 filterref_dict_1['parameters'] = filter_param_list_1 for i in params.keys(): if 'parameters_dhcp_' in i: params_key_2.append(i) params_key_2.sort() for i in range(len(params_key_2)): params_dict = {} params_dict['name'] = params[params_key_2[i]] params_dict['value'] = params['dhcp_value_%s' % i] filter_param_list_2.append(params_dict) filterref_dict_2 = {} filterref_dict_2['name'] = new_filter_2 filterref_dict_2['parameters'] = filter_param_list_2 def set_env(): """ set two interface with different network filter and change interface type """ # Add enough PCI to attach interface libvirt_pcicontr.reset_pci_num(vm_name) virsh.attach_interface(vm_name, option, debug=True) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) logging.debug("Guest xml is {}".format(vmxml)) devices = vmxml.get_devices('interface') iface_xml = devices[0] iface_xml_2 = devices[1] vmxml.del_device(iface_xml) vmxml.del_device(iface_xml_2) new_iface_1 = interface.Interface('network') new_iface_2 = interface.Interface('network') new_iface_1.xml = iface_xml.xml new_iface_2.xml = iface_xml_2.xml new_iface_1.type_name = "network" new_iface_2.type_name = "network" new_iface_1.source = {'network': source_network} new_iface_2.source = {'network': source_network} new_iface_1.target = {'dev': 'new_net0'} new_iface_2.target = {'dev': 'new_net1'} new_filterref = new_iface_1.new_filterref(**filterref_dict_1) new_iface_1.filterref = new_filterref new_filterref = new_iface_2.new_filterref(**filterref_dict_2) new_iface_2.filterref = new_filterref logging.debug("new interface xml is: %s \n %s" % (new_iface_1, new_iface_2)) vmxml.add_device(new_iface_1) vmxml.add_device(new_iface_2) vmxml.sync() return new_iface_1, new_iface_2 try: new_iface_1, new_iface_2 = set_env() # start vm virsh.start(vm_name, debug=True) # list binding port dev ret = virsh.nwfilter_binding_list(debug=True) utlv.check_exit_status(ret, status_error) virsh.nwfilter_binding_dumpxml(new_iface_1.target['dev'], to_file=new_net0_xml, debug=True) virsh.nwfilter_binding_dumpxml(new_iface_2.target['dev'], to_file=new_net1_xml, debug=True) # check dump filterbinding can pass xml validate new_net0_cmd = "virt-xml-validate %s" % new_net0_xml new_net1_cmd = "virt-xml-validate %s" % new_net1_xml valid_0 = process.run(new_net0_cmd, ignore_status=True, shell=True).exit_status valid_1 = process.run(new_net1_cmd, ignore_status=True, shell=True).exit_status if valid_0 or valid_1: test.fail("the xml can not validate successfully") # create new xml and update device newnet_iface = interface.Interface('network') newnet_iface.xml = new_iface_1.xml filterref_list = [] filterref_dict = {} filterref_dict['name'] = new_filter_name filterref_dict['parameters'] = filterref_list newnet_iface.alias = {'name': alias_name} newnet_iface.filterref = newnet_iface.new_filterref(**filterref_dict) ret = virsh.update_device(domainarg=vm_name, filearg=newnet_iface.xml, debug=True) utlv.check_exit_status(ret, status_error) ret_list = virsh.nwfilter_binding_list(debug=True) utlv.check_result(ret_list, expected_match="new_net1") ret_dump = virsh.nwfilter_binding_dumpxml('new_net0', debug=True) utlv.check_result(ret_dump, expected_match=new_filter_name) finally: if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync()
def run(test, params, env): """ Test network/interface function on 2 vms: - Test settings on 2 vms - Run ping check on 2 vms including pinging each other ... """ vms = params.get('vms').split() vm_list = [env.get_vm(v_name) for v_name in vms] if len(vm_list) != 2: test.cancel('More or less than 2 vms is currently unsupported') feature = params.get('feature', '') case = params.get('case', '') check_ping = 'yes' == params.get('check_ping') expect_ping_host = 'yes' == params.get('expect_ping_host', 'no') expect_ping_out = 'yes' == params.get('expect_ping_out', 'no') expect_ping_vm = 'yes' == params.get('expect_ping_vm', 'no') out_ip = params.get('out_ip', 'www.redhat.com') live_update = 'yes' == params.get('live_update', 'no') set_all = 'yes' == params.get('set_all', 'no') rand_id = '_' + utils_misc.generate_random_string(3) bridge_name = params.get('bridge_name', 'test_br0') + rand_id iface_name = utils_net.get_net_if(state="UP")[0] test_net = 'net_isolated' + rand_id bridge_created = False vmxml_backup_list = [] for vm_i in vm_list: vmxml_backup_list.append(vm_xml.VMXML.new_from_inactive_dumpxml(vm_i.name)) try: # Test feature: port isolated if feature == 'port_isolated': if not libvirt_version.version_compare(6, 2, 0): test.cancel('Libvirt version should be' ' > 6.2.0 to support port isolated') if case.startswith('set_iface'): create_bridge(bridge_name, iface_name) bridge_created = True iface_type = case.split('_')[-1] if iface_type == 'network': net_dict = {'net_forward': "{'mode': 'bridge'}", 'net_bridge': "{'name': '%s'}" % bridge_name} prepare_network(test_net, **net_dict) updated_iface_dict = { 'type': iface_type, 'source': "{'network': '%s'}" % test_net, } elif iface_type == 'bridge': updated_iface_dict = { 'type': iface_type, 'source': "{'bridge': '%s'}" % bridge_name, } else: test.error('Unsupported iface type: %s' % iface_type) # Set 2 vms to isolated=yes or set one to 'yes', the other to 'no' isolated_settings = ['yes'] * 2 if set_all else ['yes', 'no'] for i in (0, 1): vm_i = vm_list[i] new_iface_dict = dict( list(updated_iface_dict.items()) + [('port', "{'isolated': '%s'}" % isolated_settings[i])] ) libvirt.modify_vm_iface(vm_i.name, 'update_iface', new_iface_dict) logging.debug(virsh.dumpxml(vm_i.name).stdout_text) if case == 'update_iface': if params.get('iface_port'): iface_dict = {'port': params['iface_port']} for vm_i in vm_list: libvirt.modify_vm_iface(vm_i.name, 'update_iface', iface_dict) logging.debug(virsh.dumpxml(vm_i.name).stdout_text) if live_update: for vm_i in vm_list: vm_i.start() # Test Update iface with new attrs new_iface_dict = {} if params.get('new_iface_port'): new_iface_dict['port'] = params['new_iface_port'] elif params.get('del_port') == 'yes': new_iface_dict['del_port'] = True for vm_i in vm_list: updated_iface = libvirt.modify_vm_iface(vm_i.name, 'get_xml', new_iface_dict) result = virsh.update_device(vm_i.name, updated_iface, debug=True) libvirt.check_exit_status(result) if case == 'attach_iface': new_ifaces = {} for vm_i in vm_list: # Create iface xml to be attached new_iface = interface.Interface('network') new_iface.xml = libvirt.modify_vm_iface( vm_i.name, 'get_xml', {'port': params.get('new_iface_port')} ) new_ifaces[vm_i.name] = new_iface # Remove current ifaces on vm vmxml_i = vm_xml.VMXML.new_from_inactive_dumpxml(vm_i.name) vmxml_i.remove_all_device_by_type('interface') vmxml_i.sync() logging.debug(virsh.dumpxml(vm_i.name).stdout_text) # Start vm for hotplug vm_i.start() session = vm_i.wait_for_serial_login() # Hotplug iface virsh.attach_device(vm_i.name, new_iface.xml, debug=True, ignore_status=False) # Wait a few seconds for interface to be fully attached time.sleep(5) ip_l_before = session.cmd_output('ip l') logging.debug(ip_l_before) session.close() if case == 'set_network': create_bridge(bridge_name, iface_name) bridge_created = True net_dict = { 'net_forward': "{'mode': 'bridge'}", 'net_bridge': "{'name': '%s'}" % bridge_name, 'net_port': "{'isolated': '%s'}" % params.get( 'net_isolated', 'yes')} prepare_network(test_net, **net_dict) # Modify iface to connect to newly added network updated_iface_dict = {'type': 'network', 'source': "{'network': '%s'}" % test_net} for vm_i in vm_list: libvirt.modify_vm_iface(vm_i.name, 'update_iface', updated_iface_dict) logging.debug(virsh.domiflist(vm_i.name).stdout_text) # Check ping result from vm session to host, outside, the other vm if check_ping: for vm_i in vm_list: if vm_i.is_dead(): vm_i.start() host_ip = utils_net.get_host_ip_address() ping_expect = { host_ip: expect_ping_host, out_ip: expect_ping_out, } # A map of vm session and vm's ip addr session_n_ip = {} for vm_i in vm_list: mac = vm_i.get_mac_address() sess = vm_i.wait_for_serial_login() vm_ip = utils_net.get_guest_ip_addr(sess, mac) session_n_ip[sess] = vm_ip logging.debug('Vm %s ip: %s', vm_i.name, vm_ip) # Check ping result from each vm's session for i in (0, 1): sess = list(session_n_ip.keys())[i] another_sess = list(session_n_ip.keys())[1 - i] ping_expect[session_n_ip[another_sess]] = expect_ping_vm if not ping_func(sess, **ping_expect): test.fail('Ping check failed') # Remove the other session's ip from ping result, then the # next round of ping check will not do a ping check to the vm itself ping_expect.pop(session_n_ip[another_sess]) # Some test steps after ping check if feature == 'port_isolated': if case == 'attach_iface': # Test detach of iface for vm_name_i in new_ifaces: virsh.detach_device( vm_name_i, new_ifaces[vm_name_i].xml, wait_for_event=True, debug=True, ignore_status=False ) # Check whether iface successfully detached by checking 'ip l' output for vm_i in vm_list: session = vm_i.wait_for_serial_login() ip_l_after = session.cmd_output('ip l') session.close() if len(ip_l_before.splitlines()) == len(ip_l_after.splitlines()): test.fail('Output of "ip l" is not changed afte detach, ' 'interface not successfully detached')
def run(test, params, env): """ Test update filter rules when domain is running. 1) Prepare parameters. 2) Add filter to domain interface. 3) Start domain. 4) Update filter rule and check 5) Cleanup """ # Prepare parameters filter_name = params.get("filter_name", "testcase") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") check_vm_cmd = params.get("check_vm_cmd") vm_expect_match = params.get("vm_expect_match") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) filterref_dict = {} filterref_dict['name'] = filter_name # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_filter = libvirt_xml.NwfilterXML() filter_backup = new_filter.new_from_filter_dumpxml(filter_name) try: # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() # Start vm vm.start() session = vm.wait_for_login() vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Update filter rule by nwfilter-define filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Check ebtables on host after filter update if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for( lambda: not utils.system(check_cmd, ignore_status=True), timeout=30) if not ret: raise error.TestFail("Rum command '%s' failed" % check_cmd) out = utils.system_output(check_cmd, ignore_status=False) if expect_match and not re.search(expect_match, out): raise error.TestFail("'%s' not found in output: %s" % (expect_match, out)) # Check in vm if check_vm_cmd: output = session.cmd_output(check_vm_cmd) logging.debug("cmd output: %s", output) if vm_expect_match and not re.search(vm_expect_match, output): raise error.TestFail("'%s' not found in output: %s" % (vm_expect_match, output)) finally: # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Restore created filter virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filter_backup.xml, debug=True)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() device_name = None try: rule = params.get("rule") if rule: # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name utils.run(cmd) if ipset_command: try: os_dep.command("ipset") except ValueError: ret = utils.run("yum install ipset -y") if ret.exit_status: raise error.TestNAError("Can't install ipset on host") utils.run(ipset_command) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not utils.system(check_cmd, ignore_status=True), timeout=30) if not ret: raise error.TestFail("Rum command '%s' failed" % check_cmd) out = utils.system_output(check_cmd, ignore_status=False) if expect_match and not re.search(expect_match, out): raise error.TestFail("'%s' not found in output: %s" % (expect_match, out)) except virt_vm.VMStartError, e: # Starting VM failed. if not status_error: raise error.TestFail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -SIGTERM `pidof libvirtd`" utils.run(cmd) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) if not ret: raise error.TestFail("Failed to kill libvirtd. %s" % bug_url)