def start_net(net_name): """ start network in conversion server """ logging.info("Recover network %s in conversion server", net_name) virsh.net_autostart(net_name) if not virsh.net_state_dict()[net_name]['active']: virsh.net_start(net_name) output = virsh.net_list("--all").stdout.strip() logging.info(output)
def destroy_net(net_name): """ destroy network in conversion server """ if virsh.net_state_dict()[net_name]['active']: logging.info("Remove network %s in conversion server", net_name) virsh.net_destroy(net_name) if virsh.net_state_dict()[net_name]['autostart']: virsh.net_autostart(net_name, "--disable") output = virsh.net_list("--all").stdout.strip() logging.info(output)
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 run(test, params, env): """ Test command: virsh net-uuid. The command can convert a network name to network UUID. 1.Get all parameters from config file. 2.Get uuid by network name from network xml. 3.Perform virsh net-uuid operation. 4.Confirm the test result. """ net_ref = params.get("net_uuid_net_ref") net_name = params.get("net_uuid_network", "default") extra = params.get("net_uuid_extra", "") status_error = params.get("status_error", "no") # Confirm the network exists. output_all = virsh.net_list("--all").stdout.strip() if not re.search(net_name, output_all): test.cancel("Make sure the network exists!!") try: net_uuid = network_xml.NetworkXML.get_uuid_by_name(net_name) except IOError: test.error("Get network uuid failed!") if net_ref == "name": net_ref = net_name result = virsh.net_uuid(net_ref, extra, ignore_status=True) status = result.exit_status output = result.stdout.strip() err = result.stderr.strip() # Check status_error if status_error == "yes": if status == 0: test.fail("Run successfully with wrong command!") if err == "": test.fail("The wrong command has no error outputed!") else: logging.info("It's an expected error") elif status_error == "no": if status != 0 or output == "": test.fail("Run failed with right command!") elif output != net_uuid.strip(): test.fail("net-uuid cannot match!") else: logging.info("Normal test passed") else: test.error("The status_error must be 'yes' or 'no'!")
def network_validate(net_name, file=None, **virsh_dargs): """ Test for schema network """ if net_name is None: raise error.TestNAError("None network is specified.") # Confirm the network exists. output = virsh.net_list("--all").stdout.strip() if not re.search(net_name, output): raise error.TestNAError("Make sure the network exists!!") cmd_result = virsh.net_dumpxml(net_name, to_file=file) libvirt.check_exit_status(cmd_result)
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): 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-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") # Confirm the network exists. output_all = virsh.net_list("--all").stdout.strip() if not re.search(network_name, output_all): raise error.TestNAError("Make sure the network exists!!") # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name # Get status of network and prepare network status. network_current_status = "active" try: if not virsh.net_state_dict()[network_name]['active']: network_current_status = "inactive" if network_status == "active": virsh.net_start(network_name) else: if network_status == "inactive": virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Prepare network status failed!") status = virsh.net_destroy(net_ref, extra, ignore_status=True).exit_status # Confirm the network has been destroied. if virsh.net_state_dict()[network_name]['active']: status = 1 # Recover network status try: if (network_current_status == "active" and not virsh.net_state_dict()[network_name]['active']): virsh.net_start(network_name) if (network_current_status == "inactive" and virsh.net_state_dict()[network_name]['active']): virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") else: raise error.TestError("The status_error must be 'yes' or 'no'!")
def run(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': raise error.TestNAError("API acl test not supported in current" " libvirt version.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # Confirm the network exists. output_all = virsh.net_list("--all").stdout.strip() if not re.search(network_name, output_all): raise error.TestNAError("Make sure the network exists!!") # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name # Get status of network and prepare network status. network_current_status = "active" try: if not virsh.net_state_dict()[network_name]['active']: network_current_status = "inactive" if network_status == "active": virsh.net_start(network_name) else: if network_status == "inactive": virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Prepare network status failed!") status = virsh.net_destroy(net_ref, extra, uri=uri, debug=True, unprivileged_user=unprivileged_user, ignore_status=True).exit_status # Confirm the network has been destroied. if virsh.net_state_dict()[network_name]['active']: status = 1 # Recover network status try: if (network_current_status == "active" and not virsh.net_state_dict()[network_name]['active']): virsh.net_start(network_name) if (network_current_status == "inactive" and virsh.net_state_dict()[network_name]['active']): virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") else: raise error.TestError("The status_error must be 'yes' or 'no'!")
def run(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") # libvirt acl polkit related params if not libvirt_version.version_compare(1, 1, 1): if params.get('setup_libvirt_polkit') == 'yes': raise error.TestNAError("API acl test not supported in current" " libvirt version.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' # Confirm the network exists. output_all = virsh.net_list("--all").stdout.strip() if not re.search(network_name, output_all): raise error.TestNAError("Make sure the network exists!!") # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name # Get status of network and prepare network status. network_current_status = "active" try: if not virsh.net_state_dict()[network_name]['active']: network_current_status = "inactive" if network_status == "active": virsh.net_start(network_name) else: if network_status == "inactive": virsh.net_destroy(network_name) except process.CmdError: raise error.TestError("Prepare network status failed!") status = virsh.net_destroy(net_ref, extra, uri=uri, debug=True, unprivileged_user=unprivileged_user, ignore_status=True).exit_status # Confirm the network has been destroied. if virsh.net_state_dict()[network_name]['active']: status = 1 # Recover network status try: if (network_current_status == "active" and not virsh.net_state_dict()[network_name]['active']): virsh.net_start(network_name) if (network_current_status == "inactive" and virsh.net_state_dict()[network_name]['active']): virsh.net_destroy(network_name) except process.CmdError: raise error.TestError("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") else: raise error.TestError("The status_error must be 'yes' or 'no'!")
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()
def run_virsh_net_destroy(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") # Confirm the network exists. output_all = virsh.net_list("--all").stdout.strip() if not re.search(network_name, output_all): raise error.TestNAError("Make sure the network exists!!") # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name # Get status of network and prepare network status. network_current_status = "active" try: if not virsh.net_state_dict()[network_name]['active']: network_current_status = "inactive" if network_status == "active": virsh.net_start(network_name) else: if network_status == "inactive": virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Prepare network status failed!") status = virsh.net_destroy(net_ref, extra, ignore_status=True).exit_status # Confirm the network has been destroied. if virsh.net_state_dict()[network_name]['active']: status = 1 # Recover network status try: if (network_current_status == "active" and not virsh.net_state_dict()[network_name]['active']): virsh.net_start(network_name) if (network_current_status == "inactive" and virsh.net_state_dict()[network_name]['active']): virsh.net_destroy(network_name) except error.CmdError: raise error.TestError("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") else: raise error.TestError("The status_error must be 'yes' or 'no'!")
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-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") net_name = params.get("net_list_name", "default") persistent = params.get("net_list_persistent", "yes") net_status = params.get("net_list_error", "active") tmp_xml = os.path.join(test.tmpdir, "tmp.xml") net_current_status = "active" autostart_status = "yes" if not virsh.net_state_dict()[net_name]['active']: net_current_status = "inactive" if not virsh.net_state_dict()[net_name]['autostart']: autostart_status = "no" # 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 error.TestNAError("API acl test not supported in current" " libvirt version.") # Create a transient network. try: if persistent == "no": virsh.net_dumpxml(net_name, to_file=tmp_xml, ignore_status=False) if net_current_status == "inactive": virsh.net_destroy(net_name, ignore_status=False) virsh.net_undefine(net_name, ignore_status=False) virsh.net_create(tmp_xml, ignore_status=False) except error.CmdError: raise error.TestFail("Transient network test failed!") # Prepare network's status for testing. if net_status == "active": try: if not virsh.net_state_dict()[net_name]['active']: virsh.net_start(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Active network test failed!") else: try: if virsh.net_state_dict()[net_name]['active']: virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Inactive network test failed!") virsh_dargs = {'ignore_status': True} if params.get('setup_libvirt_polkit') == 'yes': virsh_dargs['unprivileged_user'] = unprivileged_user virsh_dargs['uri'] = uri result = virsh.net_list(option, extra, **virsh_dargs) status = result.exit_status output = result.stdout.strip() # Recover network try: if persistent == "no": virsh.net_destroy(net_name, ignore_status=False) virsh.net_define(tmp_xml, ignore_status=False) if net_current_status == "active": virsh.net_start(net_name, ignore_status=False) if autostart_status == "yes": virsh.net_autostart(net_name, ignore_status=False) else: if net_current_status == "active" and net_status == "inactive": virsh.net_start(net_name, ignore_status=False) elif net_current_status == "inactive" and net_status == "active": virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Recover network failed!") # check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") if option == "--inactive": if net_status == "active": if re.search(net_name, output): raise error.TestFail("Found an active network with" " --inactive option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Found no inactive networks with" " --inactive option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive networks" " with --inactive option") elif option == "": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with no" " option") else: if re.search(net_name, output): raise error.TestFail("Found inactive network with" " no option") elif option == "--all": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with" " --all option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Can't find inactive network with" " --all option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive network" " with --all option")
def run(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") net_persistent = "yes" == params.get("net_persistent", "yes") net_cfg_file = params.get("net_cfg_file", "/usr/share/libvirt/networks/default.xml") check_libvirtd = "yes" == params.get("check_libvirtd") vm_defined = "yes" == params.get("vm_defined") check_vm = "yes" == params.get("check_vm") # 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.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' output_all = virsh.net_list("--all").stdout.strip() # prepare the network status: active, persistent if not re.search(network_name, output_all): if net_persistent: virsh.net_define(net_cfg_file, ignore_status=False) virsh.net_start(network_name, ignore_status=False) else: virsh.create(net_cfg_file, ignore_status=False) # Backup the current network xml net_xml_bk = os.path.join(data_dir.get_tmp_dir(), "%s.xml" % network_name) virsh.net_dumpxml(network_name, to_file=net_xml_bk) if net_persistent: if not virsh.net_state_dict()[network_name]['persistent']: logging.debug("make the network persistent...") virsh.net_define(net_xml_bk) else: if virsh.net_state_dict()[network_name]['persistent']: virsh.net_undefine(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: if network_status == "active": virsh.net_start(network_name, ignore_status=False) else: if network_status == "inactive": logging.debug( "destroy network as we need to test inactive network...") virsh.net_destroy(network_name, ignore_status=False) logging.debug("After prepare: %s" % virsh.net_state_dict()) # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name if check_libvirtd or check_vm: vm_name = params.get("main_vm") if virsh.is_alive(vm_name): virsh.destroy(vm_name) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) vmxml_backup = vmxml # make sure there is interface with source network as default iface_devices = vmxml.get_devices(device_type="interface") has_default_net = False for iface in iface_devices: source = iface.get_source() if 'network' in source.keys() and source['network'] == 'default': has_default_net = True break elif 'bridge' in source.keys() and source['bridge'] == 'virbr0': has_default_net = True break if not has_default_net: options = "network default --current" virsh.attach_interface(vm_name, options, ignore_status=False) try: if vm_defined: ret = virsh.start(vm_name) else: logging.debug("undefine the vm, then create the vm...") vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) virsh.undefine(vm_name) ret = virsh.create(vmxml.xml) logging.debug(ret.stdout) # check the create or start cmd status utils_test.libvirt.check_exit_status( ret, expect_error=(network_status != 'active')) status = 1 if status_error != 'yes': libvirtd = utils_libvirtd.Libvirtd("virtqemud") daemon_name = libvirtd.service_name pid_before_run = utils_misc.get_pid(daemon_name) ret = virsh.net_destroy(net_ref, extra, uri=uri, debug=True, unprivileged_user=unprivileged_user, ignore_status=True) utils_test.libvirt.check_exit_status(ret, expect_error=False) # check_libvirtd pid no change pid_after_run = utils_misc.get_pid(daemon_name) if pid_after_run != pid_before_run: test.fail("libvirtd crash after destroy network!") status = 1 else: logging.debug( "libvirtd do not crash after destroy network!") status = 0 if check_libvirtd: # destroy vm, check libvirtd pid no change ret = virsh.destroy(vm_name) utils_test.libvirt.check_exit_status(ret, expect_error=False) pid_after_run2 = utils_misc.get_pid(daemon_name) if pid_after_run2 != pid_before_run: test.fail("libvirtd crash after destroy vm!") status = 1 else: logging.debug( "libvirtd do not crash after destroy vm!") status = 0 elif check_vm: # restart libvirtd and check vm is running libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() if not virsh.is_alive(vm_name): test.fail( "vm shutdown when transient network destroyed then libvirtd restart" ) else: status = 0 finally: if not vm_defined: vmxml_backup.define() vmxml_backup.sync() else: readonly = (params.get("net_destroy_readonly", "no") == "yes") status = virsh.net_destroy(net_ref, extra, uri=uri, readonly=readonly, debug=True, unprivileged_user=unprivileged_user, ignore_status=True).exit_status # Confirm the network has been destroyed. if net_persistent: if virsh.net_state_dict()[network_name]['active']: status = 1 else: output_all = virsh.net_list("--all").stdout.strip() if re.search(network_name, output_all): status = 1 logging.debug( "transient network should not exists after destroy") # Recover network status to system default status try: if network_name not in virsh.net_state_dict(): virsh.net_define(net_xml_bk, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: virsh.net_start(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['persistent']: virsh.net_define(net_xml_bk, ignore_status=False) if not virsh.net_state_dict()[network_name]['autostart']: virsh.net_autostart(network_name, ignore_status=False) except process.CmdError: test.error("Recover network status failed!") # Clean up the backup network xml file if os.path.isfile(net_xml_bk): data_dir.clean_tmp_files() logging.debug("Cleaning up the network backup xml") # Check status_error if status_error == "yes": if status == 0: test.fail("Run successfully with wrong command!") elif status_error == "no": if status != 0: test.fail("Run failed with right command") else: test.error("The status_error must be 'yes' or 'no'!")
def run(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") net_persistent = "yes" == params.get("net_persistent", "yes") net_cfg_file = params.get("net_cfg_file", "/usr/share/libvirt/networks/default.xml") check_libvirtd = "yes" == params.get("check_libvirtd") vm_defined = "yes" == params.get("vm_defined") # 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.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' output_all = virsh.net_list("--all").stdout.strip() # prepare the network status: active, persistent if not re.search(network_name, output_all): if net_persistent: virsh.net_define(net_cfg_file, ignore_status=False) virsh.net_start(network_name, ignore_status=False) else: virsh.create(net_cfg_file, ignore_status=False) if net_persistent: if not virsh.net_state_dict()[network_name]['persistent']: logging.debug("make the network persistent...") make_net_persistent(network_name) else: if virsh.net_state_dict()[network_name]['persistent']: virsh.net_undefine(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: if network_status == "active": virsh.net_start(network_name, ignore_status=False) else: if network_status == "inactive": logging.debug("destroy network as we need to test inactive network...") virsh.net_destroy(network_name, ignore_status=False) logging.debug("After prepare: %s" % virsh.net_state_dict()) # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name if check_libvirtd: vm_name = params.get("main_vm") if virsh.is_alive(vm_name): virsh.destroy(vm_name) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) vmxml_backup = vmxml # make sure there is interface with source network as default iface_devices = vmxml.get_devices(device_type="interface") has_default_net = False for iface in iface_devices: source = iface.get_source() if 'network' in source.keys() and source['network'] == 'default': has_default_net = True break elif 'bridge' in source.keys() and source['bridge'] == 'virbr0': has_default_net = True break if not has_default_net: options = "network default --current" virsh.attach_interface(vm_name, options, ignore_status=False) try: if vm_defined: ret = virsh.start(vm_name) else: logging.debug("undefine the vm, then create the vm...") vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) virsh.undefine(vm_name) ret = virsh.create(vmxml.xml) logging.debug(ret.stdout) # check the create or start cmd status utils_test.libvirt.check_exit_status(ret, expect_error=(network_status != 'active')) status = 1 if status_error != 'yes': cmd = "ps -ef | grep /usr/sbin/libvirtd | grep -v grep" # record the libvirt pid then destroy network libvirtd_pid = process.run(cmd, shell=True).stdout_text.strip().split()[1] ret = virsh.net_destroy(net_ref, extra, uri=uri, debug=True, unprivileged_user=unprivileged_user, ignore_status=True) utils_test.libvirt.check_exit_status(ret, expect_error=False) # check_libvirtd pid no change result = check_libvirtd_restart(libvirtd_pid, cmd) if result: test.fail("libvirtd crash after destroy network!") status = 1 else: logging.debug("libvirtd do not crash after destroy network!") status = 0 # destroy vm, check libvirtd pid no change ret = virsh.destroy(vm_name) utils_test.libvirt.check_exit_status(ret, expect_error=False) result = check_libvirtd_restart(libvirtd_pid, cmd) if result: test.fail("libvirtd crash after destroy vm!") status = 1 else: logging.debug("libvirtd do not crash after destroy vm!") status = 0 finally: if not vm_defined: vmxml_backup.define() vmxml_backup.sync() else: readonly = (params.get("net_destroy_readonly", "no") == "yes") status = virsh.net_destroy(net_ref, extra, uri=uri, readonly=readonly, debug=True, unprivileged_user=unprivileged_user, ignore_status=True).exit_status # Confirm the network has been destroied. if net_persistent: if virsh.net_state_dict()[network_name]['active']: status = 1 else: output_all = virsh.net_list("--all").stdout.strip() if re.search(network_name, output_all): status = 1 logging.debug("transient network should not exists after destroy") # Recover network status to system default status try: if network_name not in virsh.net_state_dict(): virsh.net_define(net_cfg_file, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: virsh.net_start(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['persistent']: make_net_persistent(network_name) if not virsh.net_state_dict()[network_name]['autostart']: virsh.net_autostart(network_name, ignore_status=False) except process.CmdError: test.error("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: test.fail("Run successfully with wrong command!") elif status_error == "no": if status != 0: test.fail("Run failed with right command") else: test.error("The status_error must be 'yes' or 'no'!")
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} 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()
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") net_name = params.get("net_list_name", "default") persistent = params.get("net_list_persistent", "yes") net_status = params.get("net_list_error", "active") tmp_xml = os.path.join(test.tmpdir, "tmp.xml") net_current_status = "active" autostart_status = "yes" if not virsh.net_state_dict()[net_name]['active']: net_current_status = "inactive" if not virsh.net_state_dict()[net_name]['autostart']: autostart_status = "no" # 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 error.TestNAError("API acl test not supported in current" " libvirt version.") # Create a transient network. try: if persistent == "no": virsh.net_dumpxml(net_name, to_file=tmp_xml, ignore_status=False) if net_current_status == "inactive": virsh.net_destroy(net_name, ignore_status=False) virsh.net_undefine(net_name, ignore_status=False) virsh.net_create(tmp_xml, ignore_status=False) except error.CmdError: raise error.TestFail("Transient network test failed!") # Prepare network's status for testing. if net_status == "active": try: if not virsh.net_state_dict()[net_name]['active']: virsh.net_start(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Active network test failed!") else: try: if virsh.net_state_dict()[net_name]['active']: virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Inactive network test failed!") virsh_dargs = {'ignore_status': True} if params.get('setup_libvirt_polkit') == 'yes': virsh_dargs['unprivileged_user'] = unprivileged_user virsh_dargs['uri'] = uri result = virsh.net_list(option, extra, **virsh_dargs) status = result.exit_status output = result.stdout.strip() # Recover network try: if persistent == "no": virsh.net_destroy(net_name, ignore_status=False) virsh.net_define(tmp_xml, ignore_status=False) if net_current_status == "active": virsh.net_start(net_name, ignore_status=False) if autostart_status == "yes": virsh.net_autostart(net_name, ignore_status=False) else: if net_current_status == "active" and net_status == "inactive": virsh.net_start(net_name, ignore_status=False) elif net_current_status == "inactive" and net_status == "active": virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Recover network failed!") # check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") if option == "--inactive": if net_status == "active": if re.search(net_name, output): raise error.TestFail("Found an active network with" " --inactive option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Found no inactive networks with" " --inactive option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail( "Found transient inactive networks" " with --inactive option") elif option == "": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with no" " option") else: if re.search(net_name, output): raise error.TestFail("Found inactive network with" " no option") elif option == "--all": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with" " --all option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Can't find inactive network with" " --all option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive network" " with --all option")
def get_names(self): lines = virsh.net_list('--all').stdout.strip().splitlines()[2:] return [line.split()[0] for line in lines]
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") # 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'/> <dns enable='%s'> <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 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") 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) 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') # 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 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 = results_stdout_52lts(process.run(cmd, shell=True)).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 re.search("not supported", err): test.cancel("Skip the test: %s" % err) elif 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 " # 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["interface-duplicate"] = "there is an existing interface entry " + \ "in network.* that matches" if (error_type in list(err_dic.keys()) and re.search(err_dic[error_type], err) or mismatch_expect): logging.info("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 = results_stdout_52lts(process.run(cmd, shell=True)).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"): # 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() if "ip-dhcp" in net_section: dhclient_cmd = "(if pgrep dhclient;" \ "then pkill dhclient; sleep 3; fi) " \ "&& dhclient -%s" % ip_version[-1] session.cmd(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").strip('\n') if hostname == new_dhcp_host_name.split('.')[0]: logging.info("getting hostname same with setting: %s", hostname) 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_virsh_net_list(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") net_name = params.get("net_list_name", "default") persistent = params.get("net_list_persistent", "yes") net_status = params.get("net_list_error", "active") tmp_xml = os.path.join(test.tmpdir, "tmp.xml") net_current_status = "active" autostart_status = "yes" if not virsh.net_state_dict()[net_name]['active']: net_current_status = "inactive" if not virsh.net_state_dict()[net_name]['autostart']: autostart_status = "no" # Create a transient network. try: if persistent == "no": virsh.net_dumpxml(net_name, to_file=tmp_xml, ignore_status=False) if net_current_status == "inactive": virsh.net_destroy(net_name, ignore_status=False) virsh.net_undefine(net_name, ignore_status=False) virsh.net_create(tmp_xml, ignore_status=False) except error.CmdError: raise error.TestFail("Transient network test failed!") # Prepare network's status for testing. if net_status == "active": try: if not virsh.net_state_dict()[net_name]['active']: virsh.net_start(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Active network test failed!") else: try: if virsh.net_state_dict()[net_name]['active']: virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Inactive network test failed!") result = virsh.net_list(option, extra, ignore_status=True) status = result.exit_status output = result.stdout.strip() # Recover network try: if persistent == "no": virsh.net_destroy(net_name, ignore_status=False) virsh.net_define(tmp_xml, ignore_status=False) if net_current_status == "active": virsh.net_start(net_name, ignore_status=False) if autostart_status == "yes": virsh.net_autostart(net_name, ignore_status=False) else: if net_current_status == "active" and net_status == "inactive": virsh.net_start(net_name, ignore_status=False) elif net_current_status == "inactive" and net_status == "active": virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Recover network failed!") # check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") if option == "--inactive": if net_status == "active": if re.search(net_name, output): raise error.TestFail("Found an active network with" " --inactive option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Found no inactive networks with" " --inactive option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive networks" " with --inactive option") elif option == "": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with no" " option") else: if re.search(net_name, output): raise error.TestFail("Found inactive network with" " no option") elif option == "--all": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with" " --all option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Can't find inactive network with" " --all option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive network" " with --all option")
def run_virsh_net_list(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") net_name = params.get("net_list_name", "default") persistent = params.get("net_list_persistent", "yes") net_status = params.get("net_list_error", "active") tmp_xml = os.path.join(test.tmpdir, "tmp.xml") net_current_status = "active" autostart_status = "yes" if not virsh.net_state_dict()[net_name]["active"]: net_current_status = "inactive" if not virsh.net_state_dict()[net_name]["autostart"]: autostart_status = "no" # Create a transient network. try: if persistent == "no": virsh.net_dumpxml(net_name, to_file=tmp_xml, ignore_status=False) if net_current_status == "inactive": virsh.net_destroy(net_name, ignore_status=False) virsh.net_undefine(net_name, ignore_status=False) virsh.net_create(tmp_xml, ignore_status=False) except error.CmdError: raise error.TestFail("Transient network test failed!") # Prepare network's status for testing. if net_status == "active": try: if not virsh.net_state_dict()[net_name]["active"]: virsh.net_start(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Active network test failed!") else: try: if virsh.net_state_dict()[net_name]["active"]: virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Inactive network test failed!") result = virsh.net_list(option, extra, ignore_status=True) status = result.exit_status output = result.stdout.strip() # Recover network try: if persistent == "no": virsh.net_destroy(net_name, ignore_status=False) virsh.net_define(tmp_xml, ignore_status=False) if net_current_status == "active": virsh.net_start(net_name, ignore_status=False) if autostart_status == "yes": virsh.net_autostart(net_name, ignore_status=False) else: if net_current_status == "active" and net_status == "inactive": virsh.net_start(net_name, ignore_status=False) elif net_current_status == "inactive" and net_status == "active": virsh.net_destroy(net_name, ignore_status=False) except error.CmdError: raise error.TestFail("Recover network failed!") # check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command!") elif status_error == "no": if status != 0: raise error.TestFail("Run failed with right command") if option == "--inactive": if net_status == "active": if re.search(net_name, output): raise error.TestFail("Found an active network with" " --inactive option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Found no inactive networks with" " --inactive option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive networks" " with --inactive option") elif option == "": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with no" " option") else: if re.search(net_name, output): raise error.TestFail("Found inactive network with" " no option") elif option == "--all": if net_status == "active": if not re.search(net_name, output): raise error.TestFail("Can't find active network with" " --all option") else: if persistent == "yes": if not re.search(net_name, output): raise error.TestFail("Can't find inactive network with" " --all option") else: # If network is transient, after net-destroy it, # it will disapear. if re.search(net_name, output): raise error.TestFail("Found transient inactive network" " with --all option")
def run(test, params, env): """ Test interface devices update """ vm_name = params.get("main_vm") vm = env.get_vm(vm_name) network_name = params.get('network_name', 'default') new_network_name = params.get("net_name") expect_error = "yes" == params.get("status_error", "no") expect_err_msg = params.get("expect_err_msg") iface_driver = params.get("iface_driver") iface_driver_host = params.get("iface_driver_host") iface_driver_guest = params.get("iface_driver_guest") iface_model = params.get("iface_model") iface_mtu = params.get("iface_mtu") iface_rom = params.get("iface_rom") iface_filter = params.get("iface_filter") iface_boot = params.get('iface_boot') iface_coalesce = params.get('iface_coalesce') iface_source = params.get('iface_source') new_iface_driver = params.get("new_iface_driver") new_iface_driver_host = params.get("new_iface_driver_host") new_iface_driver_guest = params.get("new_iface_driver_guest") new_iface_model = params.get("new_iface_model") new_iface_rom = params.get("new_iface_rom") new_iface_inbound = params.get("new_iface_inbound") new_iface_outbound = params.get("new_iface_outbound") new_iface_link = params.get("new_iface_link") new_iface_source = params.get("new_iface_source") new_iface_target = params.get("new_iface_target") new_iface_addr = params.get("new_iface_addr") new_iface_filter = params.get("new_iface_filter") new_iface_mtu = params.get("new_iface_mtu") new_iface_type = params.get("new_iface_type") create_new_net = "yes" == params.get("create_new_net") new_iface_alias = params.get("new_iface_alias") new_iface_coalesce = params.get('new_iface_coalesce') cold_update = "yes" == params.get("cold_update", "no") del_addr = "yes" == params.get("del_address") del_rom = "yes" == params.get("del_rom") del_filter = "yes" == params.get("del_filter") check_libvirtd = "yes" == params.get("check_libvirtd") new_iface_filter_parameters = eval( params.get("new_iface_filter_parameters", "{}")) rules = eval(params.get("rules", "{}")) del_mac = "yes" == params.get("del_mac", "no") del_coalesce = 'yes' == params.get('del_coalesce', 'no') direct_net = 'yes' == params.get('direct_net', 'no') direct_mode = params.get("direct_mode", "bridge") del_net_bandwidth = 'yes' == params.get('del_net_bandwidth', 'no') # Backup the vm xml for recover at last vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) current_net = virsh.net_list("--all").stdout.strip() netxml_backup = None if network_name in current_net: netxml_backup = network_xml.NetworkXML.new_from_net_dumpxml( network_name) try: # Prepare network # Create new network if need if create_new_net: if direct_net: net_ifs = utils_net.get_net_if(state="UP") net_forward = str({'dev': net_ifs[0], 'mode': direct_mode}) net_dict = {'net_forward': net_forward} else: net_dict = params new_net_xml = libvirt.create_net_xml(new_network_name, net_dict) new_net_xml.sync() else: netxml = network_xml.NetworkXML.new_from_net_dumpxml(network_name) logging.debug('Network xml before update:\n%s', netxml) if del_net_bandwidth: netxml.del_element('/bandwidth') netxml.sync() logging.debug('Network xml after prepare:\n%s', netxml) # According to the different os find different file for rom if (iface_rom and "file" in eval(iface_rom) and "%s" in eval(iface_rom)['file']): if rpm.RpmBackend().check_installed('ipxe-roms-qemu', '20200823'): logging.debug("Update the file path since " "ipxe-20200823-5:") iface_rom_new = iface_rom.replace('qemu-kvm', 'ipxe/qemu') iface_rom = iface_rom_new if os.path.exists(eval(iface_rom)['file'] % "pxe"): iface_rom = iface_rom % "pxe" elif os.path.exists(eval(iface_rom)['file'] % "efi"): iface_rom = iface_rom % "efi" else: logging.error("Can not find suitable rom file") iface_dict_bef = {} iface_dict_aft = {} names = locals() # Collect need update items in 2 dicts for both start vm before and after update_list_bef = [ "driver", 'driver_host', 'driver_guest', "model", "mtu", "rom", "filter", 'boot', 'coalesce', 'source' ] for update_item_bef in update_list_bef: if names['iface_' + update_item_bef]: iface_dict_bef.update( {update_item_bef: names['iface_' + update_item_bef]}) update_list_aft = [ "driver", "driver_host", "driver_guest", "model", "rom", "inbound", "outbound", "link", "source", "target", "addr", "filter", "mtu", "type", "alias", "filter_parameters", "coalesce" ] for update_item_aft in update_list_aft: if names["new_iface_" + update_item_aft]: iface_dict_aft.update( {update_item_aft: names["new_iface_" + update_item_aft]}) logging.info("iface_dict_bef is %s, iface_dict_aft is %s", iface_dict_bef, iface_dict_aft) del_list = [ "del_addr", "del_rom", "del_filter", "del_mac", "del_coalesce" ] for del_item in del_list: if names[del_item]: iface_dict_aft.update({del_item: names[del_item]}) # Operations before updating vm's iface xml if iface_boot: disk_boot = params.get('disk_book', 1) vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) # Remove os boot config vm_os = vmxml.os vm_os.del_boots() vmxml.os = vm_os # Add boot config to disk disk = vmxml.get_devices('disk')[0] target_dev = disk.target.get('dev', '') logging.debug('Will set boot order %s to device %s', disk_boot, target_dev) vmxml.set_boot_order_by_target_dev(target_dev, disk_boot) vmxml.sync() # Update vm interface with items in iface_dict_bef and start it if iface_dict_bef: libvirt.modify_vm_iface(vm_name, "update_iface", iface_dict_bef) logging.info("vm xml is %s", vm.get_xml()) if not cold_update: vm.start() if iface_mtu: # Do check for mtu size after start vm target_dev = libvirt.get_interface_details(vm_name)[0]['interface'] cmd = "ip link show %s | grep 'mtu %s'" % (target_dev, eval(iface_mtu)['size']) def check_mtu(): """ Check the mtu setting take effect for interface """ ret = process.run(cmd, ignore_status=True, shell=True) if ret.exit_status: test.fail("Can not find mtu setting in cmd result") check_mtu() utils_libvirtd.libvirtd_restart() check_mtu() # Do update for iface_driver logging.info('Creating new iface xml.') new_iface_xml = libvirt.modify_vm_iface(vm_name, "get_xml", iface_dict_aft) bef_pid = process.getoutput("pidof -s libvirtd") ret = virsh.update_device(vm_name, new_iface_xml, ignore_status=True, debug=True) libvirt.check_exit_status(ret, expect_error) if check_libvirtd: aft_pid = process.getoutput("pidof -s libvirtd") if aft_pid != bef_pid: test.fail("libvirtd crash after update-device!") else: logging.info("libvirtd do not crash after update-device!") if expect_error: real_err_msg = ret.stderr.strip() if not re.search(expect_err_msg, real_err_msg, re.IGNORECASE): test.fail("The real error msg:'%s' does not match expect one:" '%s' % (real_err_msg, expect_err_msg)) else: logging.info("Get expect result: %s", real_err_msg) else: if new_iface_inbound: iface_bandwidth = {} iface_bandwidth = vm_xml.VMXML.get_iftune_params(vm_name) for bound_para in ["inbound", "outbound"]: for tune_para in ["average", "peak", "burst"]: get_value = iface_bandwidth.get(bound_para).get( tune_para) expect_value = eval(names["new_iface_" + bound_para]).get(tune_para) logging.info("Get value for %s:%s is %s, expect is %s", bound_para, tune_para, get_value, expect_value) if get_value != expect_value: test.fail("Get value is not equal to expect") vmxml_aft = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_aft = list(vmxml_aft.get_iface_all().values())[0] if new_iface_link: iface_link_value = iface_aft.find('link').get('state') if iface_link_value == new_iface_link: logging.info("Find link state is %s in xml", new_iface_link) # Checking the statue in guest mac_addr = iface_aft.find('mac').get('address') state_map = "%s.*\n.*%s" % (iface_link_value.upper(), mac_addr) session = vm.wait_for_serial_login() logging.info("ip link output:%s", session.cmd_output("ip link")) if_name = utils_net.get_net_if(runner=session.cmd_output, state=state_map)[0] if not check_iface_link(session, mac_addr, new_iface_link): test.fail('iface link check inside vm failed.') session.close() if if_name: logging.info("Find iface state %s for %s", iface_link_value, mac_addr) else: test.fail( "Can not find iface with mac %s and state %s" % (mac_addr, iface_link_value)) else: test.fail( "Check fail to get link state, expect %s, but get %s" % (iface_link_value, new_iface_link)) if create_new_net and new_iface_source: iface_source_value = iface_aft.find('source').get('network') if iface_source_value == eval(new_iface_source)['network']: logging.info("Get %s in xml as set", iface_source_value) else: test.fail("Get source %s is not equal to set %s" % (iface_source_value, new_iface_source)) if new_iface_filter: iface_filter_value = iface_aft.find('filterref').get('filter') if iface_filter_value == new_iface_filter: logging.info("Get %s in xml as set", iface_filter_value) else: test.fail("Get filter %s is not equal to set %s" % (iface_filter_value, new_iface_filter)) if new_iface_filter_parameters: ebtables_outputs = process.run("ebtables -t nat -L", shell=True).stdout_text for rule in rules: if rule not in ebtables_outputs: test.fail( "Can not find the corresponding rule after update filter with parameters!" ) if del_filter: # if the filter is deleted, it should not exists in the xml and the rules should be deleted as well iface_filter_value = iface_aft.find('filterref') if iface_filter_value is not None: test.fail("After delete, the filter still exists: %s" % iface_filter_value) ebtables_outputs = process.run("ebtables -t nat -L", shell=True).stdout_text logging.debug("after nwfilter deleted, ebtables rules are %s" % ebtables_outputs) time.sleep(5) entries_num = re.findall(r'entries:\s+(\d)', ebtables_outputs) for i in entries_num: if i != '0': test.fail("After delete, the rules are still exists!") if new_iface_alias: iface_alias_value = iface_aft.find('alias').get('name') if iface_alias_value == eval(new_iface_alias)['name']: logging.info("Get %s in xml as set", iface_alias_value) else: test.fail("Get alias %s is not equal to set %s" % (iface_alias_value, new_iface_alias)) if 'update_coalesce' in params['name'] or new_iface_coalesce: iface_coalesce_val = iface_aft.find('coalesce').find( 'rx').find('frames').get('max') if iface_coalesce_val == str(eval(new_iface_coalesce)['max']): logging.info('coalesce update check PASS.') else: test.fail('coalesce value not updated.') if del_coalesce: if iface_aft.find('coalesce') is None: logging.info('coalesce delete check PASS.') else: test.fail('coalesce not deleted.') finally: vmxml_backup.sync() if netxml_backup: netxml_backup.sync() if create_new_net: new_net_xml.undefine()
def run(test, params, env): """ Test command: virsh net-destroy. The command can forcefully stop a given network. 1.Make sure the network exists. 2.Prepare network status. 3.Perform virsh net-destroy operation. 4.Check if the network has been destroied. 5.Recover network environment. 6.Confirm the test result. """ net_ref = params.get("net_destroy_net_ref") extra = params.get("net_destroy_extra", "") network_name = params.get("net_destroy_network", "default") network_status = params.get("net_destroy_status", "active") status_error = params.get("status_error", "no") net_persistent = "yes" == params.get("net_persistent", "yes") net_cfg_file = params.get("net_cfg_file", "/usr/share/libvirt/networks/default.xml") # 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.") uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') if unprivileged_user: if unprivileged_user.count('EXAMPLE'): unprivileged_user = '******' output_all = virsh.net_list("--all").stdout.strip() # prepare the network status: active, persistent if not re.search(network_name, output_all): if net_persistent: virsh.net_define(net_cfg_file, ignore_status=False) virsh.net_start(network_name, ignore_status=False) else: virsh.create(net_cfg_file, ignore_status=False) if net_persistent: if not virsh.net_state_dict()[network_name]['persistent']: logging.debug("!!!make the network persistent") make_net_persistent(network_name) else: if virsh.net_state_dict()[network_name]['persistent']: virsh.net_undefine(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: if network_status == "active": virsh.net_start(network_name, ignore_status=False) else: if network_status == "inactive": logging.debug("!!!destroy the network as we need to test inactive") virsh.net_destroy(network_name, ignore_status=False) logging.debug("After prepare: %s" % virsh.net_state_dict()) # Run test case if net_ref == "uuid": net_ref = virsh.net_uuid(network_name).stdout.strip() elif net_ref == "name": net_ref = network_name status = virsh.net_destroy(net_ref, extra, uri=uri, debug=True, unprivileged_user=unprivileged_user, ignore_status=True).exit_status # Confirm the network has been destroied. if net_persistent: if virsh.net_state_dict()[network_name]['active']: status = 1 else: output_all = virsh.net_list("--all").stdout.strip() if re.search(network_name, output_all): status = 1 logging.debug("transient network should not exists after destroy") # Recover network status to system default status try: if network_name not in virsh.net_state_dict(): virsh.net_define(net_cfg_file, ignore_status=False) if not virsh.net_state_dict()[network_name]['active']: virsh.net_start(network_name, ignore_status=False) if not virsh.net_state_dict()[network_name]['persistent']: make_net_persistent(network_name) if not virsh.net_state_dict()[network_name]['autostart']: virsh.net_autostart(network_name, ignore_status=False) except process.CmdError: test.error("Recover network status failed!") # Check status_error if status_error == "yes": if status == 0: test.fail("Run successfully with wrong command!") elif status_error == "no": if status != 0: test.fail("Run failed with right command") else: test.error("The status_error must be 'yes' or 'no'!")