def run(test, params, env): net_name = params.get("net_update_net_name", "updatenet") net_section = params.get("network_section", "ip-dhcp-range") update_command = params.get("update_command", "add-last") virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> </dhcp> </ip> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net test_xml.sync() except xcepts.LibvirtXMLError, detail: raise error.TestNAError("Failed to define a test network.\n" "Detail: %s." % detail)
def create_network(): """ Create a network """ net_ip_addr = params.get("net_ip_addr", "192.168.200.1") net_ip_netmask = params.get("net_ip_netmask", "255.255.255.0") net_dhcp_start = params.get("net_dhcp_start", "192.168.200.2") net_dhcp_end = params.get("net_dhcp_end", "192.168.200.254") netxml = network_xml.NetworkXML() netxml.name = net_name netxml.forward = {'mode': "nat"} range = network_xml.RangeXML() range.attrs = {'start': net_dhcp_start, "end": net_dhcp_end} ipxml = network_xml.IPXML() if range_lease: range.lease_attrs = range_lease ipxml.address = net_ip_addr ipxml.netmask = net_ip_netmask ipxml.dhcp_ranges = range if host: new_host = network_xml.DhcpHostXML() new_host.attrs = host new_host.lease_attrs = host_lease ipxml.hosts = [new_host] netxml.set_ip(ipxml) netxml.create()
def _from_scratch(self): netxml = network_xml.NetworkXML(virsh_instance=self.dummy_virsh, network_name='test0') self.assertEqual(netxml.name, 'test0') netxml.name = 'test1' netxml.uuid = 'test2' netxml.bridge = {'test3': 'test4'} return netxml
def run(test, params, env): net_name = params.get("net_update_net_name", "updatenet") net_section = params.get("network_section", "ip-dhcp-range") update_command = params.get("update_command", "add-last") add_portgroup = "yes" == params.get("add_portgroup", "no") options = params.get("cmd_options", "") net_state = params.get("net_state") virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> <host mac='52:54:00:5a:a0:8b' ip='192.168.100.152' /> </dhcp> </ip> </network> """ % (net_name, net_name) port_group = """ <portgroup name='engineering' default='no'> <virtualport type='802.1Qbh'> <parameters profileid='test'/> </virtualport> <bandwidth> <inbound average='1000' peak='5000' burst='5120'/> <outbound average='1000' peak='5000' burst='5120'/> </bandwidth> </portgroup> """ try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net if net_section == "portgroup": portgroup_xml = network_xml.PortgroupXML() portgroup_xml.xml = port_group test_xml.portgroup = portgroup_xml elif net_section == "forward-interface": test_xml.forward = {'mode': 'passthrough'} test_xml.forward_interface = [{'dev': 'eth2'}] del test_xml.bridge del test_xml.mac del test_xml.ip test_xml.define() if net_state == "active": test_xml.start() test_xml.debug_xml() virsh.net_dumpxml(net_name) except xcepts.LibvirtXMLError, detail: raise error.TestError("Failed to define a test network.\n" "Detail: %s." % detail)
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 _from_scratch(self): netxml = network_xml.NetworkXML(network_name='test0', virsh_instance=self.dummy_virsh) self.assertEqual(netxml.name, 'test0') netxml.name = 'test1' netxml.uuid = 'test2' netxml.bridge = {'test3': 'test4'} ipxml = network_xml.IPXML() ipxml.address = ('address_test') ipxml.netmask = ('netmask_test') netxml.ip = ipxml return netxml
def create_macvtap_network(): """ Create macvtap type network xml. """ forward_interface_list = [] for vf_name in vf_name_list: forward_interface = {'dev': vf_name} forward_interface_list.append(forward_interface) netxml = network_xml.NetworkXML() netxml.name = net_name netxml.forward = {'dev': vf_name_list[0], 'mode': 'passthrough'} netxml.forward_interface = forward_interface_list logging.debug(netxml) return netxml
def create_bridge_network(br_name, net_name, inbound="{'average':'0'}", outbound="{'average':'0'}"): """ 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.bandwidth_inbound = eval(inbound) test_xml.bandwidth_outbound = eval(outbound) logging.debug("The network's xml is %s", test_xml) test_xml.create()
def run(test, params, env): """ Test command: virsh net-autostart. """ # Gather test parameters status_error = "yes" == params.get("status_error", "no") net_ref = params.get("net_autostart_net_ref", "netname") disable = "yes" == params.get("net_autostart_disable", "no") extra = params.get("net_autostart_extra", "") # extra cmd-line params. net_name = params.get("net_autostart_net_name", "autotest") # Prepare environment and record current net_state_dict backup = network_xml.NetworkXML.new_all_networks_dict() backup_state = virsh.net_state_dict() logging.debug("Backed up network(s): %s", backup_state) # Generate our own bridge # First check if a bridge of this name already exists try: _ = backup[net_name] except (KeyError, AttributeError): pass # Not found - good else: raise error.TestNAError("Found network bridge '%s' - skipping" % (net_name)) # Define a very bare bones bridge, don't provide UUID - use whatever # libvirt ends up generating. We need to define a persistent network # since we'll be looking to restart libvirtd as part of this test. # # This test cannot use the 'default' bridge (virbr0) since undefining # it causes issues for libvirtd restart since it's expected that a # default network is defined # temp_bridge = """ <network> <name>%s</name> <bridge name="vir%sbr0"/> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = temp_bridge test_xml.define() except xcepts.LibvirtXMLError, detail: raise error.TestNAError("Failed to define a test network.\n" "Detail: %s." % detail)
def create_network(): """ Create a network """ net_ip_addr = params.get("net_ip_addr", "192.168.200.1") net_ip_netmask = params.get("net_ip_netmask", "255.255.255.0") net_dhcp_start = params.get("net_dhcp_start", "192.168.200.2") net_dhcp_end = params.get("net_dhcp_end", "192.168.200.254") netxml = network_xml.NetworkXML() netxml.name = net_name netxml.forward = {'mode': "nat"} ipxml = network_xml.IPXML() ipxml.address = net_ip_addr ipxml.netmask = net_ip_netmask ipxml.dhcp_ranges = {'start': net_dhcp_start, "end": net_dhcp_end} netxml.set_ip(ipxml) netxml.create()
def create_hostdev_network(): """ Create hostdev type with vf pool network xml. """ vf_addr_list = [] netxml = network_xml.NetworkXML() if vf_pool_source == "vf_list": for vf in vf_list: attrs = create_address_dict(vf) new_vf = netxml.new_vf_address(**{'attrs': attrs}) vf_addr_list.append(new_vf) netxml.driver = {'name': 'vfio'} netxml.forward = {"mode": "hostdev", "managed": managed} netxml.vf_list = vf_addr_list else: netxml.pf = {"dev": pf_name} netxml.forward = {"mode": "hostdev", "managed": managed} netxml.name = net_name logging.debug(netxml) return netxml
def get_network_xml_instance(virsh_dargs, test_xml, net_name, net_uuid, bridge): test_netxml = network_xml.NetworkXML(virsh_instance=virsh.Virsh( **virsh_dargs)) test_netxml.xml = test_xml.name # modify XML if called for if net_name is not "": test_netxml.name = net_name else: test_netxml.name = "default" if net_uuid is not "": test_netxml.uuid = net_uuid else: del test_netxml.uuid # let libvirt auto-generate if bridge is not None: test_netxml.bridge = bridge # TODO: Test other network parameters logging.debug("Modified XML:") test_netxml.debug_xml() return test_netxml
def run(test, params, env): """ Test command: virsh net-list. The command returns list of networks. 1.Get all parameters from configuration. 2.Get current network's status(State, Autostart). 3.Do some prepare works for testing. 4.Perform virsh net-list operation. 5.Recover network status. 6.Confirm the result. """ option = params.get("net_list_option", "") extra = params.get("net_list_extra", "") status_error = params.get("status_error", "no") set_status = params.get("set_status", "active") set_persistent = params.get("set_persistent", "persistent") set_autostart = params.get("set_autostart", "autostart") error_msg = params.get("error_msg", "") net_name = params.get("net_name", "net-br") net_xml = network_xml.NetworkXML(network_name=net_name) # acl polkit params uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': raise exceptions.TestSkipError("API acl test not supported" " in current libvirt version.") # Record current net_state_dict net_backup = network_xml.NetworkXML.new_all_networks_dict() net_backup_state = virsh.net_state_dict() logging.debug("Backed up network(s): %s", net_backup_state) # Check the network name is not duplicated try: _ = net_backup[net_name] except (KeyError, AttributeError): pass else: raise exceptions.TestSkipError("Duplicated network name: '%s'" % net_name) # Default the network is persistent, active, autostart # Create a persistent/transient network. if set_persistent == "persistent": net_xml.define() logging.debug("Created persistent network") else: net_xml.create() logging.debug("Created transient network") # Prepare an active/inactive network # For the new defined network, it's inactive by default if set_status == "active" and set_persistent == "persistent": net_xml.start() # Prepare an autostart/no-autostart network # For the new create network, it's no-autostart by default if set_autostart == "autostart": net_xml.set_autostart(True) try: virsh_dargs = {'ignore_status': True, 'debug': True} if params.get('setup_libvirt_polkit') == 'yes': virsh_dargs['unprivileged_user'] = unprivileged_user virsh_dargs['uri'] = uri ret = virsh.net_list(option, extra, **virsh_dargs) output = ret.stdout.strip() # Check test results if status_error == "yes": # Check the results with error parameter if error_msg: libvirt.check_result(ret, error_msg) # Check the results with correct option but inconsistent network status else: libvirt.check_exit_status(ret) if re.search(net_name, output): raise exceptions.TestFail( "virsh net-list %s get wrong results" % option) # Check the results with correct option and consistent network status else: libvirt.check_exit_status(ret) if option == "--uuid": uuid = virsh.net_uuid(net_name).stdout.strip() if not re.search(uuid, output): raise exceptions.TestFail( "Failed to find network: '%s' with:" "virsh net-list '%s'." % (net_name, option)) else: if not re.search(net_name, output): raise exceptions.TestFail( "Failed to find network: '%s' with:" "virsh net-list '%s'." % (net_name, option)) finally: # Recover network try: if set_status == "active": net_xml.del_active() if set_persistent == "persistent": net_xml.del_defined() except Exception: virsh.net_undefine()
virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> </dhcp> </ip> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net if test_create: test_xml.create() else: test_xml.define() except xcepts.LibvirtXMLError, detail: raise error.TestNAError("Failed to define a test network.\n" "Detail: %s." % detail) # Run test case try: libvirtd = utils_libvirtd.Libvirtd() if test_create: # Restart libvirtd and check state libvirtd.restart()
def run(test, params, env): """ Test command: virsh net-autostart. """ # Gather test parameters status_error = "yes" == params.get("status_error", "no") net_ref = params.get("net_autostart_net_ref", "netname") disable = "yes" == params.get("net_autostart_disable", "no") extra = params.get("net_autostart_extra", "") # extra cmd-line params. net_name = params.get("net_autostart_net_name", "autotest") net_transient = "yes" == params.get("net_transient", "no") readonly = ("yes" == params.get("readonly", "no")) sim_reboot = "yes" == params.get("sim_reboot", "no") # Prepare environment and record current net_state_dict backup = network_xml.NetworkXML.new_all_networks_dict() backup_state = virsh.net_state_dict() logging.debug("Backed up network(s): %s", backup_state) # Generate our own bridge # First check if a bridge of this name already exists try: _ = backup[net_name] except (KeyError, AttributeError): pass # Not found - good else: test.cancel("Found network bridge '%s' - skipping" % net_name) # Define a very bare bones bridge, don't provide UUID - use whatever # libvirt ends up generating. We need to define a persistent network # since we'll be looking to restart libvirtd as part of this test. # # This test cannot use the 'default' bridge (virbr0) since undefining # it causes issues for libvirtd restart since it's expected that a # default network is defined # temp_bridge = """ <network> <name>%s</name> <bridge name="vir%sbr0"/> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = temp_bridge test_xml.define() except xcepts.LibvirtXMLError as detail: test.error("Failed to define a test network.\n" "Detail: %s." % detail) # To guarantee cleanup will be executed try: # Run test case # Get the updated list and make sure our new bridge exists currents = network_xml.NetworkXML.new_all_networks_dict() current_state = virsh.net_state_dict() logging.debug("Current network(s): %s", current_state) try: testbr_xml = currents[net_name] except (KeyError, AttributeError): test.error("Did not find newly defined bridge '%s'" % net_name) # Prepare default property for network # Transient network can not be set autostart # So confirm persistent is true for test testbr_xml['persistent'] = True # Set network to inactive # Since we do not reboot host to check(instead of restarting libvirtd) # If default network is active, we cannot check "--disable". # Because active network will not be inactive after restarting libvirtd # even we set autostart to False. While inactive network will be active # after restarting libvirtd if we set autostart to True testbr_xml['active'] = False # Prepare options and arguments if net_ref == "netname": net_ref = testbr_xml.name elif net_ref == "netuuid": net_ref = testbr_xml.uuid if disable: net_ref += " --disable" if net_transient: # make the network to transient and active ret = virsh.net_start(net_name) libvirt.check_exit_status(ret) ret = virsh.net_undefine(net_name) libvirt.check_exit_status(ret) logging.debug("after make it transistent: %s" % virsh.net_state_dict()) # Run test case # Use function in virsh module directly for both normal and error test result = virsh.net_autostart(net_ref, extra, readonly=readonly) status = result.exit_status if status: logging.debug("autostart cmd return:\n%s" % result.stderr.strip()) else: logging.debug("set autostart succeed: %s" % virsh.net_state_dict()) # Check if autostart or disable is successful with libvirtd restart. # TODO: Since autostart is designed for host reboot, # we'd better check it with host reboot. autostart_file = '/var/run/libvirt/network/autostarted' check_version = libvirt_version.version_compare(5, 6, 0) if check_version and os.path.exists(autostart_file): logging.debug("the sim_reboot is %s" % sim_reboot) if sim_reboot: os.unlink(autostart_file) utils_libvirtd.libvirtd_restart() # Reopen testbr_xml currents = network_xml.NetworkXML.new_all_networks_dict() current_state = virsh.net_state_dict() logging.debug("After libvirtd reboot, current network(s): %s", current_state) testbr_xml = currents[net_name] is_active = testbr_xml['active'] # undefine the persistent&autostart network, # if "autostart" should change to 'no" if not disable and not net_transient: logging.debug("undefine the persistent/autostart network:") ret = virsh.net_undefine(net_name) libvirt.check_exit_status(ret) # after undefine, the network can not be "autostart" if net_name in virsh.net_list("").stdout.strip(): current_state = virsh.net_state_dict()[net_name] logging.debug("Current network(s): %s", current_state) net_autostart_now = current_state['autostart'] if not status_error and not disable and net_autostart_now: test.fail("transient network can not be autostart") finally: persistent_net = virsh.net_list("--persistent --all").stdout.strip() if net_name in persistent_net: virsh.net_undefine(net_name) active_net = virsh.net_list("").stdout.strip() if net_name in active_net: virsh.net_destroy(net_name) # Check Result if status_error: if status == 0: test.fail("Run successfully with wrong command!") else: if disable: if status or is_active: test.fail("Disable autostart failed.") else: if status: test.fail("The virsh cmd return error when enable autostart!") # If host reboot(sim_reboot=True), the network should be active # If host do not reboot, restart libvirtd will not start inactive # autostart network after libvirt 5.6.0 if sim_reboot: if not is_active: test.fail("Set network autostart failed.") else: if check_version and is_active: test.fail( "net turn active with libvirtd restart without host reboot!" )
def run(test, params, env): """ Test command: virsh net-start. """ # Gather test parameters uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri", "default")) status_error = "yes" == params.get("status_error", "no") inactive_default = "yes" == params.get("net_start_inactive_default", "yes") net_ref = params.get("net_start_net_ref", "netname") # default is tested extra = params.get("net_start_options_extra", "") # extra cmd-line params. route_test = "yes" == params.get("route_test", "no") # make easy to maintain virsh_dargs = {'uri': uri, 'debug': True, 'ignore_status': True} virsh_instance = virsh.VirshPersistent(**virsh_dargs) # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': test.cancel("API acl test not supported in current" " libvirt version.") virsh_uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # Get all network instance origin_nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance) # Prepare default network for following test. try: default_netxml = origin_nets['default'] except KeyError: virsh_instance.close_session() test.cancel("Test requires default network to exist") try: # To confirm default network is active if not default_netxml.active: default_netxml.active = True # inactive default according test's need if inactive_default: logging.info("Stopped default network") default_netxml.active = False # State before run command origin_state = virsh_instance.net_state_dict() logging.debug("Origin network(s) state: %s", origin_state) if route_test: # define a network "def" with route address is "192.168.122.x" # 1. start def first then start default current_state = virsh_instance.net_state_dict() if 'def' in current_state: virsh.net_destroy("def", ignore_status=True) virsh.net_undefine("def", ignore_status=True) expect_fail = "yes" == params.get("expect_start_fail", "no") test_xml = network_xml.NetworkXML(network_name="def") test_xml.forward = {'mode': 'nat'} test_xml.routes = [{ 'address': '192.168.122.0', 'prefix': '24', 'gateway': '192.168.100.1' }] ipxml = IPXML(address='192.168.100.1', netmask='255.255.255.0') ipxml.dhcp_ranges = { 'start': '192.168.100.2', 'end': '192.168.100.254' } test_xml.ip = ipxml test_xml.define() virsh.net_start("def") # start default, should fail result = virsh.net_start("default") logging.debug(result) libvirt.check_exit_status(result, expect_error=expect_fail) # 2. start default then start def virsh.net_destroy("def") virsh.net_start("default") current_state11 = virsh_instance.net_state_dict() logging.debug("before start 2nd network(s) state: %s", current_state11) # start def, should fail result = virsh.net_start("def") logging.debug(result) libvirt.check_exit_status(result, expect_error=expect_fail) current_state12 = virsh_instance.net_state_dict() logging.debug("after start 2nd network(s) state: %s", current_state12) # clear the env virsh.net_undefine("def") else: if net_ref == "netname": net_ref = default_netxml.name elif net_ref == "netuuid": net_ref = default_netxml.uuid if params.get('setup_libvirt_polkit') == 'yes': virsh_dargs = { 'uri': virsh_uri, 'unprivileged_user': unprivileged_user, 'debug': False, 'ignore_status': True } if params.get('net_start_readonly', 'no') == 'yes': virsh_dargs = { 'uri': uri, 'debug': True, 'readonly': True, 'ignore_status': True } # Run test case if 'unprivileged_user' in virsh_dargs and status_error: test_virsh = virsh.VirshPersistent( unprivileged_user=virsh_dargs['unprivileged_user']) virsh_dargs.pop('unprivileged_user') result = test_virsh.net_start(net_ref, extra, **virsh_dargs) test_virsh.close_session() elif not route_test: result = virsh.net_start(net_ref, extra, **virsh_dargs) logging.debug(result) status = result.exit_status # Get current net_stat_dict current_state = virsh_instance.net_state_dict() logging.debug("Current network(s) state: %s", current_state) if 'default' not in current_state: test.fail('Network "default" cannot be found') # Check status_error if status_error: if not status: test.fail("Run successfully with wrong command!") else: if status: test.fail("Run failed with right command") # Get current net_stat_dict current_state = virsh_instance.net_state_dict() logging.debug("Current network(s) state: %s", current_state) is_default_active = current_state['default']['active'] if not is_default_active: test.fail( "Execute cmd successfully but default is inactive actually." ) finally: virsh_instance.close_session() current_state = virsh_instance.net_state_dict() if "def" in current_state: virsh.net_destroy("def", ignore_status=True) virsh.net_undefine("def", ignore_status=True) virsh.net_start('default', debug=True, ignore_status=True)
def run(test, params, env): net_name = params.get("net_update_net_name", "updatenet") net_section = params.get("network_section", "ip-dhcp-range") update_command = params.get("update_command", "add-last") options = params.get("cmd_options", "") net_state = params.get("net_state") virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> <host mac='52:54:00:5a:a0:8b' ip='192.168.100.152' /> </dhcp> </ip> </network> """ % (net_name, net_name) port_group = """ <portgroup name='engineering' default='no'> <virtualport type='802.1Qbh'> <parameters profileid='test'/> </virtualport> <bandwidth> <inbound average='1000' peak='5000' burst='5120'/> <outbound average='1000' peak='5000' burst='5120'/> </bandwidth> </portgroup> """ try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net if net_section == "portgroup": portgroup_xml = network_xml.PortgroupXML() portgroup_xml.xml = port_group test_xml.portgroup = portgroup_xml elif net_section == "forward-interface": test_xml.forward = {'mode': 'passthrough'} test_xml.forward_interface = [{'dev': 'eth2'}] del test_xml.bridge del test_xml.mac del test_xml.ip test_xml.define() if net_state == "active": test_xml.start() test_xml.debug_xml() virsh.net_dumpxml(net_name) except xcepts.LibvirtXMLError as detail: test.error("Failed to define a test network.\n" "Detail: %s." % detail) try: # Get a tmp_dir. tmp_dir = data_dir.get_tmp_dir() # Write new xml into a tempfile tmp_file = tempfile.NamedTemporaryFile(prefix=("new_xml_"), dir=tmp_dir) xmlfile = tmp_file.name tmp_file.close() element = "/%s" % net_section.replace('-', '/') section_xml = test_xml.get_section_string(xpath=element) flag_list = [] if update_command == "delete": newxml = section_xml else: if net_section == "bridge": new_bridge_name = net_name + "_new" flag_list.append(new_bridge_name) newxml = section_xml.replace(net_name, new_bridge_name) logging.info("The new bridge xml is %s", newxml) elif net_section == "forward": new_mode = "route" flag_list.append(new_mode) newxml = section_xml.replace("nat", new_mode) logging.info("The new forward xml is %s", newxml) elif net_section == "ip": new_netmask = "255.255.0.0" flag_list.append(new_netmask) newxml = section_xml.replace("255.255.255.0", new_netmask) logging.info("The new xml of ip section is %s", newxml) elif net_section == "ip-dhcp-range": new_end_ip = "192.168.100.253" flag_list.append(new_end_ip) newxml = section_xml.replace("192.168.100.254", new_end_ip) logging.info("The new xml of ip-dhcp-range is %s", newxml) elif net_section == "portgroup": new_inbound_average = "2000" flag_list.append(new_inbound_average) newxml = section_xml.replace("1000", new_inbound_average) newxml = newxml.replace("no", "yes") flag_list.append("yes") if update_command in ['add-first', 'add-last']: newxml = newxml.replace("engineering", "sales") flag_list.append("sales") logging.info("The new xml of portgroup is %s", newxml) elif net_section == "forward-interface": new_forward_iface = params.get("new_forward_iface", "eth4") flag_list.append(new_forward_iface) newxml = section_xml.replace("eth2", new_forward_iface) logging.info("The new xml of forward-interface is %s", newxml) elif net_section == "ip-dhcp-host": new_ip_dhcp_host = params.get("new_ip_dhcp_host", "192.168.100.153") flag_list.append(new_ip_dhcp_host) newxml = section_xml.replace("192.168.100.152", new_ip_dhcp_host) if update_command in ['add-first', 'add-last']: new_ip_dhcp_mac = params.get("new_ip_dhcp_mac", "52:54:00:5a:a0:9b") newxml = newxml.replace("52:54:00:5a:a0:8b", new_ip_dhcp_mac) flag_list.append(new_ip_dhcp_mac) logging.info("The new xml of forward-interface is %s", newxml) else: test.fail("Unknown network section") fd = open(xmlfile, 'w') fd.write(newxml) fd.close() cmd_result = virsh.net_update(net_name, update_command, net_section, xmlfile, options, debug=True) if cmd_result.exit_status: err = cmd_result.stderr.strip() if re.search("not supported", err): test.cancel("Skip the test: %s" % err) else: test.fail("Failed to execute " "virsh net-update command") # Check the actual xml virsh_option = "" if options == "--config": virsh_option = "--inactive" cmd_result = virsh.net_dumpxml(net_name, virsh_option) actual_net_xml = cmd_result.stdout.strip() logging.info("After net-update, the actual net xml is %s", actual_net_xml) if update_command == "delete": new_xml_obj = network_xml.NetworkXML.new_from_net_dumpxml( net_name, extra=virsh_option) try: section_str = new_xml_obj.get_section_string(xpath=element) except xcepts.LibvirtXMLNotFoundError: section_str = None if section_str is not None: test.fail("The actual net xml is not expected," "element still exists") else: for flag_string in flag_list: if not re.search(flag_string, actual_net_xml): test.fail("The actual net xml failed to update") finally: test_xml.undefine() if os.path.exists(xmlfile): os.remove(xmlfile)
def run(test, params, env): """ Test command: virsh net-edit <network> 1) Define a temp virtual network 2) Execute virsh net-edit to modify it 3) Dump its xml then check it """ def edit_net_xml(): edit_cmd = r":%s /100.254/100.253" session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) session.sendline("virsh net-edit %s" % net_name) logging.info("Change the ip value of dhcp end") session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError) as details: log = session.get_output() session.close() test.fail("Failed to do net-edit: %s\n%s" % (details, log)) # Gather test parameters net_name = params.get("net_edit_net_name", "editnet") test_create = "yes" == params.get("test_create", "no") virsh_dargs = {'debug': True, 'ignore_status': True} virsh_instance = virsh.VirshPersistent(**virsh_dargs) # Get all network instance nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance) # First check if a bridge of this name already exists # Increment suffix integer from 1 then append it to net_name # till there is no name conflict. if net_name in nets: net_name_fmt = net_name + "%d" suffix_num = 1 while ((net_name_fmt % suffix_num) in nets): suffix_num += 1 net_name = net_name_fmt % suffix_num virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> </dhcp> </ip> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net if test_create: test_xml.create() else: test_xml.define() except xcepts.LibvirtXMLError as detail: test.cancel("Failed to define a test network.\n" "Detail: %s." % detail) # Run test case try: libvirtd = utils_libvirtd.Libvirtd() if test_create: # Restart libvirtd and check state libvirtd.restart() net_state = virsh.net_state_dict() if (not net_state[net_name]['active'] or net_state[net_name]['autostart'] or net_state[net_name]['persistent']): test.fail("Found wrong network states" " after restarting libvirtd: %s" % net_state) else: libvirtd.restart() net_state = virsh.net_state_dict() if (net_state[net_name]['active'] or net_state[net_name]['autostart'] or not net_state[net_name]['persistent']): test.fail("Found wrong network states: %s" % net_state) virsh.net_start(net_name) edit_net_xml() if test_create: # Network become persistent after editing net_state = virsh.net_state_dict() if (not net_state[net_name]['active'] or net_state[net_name]['autostart'] or not net_state[net_name]['persistent']): test.fail("Found wrong network states" " after editing: %s" % net_state) cmd_result = virsh.net_dumpxml(net_name, '--inactive', debug=True) if cmd_result.exit_status: test.fail("Failed to dump xml of virtual network %s" % net_name) # The xml should contain the match_string match_string = "100.253" xml = cmd_result.stdout.strip() if not re.search(match_string, xml): test.fail("The xml is not expected") # The active xml should not contain the match_string cmd_result = virsh.net_dumpxml(net_name, debug=True) if cmd_result.exit_status: test.fail("Failed to dump active xml of virtual network %s" % net_name) # The xml should contain the match_string match_string = "100.253" xml = cmd_result.stdout.strip() if re.search(match_string, xml): test.fail("The active xml should not change") finally: test_xml.orbital_nuclear_strike()
def run(test, params, env): """ Test command: virsh net-start. """ # Gather test parameters uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri", "default")) status_error = "yes" == params.get("status_error", "no") inactive_default = "yes" == params.get("net_start_inactive_default", "yes") net_ref = params.get("net_start_net_ref", "netname") # default is tested extra = params.get("net_start_options_extra", "") # extra cmd-line params. route_test = "yes" == params.get("route_test", "no") firewalld_operate = params.get("firewalld_operate", None) # make easy to maintain virsh_dargs = {'uri': uri, 'debug': True, 'ignore_status': True} virsh_instance = virsh.VirshPersistent(**virsh_dargs) # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': test.cancel("API acl test not supported in current" " libvirt version.") virsh_uri = params.get("virsh_uri") if virsh_uri and not utils_split_daemons.is_modular_daemon(): virsh_uri = "qemu:///system" unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # Get all network instance origin_nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance) # Prepare default network for following test. try: default_netxml = origin_nets['default'] except KeyError: virsh_instance.close_session() test.cancel("Test requires default network to exist") try: # To confirm default network is active if not default_netxml.active: default_netxml.active = True # inactive default according test's need if inactive_default: logging.info("Stopped default network") default_netxml.active = False # State before run command origin_state = virsh_instance.net_state_dict() logging.debug("Origin network(s) state: %s", origin_state) if route_test: # define a network "def" with route address is "192.168.122.x" # 1. start def first then start default current_state = virsh_instance.net_state_dict() if 'def' in current_state: virsh.net_destroy("def", ignore_status=True) virsh.net_undefine("def", ignore_status=True) expect_fail = "yes" == params.get("expect_start_fail", "no") test_xml = network_xml.NetworkXML(network_name="def") test_xml.forward = {'mode': 'nat'} test_xml.routes = [{ 'address': '192.168.122.0', 'prefix': '24', 'gateway': '192.168.100.1' }] ipxml = IPXML(address='192.168.100.1', netmask='255.255.255.0') range_4 = network_xml.RangeXML() range_4.attrs = { 'start': '192.168.100.2', 'end': '192.168.100.254' } ipxml.dhcp_ranges = range_4 test_xml.ip = ipxml test_xml.define() virsh.net_start("def") # start default, should fail result = virsh.net_start("default") logging.debug(result) libvirt.check_exit_status(result, expect_error=expect_fail) # 2. start default then start def virsh.net_destroy("def") virsh.net_start("default") current_state11 = virsh_instance.net_state_dict() logging.debug("before start 2nd network(s) state: %s", current_state11) # start def, should fail result = virsh.net_start("def") logging.debug(result) libvirt.check_exit_status(result, expect_error=expect_fail) current_state12 = virsh_instance.net_state_dict() logging.debug("after start 2nd network(s) state: %s", current_state12) # clear the env virsh.net_undefine("def") else: if net_ref == "netname": net_ref = default_netxml.name elif net_ref == "netuuid": net_ref = default_netxml.uuid if params.get('setup_libvirt_polkit') == 'yes': virsh_dargs = { 'uri': virsh_uri, 'unprivileged_user': unprivileged_user, 'debug': False, 'ignore_status': True } if params.get('net_start_readonly', 'no') == 'yes': virsh_dargs = { 'uri': uri, 'debug': True, 'readonly': True, 'ignore_status': True } # Run test case if 'unprivileged_user' in virsh_dargs and status_error: test_virsh = virsh.VirshPersistent( unprivileged_user=virsh_dargs['unprivileged_user']) virsh_dargs.pop('unprivileged_user') result = test_virsh.net_start(net_ref, extra, **virsh_dargs) test_virsh.close_session() elif not route_test: result = virsh.net_start(net_ref, extra, **virsh_dargs) logging.debug(result) status = result.exit_status # Get current net_stat_dict current_state = virsh_instance.net_state_dict() logging.debug("Current network(s) state: %s", current_state) if 'default' not in current_state: test.fail('Network "default" cannot be found') if firewalld_operate: # current network is active, ensure firewalld is active # if not, restart firewalld, then restart libvirtd firewalld_service = service.Factory.create_service("firewalld") libvirtd_obj = utils_libvirtd.Libvirtd() if not firewalld_service.status(): firewalld_service.start() libvirtd_obj.restart() virsh_instance = virsh.VirshPersistent(**virsh_dargs) if firewalld_operate == "restart": # after firewalld restart, destroy and start the network firewalld_service.restart() time.sleep(5) res1 = virsh.net_destroy(net_ref, extra, **virsh_dargs) # need to add wait time. As libvirt doesn't know that firewalld has restarted until it gets the # dbus message, but that message won't arrive until some time after all of libvirt's chains/rules # have already been removed by the firewalld restart. refer to bug 1942805 time.sleep(5) res2 = virsh.net_start(net_ref, extra, **virsh_dargs) elif firewalld_operate == "stop_start": # start network which has been destroyed before firewalld restart res1 = virsh.net_destroy(net_ref, extra, **virsh_dargs) firewalld_service.stop() firewalld_service.start() time.sleep(5) res2 = virsh.net_start(net_ref, extra, **virsh_dargs) logging.debug( "firewalld_operate is %s, result for start network after firewalld restart: %s", firewalld_operate, res2) status1 = res1.exit_status | res2.exit_status if status1: test.fail( "Start or destroy network after firewalld restart fail!") # Check status_error if status_error: if not status: test.fail("Run successfully with wrong command!") else: if status: test.fail("Run failed with right command") # Get current net_stat_dict current_state = virsh_instance.net_state_dict() logging.debug("Current network(s) state: %s", current_state) is_default_active = current_state['default']['active'] if not is_default_active: test.fail( "Execute cmd successfully but default is inactive actually." ) finally: virsh_instance.close_session() current_state = virsh_instance.net_state_dict() if "def" in current_state: virsh.net_destroy("def", ignore_status=True) virsh.net_undefine("def", ignore_status=True) virsh.net_start('default', debug=True, ignore_status=True)
def run(test, params, env): """ Test command: virsh net-edit <network> 1) Define a temp virtual network 2) Execute virsh net-edit to modify it 3) Dump its xml then check it """ def edit_net_xml(edit_cmd, expect_error, **dargs): """ Edit net xml with virsh net-edit :params edit_cmd: The edit cmd to execute :params expect_error: Boolean, expect success or not :params **dargs: The virsh edit's option """ logging.debug("edit_cmd: %s", edit_cmd) readonly = dargs.get("readonly", False) session = aexpect.ShellSession("sudo -s") try: logging.info("Execute virsh net-edit %s", net_name) virsh_cmd = "virsh net-edit %s" % net_name if readonly: virsh_cmd = "virsh -r net-edit %s" % net_name logging.debug("virsh_cmd: %s", virsh_cmd) session.sendline(virsh_cmd) session.sendline(edit_cmd) session.send('\x1b') session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() except (aexpect.ShellError, aexpect.ExpectError, remote.LoginTimeoutError) as details: log = session.get_output() session.close() if not expect_error: test.fail("Failed to do net-edit: %s\n%s" % (details, log)) logging.debug("Expected error: %s" % log) if readonly and "read only" not in log: test.fail("Not expected error") # Gather test parameters net_name = params.get("net_edit_net_name", "editnet") test_create = "yes" == params.get("test_create", "no") virsh_dargs = {'debug': True, 'ignore_status': True} virsh_instance = virsh.VirshPersistent(**virsh_dargs) change_attribute = params.get("attribute", None) old_value = params.get("old_value", None) new_value = params.get("new_value", None) edit_type = params.get("edit_type", "modify") status_error = (params.get("status_error", "no") == "yes") readonly = (params.get("net_edit_readonly", "no") == "yes") # Get all network instance nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance) # First check if a bridge of this name already exists # Increment suffix integer from 1 then append it to net_name # till there is no name conflict. if net_name in nets: net_name_fmt = net_name + "%d" suffix_num = 1 while ((net_name_fmt % suffix_num) in nets): suffix_num += 1 net_name = net_name_fmt % suffix_num virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254' /> </dhcp> </ip> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net if test_create: test_xml.create() else: test_xml.define() except xcepts.LibvirtXMLError as detail: test.cancel("Failed to define a test network.\n" "Detail: %s." % detail) # Run test case try: libvirtd = utils_libvirtd.Libvirtd() if change_attribute == "uuid": # if the attribute need to change is uuid, the old uuid should get # from current network, and new uuid can generate by uuidgen new_value = process.run("uuidgen", shell=True).stdout[:-1] old_value = virsh.net_uuid(net_name).stdout.strip() if test_create: # Restart libvirtd and check state libvirtd.restart() net_state = virsh.net_state_dict() if (not net_state[net_name]['active'] or net_state[net_name]['autostart'] or net_state[net_name]['persistent']): test.fail("Found wrong network states" " after restarting libvirtd: %s" % net_state) else: libvirtd.restart() net_state = virsh.net_state_dict() if (net_state[net_name]['active'] or net_state[net_name]['autostart'] or not net_state[net_name]['persistent']): test.fail("Found wrong network states: %s" % net_state) result = virsh.net_start(net_name) logging.debug("start the persistent network return: %s", result) if edit_type == "modify": edit_cmd = r":%%s/%s=\'%s\'/%s=\'%s\'" % ( change_attribute, old_value, change_attribute, new_value) match_string = "%s=\'%s\'" % (change_attribute, new_value) if edit_type == "delete": match_string = "%s" % change_attribute # Pattern to be more accurate if old_value and change_attribute != 'uuid': match_string = "%s=\'%s\'" % (change_attribute, old_value) else: match_string = old_value edit_cmd = r":/%s/d" % match_string edit_net_xml(edit_cmd, status_error, readonly=readonly) net_state = virsh.net_state_dict() # transient Network become persistent after editing if not status_error and (not net_state[net_name]['active'] or net_state[net_name]['autostart'] or not net_state[net_name]['persistent']): test.fail("Found wrong network states" " after editing: %s" % net_state) cmd_result = virsh.net_dumpxml(net_name, '--inactive', debug=True) if cmd_result.exit_status: test.fail("Failed to dump xml of virtual network %s" % net_name) # The inactive xml should contain the match string xml = cmd_result.stdout.strip() if edit_type == "modify": if not status_error and not re.search(match_string, xml): test.fail("The inactive xml should contain the change '%s'" % match_string) if status_error and re.search(match_string, xml): test.fail("Expect to modify failure but run success") if edit_type == "delete": if not status_error and re.search(match_string, xml): test.fail("The inactive xml should delete the change '%s'" % match_string) if status_error and not re.search(match_string, xml): test.fail("Expect to delete failure but run success") # The active xml should not contain the match string if net_state[net_name]['active']: if not status_error: cmd_result = virsh.net_dumpxml(net_name, debug=True) if cmd_result.exit_status: test.fail( "Failed to dump active xml of virtual network %s" % net_name) xml = cmd_result.stdout.strip() if edit_type == "modify" and re.search(match_string, xml): test.fail( "The active xml should not contain the change '%s'" % match_string) if edit_type == "delete" and not re.search(match_string, xml): test.fail( "The active xml should not delete the change '%s'" % match_string) finally: test_xml.orbital_nuclear_strike()
def run(test, params, env): global flag_list, flag_list_abs, update_sec, without_sec global check_sec, check_without_sec, newxml # Basic network params net_name = params.get("net_update_net_name", "updatenet") net_section = params.get("network_section") update_command = params.get("update_command", "add-last") options = params.get("cmd_options", "") net_state = params.get("net_state") use_in_guest = params.get("use_in_guest") iface_type = params.get("iface_type", "network") ip_version = params.get("ip_version", "ipv4") new_start_ip = params.get("start_ip") new_end_ip = params.get("end_ip") parent_index = params.get("parent_index") status_error = params.get("status_error", "no") # dhcp host test new_dhcp_host_ip = params.get("new_dhcp_host_ip") new_dhcp_host_id = params.get("new_dhcp_host_id") new_dhcp_host_name = params.get("new_dhcp_host_name") new_dhcp_host_mac = params.get("new_dhcp_host_mac") # ipv4 range/host test ipv4_range_start = params.get("ori_ipv4_range_start") ipv4_range_end = params.get("ori_ipv4_range_end") ipv4_host_mac = params.get("ori_ipv4_host_mac") ipv4_host_ip = params.get("ori_ipv4_host_ip") ipv4_host_name = params.get("ori_ipv4_host_name") # ipv6 range/host test ipv6_range_start = params.get("ori_ipv6_range_start") ipv6_range_end = params.get("ori_ipv6_range_end") ipv6_host_id = params.get("ori_ipv6_host_id") ipv6_host_name = params.get("ori_ipv6_host_name") ipv6_host_ip = params.get("ori_ipv6_host_ip") # dns test dns_name = params.get("ori_dns_name") dns_value = params.get("ori_dns_value") new_dns_name = params.get("new_dns_name") new_dns_value = params.get("new_dns_value") # srv test srv_service = params.get("ori_srv_service") srv_protocol = params.get("ori_srv_protocol") srv_domain = params.get("ori_srv_domain") srv_target = params.get("ori_srv_target") srv_port = params.get("ori_srv_port") srv_priority = params.get("ori_srv_priority") srv_weight = params.get("ori_srv_weight") new_srv_service = params.get("new_srv_service") new_srv_protocol = params.get("new_srv_protocol") new_srv_domain = params.get("new_srv_domain") new_srv_target = params.get("new_srv_target") new_srv_port = params.get("new_srv_port") new_srv_priority = params.get("new_srv_priority") new_srv_weight = params.get("new_srv_weight") # dns host test dns_hostip = params.get("ori_dns_hostip") dns_hostname = params.get("ori_dns_hostname") dns_hostname2 = params.get("ori_dns_hostname2") # setting for without part without_ip_dhcp = params.get("without_ip_dhcp", "no") without_dns = params.get("without_dns", "no") without_dns_host = params.get("without_dns_host", "no") without_dns_txt = params.get("without_dns_txt", "no") without_dns_srv = params.get("without_dns_srv", "no") without_dns_forwarder = params.get("without_dns_forwarder", "no") # setting for update/check/without section update_sec = params.get("update_sec") check_sec = params.get("check_sec") without_sec = params.get("without_sec") check_without_sec = params.get("check_without_sec") # forward test forward_mode = params.get("forward_mode") forward_iface = params.get("forward_iface", "eth2") # other params error_type = params.get("error_type", "") vm_name = params.get("main_vm") loop_time = int(params.get("loop_time", 1)) check_config_round = params.get("check_config_round", -1) ipv4_host_id = ipv6_host_mac = "" dns_enable = params.get("dns_enable", "yes") guest_iface_num = int(params.get("guest_iface_num", 1)) newxml = "" def get_hostfile(): """ Get the content of hostfile """ logging.info("Checking network hostfile...") hostfile = "/var/lib/libvirt/dnsmasq/%s.hostsfile" % net_name with open(hostfile) as hostfile_d: hostfile = hostfile_d.readlines() return hostfile def find_config(check_file, need_find): """ Find configure in check_file :param check_file: The file that will check :param need_find: If need to find the item in check_file, Boolean """ def _find_config(check_func): def __find_config(*args, **kwargs): logging.info("Checking content of %s", check_file) ret = False item = None with open(check_file) as checkfile_d: while True: check_line = checkfile_d.readline() if not check_line: break (ret, item) = check_func(check_line, *args, **kwargs) if ret: break if not ret: if need_find: test.fail("Fail to find %s in %s" % (item, check_file)) else: logging.info("Can not find %s in %s as expected" % (item, check_file)) return __find_config return _find_config conf_file = "/var/lib/libvirt/dnsmasq/%s.conf" % net_name @find_config(conf_file, True) def check_item(check_line, item): """ Check if the item in config file """ if item in check_line: logging.info("Find %s in %s", item, conf_file) return (True, item) else: return (False, item) host_file = "/var/lib/libvirt/dnsmasq/%s.addnhosts" % net_name @find_config(host_file, True) def check_host(check_line, item): """ Check if the item in host_file """ if re.search(item, check_line): logging.info("Find %s in %s", item, host_file) return (True, item) else: return (False, item) @find_config(conf_file, False) def check_item_absent(check_line, item): """ Check if the item not in config file """ if item in check_line: test.fail("Find %s in %s" % (item, conf_file)) else: return (False, item) @find_config(host_file, False) def check_host_absent(check_line, item): """ Check if the item not in host_file """ if re.search(item, check_line): test.fail("Find %s in %s" % (item, host_file)) else: return (False, item) def section_update(ori_pre, new_pre): """ Deal with update section and without section in func :param ori_pre: prefix of original section parameter name :param new_pre: prefix of new section parameter name """ global flag_list, flag_list_abs, update_sec, without_sec global check_sec, check_without_sec, newxml if update_sec: for sec in update_sec.split(","): newxml = newxml.replace(names[ori_pre + sec], names[new_pre + sec]) if update_command != "delete": check_sec = update_sec if without_sec: for sec_no in without_sec.split(","): newxml = re.sub(sec_no + "=\".*?\"", "", newxml) if update_command == "modify": check_without_sec = without_sec if check_sec: for c_sec in check_sec.split(","): flag_list.append(names[new_pre + c_sec]) if check_without_sec: for c_sec_no in check_without_sec.split(","): flag_list_abs.append(names[ori_pre + c_sec_no]) dns_host_xml = """ <host ip='%s'> <hostname>%s</hostname> <hostname>%s</hostname> </host> """ % (dns_hostip, dns_hostname, dns_hostname2) virtual_net = """ <network> <name>%s</name> <forward mode='nat'/> <bridge name='%s' stp='on' delay='0' /> <mac address='52:54:00:03:78:6c'/> <domain name="example.com" localOnly="no"/> <mtu size="9000"/> <dns enable='%s'> <forwarder domain='example.com' addr="8.8.4.4"/> <txt name='%s' value='%s'/> <srv service='%s' protocol='%s' domain='%s' target='%s' port='%s' priority='%s' weight='%s'/> %s </dns> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='%s' end='%s' /> <host mac='%s' ip='%s' name='%s' /> </dhcp> </ip> <ip family='ipv6' address='2001:db8:ca2:2::1' prefix='64'> <dhcp> <range start='%s' end='%s'/> <host id='%s' name='%s' ip='%s'/> </dhcp> </ip> <route family='ipv6' address='2001:db8:ca2:2::' prefix='64' gateway='2001:db8:ca2:2::4'/> <ip address='192.168.101.1' netmask='255.255.255.0'/> <ip family='ipv6' address='2001:db8:ca2:3::1' prefix='64' /> </network> """ % (net_name, net_name, dns_enable, dns_name, dns_value, srv_service, srv_protocol, srv_domain, srv_target, srv_port, srv_priority, srv_weight, dns_host_xml, ipv4_range_start, ipv4_range_end, ipv4_host_mac, ipv4_host_ip, ipv4_host_name, ipv6_range_start, ipv6_range_end, ipv6_host_id, ipv6_host_name, ipv6_host_ip) port_group = """ <portgroup name='engineering' default='no'> <virtualport type='802.1Qbh'> <parameters profileid='test'/> </virtualport> <bandwidth> <inbound average='1000' peak='5000' burst='5120'/> <outbound average='1000' peak='5000' burst='5120'/> </bandwidth> </portgroup> """ if use_in_guest == "yes": vm = env.get_vm(vm_name) vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) vmxml_backup = vmxml.copy() backup_files = [] try: for loop in range(loop_time): if loop_time > 1: logging.info("Round %s:", loop + 1) update_command = params.get("update_command").split(",")[loop] if net_section == "ip-dhcp-host": new_dhcp_host_ip = params.get("new_dhcp_host_ip").split( ",")[loop] new_dhcp_host_name = params.get( "new_dhcp_host_name").split(",")[loop] new_dhcp_host_mac = params.get("new_dhcp_host_mac").split( ",")[loop] status_error = params.get("status_error").split(",")[loop] elif net_section == "dns-txt": net_state = params.get("net_state").split(",")[loop] # Get a tmp_dir. tmp_dir = data_dir.get_tmp_dir() # Write new xml into a tempfile tmp_file = tempfile.NamedTemporaryFile(prefix=("new_xml_"), dir=tmp_dir) xmlfile = tmp_file.name tmp_file.close() # Generate testxml test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = virtual_net names = locals() if net_section == "portgroup": portgroup_xml = network_xml.PortgroupXML() portgroup_xml.xml = port_group test_xml.portgroup = portgroup_xml elif net_section == "forward-interface": if forward_mode == "bridge": forward_iface = utils_net.get_net_if(state="UP")[0] test_xml.forward = {'mode': forward_mode} test_xml.forward_interface = [{'dev': forward_iface}] del test_xml.bridge del test_xml.mac for ip_num in range(4): del test_xml.ip del test_xml.routes del test_xml.dns del test_xml.mtu del test_xml.domain_name section_index = 0 if ip_version == "ipv6": section_index = 1 element = "/%s" % net_section.replace('-', '/') try: section_xml = test_xml.get_section_string(xpath=element, index=section_index) except xcepts.LibvirtXMLNotFoundError: newxml = section_xml = test_xml.get_section_string( xpath="/ip/dhcp/range") newxml = section_xml logging.debug("section xml is %s", newxml) flag_list = [] flag_list_abs = [] if (update_command == "delete" and error_type not in ["host-mismatch", "range-mismatch"] and not without_sec and not update_sec): logging.info("The delete xml is %s", newxml) else: if net_section == "bridge": new_bridge_name = net_name + "_new" flag_list.append(new_bridge_name) newxml = section_xml.replace(net_name, new_bridge_name) logging.info("The new bridge xml is %s", newxml) elif net_section == "forward": new_mode = "route" flag_list.append(new_mode) newxml = section_xml.replace("nat", new_mode) logging.info("The new forward xml is %s", newxml) elif net_section == "ip": new_netmask = "255.255.0.0" flag_list.append(new_netmask) newxml = section_xml.replace("255.255.255.0", new_netmask) elif net_section == "ip-dhcp-range": newxml = section_xml.replace( names[ip_version + "_range_start"], new_start_ip) newxml = newxml.replace(names[ip_version + "_range_end"], new_end_ip) for location in ["end", "start"]: if names["new_" + location + "_ip"] == "": newxml = newxml.replace(location + "=\"\"", "") else: flag_list.append(names["new_" + location + "_ip"]) elif net_section == "portgroup": new_inbound_average = "2000" flag_list.append(new_inbound_average) newxml = section_xml.replace("1000", new_inbound_average) newxml = newxml.replace("default=\"no\"", "default=\"yes\"") flag_list.append("default=('|\")yes") if update_command in ['add-first', 'add-last', 'add']: newxml = newxml.replace("engineering", "sales") flag_list.append("sales") if update_command == "modify" and status_error == "yes": newxml = newxml.replace("engineering", "") elif net_section == "forward-interface": new_forward_iface = params.get("new_forward_iface") if error_type != "interface-duplicate": find_iface = 0 if not new_forward_iface and forward_mode == "bridge": new_iface_list = utils_net.get_net_if( qdisc="(mq|pfifo_fast)", state="(UP|DOWN)", optional="MULTICAST,UP") logging.info("new_iface_list is %s", new_iface_list) for iface in new_iface_list: if iface[0] != forward_iface: new_forward_iface = iface[0] find_iface = 1 break if not find_iface: test.cancel( "Can not find another physical interface to attach" ) else: new_forward_iface = forward_iface flag_list.append(new_forward_iface) newxml = section_xml.replace(forward_iface, new_forward_iface) elif net_section == "ip-dhcp-host": if (update_sec is None and update_command not in ['modify', 'delete']): if ip_version == "ipv4": update_sec = "ip,mac,name" elif ip_version == "ipv6": update_sec = "ip,id,name" section_update(ip_version + "_host_", "new_dhcp_host_") elif net_section == "dns-txt": section_update("dns_", "new_dns_") elif net_section == "dns-srv": section_update("srv_", "new_srv_") elif net_section == "dns-host": if without_sec == "hostname": newxml = re.sub("<hostname>.*</hostname>\n", "", newxml) if status_error == 'no': flag_list.append("ip=.*?" + dns_hostip) flag_list.append(dns_hostname) flag_list.append(dns_hostname2) # for negative test may have net_section do not match issues elif status_error == "no": test.fail("Unknown network section") logging.info("The new xml of %s is %s", net_section, newxml) with open(xmlfile, 'w') as xmlfile_d: xmlfile_d.write(newxml) if without_ip_dhcp == "yes": test_xml.del_element(element="/ip/dhcp") test_xml.del_element(element="/ip/dhcp") if without_dns == "yes": test_xml.del_element(element='/dns') if without_dns_host == "yes": test_xml.del_element(element='/dns/host') if without_dns_txt == "yes": test_xml.del_element(element='/dns/txt') if without_dns_srv == "yes": test_xml.del_element(element='/dns/srv') if without_dns_forwarder == "yes": test_xml.del_element(element='/dns/forwarder') # Only do net define/start in first loop if (net_section == "ip-dhcp-range" and use_in_guest == "yes" and without_ip_dhcp == "no"): test_xml.del_element(element="/ip/dhcp", index=section_index) if error_type == "index-nonexist": for idx in [3, 2, 1]: test_xml.del_element(element="/ip", index=idx) test_xml.del_element(element="/route") if loop == 0: try: # Define and start network test_xml.debug_xml() test_xml.define() ori_net_xml = virsh.net_dumpxml(net_name).stdout.strip() if "ipv6" in ori_net_xml: host_ifaces = utils_net.get_net_if(state="UP") backup_files.append( remote.RemoteFile(address='127.0.0.1', client='scp', username=params.get('username'), password=params.get('password'), port='22', remote_path='/proc/sys/net/ipv6/' 'conf/all/accept_ra')) process.run( "echo 2 > /proc/sys/net/ipv6/conf/all/accept_ra", shell=True) for host_iface in host_ifaces: backup_files.append( remote.RemoteFile( address='127.0.0.1', client='scp', username=params.get('username'), password=params.get('password'), port='22', remote_path='/proc/sys/net/ipv6/' 'conf/%s/accept_ra' % host_iface)) process.run( "echo 2 > /proc/sys/net/ipv6/conf/%s/accept_ra" % host_iface, shell=True) process.run( "cat /proc/sys/net/ipv6/conf/%s/accept_ra" % host_iface) if net_state == "active" or net_state == "transient": test_xml.start() if net_state == "transient": test_xml.del_defined() list_result = virsh.net_list("--all --name").stdout.strip() if net_name not in list_result: test.fail("Can not find %s in net-list" % net_name) except xcepts.LibvirtXMLError as detail: test.error("Failed to define a test network.\n" "Detail: %s." % detail) else: # setting net status for following loops if net_state == "active": test_xml.set_active(True) elif net_state == "inactive": test_xml.set_active(False) # get hostfile before update if without_ip_dhcp == "yes" and net_state == "active": hostfile_before = get_hostfile() if hostfile_before != []: test.fail("hostfile is not empty before update: %s" % hostfile_before) logging.info("hostfile is empty before update") # Get dnsmasq pid before update check_dnsmasq = ((update_command == "add" or update_command == "delete") and net_section == "ip-dhcp-range" and status_error == "no" and net_state == "active" and options != "--config") if check_dnsmasq: cmd = "ps aux|grep dnsmasq|grep -v grep|grep %s|awk '{print $2}'" % net_name pid_list_bef = process.run( cmd, shell=True).stdout_text.strip().split('\n') if parent_index: options += " --parent-index %s" % parent_index # Check config before update if net_state == "active": dns_txt = dns_srv = dns_host_str = None try: dns_txt = test_xml.get_section_string(xpath="/dns/txt") dns_srv = test_xml.get_section_string(xpath="/dns/srv") dns_host_str = test_xml.get_section_string( xpath="/dns/host") except xcepts.LibvirtXMLNotFoundError: pass txt_record = "txt-record=%s,%s" % (dns_name, dns_value) srv_host = "srv-host=_%s._%s.%s,%s,%s,%s,%s" % ( srv_service, srv_protocol, srv_domain, srv_target, srv_port, srv_priority, srv_weight) hostline = "%s.*%s.*%s" % (dns_hostip, dns_hostname, dns_hostname2) if dns_txt: check_item(txt_record) if dns_srv: check_item(srv_host) if dns_host_str: check_host(hostline) # Do net-update operation cmd_result = virsh.net_update(net_name, update_command, net_section, xmlfile, options, debug=True) if cmd_result.exit_status: err = cmd_result.stderr.strip() if status_error == "yes": # index-mismatch error info and judgement index_err1 = "the address family of a host entry IP must match the" + \ " address family of the dhcp element's parent" index_err2 = "XML error: Invalid to specify MAC address.* in network" + \ ".* IPv6 static host definition" index_err3 = "mismatch of address family in range.* for network" mismatch_expect = (error_type == "index-mismatch" and (re.search(index_err1, err) or re.search(index_err2, err) or re.search(index_err3, err))) err_dic = {} # multi-host error info err_dic["multi-hosts"] = "dhcp is supported only for a single.*" + \ " address on each network" # range-mismatch error info err_dic["range-mismatch"] = "couldn't locate a matching dhcp " + \ "range entry in network " # index-nonexist error info err_dic["index-nonexist"] = "couldn't update dhcp host entry " + \ "- no <ip.* element found at index 1 in network" # host-mismatch error info err_dic["host-mismatch"] = "couldn't locate a matching dhcp " + \ "host entry in network " # dns-mismatch error info err_dic["dns-mismatch"] = "couldn't locate a matching DNS TXT " + \ "record in network " # range-duplicate error info err_dic["range-duplicate"] = "there is an existing dhcp range" + \ " entry in network.* that matches" # host-duplicate error info err_dic["host-duplicate"] = "there is an existing dhcp host" + \ " entry in network.* that matches" # out_of_range error info err_dic[ "out-of-range"] = "range.* is not entirely within network" # no end for range error err_dic["range-no-end"] = "Missing 'end' attribute in dhcp " + \ "range for network" # no match item for host modify err err_dic["no-match-item"] = "couldn't locate an existing dhcp" + \ " host entry with.* in network" # no host name and mac for modify err err_dic["host-no-name-mac"] = "Static host definition in IPv4 network" + \ ".* must have mac or name attribute" # no host ip for modify err err_dic["host-no-ip"] = "Missing IP address in static host " + \ "definition for network" # wrong command name err_dic["wrong-command-name"] = "unrecognized command name" # wrong section name err_dic["wrong-section-name"] = "unrecognized section name" # delete with only id err_dic["only-id"] = "At least one of name, mac, or ip attribute must be" + \ " specified for static host definition in network" # options exclusive err_dic[ "opt-exclusive"] = "Options --current and.* are mutually exclusive" # range_reverse error info if ip_version == "ipv4": err_dic["range-reverse"] = "range.* is reversed" elif ip_version == "ipv6": err_dic[ "range-reverse"] = "range.*start larger than end" # --live with inactive net err_dic["invalid-state"] = "network is not running" err_dic[ "transient"] = "cannot change persistent config of a transient network" err_dic["dns-disable"] = "Extra data in disabled network" err_dic[ "modify"] = "cannot be modified, only added or deleted" err_dic["not-support"] = "can't update.*section of network" err_dic["unrecognized"] = "unrecognized section name" err_dic["interface-duplicate"] = "there is an existing interface entry " + \ "in network.* that matches" err_dic[ "XML error"] = "XML error: Missing required name attribute in portgroup" if (error_type in list(err_dic.keys()) and re.search(err_dic[error_type], err) or mismatch_expect): logging.debug("Get expect error: %s", err) else: test.fail("Do not get expect err msg: %s, %s" % (error_type, err_dic)) else: test.fail("Failed to execute net-update command") elif status_error == "yes": test.fail("Expect fail, but succeed") # Get dnsmasq pid after update if check_dnsmasq: pid_list_aft = process.run( cmd, shell=True).stdout_text.strip().split('\n') for pid in pid_list_aft: if pid in pid_list_bef: test.fail("dnsmasq do not updated") # Check the actual xml cmd_result = virsh.net_dumpxml(net_name) actual_net_xml = cmd_result.stdout.strip() new_xml_obj = network_xml.NetworkXML.new_from_net_dumpxml(net_name) logging.info("After net-update, the actual net xml is %s", actual_net_xml) if "ip-dhcp" in net_section: if ip_version == "ipv6": new_xml_obj.del_element(element="/ip", index=0) if ip_version == "ipv4": new_xml_obj.del_element(element="/ip", index=1) config_not_work = ("--config" in options and net_state == "active" and "--live" not in options) if config_not_work: if update_command != "delete": flag_list_abs = flag_list flag_list = [] else: flag_list = flag_list_abs flag_list_abs = [] logging.info("The check list is %s, absent list is %s", flag_list, flag_list_abs) if (update_command == "delete" and status_error == "no" and not config_not_work and loop_time == 1): try: section_str = new_xml_obj.get_section_string(xpath=element) except xcepts.LibvirtXMLNotFoundError: section_str = None logging.info("Can not find section %s in xml after delete", element) if section_str is not None: test.fail("The actual net xml is not expected," "element still exists") elif ("duplicate" not in error_type and error_type != "range-mismatch" and error_type != "host-mismatch" and error_type != "not-support"): # check xml should exists for flag_string in flag_list: logging.info( "checking %s should in xml in positive test," "and absent in negative test", flag_string) if not re.search(flag_string, actual_net_xml): if ((status_error == "no" and update_command != "delete") or (update_command == "delete" and status_error == "yes")): test.fail("The actual net xml failed to update," "or expect delete fail but xml missing" ":%s" % flag_string) else: if ((status_error == "yes" and update_command != "delete") or (status_error == "no" and update_command == "delete" and not config_not_work)): test.fail("Expect test fail, but find xml %s" " actual, or expect delete succeed," "but fail in fact" % flag_string) # check xml should not exists for flag_string_abs in flag_list_abs: logging.info( "checking %s should NOT in xml in positive test," "and exist in negative test", flag_string_abs) if re.search(flag_string_abs, actual_net_xml): if status_error == "no": test.fail("Expect absent in net xml, but exists" "in fact: %s" % flag_string_abs) else: if status_error == "yes": test.fail("Should exists in net xml, but it " "disappeared: %s" % flag_string_abs) # Check if add-last, add-fist works well if (status_error == "no" and not config_not_work and update_command in ["add-last", "add", "add-first"]): if update_command == "add-first": find_index = 0 else: find_index = -1 section_str_aft = new_xml_obj.get_section_string( xpath=element, index=find_index) logging.info( "xpath is %s, find_index is %s, section_str_aft is %s", element, find_index, section_str_aft) for flag_string in flag_list: logging.info("flag_string is %s", flag_string) if not re.search(flag_string, section_str_aft): test.fail("Can not find %s in %s" % (flag_string, section_str_aft)) logging.info("%s %s in right place", update_command, section_str_aft) # Check the positive test result if status_error == "no": # Check the network conf file # live update if ("--live" in options or "--config" not in options) and net_state == "active": if net_section == "ip-dhcp-range" and update_command == "add-first": ip_range = "%s,%s" % (new_start_ip, new_end_ip) if ip_version == "ipv6": ip_range = ip_range + ",64" check_item(ip_range) if "dns" in net_section: if update_command == "delete" and loop == 0: if net_section == "dns-srv": check_item_absent(srv_host) if net_section == "dns-txt": check_item_absent(txt_record) if net_section == "dns-host": check_host_absent(dns_host_str) elif "add" in update_command: if net_section == "dns-srv": for sec in update_sec.split(","): srv_host = srv_host.replace( names["srv_" + sec], names["new_srv_" + sec]) check_item(srv_host) if net_section == "dns-txt": for sec in update_sec.split(","): txt_record = txt_record.replace( names["dns_" + sec], names["new_dns_" + sec]) check_item(txt_record) if net_section == "dns-host": check_host(hostline) # Check the hostfile if (net_section == "ip-dhcp-host" and update_command != "modify" and update_command != "delete"): dic_hostfile = {} for sec in ["ip", "mac", "name", "id"]: if update_sec is not None and sec in update_sec.split( ","): dic_hostfile[sec] = names["new_dhcp_host_" + sec] + "," else: dic_hostfile[sec] = names[ip_version + "_host_" + sec] + "," if sec == "ip" and ip_version == "ipv6": dic_hostfile[sec] = "[" + dic_hostfile[ sec].strip(",") + "]" if without_sec is not None and sec in without_sec.split( ","): dic_hostfile[sec] = "" if ip_version == "ipv4": host_info = (dic_hostfile["mac"] + dic_hostfile["ip"] + dic_hostfile["name"]) if dic_hostfile["mac"] == "": host_info = dic_hostfile[ "name"] + dic_hostfile["ip"] if ip_version == "ipv6": host_info = ("id:" + dic_hostfile["id"] + dic_hostfile["name"] + dic_hostfile["ip"]) hostfile = get_hostfile() host_info_patten = host_info.strip(",") + "\n" if host_info_patten in hostfile: logging.info("host info %s is in hostfile %s", host_info, hostfile) else: test.fail("Can not find %s in host file: %s" % (host_info, hostfile)) # Check the net in guest if use_in_guest == "yes" and loop == 0: # Detach all interfaces of vm first iface_index = 0 mac_list = vm_xml.VMXML.get_iface_dev(vm_name) for mac in mac_list: iface_dict = vm_xml.VMXML.get_iface_by_mac( vm_name, mac) virsh.detach_interface( vm_name, "--type %s --mac %s --config" % (iface_dict.get('type'), mac)) vm.free_mac_address(iface_index) iface_index += 1 # attach new interface to guest for j in range(guest_iface_num): if net_section == "ip-dhcp-host" and new_dhcp_host_mac: mac = new_dhcp_host_mac else: mac = utils_net.generate_mac_address_simple() ret = virsh.attach_interface( vm_name, "--type %s --source %s --mac %s --config" % (iface_type, net_name, mac)) if ret.exit_status: test.fail( "Fail to attach new interface to guest: %s" % ret.stderr.strip()) # The sleep here is to make sure the update make effect time.sleep(2) # Start guest and check ip/mac/hostname... vm.start() logging.debug("vm xml is %s", vm.get_xml()) session = vm.wait_for_serial_login(internal_timeout=60) if "ip-dhcp" in net_section: dhclient_cmd = "(if pgrep dhclient;" \ "then pkill dhclient; sleep 3; fi) " \ "&& dhclient -%s -lf /dev/stdout" % ip_version[-1] leases = session.cmd_output(dhclient_cmd) iface_ip = utils_net.get_guest_ip_addr( session, mac, ip_version=ip_version, timeout=10) if net_section == "ip-dhcp-range": if new_start_ip <= iface_ip <= new_end_ip: logging.info("getting ip %s is in range [%s ~ %s]", iface_ip, new_start_ip, new_end_ip) else: test.fail("getting ip %s not in range [%s ~ %s]" % (iface_ip, new_start_ip, new_end_ip)) if net_section == "ip-dhcp-host": if iface_ip == new_dhcp_host_ip: logging.info("getting ip is same with set: %s", iface_ip) else: test.fail( "getting ip %s is not same with setting %s" % (iface_ip, new_dhcp_host_ip)) hostname = session.cmd_output("hostname -s").strip( '\n') # option host-name "redhatipv4-2" dhcp_hostname = "option host-name \"%s\"" % new_dhcp_host_name.split( '.')[0] if hostname == new_dhcp_host_name.split( '.')[0] or dhcp_hostname in leases: logging.info( "getting hostname same with setting: %s", new_dhcp_host_name.split('.')[0]) else: test.fail("getting hostname %s is not same with " "setting: %s" % (hostname, new_dhcp_host_name)) session.close() # Check network connection for macvtap if (use_in_guest == "yes" and net_section == "forward-interface" and forward_mode == "bridge"): xml_obj_use = network_xml.NetworkXML.new_from_net_dumpxml( net_name) net_conn = int(xml_obj_use.connection) iface_conn = xml_obj_use.get_interface_connection() conn_count = 0 for k in iface_conn: conn_count = conn_count + int(k) logging.info( "net_conn=%s, conn_count=%s, guest_iface_num=%s" % (net_conn, conn_count, guest_iface_num)) if (net_conn != conn_count or (loop == 1 and guest_iface_num != net_conn)): test.fail("Can not get expected connection num: " "net_conn = %s, iface_conn = %s" % (net_conn, conn_count)) #Check --config option after net destroyed if (int(check_config_round) == loop or (loop_time == 1 and "--current" in options and net_state == "active")): test_xml.set_active(False) logging.info("Checking xml after net destroyed") cmd_result = virsh.net_dumpxml(net_name) inactive_xml = cmd_result.stdout.strip() logging.info("inactive_xml is %s", inactive_xml) #Check the inactive xml for check_str in flag_list: if update_command != "delete": if "--config" in options: if not re.search(check_str, inactive_xml): test.fail( "Can not find xml after net destroyed") if "--current" in options: if re.search(check_str, inactive_xml): test.fail( "XML still exists after net destroyed") else: if "--config" in options: if re.search(check_str, inactive_xml): test.fail( "XML still exists after net destroyed") if "--current" in options: if not re.search(check_str, inactive_xml): test.fail( "Can not find xml after net destroyed") logging.info("Check for net inactive PASS") finally: if test_xml.get_active(): test_xml.del_active() if test_xml.get_defined(): test_xml.del_defined() if os.path.exists(xmlfile): os.remove(xmlfile) if use_in_guest == "yes": vm = env.get_vm(vm_name) if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync() for config_file in backup_files: config_file._reset_file()
def run(test, params, env): """ Test command: virsh net-autostart. """ # Gather test parameters status_error = "yes" == params.get("status_error", "no") net_ref = params.get("net_autostart_net_ref", "netname") disable = "yes" == params.get("net_autostart_disable", "no") extra = params.get("net_autostart_extra", "") # extra cmd-line params. net_name = params.get("net_autostart_net_name", "autotest") # Prepare environment and record current net_state_dict backup = network_xml.NetworkXML.new_all_networks_dict() backup_state = virsh.net_state_dict() logging.debug("Backed up network(s): %s", backup_state) # Generate our own bridge # First check if a bridge of this name already exists try: _ = backup[net_name] except (KeyError, AttributeError): pass # Not found - good else: test.cancel("Found network bridge '%s' - skipping" % net_name) # Define a very bare bones bridge, don't provide UUID - use whatever # libvirt ends up generating. We need to define a persistent network # since we'll be looking to restart libvirtd as part of this test. # # This test cannot use the 'default' bridge (virbr0) since undefining # it causes issues for libvirtd restart since it's expected that a # default network is defined # temp_bridge = """ <network> <name>%s</name> <bridge name="vir%sbr0"/> </network> """ % (net_name, net_name) try: test_xml = network_xml.NetworkXML(network_name=net_name) test_xml.xml = temp_bridge test_xml.define() except xcepts.LibvirtXMLError as detail: test.error("Failed to define a test network.\n" "Detail: %s." % detail) # To guarantee cleanup will be executed try: # Run test case # Get the updated list and make sure our new bridge exists currents = network_xml.NetworkXML.new_all_networks_dict() current_state = virsh.net_state_dict() logging.debug("Current network(s): %s", current_state) try: testbr_xml = currents[net_name] except (KeyError, AttributeError): test.error("Did not find newly defined bridge '%s'" % net_name) # Prepare default property for network # Transient network can not be set autostart # So confirm persistent is true for test testbr_xml['persistent'] = True # Set network to inactive # Since we do not reboot host to check(instead of restarting libvirtd) # If default network is active, we cannot check "--disable". # Because active network will not be inactive after restarting libvirtd # even we set autostart to False. While inactive network will be active # after restarting libvirtd if we set autostart to True testbr_xml['active'] = False # Prepare options and arguments if net_ref == "netname": net_ref = testbr_xml.name elif net_ref == "netuuid": net_ref = testbr_xml.uuid if disable: net_ref += " --disable" # Run test case # Use function in virsh module directly for both normal and error test result = virsh.net_autostart(net_ref, extra) logging.debug(result) status = result.exit_status # Check if autostart or disable is successful with libvirtd restart. # TODO: Since autostart is designed for host reboot, # we'd better check it with host reboot. utils_libvirtd.libvirtd_restart() # Reopen testbr_xml currents = network_xml.NetworkXML.new_all_networks_dict() current_state = virsh.net_state_dict() logging.debug("Current network(s): %s", current_state) testbr_xml = currents[net_name] is_active = testbr_xml['active'] finally: test_xml.undefine() # Check Result if status_error: if status == 0: test.fail("Run successfully with wrong command!") else: if disable: if status or is_active: test.fail("Disable autostart failed.") else: if status or (not is_active): test.fail("Set network autostart failed.")