def nwfilter_sync_loop(filter_name, filerxml): """ Undefine filter and redefine filter from xml in loop """ for i in range(2400): virsh.nwfilter_undefine(filter_name, ignore_status=True) time.sleep(0.1) virsh.nwfilter_define(filterxml.xml, ignore_status=True)
def run(test, params, env): """ Test virsh nwfilter-edit with uuid. 1) Prepare parameters. 2) Run nwfilter-edit command. 3) Check result. 4) Clean env """ # Prepare parameters filter_name = params.get("edit_filter_name", "") status_error = params.get("status_error", "no") new_uuid = "11111111-1111-1111-1111-111111111111" edit_cmd = ":2s/<uuid>.*$/<uuid>%s<\/uuid>/" % new_uuid # Since commit 46a811d, the logic changed for not allow update filter # uuid, so decide status_error with libvirt version. if libvirt_version.version_compare(1, 2, 7): status_error = True else: status_error = False # Backup filter xml new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(filter_name) logging.debug("the filter xml is: %s" % filterxml.xmltreefile) try: # Run command session = aexpect.ShellSession("sudo -s") try: session.sendline("virsh nwfilter-edit %s" % filter_name) session.sendline(edit_cmd) # Press ESC session.send('\x1b') # Save and quit session.send('ZZ') remote.handle_prompts(session, None, None, r"[\#\$]\s*$") session.close() if not status_error: logging.info("Succeed to do nwfilter edit") else: test.fail("edit uuid should fail but got succeed.") except (aexpect.ShellError, aexpect.ExpectError, remote.LoginTimeoutError) as details: log = session.get_output() session.close() if "Try again? [y,n,f,?]:" in log and status_error: logging.debug("edit uuid failed as expected.") else: test.fail("Failed to do nwfilter-edit: %s\n%s" % (details, log)) finally: # Clean env virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filterxml.xml, debug=True)
def run(test, params, env): """ Test command: virsh nwfilter-undefine. 1) Prepare parameters. 2) Run nwfilter-undefine command. 3) Check result. 4) Clean env """ # Prepare parameters filter_ref = params.get("undefine_filter_ref", "") options_ref = params.get("undefine_options_ref", "") status_error = params.get("status_error", "no") # libvirt acl polkit related params uri = params.get("virsh_uri") unprivileged_user = params.get('unprivileged_user') try: 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': test.cancel("API acl test not supported in current" " libvirt version.") # Backup filter xml if filter_ref: new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(filter_ref) logging.debug("the filter xml is: %s" % filterxml.xmltreefile) filter_xml = filterxml.xmltreefile.name # Run command cmd_result = virsh.nwfilter_undefine( filter_ref, options=options_ref, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result if status_error == "yes": if status == 0: test.fail("Run successfully with wrong command.") elif status_error == "no": if status: test.fail("Run failed with right command.") chk_result = check_list(filter_ref) if chk_result: test.fail("filter %s show up in filter list." % filter_ref) finally: # Clean env if status == 0: virsh.nwfilter_define(filter_xml, options="", ignore_status=True, debug=True)
def run(test, params, env): """ Test command: virsh nwfilter-undefine. 1) Prepare parameters. 2) Run nwfilter-undefine command. 3) Check result. 4) Clean env """ # Prepare parameters filter_ref = params.get("undefine_filter_ref", "") options_ref = params.get("undefine_options_ref", "") status_error = params.get("status_error", "no") # libvirt acl polkit related 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.") # Backup filter xml if filter_ref: new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(filter_ref) logging.debug("the filter xml is: %s" % filterxml.xmltreefile) filter_xml = filterxml.xmltreefile.name # Run command cmd_result = virsh.nwfilter_undefine(filter_ref, options=options_ref, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command.") elif status_error == "no": if status: raise error.TestFail("Run failed with right command.") chk_result = check_list(filter_ref) if chk_result: raise error.TestFail("filter %s show up in filter list." % filter_ref) # Clean env if status == 0: virsh.nwfilter_define(filter_xml, options="", ignore_status=True, debug=True)
def run(test, params, env): """ Test command: virsh nwfilter-undefine. 1) Prepare parameters. 2) Run nwfilter-undefine command. 3) Check result. 4) Clean env """ # Prepare parameters filter_ref = params.get("undefine_filter_ref", "") options_ref = params.get("undefine_options_ref", "") status_error = params.get("status_error", "no") # Backup filter xml if filter_ref: new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(filter_ref) logging.debug("the filter xml is: %s" % filterxml.xmltreefile) filter_xml = filterxml.xmltreefile.name # Run command cmd_result = virsh.nwfilter_undefine(filter_ref, options=options_ref, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command.") elif status_error == "no": if status: raise error.TestFail("Run failed with right command.") chk_result = check_list(filter_ref) if chk_result: raise error.TestFail("filter %s show up in filter list." % filter_ref) # Clean env if status == 0: virsh.nwfilter_define(filter_xml, options="", ignore_status=True, debug=True)
def run(test, params, env): """ Test command: virsh nwfilter-define. 1) Prepare parameters. 2) Set options of virsh define. 3) Run define command. 4) Check result. 5) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") filter_chain = params.get("filter_chain", "root") filter_priority = params.get("filter_priority", "") filter_uuid = params.get("filter_uuid", "5c6d49af-b071-6127-b4ec-6f8ed4b55335") filterref = params.get("filterref") filterref_name = params.get("filterref_name") exist_filter = params.get("exist_filter", "no-mac-spoofing") filter_xml = params.get("filter_create_xml_file") options_ref = params.get("options_ref", "") status_error = params.get("status_error", "no") # prepare rule and protocol attributes protocol = {} rule_dict = {} rule_dict_tmp = {} # rule string should end with EOL as separator, multiple rules is supported rule = params.get( "rule", "rule_action=accept rule_direction=out protocol=mac EOL") rule_list = rule.split('EOL') for i in range(len(rule_list)): if rule_list[i]: attr = rule_list[i].split() for j in range(len(attr)): attr_list = attr[j].split('=') rule_dict_tmp[attr_list[0]] = attr_list[1] rule_dict[i] = rule_dict_tmp rule_dict_tmp = {} # process protocol parameter for i in rule_dict.keys(): if 'protocol' not in rule_dict[i]: # Set protocol as string 'None' as parse from cfg is # string 'None' protocol[i] = 'None' else: protocol[i] = rule_dict[i]['protocol'] rule_dict[i].pop('protocol') if protocol[i] in PROTOCOL_TYPES: # replace '-' with '_' in ipv6 types as '-' is not # supposed to be in class name if '-' in protocol[i]: protocol[i] = protocol[i].replace('-', '_') else: raise error.TestFail("Given protocol type %s" % protocol[i] + " is not in supported list %s" % PROTOCOL_TYPES) if filter_xml == "invalid-filter-xml": tmp_xml = xml_utils.TempXMLFile() tmp_xml.write('"<filter><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</filter>') tmp_xml.flush() filter_xml = tmp_xml.name logging.info("Test invalid xml is: %s" % filter_xml) elif filter_xml != " ": # Use exist xml as template with new attributes new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(exist_filter) logging.debug("the exist xml is:\n%s" % filterxml.xmltreefile) # Backup xml if only update exist filter if exist_filter == filter_name: backup_xml = filterxml.xmltreefile.backup_copy() # Set filter attribute filterxml.filter_name = filter_name filterxml.filter_chain = filter_chain filterxml.filter_priority = filter_priority filterxml.uuid = filter_uuid if filterref: filterxml.filterref = filterref filterxml.filterref_name = filterref_name # Set rule attribute index_total = filterxml.get_rule_index() rule = filterxml.get_rule(0) rulexml = rule.backup_rule() for i in range(len(rule_dict.keys())): rulexml.rule_action = rule_dict[i].get('rule_action') rulexml.rule_direction = rule_dict[i].get('rule_direction') rulexml.rule_priority = rule_dict[i].get('rule_priority') rulexml.rule_statematch = rule_dict[i].get('rule_statematch') for j in RULE_ATTR: if j in rule_dict[i].keys(): rule_dict[i].pop(j) # set protocol attribute if protocol[i] != 'None': protocolxml = rulexml.get_protocol(protocol[i]) new_one = protocolxml.new_attr(**rule_dict[i]) protocolxml.attrs = new_one rulexml.xmltreefile = protocolxml.xmltreefile else: rulexml.del_protocol() if i <= len(index_total) - 1: filterxml.set_rule(rulexml, i) else: filterxml.add_rule(rulexml) # Reset rulexml rulexml = rule.backup_rule() logging.info("The xml for define is:\n%s" % filterxml.xmltreefile) filterxml.xmltreefile.write(filter_xml) # Run command cmd_result = virsh.nwfilter_define(filter_xml, options=options_ref, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result chk_result = check_list(filter_uuid, filter_name) xml_path = "%s/%s.xml" % (NWFILTER_ETC_DIR, filter_name) if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command.") elif status_error == "no": if status: raise error.TestFail("Run failed with right command.") if not chk_result: raise error.TestFail("Can't find filter in nwfilter-list output") if not os.path.exists(xml_path): raise error.TestFail("Can't find filter xml under %s" % NWFILTER_ETC_DIR) logging.info("Dump the xml after define:") virsh.nwfilter_dumpxml(filter_name, ignore_status=True, debug=True) # Clean env if exist_filter == filter_name: logging.info("Restore exist filter: %s" % exist_filter) backup_xml.write(filter_xml) virsh.nwfilter_define(filter_xml, options="", ignore_status=True, debug=True) else: if chk_result: virsh.nwfilter_undefine(filter_name, options="", ignore_status=True, debug=True) if os.path.exists(filter_xml): os.remove(filter_xml)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") bug_url = params.get("bug_url", "") vm_name = params.get("main_vm") if not libvirt_version.version_compare(1, 2, 6): raise error.TestNAError("Bug %s not fixed on current build" % bug_url) vm = env.get_vm(vm_name) # Prepare vm filterref parameters dict list filterref_dict = {} filterref_dict['name'] = filter_name # backup vm and filter xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) backup_filter = libvirt_xml.NwfilterXML() filterxml = backup_filter.new_from_filter_dumpxml(filter_name) libvirtd = utils_libvirtd.LibvirtdSession() def nwfilter_sync_loop(filter_name, filerxml): """ Undefine filter and redefine filter from xml in loop """ for i in range(2400): virsh.nwfilter_undefine(filter_name, ignore_status=True) time.sleep(0.1) virsh.nwfilter_define(filterxml.xml, ignore_status=True) def vm_start_destory_loop(vm): """ Start and destroy vm in loop """ for i in range(2400): vm.start() time.sleep(0.1) vm.destroy(gracefully=False) try: libvirtd.start() # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() filter_thread = threading.Thread(target=nwfilter_sync_loop, args=(filter_name, filterxml)) vm_thread = threading.Thread(target=vm_start_destory_loop, args=(vm,)) filter_thread.start() time.sleep(0.3) vm_thread.start() ret = utils_misc.wait_for(lambda: not libvirtd.is_working(), timeout=240, step=1) filter_thread.join() vm_thread.join() if ret: raise error.TestFail("Libvirtd hang, %s" % bug_url) finally: libvirtd.exit() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm and filter. vmxml_backup.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) virsh.nwfilter_define(filterxml.xml, ignore_status=True)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") need_vm2 = "yes" == params.get("need_vm2", "no") add_vm_name = params.get("add_vm_name", "vm2") vms = [vm] dst_outside = params.get("dst_outside", "www.google.com") ping_timeout = int(params.get("ping_timeout", "10")) # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] if params_dict['value'] == "MAC_of_virbr0": virbr0_info = process.run("ip a | grep virbr0: -A1", shell=True).stdout_text.strip() virbr0_mac = re.search( r'link/ether\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})', virbr0_info, re.M | re.I).group(1) params_dict['value'] = virbr0_mac logging.debug("params_dict['value'] is %s " % params_dict['value']) filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list params['filter_uuid'] = process.run("uuidgen", ignore_status=True, shell=True).stdout_text.strip() # get all the check commands and corresponding expected results form config file and make a dictionary cmd_list_ = params.get('check_cmd', '') if cmd_list_: cmd_list = cmd_list_.split(',') expect_res = params.get('expect_match', '').split(',') logging.debug("cmd_list is %s" % cmd_list) logging.debug("expect_res is %s" % expect_res) cmd_result_dict = dict(zip(cmd_list, expect_res)) logging.debug("the check dict is %s" % cmd_result_dict) # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd("virtqemud") device_name = None def check_nwfilter_rules(check_cmd, expect_match): """"check the nwfilter corresponding rule is added by iptables commands""" ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) # This change anchors nwfilter_vm_start.possitive_test.new_filter.variable_notation case # The matched destination could be ip address or hostname if "iptables -L" in check_cmd and expect_match and 'ACCEPT' in expect_match: # ip address that need to be replaced replace_param = params.get("parameter_value_2") # Get hostname by ip address. hostname_info = None try: hostname_info = socket.gethostbyaddr(replace_param) except socket.error as e: logging.info( "Failed to get hostname from ip address with error: %s", str(e)) if hostname_info: # String is used to replace ip address replace_with = "%s|%s" % (replace_param, hostname_info[0]) expect_match = r"%s" % expect_match.replace( replace_param, replace_with) logging.debug("final iptables match string:%s", expect_match) out = astring.to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) def clean_up_dirty_nwfilter_binding(): cmd_result = virsh.nwfilter_binding_list(debug=True) binding_list = cmd_result.stdout_text.strip().splitlines() binding_list = binding_list[2:] result = [] # If binding list is not empty. if binding_list: for line in binding_list: # Split on whitespace, assume 1 column linesplit = line.split(None, 1) result.append(linesplit[0]) logging.info("nwfilter binding list is: %s", result) for binding_uuid in result: try: virsh.nwfilter_binding_delete(binding_uuid) except Exception as e: logging.error( "Exception thrown while undefining nwfilter-binding: %s", str(e)) raise try: # Clean up dirty nwfilter binding if there are. clean_up_dirty_nwfilter_binding() rule = params.get("rule") if rule: # Add pre-check whether nwfilter exists or not since # utlv.create_nwfilter_xml will fail if there is no any nwfilter exists nwfilter_list = libvirt_nwfilter.get_nwfilter_list() if not nwfilter_list: test.error("There is no any nwfilter existed on the host") # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: pkg = "ipset" if not utils_package.package_install(pkg): test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] iface_mac = iface_xml.mac_address logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if need_vm2: # Clone more vm for testing result = virsh.dom_list('--inactive').stdout_text if add_vm_name in result: logging.debug("%s is already exists!" % add_vm_name) vms.append(env.get_vm(add_vm_name)) else: vm.destroy() ret_clone = utils_libguestfs.virt_clone_cmd(vm_name, add_vm_name, True, timeout=360) if ret_clone.exit_status: test.fail("Error when clone a second vm!") vms.append(vm.clone(add_vm_name)) vm.start() vm2 = vms[1] logging.debug("Now the vms is: %s", [dom.name for dom in vms]) # update the vm2 interface with the nwfilter logging.debug("filter_params_list is %s" % filter_param_list) iface_dict = { "filter": filter_name, "filter_parameters": filter_param_list, "del_mac": True } if vm2.is_alive(): vm2.destroy() utlv.modify_vm_iface(vm2.name, "update_iface", iface_dict) vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm2.name) iface_xml = vmxml.get_devices('interface')[0] logging.debug("iface_xml for vm2 is %s" % iface_xml) vm2.start() vm2_session = vm2.wait_for_serial_login() vm2_mac = vm2.get_mac_address() vm2_ip = utils_net.get_guest_ip_addr(vm2_session, vm2_mac) vm.session = vm.wait_for_serial_login() # test network functions, the 2 vms can not access to each other gateway_ip = utils_net.get_ip_address_by_interface("virbr0") status1, output1 = utils_net.ping(dest=vm2_ip, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) status2, output2 = utils_net.ping(dest=gateway_ip, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) status3, output3 = utils_net.ping(dest=dst_outside, count='3', timeout=ping_timeout, session=vm.session, force_ipv4=True) if not status1: test.fail( "vm with clean-traffic-gateway ping succeed to %s %s, but it is not expected!" % (vm2.name, vm2_ip)) if status2 or status3: test.fail("vm ping failed! check %s \n %s" % (output2, output3)) if cmd_list_: loop = 0 for check_cmd_, expect_match_ in cmd_result_dict.items(): check_cmd = check_cmd_.strip() expect_match = expect_match_.strip() if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) if "VMMAC" in expect_match: expect_match = expect_match.replace("VMMAC", iface_mac) logging.debug( "the check_cmd is %s, and expected result is %s" % (check_cmd, expect_match)) check_nwfilter_rules(check_cmd, expect_match) loop += 1 except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: daemon_name = libvirtd.service_name pid = process.run('pidof %s' % daemon_name, shell=True).stdout_text.strip() cmd = "kill -s TERM %s" % pid process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) # After libvirt 5.6.0, libvirtd is using systemd socket activation by default if not ret and not libvirt_version.version_compare(5, 6, 0): test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter except clean-traffic as it is built-in nwfilter if filter_name != exist_filter and filter_name != 'clean-traffic': virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True) # Remove additional vms if need_vm2: result = virsh.dom_list("--all").stdout_text if add_vm_name in result: virsh.remove_domain(add_vm_name, "--remove-all-storage")
def run(test, params, env): """ Test command: virsh nwfilter-define. 1) Prepare parameters. 2) Set options of virsh define. 3) Run define command. 4) Check result. 5) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") exist_filter = params.get("exist_filter", "no-mac-spoofing") filter_xml = params.get("filter_create_xml_file") options_ref = params.get("options_ref", "") status_error = params.get("status_error", "no") boundary_test_skip = "yes" == params.get("boundary_test_skip") new_uuid = "yes" == params.get("new_uuid", 'no') bug_url = params.get("bug_url") # libvirt acl polkit related 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': test.cancel("API acl test not supported in current" " libvirt version.") if exist_filter == filter_name and new_uuid: # Since commit 46a811d, update filter with new uuid will fail. if libvirt_version.version_compare(1, 2, 7): status_error = 'yes' else: status_error = 'no' try: if filter_xml == "invalid-filter-xml": tmp_xml = xml_utils.TempXMLFile() tmp_xml.write('"<filter><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</filter>') tmp_xml.flush() filter_xml = tmp_xml.name logging.info("Test invalid xml is: %s" % filter_xml) elif filter_xml: # Create filter xml new_filter = libvirt_xml.NwfilterXML() filterxml_backup = new_filter.new_from_filter_dumpxml(exist_filter) # Backup xml if only update exist filter if exist_filter == filter_name and not new_uuid: filter_uuid = filterxml_backup.uuid params['filter_uuid'] = filter_uuid filterxml = utlv.create_nwfilter_xml(params) filterxml.xmltreefile.write(filter_xml) # Run command cmd_result = virsh.nwfilter_define(filter_xml, options=options_ref, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result chk_result = check_list(filter_uuid, filter_name) xml_path = "%s/%s.xml" % (NWFILTER_ETC_DIR, filter_name) if status_error == "yes": if status == 0: if boundary_test_skip: test.cancel("Boundary check commit 4f20943 not" " in this libvirt build yet.") else: err_msg = "Run successfully with wrong command." if bug_url: err_msg += " Check more info in %s" % bug_url test.fail(err_msg) elif status_error == "no": if status: err_msg = "Run failed with right command." if bug_url: err_msg += " Check more info in %s" % bug_url test.fail(err_msg) if not chk_result: test.fail("Can't find filter in nwfilter-list" + " output") if not os.path.exists(xml_path): test.fail("Can't find filter xml under %s" % NWFILTER_ETC_DIR) logging.info("Dump the xml after define:") virsh.nwfilter_dumpxml(filter_name, ignore_status=True, debug=True) finally: # Clean env if exist_filter == filter_name: logging.info("Restore exist filter: %s" % exist_filter) virsh.nwfilter_undefine(filter_name, ignore_status=True) virsh.nwfilter_define(filterxml_backup.xml, ignore_status=True) else: if chk_result: virsh.nwfilter_undefine(filter_name, ignore_status=True) if os.path.exists(filter_xml): os.remove(filter_xml)
# Starting VM failed. if not status_error: raise error.TestFail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -SIGTERM `pidof libvirtd`" utils.run(cmd) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) if not ret: raise error.TestFail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: utils.run("umount -l %s" % device_name, ignore_status=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: utils.run("ipset destroy blacklist")
def run(test, params, env): """ Test bridge support from network 1) create a linux bridge and connect a physical interface to it 2) define nwfilter with "vdsm-no-mac-spoofing" 3) redefine the vm with the new create bridge and filter 4) check if guest can get public ip after vm start 5) check if guest and host can ping each other 6) check if guest and host can ping outside 7) start another vm connected to the same bridge 8) check if the 2 guests can ping each other """ def create_bridge(br_name, iface_name): """ Create a linux bridge by virsh cmd: 1. Stop NetworkManager and Start network service 2. virsh iface-bridge <iface> <name> [--no-stp] :param br_name: bridge name :param iface_name: physical interface name :return: bridge created or raise exception """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge # This cmd run a long time, so set timeout=240 result = virsh.iface_bridge(iface_name, br_name, "--no-stp", debug=True, timeout=240) if result.exit_status: test.fail("Failed to create bridge:\n%s" % result.stderr) def define_nwfilter(filter_name): """ Define nwfilter vdsm-no-mac-spoofing with content like: <filter name='vdsm-no-mac-spoofing' chain='root'> <filterref filter='no-mac-spoofing'/> <filterref filter='no-arp-mac-spoofing'/> </filter> :param filter_name: the name of nwfilter :return: filter created or raise exception """ filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") filter_params = { "filter_name": "vdsm-no-mac-spoofing", "filter_chain": "root", "filter_uuid": filter_uuid, "filterref_name_1": "no-mac-spoofing", "filterref_name_2": "no-arp-mac-spoofing" } filter_xml = libvirt.create_nwfilter_xml(filter_params).xml # Run command result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True) if result.exit_status: test.fail("Failed to define nwfilter with %s" % filter_xml) def modify_iface_xml(br_name, nwfilter, vm_name): """ Modify interface xml with the new bridge and the nwfilter :param br_name: bridge name :param nwfilter: nwfilter name :param vm_name: vm name """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) iface_xml.source = {'bridge': br_name} iface_xml.filterref = iface_xml.new_filterref(name=nwfilter) logging.debug("new interface xml is: %s" % iface_xml) vmxml.add_device(iface_xml) vmxml.sync() def ping(src_ip, dest_ip, ping_count, timeout, session=None): """ Wrap of ping :param src_ip: source address :param dest_ip: destination address :param ping_count: count of icmp packet :param timeout: timeout for the ping command :param session: local execution or session to execute the ping command :return: ping succeed or raise exception """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session) if status: test.fail("Fail to ping %s from %s" % (dest_ip, src_ip)) # Get test params bridge_name = params.get("bridge_name", "br0") filter_name = params.get("filter_name", "vdsm-no-mac-spoofing") ping_count = params.get("ping_count", "5") ping_timeout = float(params.get("ping_timeout", "10")) iface_name = utils_net.get_net_if(state="UP")[0] bridge_script = NETWORK_SCRIPT + bridge_name iface_script = NETWORK_SCRIPT + iface_name iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name) vms = params.get("vms").split() if len(vms) <= 1: test.cancel("Need two VMs to test") else: vm1_name = vms[0] vm2_name = vms[1] vm1 = env.get_vm(vm1_name) vm2 = env.get_vm(vm2_name) # Back up the interface script process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True) # Back up vm xml vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name) vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name) # Stop NetworkManager service NM_service = service.Factory.create_service("NetworkManager") NM_status = NM_service.status() if NM_status is True: NM_service.stop() # Start network service NW_service = service.Factory.create_service("network") NW_status = NW_service.status() if NW_status is None: logging.debug("network service not found") if not utils_package.package_install('network-scripts') or \ not utils_package.package_install('initscripts'): test.cancel("Failed to install network service") if NW_status is not True: logging.debug("network service is not running") NW_service.start() try: create_bridge(bridge_name, iface_name) define_nwfilter(filter_name) modify_iface_xml(bridge_name, filter_name, vm1_name) if vm1.is_alive(): vm1.destroy() vm1.start() # Check if vm can get ip with the new create bridge session1 = session2 = None try: utils_net.update_mac_ip_address(vm1, timeout=120) vm1_ip = vm1.get_address() except Exception as errs: test.fail("vm1 can't get IP with the new create bridge: %s" % errs) # Check guest and host can ping each other host_ip = utils_net.get_ip_address_by_interface(bridge_name) remote_ip = params.get("remote_ip", "www.baidu.com") ping(host_ip, vm1_ip, ping_count, ping_timeout) ping(host_ip, remote_ip, ping_count, ping_timeout) session1 = vm1.wait_for_login() ping(vm1_ip, host_ip, ping_count, ping_timeout, session=session1) ping(vm1_ip, remote_ip, ping_count, ping_timeout, session=session1) # Start vm2 connect to the same bridge modify_iface_xml(bridge_name, filter_name, vm2_name) if vm2.is_alive(): vm2.destroy() vm2.start() # Check if vm1 and vm2 can ping each other try: utils_net.update_mac_ip_address(vm2, timeout=120) vm2_ip = vm2.get_address() except Exception as errs: test.fail("vm2 can't get IP with the new create bridge: %s" % errs) session2 = vm2.wait_for_login() ping(vm2_ip, vm1_ip, ping_count, ping_timeout, session=session2) ping(vm1_ip, vm2_ip, ping_count, ping_timeout, session=session1) finally: logging.debug("Start to restore") vm1_xml_bak.sync() vm2_xml_bak.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) if libvirt.check_iface(bridge_name, "exists", "--all"): virsh.iface_unbridge(bridge_name, timeout=60, debug=True) if os.path.exists(iface_script_bk): process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True) if os.path.exists(bridge_script): process.run("rm -rf %s" % bridge_script, shell=True) # reload network configuration NW_service.restart() # recover NetworkManager if NM_status is True: NM_service.start()
def run(test, params, env): """ Test update filter rules when domain is running. 1) Prepare parameters. 2) Add filter to domain interface. 3) Start domain. 4) Update filter rule and check 5) Cleanup """ # Prepare parameters filter_name = params.get("filter_name", "testcase") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") check_vm_cmd = params.get("check_vm_cmd") vm_expect_match = params.get("vm_expect_match") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) filterref_dict = {} filterref_dict['name'] = filter_name # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_filter = libvirt_xml.NwfilterXML() filter_backup = new_filter.new_from_filter_dumpxml(filter_name) def clean_up_dirty_nwfilter_binding(): cmd_result = virsh.nwfilter_binding_list(debug=True) binding_list = cmd_result.stdout_text.strip().splitlines() binding_list = binding_list[2:] result = [] # If binding list is not empty. if binding_list: for line in binding_list: # Split on whitespace, assume 1 column linesplit = line.split(None, 1) result.append(linesplit[0]) logging.info("nwfilter binding list is: %s", result) for binding_uuid in result: try: virsh.nwfilter_binding_delete(binding_uuid) except Exception as e: logging.error( "Exception thrown while undefining nwfilter-binding: %s", str(e)) raise try: # Clean up dirty nwfilter binding if there are. clean_up_dirty_nwfilter_binding() # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() # Start vm vm.start() session = vm.wait_for_login() vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Update filter rule by nwfilter-define filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Check ebtables on host after filter update if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) out = astring.to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) # Check in vm if check_vm_cmd: output = session.cmd_output(check_vm_cmd) logging.debug("cmd output: %s", output) if vm_expect_match and not re.search(vm_expect_match, output): test.fail("'%s' not found in output: %s" % (vm_expect_match, output)) finally: # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Restore created filter virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filter_backup.xml, debug=True)
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() device_name = None try: rule = params.get("rule") if rule: # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: pkg = "ipset" if not utils_package.package_install(pkg): test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) # This change anchors nwfilter_vm_start.possitive_test.new_filter.variable_notation case # The matched destination could be ip address or hostname if "iptables -L" in check_cmd and expect_match: # ip address that need to be replaced replace_param = params.get("parameter_value_2") #Get hostname by ip address. hostname_info = None try: hostname_info = socket.gethostbyaddr(replace_param) except socket.error as e: logging.info( "Failed to get hostname from ip address with error: %s", str(e)) if hostname_info: # String is used to replace ip address replace_with = "%s|%s" % (replace_param, hostname_info[0]) expect_match = r"%s" % expect_match.replace( replace_param, replace_with) logging.debug("final iptables match string:%s", expect_match) out = to_text( process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -s TERM `pidof libvirtd`" process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) # After libvirt 5.6.0, libvirtd is using systemd socket activation by default if not ret and not libvirt_version.version_compare(5, 6, 0): test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True)
def run(test, params, env): """ Test bridge support from network 1) create a linux bridge and connect a physical interface to it 2) define nwfilter with "vdsm-no-mac-spoofing" 3) redefine the vm with the new create bridge and filter 4) check if guest can get public ip after vm start 5) check if guest and host can ping each other 6) check if guest and host can ping outside 7) start another vm connected to the same bridge 8) check if the 2 guests can ping each other """ def create_bridge(br_name, iface_name): """ Create a linux bridge by virsh cmd: 1. Stop NetworkManager and Start network service 2. virsh iface-bridge <iface> <name> [--no-stp] :param br_name: bridge name :param iface_name: physical interface name :return: bridge created or raise exception """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge utils_package.package_install('tmux') cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \ ' ip link set {1} master {0}; ip link set {0} up;' \ ' pkill dhclient; sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name) process.run(cmd, shell=True, verbose=True) def create_bridge_network(br_name, net_name): """ Define and start the bridge type network """ # check if network with the same name already exists output_all = virsh.net_list("--all").stdout.strip() if re.search(net_name, output_all): test.cancel("Network with the same name already exists!") test_xml = network_xml.NetworkXML(network_name="%s" % net_name) test_xml.forward = {"mode": "bridge"} test_xml.bridge = {"name": br_name} test_xml.create() def define_nwfilter(filter_name): """ Define nwfilter vdsm-no-mac-spoofing with content like: <filter name='vdsm-no-mac-spoofing' chain='root'> <filterref filter='no-mac-spoofing'/> <filterref filter='no-arp-mac-spoofing'/> </filter> :param filter_name: the name of nwfilter :return: filter created or raise exception """ filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") filter_params = { "filter_name": "vdsm-no-mac-spoofing", "filter_chain": "root", "filter_uuid": filter_uuid, "filterref_name_1": "no-mac-spoofing", "filterref_name_2": "no-arp-mac-spoofing" } filter_xml = libvirt.create_nwfilter_xml(filter_params).xml # Run command result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True) if result.exit_status: test.fail("Failed to define nwfilter with %s" % filter_xml) def ping(src_ip, dest_ip, ping_count, timeout, session=None): """ Wrap of ping :param src_ip: source address :param dest_ip: destination address :param ping_count: count of icmp packet :param timeout: timeout for the ping command :param session: local execution or session to execute the ping command :return: ping succeed or raise exception """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session, force_ipv4=True) if status: test.fail("Fail to ping %s from %s" % (dest_ip, src_ip)) def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session, host_ip, remote_url, endpoint_ip): # make sure host network works well # host ping remote url ping(host_ip, remote_url, ping_count, ping_timeout) # host ping guest ping(host_ip, guest_ip, ping_count, ping_timeout) # guest ping host ping(guest_ip, host_ip, ping_count, ping_timeout, session=guest_session) # guest ping remote url ping(guest_ip, remote_url, ping_count, ping_timeout, session=guest_session) # guest ping endpoint ping(guest_ip, endpoint_ip, ping_count, ping_timeout, session=guest_session) # Get test params bridge_name = params.get("bridge_name", "test_br0") filter_name = params.get("filter_name", "vdsm-no-mac-spoofing") ping_count = params.get("ping_count", "5") ping_timeout = float(params.get("ping_timeout", "10")) iface_name = utils_net.get_net_if(state="UP")[0] bridge_script = NETWORK_SCRIPT + bridge_name iface_script = NETWORK_SCRIPT + iface_name iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name) attach_interface = "yes" == params.get("attach_interface", "no") iface_model = params.get("iface_model", "virtio") iface_source = eval(params.get("iface_source", "{'bridge':'test_br0'}")) iface_type = params.get("iface_type", None) iface_target = params.get("iface_target", "br_target") iface_alias = params.get("iface_alias", None) hotplug = "yes" == params.get("hotplug", "no") iface_driver = params.get("iface_driver", None) start_vm2 = "yes" == params.get("start_vm2", "no") create_network = "yes" == params.get("create_network", "no") update_device = "yes" == params.get("update_with_diff_type", "no") vms = params.get("vms").split() if len(vms) <= 1: test.cancel("Need two VMs to test") else: vm1_name = vms[0] vm2_name = vms[1] vm1 = env.get_vm(vm1_name) vm2 = env.get_vm(vm2_name) # Back up the interface script process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True, verbose=True) # Back up vm xml vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name) vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name) # Stop NetworkManager service NM_service = service.Factory.create_service("NetworkManager") NM_status = NM_service.status() if not NM_status: NM_service.start() mac = utils_net.generate_mac_address_simple() try: create_bridge(bridge_name, iface_name) define_nwfilter(filter_name) if hotplug: err_msgs = ("No more available PCI slots", "No more available PCI addresses") # delete the original interface on the vm before hot-plug if vm1.is_alive(): vm1.destroy() vmxml = vm_xml.VMXML.new_from_dumpxml(vm1_name) iface_xml = vmxml.get_devices('interface')[0] logging.debug("Delete the original interface") vmxml.del_device(iface_xml) vmxml.sync() vm1.start() # do hot-plug if attach_interface: logging.info("Try to hot-plug interface") options = ( "%s %s --model %s --mac %s" % (iface_type, iface_source['bridge'], iface_model, mac)) ret = virsh.attach_interface(vm1_name, options, ignore_status=True) else: logging.info("Try to hot-plug device") if create_network: create_bridge_network(bridge_name, iface_source["network"]) target = str({'dev': iface_target}) iface_alias = str({'name': iface_alias}) vm_iface_source = str(iface_source) iface_params = { "type": iface_type, "source": vm_iface_source, "filter": filter_name, "mac": mac, 'alias': iface_alias, 'target': target, 'model': iface_model, 'driver': iface_driver } attach_xml = interface.Interface(iface_params['type']) attach_xml.xml = libvirt.modify_vm_iface( vm1_name, 'get_xml', iface_params) ret = virsh.attach_device(vm1_name, attach_xml.xml, ignore_status=True, debug=True) if ret.exit_status: if any([msg in ret.stderr for msg in err_msgs]): test.error("No more pci slots, can't attach more devices") else: test.fail("Failed to attach-interface: %s" % ret.stderr.strip()) else: logging.debug("Hot-plug interface or device pass") if update_device: # As the interface type will change to actual type "bridge" in live xml, we need to ensure # the update with original "network" type will not fail. # Try to delete the nwfilter with original type in iface_params update_xml = interface.Interface(iface_type) iface_params_update = { "del_filter": "yes", "type": "network", "source": vm_iface_source } update_xml.xml = libvirt.modify_vm_iface( vm1_name, 'get_xml', iface_params_update) ret = virsh.update_device(vm1_name, update_xml.xml, ignore_status=True, debug=True) libvirt.check_exit_status(ret) else: vm_iface_source = str(iface_source) vm1_iface_params = { "type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac, 'driver': iface_driver, "iface_model": iface_model } libvirt.modify_vm_iface(vm1_name, "update_iface", vm1_iface_params) if vm1.is_alive(): vm1.destroy() vm1.start() # apply ip address as it may not be initialized session1 = session2 = None session1 = vm1.wait_for_serial_login() utils_net.restart_guest_network(session1) output = session1.cmd_output("ifconfig || ip a") logging.debug("guest1 ip info %s" % output) # Check guest's network function host_ip = utils_net.get_ip_address_by_interface(bridge_name) remote_url = params.get("remote_ip", "www.google.com") try: vm1_ip = utils_net.get_guest_ip_addr(session1, mac) except Exception as errs: test.fail("vm1 can't get IP with the new create bridge: %s" % errs) if hotplug: # reboot vm1 then check network function to ensure the interface still there and works fine logging.info("reboot the vm") virsh.reboot(vm1) if session1 is None: session1 = vm1.wait_for_serial_login() ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1) # restart libvirtd service then check the interface still works fine libvirtd = utils_libvirtd.Libvirtd() libvirtd.restart() vm1.cleanup_serial_console() vm1.create_serial_console() session1 = vm1.wait_for_serial_login() ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1) logging.info( "after reboot and restart libvirtd, the network works fine") if iface_driver: try: driver_dict = eval(iface_driver) if session1 is None: session1 = vm1.wait_for_serial_login() guest_iface_info = session1.cmd_output("ip l").strip() guest_iface_name = re.findall( r"^\d+: (\S+?)[@:].*state UP.*$", guest_iface_info, re.MULTILINE)[0] comb_size = driver_dict.get('queues') rx_size = driver_dict.get('rx_queue_size') session1.cmd_status("ethtool -L %s combined %s" % (guest_iface_name, comb_size)) ret, outp = session1.cmd_status_output("ethtool -l %s" % guest_iface_name) logging.debug("ethtool cmd output:%s" % outp) if not ret: pre_comb = re.search( "Pre-set maximums:[\s\S]*?Combined:.*?(\d+)", outp).group(1) cur_comb = re.search( "Current hardware settings:[\s\S]*?Combined:.*?(\d+)", outp).group(1) if int(pre_comb) != int(comb_size) or int( cur_comb) != int(comb_size): test.fail( "Fail to check the combined size: setting: %s," "Pre-set: %s, Current-set: %s" % (comb_size, pre_comb, cur_comb)) else: logging.info( "Getting correct Pre-set and Current set value" ) else: test.error("ethtool list fail: %s" % outp) # as tx_queue size is only supported for vhost-user interface, only check rx_queue size ret1, outp1 = session1.cmd_status_output("ethtool -g %s" % guest_iface_name) logging.debug("guest queue size setting is %s" % outp1) if not ret1: pre_set = re.search(r"Pre-set maximums:\s*RX:\s*(\d+)", outp1).group(1) cur_set = re.search( r"Current hardware settings:\s*RX:\s*(\d+)", outp1).group(1) if int(pre_set) != int(rx_size) or int(cur_set) != int( rx_size): test.fail("Fail to check the rx_queue_size!") except Exception as errs: test.fail("fail to get driver info") # hot-unplug interface/device if attach_interface: ret = virsh.detach_interface(vm1_name, "bridge", ignore_status=True) else: ret = virsh.detach_device(vm1_name, attach_xml.xml, ignore_status=True, debug=True) if ret.exit_status: test.fail("Hot-unplug interface/device fail") else: logging.info("hot-unplug interface/device succeed") else: if start_vm2: # Start vm2 connect to the same bridge mac2 = utils_net.generate_mac_address_simple() vm2_iface_params = { "type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac2 } libvirt.modify_vm_iface(vm2_name, "update_iface", vm2_iface_params) if vm2.is_alive(): vm2.destroy() vm2.start() # Check if vm1 and vm2 can ping each other try: utils_net.update_mac_ip_address(vm2, timeout=120) vm2_ip = vm2.get_address() except Exception as errs: test.fail( "vm2 can't get IP with the new create bridge: %s" % errs) session2 = vm2.wait_for_login() # make sure guest has got ip address utils_net.restart_guest_network(session2) output2 = session2.cmd_output("ifconfig || ip a") logging.debug("guest ip info %s" % output2) # check 2 guests' network functions check_net_functions(vm1_ip, ping_count, ping_timeout, session1, host_ip, remote_url, vm2_ip) check_net_functions(vm2_ip, ping_count, ping_timeout, session2, host_ip, remote_url, vm1_ip) finally: logging.debug("Start to restore") vm1_xml_bak.sync() vm2_xml_bak.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) if libvirt.check_iface(bridge_name, "exists", "--all"): virsh.iface_unbridge(bridge_name, timeout=60, debug=True) if os.path.exists(iface_script_bk): process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True, verbose=True) if os.path.exists(bridge_script): process.run("rm -rf %s" % bridge_script, shell=True, verbose=True) cmd = 'tmux -c "ip link set {1} nomaster; ip link delete {0};' \ 'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name) process.run(cmd, shell=True, verbose=True) # reload network configuration NM_service.restart() # recover NetworkManager if NM_status is True: NM_service.start() if 'network' in iface_source and iface_source[ "network"] in virsh.net_state_dict(): virsh.net_destroy(iface_source["network"], ignore_status=False)
except virt_vm.VMStartError, e: # Starting VM failed. if not status_error: raise error.TestFail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -SIGTERM `pidof libvirtd`" utils.run(cmd) ret = utils.wait_for(lambda: not libvirtd.is_running(), timeout=30) if not ret: raise error.TestFail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: utils.run("umount -l %s" % device_name) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: utils.run("ipset destroy blacklist")
def run(test, params, env): """ Test bridge support from network 1) create a linux bridge and connect a physical interface to it 2) define nwfilter with "vdsm-no-mac-spoofing" 3) redefine the vm with the new create bridge and filter 4) check if guest can get public ip after vm start 5) check if guest and host can ping each other 6) check if guest and host can ping outside 7) start another vm connected to the same bridge 8) check if the 2 guests can ping each other """ def create_bridge(br_name, iface_name): """ Create a linux bridge by virsh cmd: 1. Stop NetworkManager and Start network service 2. virsh iface-bridge <iface> <name> [--no-stp] :param br_name: bridge name :param iface_name: physical interface name :return: bridge created or raise exception """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge # This cmd run a long time, so set timeout=240 result = virsh.iface_bridge(iface_name, br_name, "--no-stp", debug=True, timeout=240) if result.exit_status: test.fail("Failed to create bridge:\n%s" % result.stderr) def define_nwfilter(filter_name): """ Define nwfilter vdsm-no-mac-spoofing with content like: <filter name='vdsm-no-mac-spoofing' chain='root'> <filterref filter='no-mac-spoofing'/> <filterref filter='no-arp-mac-spoofing'/> </filter> :param filter_name: the name of nwfilter :return: filter created or raise exception """ filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") filter_params = {"filter_name": "vdsm-no-mac-spoofing", "filter_chain": "root", "filter_uuid": filter_uuid, "filterref_name_1": "no-mac-spoofing", "filterref_name_2": "no-arp-mac-spoofing"} filter_xml = libvirt.create_nwfilter_xml(filter_params).xml # Run command result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True) if result.exit_status: test.fail("Failed to define nwfilter with %s" % filter_xml) def modify_iface_xml(br_name, nwfilter, vm_name): """ Modify interface xml with the new bridge and the nwfilter :param br_name: bridge name :param nwfilter: nwfilter name :param vm_name: vm name """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) iface_xml.source = {'bridge': br_name} iface_xml.filterref = iface_xml.new_filterref(name=nwfilter) logging.debug("new interface xml is: %s" % iface_xml) vmxml.add_device(iface_xml) vmxml.sync() def ping(src_ip, dest_ip, ping_count, timeout, session=None): """ Wrap of ping :param src_ip: source address :param dest_ip: destination address :param ping_count: count of icmp packet :param timeout: timeout for the ping command :param session: local execution or session to execute the ping command :return: ping succeed or raise exception """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session) if status: test.fail("Fail to ping %s from %s" % (dest_ip, src_ip)) # Get test params bridge_name = params.get("bridge_name", "br0") filter_name = params.get("filter_name", "vdsm-no-mac-spoofing") ping_count = params.get("ping_count", "5") ping_timeout = float(params.get("ping_timeout", "10")) iface_name = utils_net.get_net_if(state="UP")[0] bridge_script = NETWORK_SCRIPT + bridge_name iface_script = NETWORK_SCRIPT + iface_name iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name) vms = params.get("vms").split() if len(vms) <= 1: test.cancel("Need two VMs to test") else: vm1_name = vms[0] vm2_name = vms[1] vm1 = env.get_vm(vm1_name) vm2 = env.get_vm(vm2_name) # Back up the interface script process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True) # Back up vm xml vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name) vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name) # Stop NetworkManager service NM_service = service.Factory.create_service("NetworkManager") NM_status = NM_service.status() if NM_status is True: NM_service.stop() # Start network service NW_service = service.Factory.create_service("network") NW_status = NW_service.status() if NW_status is None: logging.debug("network service not found") if not utils_package.package_install('network-scripts') or \ not utils_package.package_install('initscripts'): test.cancel("Failed to install network service") if NW_status is not True: logging.debug("network service is not running") NW_service.start() try: create_bridge(bridge_name, iface_name) define_nwfilter(filter_name) modify_iface_xml(bridge_name, filter_name, vm1_name) if vm1.is_alive(): vm1.destroy() vm1.start() # Check if vm can get ip with the new create bridge session1 = session2 = None try: utils_net.update_mac_ip_address(vm1, timeout=120) vm1_ip = vm1.get_address() except Exception as errs: test.fail("vm1 can't get IP with the new create bridge: %s" % errs) # Check guest and host can ping each other host_ip = utils_net.get_ip_address_by_interface(bridge_name) remote_ip = params.get("remote_ip", "www.baidu.com") ping(host_ip, vm1_ip, ping_count, ping_timeout) ping(host_ip, remote_ip, ping_count, ping_timeout) session1 = vm1.wait_for_login() ping(vm1_ip, host_ip, ping_count, ping_timeout, session=session1) ping(vm1_ip, remote_ip, ping_count, ping_timeout, session=session1) # Start vm2 connect to the same bridge modify_iface_xml(bridge_name, filter_name, vm2_name) if vm2.is_alive(): vm2.destroy() vm2.start() # Check if vm1 and vm2 can ping each other try: utils_net.update_mac_ip_address(vm2, timeout=120) vm2_ip = vm2.get_address() except Exception as errs: test.fail("vm2 can't get IP with the new create bridge: %s" % errs) session2 = vm2.wait_for_login() ping(vm2_ip, vm1_ip, ping_count, ping_timeout, session=session2) ping(vm1_ip, vm2_ip, ping_count, ping_timeout, session=session1) finally: logging.debug("Start to restore") vm1_xml_bak.sync() vm2_xml_bak.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) if libvirt.check_iface(bridge_name, "exists", "--all"): virsh.iface_unbridge(bridge_name, timeout=60, debug=True) if os.path.exists(iface_script_bk): process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True) if os.path.exists(bridge_script): process.run("rm -rf %s" % bridge_script, shell=True) # reload network configuration NW_service.restart() # recover NetworkManager if NM_status is True: NM_service.start()
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() device_name = None try: rule = params.get("rule") if rule: # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: try: path.find_command("ipset") except path.CmdNotFoundError: ret = process.run("yum install ipset -y", shell=True) if ret.exit_status: test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system( check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) out = process.system_output(check_cmd, ignore_status=False, shell=True) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -SIGTERM `pidof libvirtd`" process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) if not ret: test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True)
def run(test, params, env): """ Test bridge support from network 1) create a linux bridge and connect a physical interface to it 2) define nwfilter with "vdsm-no-mac-spoofing" 3) redefine the vm with the new create bridge and filter 4) check if guest can get public ip after vm start 5) check if guest and host can ping each other 6) check if guest and host can ping outside 7) start another vm connected to the same bridge 8) check if the 2 guests can ping each other """ def create_bridge(br_name, iface_name): """ Create a linux bridge by virsh cmd: 1. Stop NetworkManager and Start network service 2. virsh iface-bridge <iface> <name> [--no-stp] :param br_name: bridge name :param iface_name: physical interface name :return: bridge created or raise exception """ # Make sure the bridge not exist if libvirt.check_iface(br_name, "exists", "--all"): test.cancel("The bridge %s already exist" % br_name) # Create bridge utils_package.package_install('tmux') cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \ ' ip link set {1} master {0}; ip link set {0} up;' \ ' pkill dhclient; sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name) process.run(cmd, shell=True, verbose=True) def define_nwfilter(filter_name): """ Define nwfilter vdsm-no-mac-spoofing with content like: <filter name='vdsm-no-mac-spoofing' chain='root'> <filterref filter='no-mac-spoofing'/> <filterref filter='no-arp-mac-spoofing'/> </filter> :param filter_name: the name of nwfilter :return: filter created or raise exception """ filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") filter_params = {"filter_name": "vdsm-no-mac-spoofing", "filter_chain": "root", "filter_uuid": filter_uuid, "filterref_name_1": "no-mac-spoofing", "filterref_name_2": "no-arp-mac-spoofing"} filter_xml = libvirt.create_nwfilter_xml(filter_params).xml # Run command result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True) if result.exit_status: test.fail("Failed to define nwfilter with %s" % filter_xml) def modify_iface_xml(br_name, nwfilter, vm_name): """ Modify interface xml with the new bridge and the nwfilter :param br_name: bridge name :param nwfilter: nwfilter name :param vm_name: vm name """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) iface_xml = Interface(type_name='bridge') iface_xml.source = {'bridge': br_name} iface_xml.model = 'virtio' iface_xml.filterref = iface_xml.new_filterref(name=nwfilter) logging.debug("new interface xml is: %s" % iface_xml) vmxml.add_device(iface_xml) vmxml.sync() def ping(src_ip, dest_ip, ping_count, timeout, session=None): """ Wrap of ping :param src_ip: source address :param dest_ip: destination address :param ping_count: count of icmp packet :param timeout: timeout for the ping command :param session: local execution or session to execute the ping command :return: ping succeed or raise exception """ status, output = utils_net.ping(dest=dest_ip, count=ping_count, interface=src_ip, timeout=timeout, session=session) if status: test.fail("Fail to ping %s from %s" % (dest_ip, src_ip)) def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session, host_ip, remote_url, endpoint_ip): # make sure host network works well # host ping remote url ping(host_ip, remote_url, ping_count, ping_timeout) # host ping guest ping(host_ip, guest_ip, ping_count, ping_timeout) # guest ping host ping(guest_ip, host_ip, ping_count, ping_timeout, session=guest_session) # guest ping remote url ping(guest_ip, remote_url, ping_count, ping_timeout, session=guest_session) # guest ping endpoint ping(guest_ip, endpoint_ip, ping_count, ping_timeout, session=guest_session) # Get test params bridge_name = params.get("bridge_name", "test_br0") filter_name = params.get("filter_name", "vdsm-no-mac-spoofing") ping_count = params.get("ping_count", "5") ping_timeout = float(params.get("ping_timeout", "10")) iface_name = utils_net.get_net_if(state="UP")[0] bridge_script = NETWORK_SCRIPT + bridge_name iface_script = NETWORK_SCRIPT + iface_name iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name) vms = params.get("vms").split() if len(vms) <= 1: test.cancel("Need two VMs to test") else: vm1_name = vms[0] vm2_name = vms[1] vm1 = env.get_vm(vm1_name) vm2 = env.get_vm(vm2_name) # Back up the interface script process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True, verbose=True) # Back up vm xml vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name) vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name) # Stop NetworkManager service NM_service = service.Factory.create_service("NetworkManager") NM_status = NM_service.status() if not NM_status: NM_service.start() try: create_bridge(bridge_name, iface_name) define_nwfilter(filter_name) modify_iface_xml(bridge_name, filter_name, vm1_name) if vm1.is_alive(): vm1.destroy() vm1.start() # Check if vm can get ip with the new create bridge session1 = session2 = None try: utils_net.update_mac_ip_address(vm1, timeout=120) vm1_ip = vm1.get_address() except Exception as errs: test.fail("vm1 can't get IP with the new create bridge: %s" % errs) # Check guest's network function host_ip = utils_net.get_ip_address_by_interface(bridge_name) remote_url = params.get("remote_ip", "www.google.com") # make sure the guest has got ip address session1 = vm1.wait_for_login() session1.cmd("pkill -9 dhclient", ignore_all_errors=True) session1.cmd("dhclient %s " % iface_name, ignore_all_errors=True) output = session1.cmd_output("ifconfig || ip a") logging.debug("guest1 ip info %s" % output) # Start vm2 connect to the same bridge modify_iface_xml(bridge_name, filter_name, vm2_name) if vm2.is_alive(): vm2.destroy() vm2.start() # Check if vm1 and vm2 can ping each other try: utils_net.update_mac_ip_address(vm2, timeout=120) vm2_ip = vm2.get_address() except Exception as errs: test.fail("vm2 can't get IP with the new create bridge: %s" % errs) session2 = vm2.wait_for_login() # make sure guest has got ip address session2.cmd("pkill -9 dhclient", ignore_all_errors=True) session2.cmd("dhclient %s " % iface_name, ignore_all_errors=True) output2 = session2.cmd_output("ifconfig || ip a") logging.debug("guest ip info %s" % output2) # check 2 guests' network functions check_net_functions(vm1_ip, ping_count, ping_timeout, session1, host_ip, remote_url, vm2_ip) check_net_functions(vm2_ip, ping_count, ping_timeout, session2, host_ip, remote_url, vm1_ip) finally: logging.debug("Start to restore") vm1_xml_bak.sync() vm2_xml_bak.sync() virsh.nwfilter_undefine(filter_name, ignore_status=True) if libvirt.check_iface(bridge_name, "exists", "--all"): virsh.iface_unbridge(bridge_name, timeout=60, debug=True) if os.path.exists(iface_script_bk): process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True, verbose=True) if os.path.exists(bridge_script): process.run("rm -rf %s" % bridge_script, shell=True, verbose=True) cmd = 'tmux -c "ip link set {1} nomaster; ip link delete {0};' \ 'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name) process.run(cmd, shell=True, verbose=True) # reload network configuration NM_service.restart() # recover NetworkManager if NM_status is True: NM_service.start()
def run(test, params, env): """ Test start domain with nwfilter rules. 1) Prepare parameters. 2) Prepare nwfilter rule and update domain interface to apply. 3) Start domain and check rule. 4) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") exist_filter = params.get("exist_filter", "no-mac-spoofing") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") status_error = "yes" == params.get("status_error", "no") mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no") kill_libvirtd = "yes" == params.get("kill_libvirtd", "no") bug_url = params.get("bug_url", "") ipset_command = params.get("ipset_command") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) username = params.get("username") password = params.get("password") # Prepare vm filterref parameters dict list filter_param_list = [] params_key = [] for i in params.keys(): if 'parameter_name_' in i: params_key.append(i) params_key.sort() for i in range(len(params_key)): params_dict = {} params_dict['name'] = params[params_key[i]] params_dict['value'] = params['parameter_value_%s' % i] filter_param_list.append(params_dict) filterref_dict = {} filterref_dict['name'] = filter_name filterref_dict['parameters'] = filter_param_list # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) libvirtd = utils_libvirtd.Libvirtd() device_name = None try: rule = params.get("rule") if rule: # Create new filter xml filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() if mount_noexec_tmp: device_name = utlv.setup_or_cleanup_iscsi(is_setup=True) utlv.mkfs(device_name, 'ext4') cmd = "mount %s /tmp -o noexec,nosuid" % device_name process.run(cmd, shell=True) if ipset_command: pkg = "ipset" if not utils_package.package_install(pkg): test.cancel("Can't install ipset on host") process.run(ipset_command, shell=True) # Run command try: vm.start() if not mount_noexec_tmp: vm.wait_for_serial_login(username=username, password=password) vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Check iptables or ebtables on host if check_cmd: if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not process.system(check_cmd, ignore_status=True, shell=True), timeout=30) if not ret: test.fail("Rum command '%s' failed" % check_cmd) out = to_text(process.system_output(check_cmd, ignore_status=False, shell=True)) if expect_match and not re.search(expect_match, out): test.fail("'%s' not found in output: %s" % (expect_match, out)) except virt_vm.VMStartError as e: # Starting VM failed. if not status_error: test.fail("Test failed in positive case.\n error:" " %s\n%s" % (e, bug_url)) if kill_libvirtd: cmd = "kill -s TERM `pidof libvirtd`" process.run(cmd, shell=True) ret = utils_misc.wait_for(lambda: not libvirtd.is_running(), timeout=30) if not ret: test.fail("Failed to kill libvirtd. %s" % bug_url) finally: if kill_libvirtd: libvirtd.restart() # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Undefine created filter if filter_name != exist_filter: virsh.nwfilter_undefine(filter_name, debug=True) if mount_noexec_tmp: if device_name: process.run("umount -l %s" % device_name, ignore_status=True, shell=True) utlv.setup_or_cleanup_iscsi(is_setup=False) if ipset_command: process.run("ipset destroy blacklist", shell=True)
def run(test, params, env): """ Test command: virsh nwfilter-define. 1) Prepare parameters. 2) Set options of virsh define. 3) Run define command. 4) Check result. 5) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") filter_chain = params.get("filter_chain", "root") filter_priority = params.get("filter_priority", "") filter_uuid = params.get("filter_uuid", "5c6d49af-b071-6127-b4ec-6f8ed4b55335") filterref = params.get("filterref") filterref_name = params.get("filterref_name") exist_filter = params.get("exist_filter", "no-mac-spoofing") filter_xml = params.get("filter_create_xml_file") options_ref = params.get("options_ref", "") status_error = params.get("status_error", "no") # prepare rule and protocol attributes protocol = {} rule_dict = {} rule_dict_tmp = {} # rule string should end with EOL as separator, multiple rules is supported rule = params.get("rule", "rule_action=accept rule_direction=out protocol=mac EOL") rule_list = rule.split('EOL') for i in range(len(rule_list)): if rule_list[i]: attr = rule_list[i].split() for j in range(len(attr)): attr_list = attr[j].split('=') rule_dict_tmp[attr_list[0]] = attr_list[1] rule_dict[i] = rule_dict_tmp rule_dict_tmp = {} # process protocol parameter for i in rule_dict.keys(): if 'protocol' not in rule_dict[i]: # Set protocol as string 'None' as parse from cfg is # string 'None' protocol[i] = 'None' else: protocol[i] = rule_dict[i]['protocol'] rule_dict[i].pop('protocol') if protocol[i] in PROTOCOL_TYPES: # replace '-' with '_' in ipv6 types as '-' is not # supposed to be in class name if '-' in protocol[i]: protocol[i] = protocol[i].replace('-', '_') else: raise error.TestFail("Given protocol type %s" % protocol[i] + " is not in supported list %s" % PROTOCOL_TYPES) if filter_xml == "invalid-filter-xml": tmp_xml = xml_utils.TempXMLFile() tmp_xml.write('"<filter><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</filter>') tmp_xml.flush() filter_xml = tmp_xml.name logging.info("Test invalid xml is: %s" % filter_xml) elif filter_xml != " ": # Use exist xml as template with new attributes new_filter = libvirt_xml.NwfilterXML() filterxml = new_filter.new_from_filter_dumpxml(exist_filter) logging.debug("the exist xml is:\n%s" % filterxml.xmltreefile) # Backup xml if only update exist filter if exist_filter == filter_name: backup_xml = filterxml.xmltreefile.backup_copy() # Set filter attribute filterxml.filter_name = filter_name filterxml.filter_chain = filter_chain filterxml.filter_priority = filter_priority filterxml.uuid = filter_uuid if filterref: filterxml.filterref = filterref filterxml.filterref_name = filterref_name # Set rule attribute index_total = filterxml.get_rule_index() rule = filterxml.get_rule(0) rulexml = rule.backup_rule() for i in range(len(rule_dict.keys())): rulexml.rule_action = rule_dict[i].get('rule_action') rulexml.rule_direction = rule_dict[i].get('rule_direction') rulexml.rule_priority = rule_dict[i].get('rule_priority') rulexml.rule_statematch = rule_dict[i].get('rule_statematch') for j in RULE_ATTR: if j in rule_dict[i].keys(): rule_dict[i].pop(j) # set protocol attribute if protocol[i] != 'None': protocolxml = rulexml.get_protocol(protocol[i]) new_one = protocolxml.new_attr(**rule_dict[i]) protocolxml.attrs = new_one rulexml.xmltreefile = protocolxml.xmltreefile else: rulexml.del_protocol() if i <= len(index_total) - 1: filterxml.set_rule(rulexml, i) else: filterxml.add_rule(rulexml) # Reset rulexml rulexml = rule.backup_rule() logging.info("The xml for define is:\n%s" % filterxml.xmltreefile) filterxml.xmltreefile.write(filter_xml) # Run command cmd_result = virsh.nwfilter_define(filter_xml, options=options_ref, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result chk_result = check_list(filter_uuid, filter_name) xml_path = "%s/%s.xml" % (NWFILTER_ETC_DIR, filter_name) if status_error == "yes": if status == 0: raise error.TestFail("Run successfully with wrong command.") elif status_error == "no": if status: raise error.TestFail("Run failed with right command.") if not chk_result: raise error.TestFail("Can't find filter in nwfilter-list output") if not os.path.exists(xml_path): raise error.TestFail("Can't find filter xml under %s" % NWFILTER_ETC_DIR) logging.info("Dump the xml after define:") virsh.nwfilter_dumpxml(filter_name, ignore_status=True, debug=True) # Clean env if exist_filter == filter_name: logging.info("Restore exist filter: %s" % exist_filter) backup_xml.write(filter_xml) virsh.nwfilter_define(filter_xml, options="", ignore_status=True, debug=True) else: if chk_result: virsh.nwfilter_undefine(filter_name, options="", ignore_status=True, debug=True) if os.path.exists(filter_xml): os.remove(filter_xml)
def run(test, params, env): """ Test update filter rules when domain is running. 1) Prepare parameters. 2) Add filter to domain interface. 3) Start domain. 4) Update filter rule and check 5) Cleanup """ # Prepare parameters filter_name = params.get("filter_name", "testcase") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") check_vm_cmd = params.get("check_vm_cmd") vm_expect_match = params.get("vm_expect_match") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) filterref_dict = {} filterref_dict['name'] = filter_name # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_filter = libvirt_xml.NwfilterXML() filter_backup = new_filter.new_from_filter_dumpxml(filter_name) try: # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() # Start vm vm.start() session = vm.wait_for_login() vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Update filter rule by nwfilter-define filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Check ebtables on host after filter update if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for(lambda: not utils.system(check_cmd, ignore_status=True), timeout=30) if not ret: raise error.TestFail("Rum command '%s' failed" % check_cmd) out = utils.system_output(check_cmd, ignore_status=False) if expect_match and not re.search(expect_match, out): raise error.TestFail("'%s' not found in output: %s" % (expect_match, out)) # Check in vm if check_vm_cmd: output = session.cmd_output(check_vm_cmd) logging.debug("cmd output: %s", output) if vm_expect_match and not re.search(vm_expect_match, output): raise error.TestFail("'%s' not found in output: %s" % (vm_expect_match, output)) finally: # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Restore created filter virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filter_backup.xml, debug=True)
def run(test, params, env): """ Test update filter rules when domain is running. 1) Prepare parameters. 2) Add filter to domain interface. 3) Start domain. 4) Update filter rule and check 5) Cleanup """ # Prepare parameters filter_name = params.get("filter_name", "testcase") check_cmd = params.get("check_cmd") expect_match = params.get("expect_match") check_vm_cmd = params.get("check_vm_cmd") vm_expect_match = params.get("vm_expect_match") vm_name = params.get("main_vm") vm = env.get_vm(vm_name) filterref_dict = {} filterref_dict['name'] = filter_name # backup vm xml vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) new_filter = libvirt_xml.NwfilterXML() filter_backup = new_filter.new_from_filter_dumpxml(filter_name) try: # Update first vm interface with filter vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] vmxml.del_device(iface_xml) new_iface = interface.Interface('network') new_iface.xml = iface_xml.xml new_filterref = new_iface.new_filterref(**filterref_dict) new_iface.filterref = new_filterref logging.debug("new interface xml is: %s" % new_iface) vmxml.add_device(new_iface) vmxml.sync() # Start vm vm.start() session = vm.wait_for_login() vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name) iface_xml = vmxml.get_devices('interface')[0] iface_target = iface_xml.target['dev'] logging.debug("iface target dev name is %s", iface_target) # Update filter rule by nwfilter-define filterxml = utlv.create_nwfilter_xml(params) # Define filter xml virsh.nwfilter_define(filterxml.xml, debug=True) # Check ebtables on host after filter update if "DEVNAME" in check_cmd: check_cmd = check_cmd.replace("DEVNAME", iface_target) ret = utils_misc.wait_for( lambda: not utils.system(check_cmd, ignore_status=True), timeout=30) if not ret: raise error.TestFail("Rum command '%s' failed" % check_cmd) out = utils.system_output(check_cmd, ignore_status=False) if expect_match and not re.search(expect_match, out): raise error.TestFail("'%s' not found in output: %s" % (expect_match, out)) # Check in vm if check_vm_cmd: output = session.cmd_output(check_vm_cmd) logging.debug("cmd output: %s", output) if vm_expect_match and not re.search(vm_expect_match, output): raise error.TestFail("'%s' not found in output: %s" % (vm_expect_match, output)) finally: # Clean env if vm.is_alive(): vm.destroy(gracefully=False) # Recover xml of vm. vmxml_backup.sync() # Restore created filter virsh.nwfilter_undefine(filter_name, debug=True) virsh.nwfilter_define(filter_backup.xml, debug=True)
def run(test, params, env): """ Test command: virsh nwfilter-define. 1) Prepare parameters. 2) Set options of virsh define. 3) Run define command. 4) Check result. 5) Clean env """ # Prepare parameters filter_name = params.get("filter_name", "testcase") filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111") exist_filter = params.get("exist_filter", "no-mac-spoofing") filter_xml = params.get("filter_create_xml_file") options_ref = params.get("options_ref", "") status_error = params.get("status_error", "no") boundary_test_skip = "yes" == params.get("boundary_test_skip") new_uuid = "yes" == params.get("new_uuid", 'no') bug_url = params.get("bug_url") # libvirt acl polkit related 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.") if exist_filter == filter_name and new_uuid: # Since commit 46a811d, update filter with new uuid will fail. if libvirt_version.version_compare(1, 2, 7): status_error = 'yes' else: status_error = 'no' try: if filter_xml == "invalid-filter-xml": tmp_xml = xml_utils.TempXMLFile() tmp_xml.write('"<filter><<<BAD>>><\'XML</name\>' '!@#$%^&*)>(}>}{CORRUPTE|>!</filter>') tmp_xml.flush() filter_xml = tmp_xml.name logging.info("Test invalid xml is: %s" % filter_xml) elif filter_xml: # Create filter xml new_filter = libvirt_xml.NwfilterXML() filterxml_backup = new_filter.new_from_filter_dumpxml(exist_filter) # Backup xml if only update exist filter if exist_filter == filter_name and not new_uuid: filter_uuid = filterxml_backup.uuid params['filter_uuid'] = filter_uuid filterxml = utlv.create_nwfilter_xml(params) filterxml.xmltreefile.write(filter_xml) # Run command cmd_result = virsh.nwfilter_define(filter_xml, options=options_ref, unprivileged_user=unprivileged_user, uri=uri, ignore_status=True, debug=True) status = cmd_result.exit_status # Check result chk_result = check_list(filter_uuid, filter_name) xml_path = "%s/%s.xml" % (NWFILTER_ETC_DIR, filter_name) if status_error == "yes": if status == 0: if boundary_test_skip: raise error.TestNAError("Boundary check commit 4f20943 not" " in this libvirt build yet.") else: err_msg = "Run successfully with wrong command." if bug_url: err_msg += " Check more info in %s" % bug_url raise error.TestFail(err_msg) elif status_error == "no": if status: err_msg = "Run failed with right command." if bug_url: err_msg += " Check more info in %s" % bug_url raise error.TestFail(err_msg) if not chk_result: raise error.TestFail("Can't find filter in nwfilter-list" + " output") if not os.path.exists(xml_path): raise error.TestFail("Can't find filter xml under %s" % NWFILTER_ETC_DIR) logging.info("Dump the xml after define:") virsh.nwfilter_dumpxml(filter_name, ignore_status=True, debug=True) finally: # Clean env if exist_filter == filter_name: logging.info("Restore exist filter: %s" % exist_filter) virsh.nwfilter_undefine(filter_name, ignore_status=True) virsh.nwfilter_define(filterxml_backup.xml, ignore_status=True) else: if chk_result: virsh.nwfilter_undefine(filter_name, ignore_status=True) if os.path.exists(filter_xml): os.remove(filter_xml)