示例#1
0
    def test_connection():
        """
        Test network connections

        1. Create a network
        2. Attach the interfaces and check network connections
        3. Check the network connections after detaching ifaces, restarting
            libvirtd and destroying the VM
        """
        vf_no = int(params.get("vf_no", "4"))
        net_name = params.get("net_name")
        iface_type = params.get("iface_type")

        logging.info("Define network - %s.", net_name)
        create_network(params)
        libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface')
        libvirt_pcicontr.reset_pci_num(vm_name)
        vm.start()
        vm.wait_for_serial_login(timeout=240)

        logging.info("Attach 4 interfaces to the guest.")
        opts = ' '.join(
            ["network", net_name,
             params.get('attach_extra_opts', "")])
        for i in range(vf_no):
            virsh.attach_interface(vm_name,
                                   option=opts,
                                   debug=True,
                                   ignore_status=False)
            libvirt_network.check_network_connection(net_name, i + 1)

        logging.info("Try to attach one more interface.")
        res = virsh.attach_interface(vm_name, option=opts, debug=True)
        libvirt.check_exit_status(res, True)

        logging.info("Detach an interface.")
        vm_ifaces = [
            iface for iface in vm_xml.VMXML.new_from_dumpxml(
                vm_name).devices.by_device_tag("interface")
        ]
        mac_addr = vm_ifaces[0].get_mac_address()
        opts = ' '.join([iface_type, "--mac %s" % mac_addr])
        virsh.detach_interface(vm_name,
                               option=opts,
                               debug=True,
                               wait_for_event=True,
                               ignore_status=False)
        libvirt_network.check_network_connection(net_name, vf_no - 1)

        logging.info(
            "Restart libvirtd service and check the network connection.")
        utils_libvirtd.Libvirtd().restart()
        libvirt_network.check_network_connection(net_name, vf_no - 1)
        logging.info("Destroy the VM and check the network connection.")
        vm.destroy(gracefully=False)
        libvirt_network.check_network_connection(net_name, 0)
示例#2
0
 def modify_network(vm_name, first_nic):
     """
     Modify domain's interface to make sure domain can be login.
     """
     iface_type = first_nic.type
     iface_source = first_nic.source.get('bridge')
     mac_address = first_nic.mac_address
     try:
         virsh.detach_interface(vm_name, "--type=%s --config" % iface_type,
                                ignore_status=False)
         virsh.attach_interface(vm_name,
                                "--type=%s --source %s --mac %s --config"
                                % (iface_type, iface_source, mac_address),
                                ignore_status=False)
     except (remote.LoginError, virt_vm.VMError, aexpect.ShellError), detail:
         raise error.TestFail("Modify network failed:%s" % detail)
示例#3
0
 def modify_network(vm_name, first_nic):
     """
     Modify domain's interface to make sure domain can be login.
     """
     iface_type = first_nic.type_name
     iface_source = first_nic.source.get('bridge')
     mac_address = first_nic.mac_address
     try:
         virsh.detach_interface(vm_name,
                                "--type=%s --config" % iface_type,
                                ignore_status=False)
         virsh.attach_interface(vm_name,
                                "--type=%s --source %s --mac %s --config" %
                                (iface_type, iface_source, mac_address),
                                ignore_status=False)
     except (remote.LoginError, virt_vm.VMError,
             aexpect.ShellError), detail:
         raise error.TestFail("Modify network failed:%s" % detail)
    def detach_device(vm_name):
        """
        Detach a device from the given guest

        :param vm_name: The guest name
        :return: None
        """
        attach_dev_type = params.get("attach_dev_type", 'disk')
        detach_option = params.get("detach_option")
        if attach_dev_type == 'interface':
            ret = virsh.detach_interface(vm_name, detach_option, **virsh_dargs)
        else:
            logging.debug("No need to detach any device.")
示例#5
0
    def network_hook():
        """
        Check network hooks.
        """
        # Set interface to use default network
        net_name = params.get("net_name", "default")
        edit_iface(net_name)
        prepare_hook_file(hook_script %
                          (net_name, hook_log))
        try:
            # destroy the network
            ret = virsh.net_destroy(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " stopped end -"
            assert check_hooks(hook_str)

            # start network
            ret = virsh.net_start(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " start begin -"
            assert check_hooks(hook_str)
            hook_str = hook_file + " " + net_name + " started begin -"
            assert check_hooks(hook_str)

            # plug a interface
            if vm.is_dead():
                vm.start()
                vm.wait_for_login().close()
            mac_addr = "52:54:00:9a:53:a9"
            ret = virsh.attach_interface(vm_name,
                                         ("network %s --mac %s" %
                                          (net_name, mac_addr)))
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " plugged begin -"
            assert check_hooks(hook_str)
            ret = virsh.detach_interface(vm_name,
                                         "network --mac %s" % mac_addr)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
            # remove the log file
            if os.path.exists(hook_log):
                os.remove(hook_log)
            # destroy the domain
            vm.destroy()
            hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
        except AssertionError:
            utils_misc.log_last_traceback()
            test.fail("Failed to check"
                      " network hooks")
示例#6
0
    def network_hook():
        """
        Check network hooks.
        """
        # Set interface to use default network
        net_name = params.get("net_name", "default")
        edit_iface(net_name)
        prepare_hook_file(hook_script %
                          (net_name, hook_log))
        try:
            # destroy the network
            ret = virsh.net_destroy(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " stopped end -"
            assert check_hooks(hook_str)

            # start network
            ret = virsh.net_start(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " start begin -"
            assert check_hooks(hook_str)
            hook_str = hook_file + " " + net_name + " started begin -"
            assert check_hooks(hook_str)

            # plug a interface
            if vm.is_dead():
                vm.start()
                vm.wait_for_login().close()
            mac_addr = "52:54:00:9a:53:a9"
            ret = virsh.attach_interface(vm_name,
                                         ("network %s --mac %s" %
                                          (net_name, mac_addr)))
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " plugged begin -"
            assert check_hooks(hook_str)
            ret = virsh.detach_interface(vm_name,
                                         "network --mac %s" % mac_addr)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
            # remove the log file
            if os.path.exists(hook_log):
                os.remove(hook_log)
            # destroy the domain
            vm.destroy()
            hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
        except AssertionError:
            utils.log_last_traceback()
            raise error.TestFail("Failed to check"
                                 " network hooks")
示例#7
0
def run(test, params, env):
    """
    Test virsh interface related commands.

    (1) If using given exist interface for testing(eg. lo or ethX):
        1.1 Dumpxml for the interface(with --inactive option)
        1.2 Destroy the interface
        1.3 Undefine the interface
    (2) Define an interface from XML file
    (3) List interfaces with '--inactive' optioin
    (4) Start the interface
    (5) List interfaces with no option
    (6) Dumpxml for the interface
    (7) Get interface MAC address by interface name
    (8) Get interface name by interface MAC address
    (9) Delete interface if not use the exist interface for testing
        9.1 Destroy the interface
        9.2 Undefine the interface

    Caveat, this test may affect the host network, so using the loopback(lo)
    device by default. You can specify the interface which you want, but be
    careful.
    """

    iface_name = params.get("iface_name")
    iface_xml = params.get("iface_xml")
    iface_type = params.get("iface_type", "ethernet")
    iface_pro = params.get("iface_pro", "")
    iface_eth = params.get("iface_eth", "")
    iface_tag = params.get("iface_tag", "0")
    if iface_type == "vlan":
        iface_name = iface_eth + "." + iface_tag
    iface_eth_using = "yes" == params.get("iface_eth_using", "no")
    ping_ip = params.get("ping_ip", "localhost")
    use_exist_iface = "yes" == params.get("use_exist_iface", "no")
    status_error = "yes" == params.get("status_error", "no")
    net_restart = "yes" == params.get("iface_net_restart", "no")
    if ping_ip.count("ENTER"):
        raise error.TestNAError("Please input a valid ip address")
    if iface_name.count("ENTER"):
        raise error.TestNAError("Please input a existing bridge/ethernet name")
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm:
        xml_bak = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(test.tmpdir, "iface-%s.bk" % iface_name)
    net_bridge = utils_net.Bridge()
    if use_exist_iface:
        if iface_type == "bridge":
            if iface_name not in net_bridge.list_br():
                raise error.TestError("Bridge '%s' not exists" % iface_name)
            ifaces = net_bridge.get_structure()[iface_name]
            if len(ifaces) < 1:
                # In this situation, dhcp maybe cannot get ip address
                # Unless you use static, we'd better skip such case
                raise error.TestNAError("Bridge '%s' has no interface"
                                        " bridged, perhaps cannot get"
                                        " ipaddress" % iface_name)
    net_iface = utils_net.Interface(name=iface_name)
    iface_is_up = True
    list_option = "--all"
    if use_exist_iface:
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            raise error.TestError("Interface '%s' not exists" % iface_name)
        iface_xml = os.path.join(test.tmpdir, "iface.xml.tmp")
        iface_is_up = net_iface.is_up()
    else:
        # Note, if not use the interface which already exists, iface_name must
        # be equal to the value specified in XML file
        if libvirt.check_iface(iface_name, "exists", "--all"):
            raise error.TestError("Interface '%s' already exists" % iface_name)
        if not iface_xml:
            raise error.TestError("XML file is needed.")
        iface_xml = os.path.join(test.tmpdir, iface_xml)
        create_xml_file(iface_xml, params)

    # Stop NetworkManager as which may conflict with virsh iface commands
    try:
        NM = utils_misc.find_command("NetworkManager")
    except ValueError:
        logging.debug("No NetworkManager service.")
        NM = None
    NM_is_running = False
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            NM_service.stop()

    # run test cases
    try:
        if use_exist_iface:
            # back up the interface script
            utils.run("cp %s %s" % (iface_script, iface_script_bk))
            # step 1.1
            # dumpxml for interface
            xml = virsh.iface_dumpxml(iface_name,
                                      "--inactive",
                                      to_file=iface_xml,
                                      debug=True)
            # Step 1.2
            # Destroy interface
            if iface_is_up:
                result = virsh.iface_destroy(iface_name, debug=True)
                libvirt.check_exit_status(result, status_error)

            # Step 1.3
            # Undefine interface
            result = virsh.iface_undefine(iface_name, debug=True)
            libvirt.check_exit_status(result, status_error)
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("%s is still present." % iface_name)

        # Step 2
        # Define interface
        result = virsh.iface_define(iface_xml, debug=True)
        if iface_type == "bond" and not ping_ip:
            libvirt.check_exit_status(result, True)
            return
        else:
            libvirt.check_exit_status(result, status_error)

        if net_restart:
            network = service.Factory.create_service("network")
            network.restart()

        # After network restart, (ethernet)interface will be started
        if (not net_restart and iface_type in ("bridge", "ethernet")) or\
           (not use_exist_iface and iface_type in ("vlan", "bond")):
            # Step 3
            # List inactive interfaces
            list_option = "--inactive"
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("Fail to find %s." % iface_name)

            # Step 4
            # Start interface
            result = virsh.iface_start(iface_name, debug=True)
            if not net_restart and not use_exist_iface and\
               (iface_type == "ethernet" and iface_pro in ["", "dhcp"] or
                    iface_type == "bridge" and iface_pro == "dhcp"):
                libvirt.check_exit_status(result, True)
            else:
                libvirt.check_exit_status(result, status_error)
            if not status_error:
                iface_ip = net_iface.get_ip()
                ping_ip = ping_ip if not iface_ip else iface_ip
                if ping_ip:
                    if not libvirt.check_iface(iface_name, "ping", ping_ip):
                        raise error.TestFail("Ping %s fail." % ping_ip)

        # Step 5
        # List active interfaces
        if use_exist_iface or\
           (iface_pro != "dhcp" and iface_type == "bridge") or\
           (iface_eth_using and iface_type == "vlan"):
            list_option = ""
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("Fail to find %s in active "
                                         "interface list" % iface_name)
            if vm:
                iface_mac_list = vm_xml.VMXML.get_iface_dev(vm_name)
                # Before test, detach all interfaces in guest
                for mac in iface_mac_list:
                    iface_info = vm_xml.VMXML.get_iface_by_mac(vm_name, mac)
                    type = iface_info.get('type')
                    virsh.detach_interface(
                        vm_name, "--type %s --mac %s"
                        " --config" % (type, mac))
                virsh.attach_interface(
                    vm_name, "--type %s --source %s"
                    " --config" % (iface_type, iface_name))
                vm.start()
                try:
                    # Test if guest can be login
                    vm.wait_for_login()
                except remote.LoginError:
                    raise error.TestFail("Cannot login guest with %s" %
                                         iface_name)

        # Step 6
        # Dumpxml for interface
        xml = virsh.iface_dumpxml(iface_name, "", to_file="", debug=True)
        logging.debug("Interface '%s' XML:\n%s", iface_name, xml)

        # Step 7
        # Get interface MAC address by name
        result = virsh.iface_mac(iface_name, debug=True)
        libvirt.check_exit_status(result, status_error)
        if not status_error and result.stdout.strip():
            if not libvirt.check_iface(iface_name, "mac",
                                       result.stdout.strip()):
                raise error.TestFail("Mac address check fail")

        # Step 8
        # Get interface name by MAC address
        # Bridge's Mac equal to bridged interface's mac
        if iface_type not in ("bridge", "vlan") and result.stdout.strip():
            iface_mac = net_iface.get_mac()
            result = virsh.iface_name(iface_mac, debug=True)
            libvirt.check_exit_status(result, status_error)

        # Step 9
        if not use_exist_iface:
            # Step 9.1
            # Destroy interface
            result = virsh.iface_destroy(iface_name, debug=True)
            if not net_restart and\
               iface_type == "ethernet" and iface_pro in ["", "dhcp"] or\
               iface_type == "bridge" and iface_pro == "dhcp":
                libvirt.check_exit_status(result, True)
            else:
                libvirt.check_exit_status(result, status_error)

            # Step 9.2
            # Undefine interface
            result = virsh.iface_undefine(iface_name, debug=True)
            libvirt.check_exit_status(result, status_error)
            list_option = "--all"
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("%s is still present." % iface_name)
    finally:
        if os.path.exists(iface_xml):
            os.remove(iface_xml)
        if os.path.exists(iface_script):
            os.remove(iface_script)

        if use_exist_iface:
            if not os.path.exists(iface_script):
                utils.run("mv %s %s" % (iface_script_bk, iface_script))
            if iface_is_up and\
               not libvirt.check_iface(iface_name, "exists", ""):
                # Need reload script
                utils.run("ifup %s" % iface_name)
            elif not iface_is_up and libvirt.check_iface(
                    iface_name, "exists", ""):
                net_iface.down()
            if vm:
                xml_bak.sync()
        else:
            if libvirt.check_iface(iface_name, "exists", "--all"):
                # Remove the interface
                try:
                    utils_net.bring_down_ifname(iface_name)
                except utils_net.TAPBringDownError:
                    pass
            if iface_type == "bridge":
                if iface_name in net_bridge.list_br():
                    try:
                        net_bridge.del_bridge(iface_name)
                    except IOError:
                        pass
        if NM_is_running:
            NM_service.start()
def run(test, params, env):
    """
    Test virsh nwfilter-binding-list

    1)Prepare parameters
    2)Run nwfilter_binding_list command
    3)check result
    4)Clean env
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    status_error = "yes" == params.get("status_error")
    new_filter_1 = params.get("newfilter_1")
    new_filter_2 = params.get("newfilter_2")
    time_wait = params.get("time_wait", 10)
    option = params.get("option")
    vmxml_backup = libvirt_xml.vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    # prepare vm filterrfer parameters dict list
    filter_param_list_1 = []
    params_key_1 = []
    filter_param_list_2 = []
    params_key_2 = []
    for i in params.keys():
        if 'parameters_name_' in i:
            params_key_1.append(i)
    params_key_1.sort()
    for i in range(len(params_key_1)):
        params_dict = {}
        params_dict['name'] = params[params_key_1[i]]
        params_dict['value'] = params['parameters_value_%s' % i]
        filter_param_list_1.append(params_dict)
    filterref_dict_1 = {}
    filterref_dict_1['name'] = new_filter_1
    filterref_dict_1['parameters'] = filter_param_list_1

    for i in params.keys():
        if 'parameters_dhcp_' in i:
            params_key_2.append(i)
    params_key_2.sort()
    for i in range(len(params_key_2)):
        params_dict = {}
        params_dict['name'] = params[params_key_2[i]]
        params_dict['value'] = params['dhcp_value_%s' % i]
        filter_param_list_2.append(params_dict)
    filterref_dict_2 = {}
    filterref_dict_2['name'] = new_filter_2
    filterref_dict_2['parameters'] = filter_param_list_2

    def env_setting(filterref_dict_1, filterref_dict_2):
        ret = virsh.attach_interface(vm_name, option)
        utlv.check_exit_status(ret, status_error)
        vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name)
        devices = vmxml.get_devices('interface')
        iface_xml = devices[0]
        logging.debug("iface_xml : %s" % iface_xml)
        iface_xml_2 = devices[1]
        vmxml.del_device(iface_xml)
        vmxml.del_device(iface_xml_2)
        new_iface_1 = interface.Interface('network')
        logging.debug("new_iface_1 : %s" % new_iface_1)
        new_iface_2 = interface.Interface('network')
        new_iface_1.xml = iface_xml.xml
        new_iface_1.type_name = "network"
        logging.debug("new_iface_1 : %s" % new_iface_1)
        new_iface_2.xml = iface_xml_2.xml

        new_iface_1.source = {'network': "default"}
        new_filterref = new_iface_1.new_filterref(**filterref_dict_1)
        new_iface_1.filterref = new_filterref
        new_filterref = new_iface_2.new_filterref(**filterref_dict_2)
        new_iface_2.filterref = new_filterref
        logging.debug("new interface xml is: %s \n %s" %
                      (new_iface_1, new_iface_2))
        vmxml.add_device(new_iface_1)
        vmxml.add_device(new_iface_2)
        vmxml.sync()
        return new_iface_1, new_iface_2

    def attach_new_device():
        newnet_iface = interface.Interface('network')
        newnet_iface.source = {'network': "default"}
        filterref_dict = {}
        filterref_list = [{'name': "CTRL_IP_LEARNING", 'value': "dhcp"}]
        filterref_dict['name'] = "clean-traffic"
        filterref_dict['parameters'] = filterref_list
        newnet_iface.filterref = newnet_iface.new_filterref(**filterref_dict)
        ret = virsh.attach_device(domainarg=vm_name,
                                  filearg=newnet_iface.xml,
                                  debug=True)
        utlv.check_exit_status(ret, status_error)

    try:
        # set env of start vm
        new_iface_1, new_iface_2 = env_setting(filterref_dict_1,
                                               filterref_dict_2)
        # start vm
        virsh.start(vm_name, debug=True)
        # list binding port dev
        ret = virsh.nwfilter_binding_list(debug=True)
        utlv.check_exit_status(ret, status_error)
        # detach a interface
        option = "--type network" + " --mac " + new_iface_1.mac_address
        time.sleep(time_wait)
        ret = virsh.detach_interface(vm_name, option, debug=True)
        utlv.check_exit_status(ret, status_error)
        ret = virsh.nwfilter_binding_list(debug=True)
        utlv.check_exit_status(ret, status_error)

        # update_device
        vnet1_iface = interface.Interface('network')
        vnet1_iface.xml = new_iface_2.xml
        target = {'dev': "vnet1"}
        vnet1_iface.target = target
        virsh.update_device(domainarg=vm_name,
                            filearg=vnet1_iface.xml,
                            debug=True)
        ret = virsh.nwfilter_binding_list(debug=True)
        utlv.check_exit_status(ret, status_error)

        # attach new interface
        attach_new_device()
        ret = virsh.nwfilter_binding_list(debug=True)
        utlv.check_exit_status(ret, status_error)

    finally:
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#9
0
def run(test, params, env):
    """
    Test bridge support from network

    1) create a linux bridge and connect a physical interface to it
    2) define nwfilter with "vdsm-no-mac-spoofing"
    3) redefine the vm with the new create bridge and filter
    4) check if guest can get public ip after vm start
    5) check if guest and host can ping each other
    6) check if guest and host can ping outside
    7) start another vm connected to the same bridge
    8) check if the 2 guests can ping each other
    """
    def create_bridge(br_name, iface_name):
        """
        Create a linux bridge by virsh cmd:
        1. Stop NetworkManager and Start network service
        2. virsh iface-bridge <iface> <name> [--no-stp]

        :param br_name: bridge name
        :param iface_name: physical interface name
        :return: bridge created or raise exception
        """
        # Make sure the bridge not exist
        if libvirt.check_iface(br_name, "exists", "--all"):
            test.cancel("The bridge %s already exist" % br_name)

        # Create bridge
        utils_package.package_install('tmux')
        cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \
              ' ip link set {1} master {0}; ip link set {0} up;' \
              ' pkill dhclient; sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name)
        process.run(cmd, shell=True, verbose=True)

    def create_bridge_network(br_name, net_name):
        """
        Define and start the bridge type network
        """
        # check if network with the same name already exists
        output_all = virsh.net_list("--all").stdout.strip()
        if re.search(net_name, output_all):
            test.cancel("Network with the same name already exists!")
        test_xml = network_xml.NetworkXML(network_name="%s" % net_name)
        test_xml.forward = {"mode": "bridge"}
        test_xml.bridge = {"name": br_name}
        test_xml.create()

    def define_nwfilter(filter_name):
        """
        Define nwfilter vdsm-no-mac-spoofing with content like:
        <filter name='vdsm-no-mac-spoofing' chain='root'>
            <filterref filter='no-mac-spoofing'/>
            <filterref filter='no-arp-mac-spoofing'/>
        </filter>

        :param filter_name: the name of nwfilter
        :return: filter created or raise exception
        """
        filter_uuid = params.get("filter_uuid",
                                 "11111111-b071-6127-b4ec-111111111111")
        filter_params = {
            "filter_name": "vdsm-no-mac-spoofing",
            "filter_chain": "root",
            "filter_uuid": filter_uuid,
            "filterref_name_1": "no-mac-spoofing",
            "filterref_name_2": "no-arp-mac-spoofing"
        }
        filter_xml = libvirt.create_nwfilter_xml(filter_params).xml
        # Run command
        result = virsh.nwfilter_define(filter_xml,
                                       ignore_status=True,
                                       debug=True)
        if result.exit_status:
            test.fail("Failed to define nwfilter with %s" % filter_xml)

    def ping(src_ip, dest_ip, ping_count, timeout, session=None):
        """
        Wrap of ping

        :param src_ip: source address
        :param dest_ip: destination address
        :param ping_count: count of icmp packet
        :param timeout: timeout for the ping command
        :param session: local execution or session to execute the ping command
        :return: ping succeed or raise exception
        """
        status, output = utils_net.ping(dest=dest_ip,
                                        count=ping_count,
                                        interface=src_ip,
                                        timeout=timeout,
                                        session=session,
                                        force_ipv4=True)
        if status:
            test.fail("Fail to ping %s from %s" % (dest_ip, src_ip))

    def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session,
                            host_ip, remote_url, endpoint_ip):
        # make sure host network works well
        # host ping remote url
        ping(host_ip, remote_url, ping_count, ping_timeout)
        # host ping guest
        ping(host_ip, guest_ip, ping_count, ping_timeout)
        # guest ping host
        ping(guest_ip,
             host_ip,
             ping_count,
             ping_timeout,
             session=guest_session)
        # guest ping remote url
        ping(guest_ip,
             remote_url,
             ping_count,
             ping_timeout,
             session=guest_session)
        # guest ping endpoint
        ping(guest_ip,
             endpoint_ip,
             ping_count,
             ping_timeout,
             session=guest_session)

    # Get test params
    bridge_name = params.get("bridge_name", "test_br0")
    filter_name = params.get("filter_name", "vdsm-no-mac-spoofing")
    ping_count = params.get("ping_count", "5")
    ping_timeout = float(params.get("ping_timeout", "10"))
    iface_name = utils_net.get_net_if(state="UP")[0]
    bridge_script = NETWORK_SCRIPT + bridge_name
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(),
                                   "iface-%s.bk" % iface_name)
    attach_interface = "yes" == params.get("attach_interface", "no")
    iface_model = params.get("iface_model", "virtio")
    iface_source = eval(params.get("iface_source", "{'bridge':'test_br0'}"))
    iface_type = params.get("iface_type", None)
    iface_target = params.get("iface_target", "br_target")
    iface_alias = params.get("iface_alias", None)
    hotplug = "yes" == params.get("hotplug", "no")
    iface_driver = params.get("iface_driver", None)
    start_vm2 = "yes" == params.get("start_vm2", "no")
    create_network = "yes" == params.get("create_network", "no")
    update_device = "yes" == params.get("update_with_diff_type", "no")

    vms = params.get("vms").split()
    if len(vms) <= 1:
        test.cancel("Need two VMs to test")
    else:
        vm1_name = vms[0]
        vm2_name = vms[1]

    vm1 = env.get_vm(vm1_name)
    vm2 = env.get_vm(vm2_name)

    # Back up the interface script
    process.run("cp %s %s" % (iface_script, iface_script_bk),
                shell=True,
                verbose=True)
    # Back up vm xml
    vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name)
    vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name)

    # Stop NetworkManager service
    NM_service = service.Factory.create_service("NetworkManager")
    NM_status = NM_service.status()
    if not NM_status:
        NM_service.start()
    mac = utils_net.generate_mac_address_simple()

    try:
        create_bridge(bridge_name, iface_name)
        define_nwfilter(filter_name)
        if hotplug:
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            # delete the original interface on the vm before hot-plug
            if vm1.is_alive():
                vm1.destroy()
            vmxml = vm_xml.VMXML.new_from_dumpxml(vm1_name)
            iface_xml = vmxml.get_devices('interface')[0]
            logging.debug("Delete the original interface")
            vmxml.del_device(iface_xml)
            vmxml.sync()
            vm1.start()
            # do hot-plug
            if attach_interface:
                logging.info("Try to hot-plug interface")
                options = (
                    "%s %s --model %s --mac %s" %
                    (iface_type, iface_source['bridge'], iface_model, mac))
                ret = virsh.attach_interface(vm1_name,
                                             options,
                                             ignore_status=True)
            else:
                logging.info("Try to hot-plug device")
                if create_network:
                    create_bridge_network(bridge_name, iface_source["network"])
                target = str({'dev': iface_target})
                iface_alias = str({'name': iface_alias})
                vm_iface_source = str(iface_source)
                iface_params = {
                    "type": iface_type,
                    "source": vm_iface_source,
                    "filter": filter_name,
                    "mac": mac,
                    'alias': iface_alias,
                    'target': target,
                    'model': iface_model,
                    'driver': iface_driver
                }
                attach_xml = interface.Interface(iface_params['type'])
                attach_xml.xml = libvirt.modify_vm_iface(
                    vm1_name, 'get_xml', iface_params)
                ret = virsh.attach_device(vm1_name,
                                          attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                if any([msg in ret.stderr for msg in err_msgs]):
                    test.error("No more pci slots, can't attach more devices")
                else:
                    test.fail("Failed to attach-interface: %s" %
                              ret.stderr.strip())
            else:
                logging.debug("Hot-plug interface or device pass")
                if update_device:
                    # As the interface type will change to actual type "bridge" in live xml, we need to ensure
                    # the update with original "network" type will not fail.
                    # Try to delete the nwfilter with original type in iface_params
                    update_xml = interface.Interface(iface_type)
                    iface_params_update = {
                        "del_filter": "yes",
                        "type": "network",
                        "source": vm_iface_source
                    }
                    update_xml.xml = libvirt.modify_vm_iface(
                        vm1_name, 'get_xml', iface_params_update)
                    ret = virsh.update_device(vm1_name,
                                              update_xml.xml,
                                              ignore_status=True,
                                              debug=True)
                    libvirt.check_exit_status(ret)

        else:
            vm_iface_source = str(iface_source)
            vm1_iface_params = {
                "type": "bridge",
                "source": vm_iface_source,
                "filter": filter_name,
                "mac": mac,
                'driver': iface_driver,
                "iface_model": iface_model
            }
            libvirt.modify_vm_iface(vm1_name, "update_iface", vm1_iface_params)

            if vm1.is_alive():
                vm1.destroy()

            vm1.start()
        # apply ip address as it may not be initialized
        session1 = session2 = None
        session1 = vm1.wait_for_serial_login()
        utils_net.restart_guest_network(session1)
        output = session1.cmd_output("ifconfig || ip a")
        logging.debug("guest1 ip info %s" % output)

        # Check guest's network function
        host_ip = utils_net.get_ip_address_by_interface(bridge_name)
        remote_url = params.get("remote_ip", "www.google.com")

        try:
            vm1_ip = utils_net.get_guest_ip_addr(session1, mac)
        except Exception as errs:
            test.fail("vm1 can't get IP with the new create bridge: %s" % errs)
        if hotplug:
            # reboot vm1 then check network function to ensure the interface still there and works fine
            logging.info("reboot the vm")
            virsh.reboot(vm1)
            if session1 is None:
                session1 = vm1.wait_for_serial_login()
            ping(vm1_ip,
                 remote_url,
                 ping_count,
                 ping_timeout,
                 session=session1)
            # restart libvirtd service then check the interface still works fine
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()
            vm1.cleanup_serial_console()
            vm1.create_serial_console()
            session1 = vm1.wait_for_serial_login()
            ping(vm1_ip,
                 remote_url,
                 ping_count,
                 ping_timeout,
                 session=session1)
            logging.info(
                "after reboot and restart libvirtd, the network works fine")
            if iface_driver:
                try:
                    driver_dict = eval(iface_driver)
                    if session1 is None:
                        session1 = vm1.wait_for_serial_login()
                    guest_iface_info = session1.cmd_output("ip l").strip()
                    guest_iface_name = re.findall(
                        r"^\d+: (\S+?)[@:].*state UP.*$", guest_iface_info,
                        re.MULTILINE)[0]
                    comb_size = driver_dict.get('queues')
                    rx_size = driver_dict.get('rx_queue_size')
                    session1.cmd_status("ethtool -L %s combined %s" %
                                        (guest_iface_name, comb_size))
                    ret, outp = session1.cmd_status_output("ethtool -l %s" %
                                                           guest_iface_name)
                    logging.debug("ethtool cmd output:%s" % outp)
                    if not ret:
                        pre_comb = re.search(
                            "Pre-set maximums:[\s\S]*?Combined:.*?(\d+)",
                            outp).group(1)
                        cur_comb = re.search(
                            "Current hardware settings:[\s\S]*?Combined:.*?(\d+)",
                            outp).group(1)
                        if int(pre_comb) != int(comb_size) or int(
                                cur_comb) != int(comb_size):
                            test.fail(
                                "Fail to check the combined size: setting: %s,"
                                "Pre-set: %s, Current-set: %s" %
                                (comb_size, pre_comb, cur_comb))
                        else:
                            logging.info(
                                "Getting correct Pre-set and Current set value"
                            )
                    else:
                        test.error("ethtool list fail: %s" % outp)
                    # as tx_queue size is only supported for vhost-user interface, only check rx_queue size
                    ret1, outp1 = session1.cmd_status_output("ethtool -g %s" %
                                                             guest_iface_name)
                    logging.debug("guest queue size setting is %s" % outp1)
                    if not ret1:
                        pre_set = re.search(r"Pre-set maximums:\s*RX:\s*(\d+)",
                                            outp1).group(1)
                        cur_set = re.search(
                            r"Current hardware settings:\s*RX:\s*(\d+)",
                            outp1).group(1)
                        if int(pre_set) != int(rx_size) or int(cur_set) != int(
                                rx_size):
                            test.fail("Fail to check the rx_queue_size!")
                except Exception as errs:
                    test.fail("fail to get driver info")
            # hot-unplug interface/device
            if attach_interface:
                ret = virsh.detach_interface(vm1_name,
                                             "bridge",
                                             ignore_status=True)
            else:
                ret = virsh.detach_device(vm1_name,
                                          attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                test.fail("Hot-unplug interface/device fail")
            else:
                logging.info("hot-unplug interface/device succeed")

        else:
            if start_vm2:
                # Start vm2 connect to the same bridge
                mac2 = utils_net.generate_mac_address_simple()
                vm2_iface_params = {
                    "type": "bridge",
                    "source": vm_iface_source,
                    "filter": filter_name,
                    "mac": mac2
                }
                libvirt.modify_vm_iface(vm2_name, "update_iface",
                                        vm2_iface_params)
                if vm2.is_alive():
                    vm2.destroy()
                vm2.start()

                # Check if vm1 and vm2 can ping each other
                try:
                    utils_net.update_mac_ip_address(vm2, timeout=120)
                    vm2_ip = vm2.get_address()
                except Exception as errs:
                    test.fail(
                        "vm2 can't get IP with the new create bridge: %s" %
                        errs)
                session2 = vm2.wait_for_login()
                # make sure guest has got ip address
                utils_net.restart_guest_network(session2)
                output2 = session2.cmd_output("ifconfig || ip a")
                logging.debug("guest ip info %s" % output2)
                # check 2 guests' network functions
                check_net_functions(vm1_ip, ping_count, ping_timeout, session1,
                                    host_ip, remote_url, vm2_ip)
                check_net_functions(vm2_ip, ping_count, ping_timeout, session2,
                                    host_ip, remote_url, vm1_ip)

    finally:
        logging.debug("Start to restore")
        vm1_xml_bak.sync()
        vm2_xml_bak.sync()
        virsh.nwfilter_undefine(filter_name, ignore_status=True)
        if libvirt.check_iface(bridge_name, "exists", "--all"):
            virsh.iface_unbridge(bridge_name, timeout=60, debug=True)
        if os.path.exists(iface_script_bk):
            process.run("mv %s %s" % (iface_script_bk, iface_script),
                        shell=True,
                        verbose=True)
        if os.path.exists(bridge_script):
            process.run("rm -rf %s" % bridge_script, shell=True, verbose=True)
        cmd = 'tmux -c "ip link set {1} nomaster;  ip link delete {0};' \
              'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name)
        process.run(cmd, shell=True, verbose=True)
        # reload network configuration
        NM_service.restart()
        # recover NetworkManager
        if NM_status is True:
            NM_service.start()
        if 'network' in iface_source and iface_source[
                "network"] in virsh.net_state_dict():
            virsh.net_destroy(iface_source["network"], ignore_status=False)
def run_virsh_attach_detach_interface(test, params, env):
    """
    Test virsh {at|de}tach-interface command.

    1) Prepare test environment and its parameters
    2) Attach the required interface
    3) According test type(only attach or both attach and detach):
       a.Go on to test detach(if attaching is correct)
       b.Return GOOD or raise TestFail(if attaching is wrong)
    4) Check if attached interface is correct:
       a.Try to catch it in vm's XML file
       b.Try to catch it in vm
    5) Detach the attached interface
    6) Check result
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    # Test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    vm_ref = params.get("at_detach_iface_vm_ref", "domname")
    options_suffix = params.get("at_detach_iface_options_suffix", "")
    status_error = "yes" == params.get("status_error", "no")
    start_vm = params.get("start_vm")
    # Should attach must be pass for detach test.
    correct_attach = "yes" == params.get("correct_attach", "no")

    # Interface specific attributes.
    iface_type = params.get("at_detach_iface_type", "network")
    iface_source = params.get("at_detach_iface_source", "default")
    iface_mac = params.get("at_detach_iface_mac", "created")
    virsh_dargs = {'ignore_status': True, 'uri': uri}

    # Get a bridge name for test if iface_type is bridge.
    # If there is no bridge other than virbr0, raise TestNAError
    if iface_type == "bridge":
        host_bridge = utils_net.Bridge()
        bridge_list = host_bridge.list_br()
        try:
            bridge_list.remove("virbr0")
        except AttributeError:
            pass  # If no virbr0, just pass is ok
        logging.debug("Useful bridges:%s", bridge_list)
        # just choosing one bridge on host.
        if len(bridge_list):
            iface_source = bridge_list[0]
        else:
            raise error.TestNAError("No useful bridge on host "
                                    "other than 'virbr0'.")

    dom_uuid = vm.get_uuid()
    dom_id = vm.get_id()

    # To confirm vm's state
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # Test both detach and attach, So collect info
    # both of them for result check.
    # When something wrong with interface, set it to 1
    fail_flag = 0
    result_info = []

    # Set attach-interface domain
    if vm_ref == "domname":
        vm_ref = vm_name
    elif vm_ref == "domid":
        vm_ref = dom_id
    elif vm_ref == "domuuid":
        vm_ref = dom_uuid
    elif vm_ref == "hexdomid" and dom_id is not None:
        vm_ref = hex(int(dom_id))

    # Get a mac address if iface_mac is 'created'.
    if iface_mac == "created" or correct_attach:
        iface_mac = utils_net.generate_mac_address_simple()

    # Set attach-interface options and Start attach-interface test
    if correct_attach:
        options = set_options("network", "default", iface_mac, "", "attach")
        attach_result = virsh.attach_interface(vm_name, options, **virsh_dargs)
    else:
        options = set_options(iface_type, iface_source, iface_mac,
                              options_suffix, "attach")
        attach_result = virsh.attach_interface(vm_ref, options, **virsh_dargs)
    attach_status = attach_result.exit_status
    logging.debug(attach_result)

    # If attach interface failed.
    if attach_status:
        if not status_error:
            fail_flag = 1
            result_info.append("Attach Failed: %s" % attach_result)
        elif status_error:
            # Here we just use it to exit, do not mean test failed
            fail_flag = 1
    # If attach interface succeeded.
    else:
        if status_error and not correct_attach:
            fail_flag = 1
            result_info.append("Attach Success with wrong command.")

    if fail_flag and start_vm == "yes":
        vm.destroy()
        if len(result_info):
            raise error.TestFail(result_info)
        else:
            # Exit because it is error_test for attach-interface.
            return

    # Check dumpxml file whether the interface is added successfully.
    status, ret = check_dumpxml_iface(vm_name, iface_mac, iface_type,
                                      iface_source)
    if status:
        fail_flag = 1
        result_info.append(ret)

    # Login to domain to check new interface.
    if not vm.is_alive():
        vm.start()
    elif vm.state() == "paused":
        vm.resume()

    status, ret = login_to_check(vm, iface_mac)
    if status:
        fail_flag = 1
        result_info.append(ret)

    # Set detach-interface options
    options = set_options(iface_type, None, iface_mac, options_suffix,
                          "detach")

    # Start detach-interface test
    detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs)
    detach_status = detach_result.exit_status

    logging.debug(detach_result)

    # Clean up.
    if check_dumpxml_iface(vm_name, iface_mac) is not None:
        cleanup_options = "--type %s --mac %s" % (iface_type, iface_mac)
        virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs)

    # Shutdown vm to be afraid of cleaning up failed
    if vm.is_alive():
        vm.destroy()

    # Check results.
    if status_error:
        if detach_status == 0:
            raise error.TestFail("Detach Success with wrong command.")
    else:
        if detach_status != 0:
            raise error.TestFail("Detach Failed.")
        else:
            if fail_flag:
                raise error.TestFail("Attach-Detach Success but "
                                     "something wrong with its "
                                     "functional use:%s" % result_info)
示例#11
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    status_error = "yes" == params.get("status_error", "no")

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source", "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    if vm.is_alive():
        time.sleep(20)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if attach_device:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name,
                                              iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s" %
                                               attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-device")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_obj.xml,
                                                  flagstr=attach_option,
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({
                            'mac': mac,
                            'iface_xml': iface_xml_obj
                        })
                # Need sleep here for attachment take effect
                time.sleep(5)
            elif attach_iface:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name,
                                                 options,
                                                 ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s" %
                                               attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-interface")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        ret = virsh.attach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac})
                # Need sleep here for attachment take effect
                time.sleep(5)

            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                vm.cleanup_serial_console()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login()

            # Check if interface was attached
            for iface in iface_list:
                if iface.has_key('mac'):
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(
                        vm_name, iface['mac'])
                    if not if_attr:
                        raise error.TestFail("Can't see interface "
                                             " in dumpxml")
                    if (if_attr['type'] != iface_type
                            or if_attr['source'] != iface_source['network']):
                        raise error.TestFail("Interface attribute doesn't"
                                             " match attachment opitons")
                    # Check interface on guest
                    if not utils_net.get_linux_ifname(session, iface['mac']):
                        raise error.TestFail("Can't see interface" " on guest")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if iface.has_key('iface_xml'):
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" % (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if iface.has_key('mac'):
                        # Check interface in dumpxml output
                        if vm_xml.VMXML.get_iface_by_mac(
                                vm_name, iface['mac']):
                            raise error.TestFail("Interface still exist"
                                                 " after detachment")
            session.close()
        except virt_vm.VMStartError, e:
            logging.info(str(e))
            raise error.TestFail('VM Failed to start for some reason!')

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
def run_virsh_attach_detach_interface(test, params, env):
    """
    Test virsh {at|de}tach-interface command.

    1) Prepare test environment and its parameters
    2) Attach the required interface
    3) According test type(only attach or both attach and detach):
       a.Go on to test detach(if attaching is correct)
       b.Return GOOD or raise TestFail(if attaching is wrong)
    4) Check if attached interface is correct:
       a.Try to catch it in vm's XML file
       b.Try to catch it in vm
    5) Detach the attached interface
    6) Check result
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    # Test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    vm_ref = params.get("at_detach_iface_vm_ref", "domname")
    options_suffix = params.get("at_detach_iface_options_suffix", "")
    status_error = "yes" == params.get("status_error", "no")
    start_vm = params.get("start_vm")
    # Should attach must be pass for detach test.
    correct_attach = "yes" == params.get("correct_attach", "no")

    # Interface specific attributes.
    iface_type = params.get("at_detach_iface_type", "network")
    iface_source = params.get("at_detach_iface_source", "default")
    iface_mac = params.get("at_detach_iface_mac", "created")
    virsh_dargs = {'ignore_status': True, 'uri': uri}

    # Get a bridge name for test if iface_type is bridge.
    # If there is no bridge other than virbr0, raise TestNAError
    if iface_type == "bridge":
        host_bridge = utils_net.Bridge()
        bridge_list = host_bridge.list_br()
        try:
            bridge_list.remove("virbr0")
        except AttributeError:
            pass  # If no virbr0, just pass is ok
        logging.debug("Useful bridges:%s", bridge_list)
        # just choosing one bridge on host.
        if len(bridge_list):
            iface_source = bridge_list[0]
        else:
            raise error.TestNAError("No useful bridge on host "
                                    "other than 'virbr0'.")

    dom_uuid = vm.get_uuid()
    dom_id = vm.get_id()

    # To confirm vm's state
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # Test both detach and attach, So collect info
    # both of them for result check.
    # When something wrong with interface, set it to 1
    fail_flag = 0
    result_info = []

    # Set attach-interface domain
    if vm_ref == "domname":
        vm_ref = vm_name
    elif vm_ref == "domid":
        vm_ref = dom_id
    elif vm_ref == "domuuid":
        vm_ref = dom_uuid
    elif vm_ref == "hexdomid" and dom_id is not None:
        vm_ref = hex(int(dom_id))

    # Get a mac address if iface_mac is 'created'.
    if iface_mac == "created" or correct_attach:
        iface_mac = utils_net.generate_mac_address_simple()

    # Set attach-interface options and Start attach-interface test
    if correct_attach:
        options = set_options("network", "default", iface_mac, "", "attach")
        attach_result = virsh.attach_interface(vm_name, options,
                                               **virsh_dargs)
    else:
        options = set_options(iface_type, iface_source, iface_mac,
                              options_suffix, "attach")
        attach_result = virsh.attach_interface(vm_ref, options, **virsh_dargs)
    attach_status = attach_result.exit_status
    logging.debug(attach_result)

    # If attach interface failed.
    if attach_status:
        if not status_error:
            fail_flag = 1
            result_info.append("Attach Failed: %s" % attach_result)
        elif status_error:
            # Here we just use it to exit, do not mean test failed
            fail_flag = 1
    # If attach interface succeeded.
    else:
        if status_error and not correct_attach:
            fail_flag = 1
            result_info.append("Attach Success with wrong command.")

    if fail_flag and start_vm == "yes":
        vm.destroy()
        if len(result_info):
            raise error.TestFail(result_info)
        else:
            # Exit because it is error_test for attach-interface.
            return

    # Check dumpxml file whether the interface is added successfully.
    status, ret = check_dumpxml_iface(
        vm_name, iface_mac, iface_type, iface_source)
    if status:
        fail_flag = 1
        result_info.append(ret)

    # Login to domain to check new interface.
    if not vm.is_alive():
        vm.start()
    elif vm.state() == "paused":
        vm.resume()

    status, ret = login_to_check(vm, iface_mac)
    if status:
        fail_flag = 1
        result_info.append(ret)

    # Set detach-interface options
    options = set_options(iface_type, None, iface_mac,
                          options_suffix, "detach")

    # Start detach-interface test
    detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs)
    detach_status = detach_result.exit_status

    logging.debug(detach_result)

    # Clean up.
    if check_dumpxml_iface(vm_name, iface_mac) is not None:
        cleanup_options = "--type %s --mac %s" % (iface_type, iface_mac)
        virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs)

    # Shutdown vm to be afraid of cleaning up failed
    if vm.is_alive():
        vm.destroy()

    # Check results.
    if status_error:
        if detach_status == 0:
            raise error.TestFail("Detach Success with wrong command.")
    else:
        if detach_status != 0:
            raise error.TestFail("Detach Failed.")
        else:
            if fail_flag:
                raise error.TestFail("Attach-Detach Success but "
                                     "something wrong with its "
                                     "functional use:%s" % result_info)
示例#13
0
     vm_cmd(cmd)
 if checkpoint == 'sync_ntp':
     logging.info('Sync time with %s', ntp_server)
     cmd = ['yum -y install ntpdate',
            'ntpdate %s' % ntp_server]
     vm_cmd(cmd)
 if checkpoint == 'blank_2nd_disk':
     disk_path = os.path.join(data_dir.get_tmp_dir(), 'blank.img')
     logging.info('Create blank disk %s', disk_path)
     process.run('truncate -s 1G %s' % disk_path)
     logging.info('Attach blank disk to vm')
     attach_removable_media('disk', disk_path, 'vdc')
     logging.debug(virsh.dumpxml(vm_name))
 if checkpoint in ['only_net', 'only_br']:
     logging.info('Detatch all networks')
     virsh.detach_interface(vm_name, 'network --current', debug=True)
     logging.info('Detatch all bridges')
     virsh.detach_interface(vm_name, 'bridge --current', debug=True)
 if checkpoint == 'only_net':
     logging.info('Attach network')
     virsh.attach_interface(vm_name, 'network default --current', debug=True)
     v2v_params.pop('bridge')
 if checkpoint == 'only_br':
     logging.info('Attatch bridge')
     virsh.attach_interface(vm_name, 'bridge virbr0 --current', debug=True)
     v2v_params.pop('network')
 if checkpoint == 'no_libguestfs_backend':
     os.environ.pop('LIBGUESTFS_BACKEND')
 if checkpoint == 'file_image':
     vm = env.get_vm(vm_name)
     disk = vm.get_first_disk_devices()
示例#14
0
    def vm_stress_events(self, event, vm, params):
        """
        Stress events

        :param event: event name
        :param vm: vm object
        """
        current_vcpu = int(params.get("smp", 2))
        max_vcpu = int(params.get("vcpu_maxcpus", 2))
        iface_num = params.get("iface_num", '1')
        iface_type = params.get("iface_type", "network")
        iface_model = params.get("iface_model", "virtio")
        iface_source = eval(params.get("iface_source",
                                       "{'network':'default'}"))
        attach_option = params.get("attach_option", "")
        detach_option = params.get("detach_option", "")
        disk_size = params.get("virt_disk_device_size", "1")
        disk_type = params.get("disk_type", "file")
        disk_device = params.get("disk_device", "disk")
        disk_format = params.get("disk_format", "qcow2")
        device_target = params.get("virt_disk_device_target", "vda").split()
        path = params.get("path", "")
        device_source_names = params.get("virt_disk_device_source", "").split()
        disk_driver = params.get("driver_name", "qemu")
        self.ignore_status = params.get("ignore_status", "no") == "yes"
        dargs = {'ignore_status': True, 'debug': True}
        for itr in range(self.iterations):
            if "vcpupin" in event:
                for vcpu in range(current_vcpu):
                    result = virsh.vcpupin(vm.name, vcpu,
                                           random.choice(self.host_cpu_list),
                                           **dargs)
                    if not self.ignore_status:
                        libvirt.check_exit_status(result)
            elif "emulatorpin" in event:
                result = virsh.emulatorpin(vm.name,
                                           random.choice(self.host_cpu_list),
                                           **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
            elif "suspend" in event:
                result = virsh.suspend(vm.name, **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                time.sleep(self.event_sleep_time)
                result = virsh.resume(vm.name, **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
            elif "cpuhotplug" in event:
                result = virsh.setvcpus(vm.name, max_vcpu, "--live", **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                    exp_vcpu = {
                        'max_config': max_vcpu,
                        'max_live': max_vcpu,
                        'cur_config': current_vcpu,
                        'cur_live': max_vcpu,
                        'guest_live': max_vcpu
                    }
                    utils_hotplug.check_vcpu_value(vm,
                                                   exp_vcpu,
                                                   option="--live")
                time.sleep(self.event_sleep_time)
                result = virsh.setvcpus(vm.name, current_vcpu, "--live",
                                        **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                    exp_vcpu = {
                        'max_config': max_vcpu,
                        'max_live': max_vcpu,
                        'cur_config': current_vcpu,
                        'cur_live': current_vcpu,
                        'guest_live': current_vcpu
                    }
                    utils_hotplug.check_vcpu_value(vm,
                                                   exp_vcpu,
                                                   option="--live")
            elif "reboot" in event:
                vm.reboot()
            elif "nethotplug" in event:
                for iface_num in range(int(iface_num)):
                    logging.debug("Try to attach interface %d" % iface_num)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    logging.debug(
                        "VM name: %s , Options for Network attach: %s",
                        vm.name, options)
                    ret = virsh.attach_interface(vm.name,
                                                 options,
                                                 ignore_status=True)
                    time.sleep(self.event_sleep_time)
                    if not self.ignore_status:
                        libvirt.check_exit_status(ret)
                    if detach_option:
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        logging.debug(
                            "VM name: %s , Options for Network detach: %s",
                            vm.name, options)
                        ret = virsh.detach_interface(vm.name,
                                                     options,
                                                     ignore_status=True)
                        if not self.ignore_status:
                            libvirt.check_exit_status(ret)
            elif "diskhotplug" in event:
                for disk_num in range(len(device_source_names)):
                    disk = {}
                    disk_attach_error = False
                    disk_name = os.path.join(path, vm.name,
                                             device_source_names[disk_num])
                    device_source = libvirt.create_local_disk(
                        disk_type,
                        disk_name,
                        disk_size,
                        disk_format=disk_format)
                    disk.update({
                        "format": disk_format,
                        "source": device_source
                    })
                    disk_xml = Disk(disk_type)
                    disk_xml.device = disk_device
                    disk_xml.driver = {
                        "name": disk_driver,
                        "type": disk_format
                    }
                    ret = virsh.attach_disk(vm.name,
                                            disk["source"],
                                            device_target[disk_num],
                                            attach_option,
                                            debug=True)
                    if not self.ignore_status:
                        libvirt.check_exit_status(ret, disk_attach_error)
                    if detach_option:
                        ret = virsh.detach_disk(vm.name,
                                                device_target[disk_num],
                                                extra=detach_option)
                        if not self.ignore_status:
                            libvirt.check_exit_status(ret)
                        libvirt.delete_local_disk(disk_type, disk_name)
            else:
                raise NotImplementedError
            time.sleep(self.itr_sleep_time)
示例#15
0
def run(test, params, env):
    """
    convert specific kvm guest to rhev
    """
    for v in list(params.values()):
        if "V2V_EXAMPLE" in v:
            test.cancel("Please set real value for %s" % v)
    if utils_v2v.V2V_EXEC is None:
        raise ValueError('Missing command: virt-v2v')
    hypervisor = params.get("hypervisor")
    vm_name = params.get('main_vm', 'EXAMPLE')
    target = params.get('target')
    remote_host = params.get('remote_host', 'EXAMPLE')
    input_mode = params.get("input_mode")
    output_mode = params.get('output_mode')
    output_format = params.get('output_format')
    source_user = params.get("username", "root")
    storage = params.get('output_storage')
    storage_name = params.get('storage_name')
    bridge = params.get('bridge')
    network = params.get('network')
    ntp_server = params.get('ntp_server')
    vpx_dc = params.get("vpx_dc")
    esx_ip = params.get("esx_hostname")
    address_cache = env.get('address_cache')
    pool_name = params.get('pool_name', 'v2v_test')
    pool_type = params.get('pool_type', 'dir')
    pool_target = params.get('pool_target_path', 'v2v_pool')
    pvt = utlv.PoolVolumeTest(test, params)
    v2v_opts = params.get('v2v_opts', '-v -x')
    v2v_timeout = int(params.get('v2v_timeout', 3600))
    skip_check = 'yes' == params.get('skip_check', 'no')
    status_error = 'yes' == params.get('status_error', 'no')
    checkpoint = params.get('checkpoint', '')
    debug_kernel = 'debug_kernel' == checkpoint
    backup_list = ['floppy', 'floppy_devmap', 'fstab_cdrom',
                   'sata_disk', 'network_rtl8139', 'network_e1000',
                   'spice', 'spice_encrypt', 'spice_qxl',
                   'spice_cirrus', 'vnc_qxl', 'vnc_cirrus', 'blank_2nd_disk',
                   'listen_none', 'listen_socket', 'only_net', 'only_br']
    error_list = []

    # Prepare step for different hypervisor
    if hypervisor == "esx":
        source_ip = params.get("vpx_hostname")
        source_pwd = params.get("vpx_password")
        vpx_passwd_file = params.get("vpx_passwd_file")
        # Create password file to access ESX hypervisor
        with open(vpx_passwd_file, 'w') as f:
            f.write(source_pwd)
    elif hypervisor == "xen":
        source_ip = params.get("xen_hostname")
        source_pwd = params.get("xen_host_passwd")
        # Set up ssh access using ssh-agent and authorized_keys
        ssh_key.setup_ssh_key(source_ip, source_user, source_pwd)
        try:
            utils_misc.add_identities_into_ssh_agent()
        except Exception as e:
            process.run("ssh-agent -k")
            test.error("Fail to setup ssh-agent \n %s" % str(e))
    elif hypervisor == "kvm":
        source_ip = None
        source_pwd = None
    else:
        test.cancel("Unspported hypervisor: %s" % hypervisor)

    # Create libvirt URI
    v2v_uri = utils_v2v.Uri(hypervisor)
    remote_uri = v2v_uri.get_uri(source_ip, vpx_dc, esx_ip)
    logging.debug("libvirt URI for converting: %s", remote_uri)

    # Make sure the VM exist before convert
    v2v_virsh = None
    close_virsh = False
    if hypervisor == 'kvm':
        v2v_virsh = virsh
    else:
        virsh_dargs = {'uri': remote_uri,
                       'remote_ip': source_ip,
                       'remote_user': source_user,
                       'remote_pwd': source_pwd,
                       'debug': True}
        v2v_virsh = virsh.VirshPersistent(**virsh_dargs)
        close_virsh = True
    if not v2v_virsh.domain_exists(vm_name):
        test.error("VM '%s' not exist" % vm_name)

    def log_fail(msg):
        """
        Log error and update error list
        """
        logging.error(msg)
        error_list.append(msg)

    def vm_shell(func):
        """
        Decorator of shell session to vm
        """

        def wrapper(*args, **kwargs):
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_dead():
                logging.info('VM is down. Starting it now.')
                vm.start()
            session = vm.wait_for_login()
            kwargs['session'] = session
            kwargs['vm'] = vm
            func(*args, **kwargs)
            if session:
                session.close()
            vm.shutdown()

        return wrapper

    def check_disks(vmcheck):
        """
        Check disk counts inside the VM
        """
        # Initialize windows boot up
        os_type = params.get("os_type", "linux")
        expected_disks = int(params.get("ori_disks", "1"))
        logging.debug("Expect %s disks im VM after convert", expected_disks)
        # Get disk counts
        if os_type == "linux":
            cmd = "lsblk |grep disk |wc -l"
            disks = int(vmcheck.session.cmd(cmd).strip())
        else:
            cmd = r"echo list disk > C:\list_disk.txt"
            vmcheck.session.cmd(cmd)
            cmd = r"diskpart /s C:\list_disk.txt"
            output = vmcheck.session.cmd(cmd).strip()
            logging.debug("Disks in VM: %s", output)
            disks = len(re.findall('Disk\s\d', output))
        logging.debug("Find %s disks in VM after convert", disks)
        if disks == expected_disks:
            logging.info("Disk counts is expected")
        else:
            log_fail("Disk counts is wrong")

    def check_vmlinuz_initramfs(v2v_output):
        """
        Check if vmlinuz matches initramfs on multi-kernel case
        """
        logging.debug('Checking if vmlinuz matches initramfs')
        kernel_strs = re.findall('(\* kernel.*?\/boot\/config){1,}', v2v_output, re.DOTALL)
        if len(kernel_strs) == 0:
            test.error("Not find kernel information")

        # Remove duplicate items by set
        logging.debug('Boots and kernel info: %s' % set(kernel_strs))
        for str_i in set(kernel_strs):
            # Fine all versions
            kernel_vers = re.findall('((?:\d+\.){1,}\d+-(?:\d+\.){1,}\w+)', str_i)
            logging.debug('kernel related versions: %s' % kernel_vers)
            # kernel_vers = [kernel, vmlinuz, initramfs] and they should be same
            if len(kernel_vers) < 3 or len(set(kernel_vers)) != 1:
                log_fail("kernel versions does not match: %s" % kernel_vers)

    def check_boot_kernel(vmcheck):
        """
        Check if converted vm use the latest kernel
        """
        _, current_kernel = vmcheck.run_cmd('uname -r')

        if 'debug' in current_kernel:
            log_fail('Current kernel is a debug kernel: %s' % current_kernel)

        # 'sort -V' can satisfy our testing, even though it's not strictly perfect.
        # The last one is always the latest kernel version
        kernel_normal_list = vmcheck.run_cmd('rpm -q kernel | sort -V')[1].strip().splitlines()
        status, kernel_debug = vmcheck.run_cmd('rpm -q kernel-debug')
        if status != 0:
            test.error('Not found kernel-debug package')
        all_kernel_list = kernel_normal_list + kernel_debug.strip().splitlines()
        logging.debug('All kernels: %s' % all_kernel_list)
        if len(all_kernel_list) < 3:
            test.error('Needs at least 2 normal kernels and 1 debug kernel in VM')

        # The latest non-debug kernel must be kernel_normal_list[-1]
        if current_kernel.strip() != kernel_normal_list[-1].lstrip('kernel-'):
            log_fail('Check boot kernel failed')

    def check_floppy_exist(vmcheck):
        """
        Check if floppy exists after convertion
        """
        blk = vmcheck.session.cmd('lsblk')
        logging.info(blk)
        if not re.search('fd0', blk):
            log_fail('Floppy not found')

    def attach_removable_media(type, source, dev):
        bus = {'cdrom': 'ide', 'floppy': 'fdc', 'disk': 'virtio'}
        args = {'driver': 'qemu', 'subdriver': 'raw', 'sourcetype': 'file',
                'type': type, 'targetbus': bus[type]}
        if type == 'cdrom':
            args.update({'mode': 'readonly'})
        config = ''
        # Join all options together to get command line
        for key in list(args.keys()):
            config += ' --%s %s' % (key, args[key])
        config += ' --current'
        virsh.attach_disk(vm_name, source, dev, extra=config)

    def change_disk_bus(dest):
        """
        Change all disks' bus type to $dest
        """
        bus_list = ['ide', 'sata', 'virtio']
        if dest not in bus_list:
            test.error('Bus type not support')
        dev_prefix = ['h', 's', 'v']
        dev_table = dict(list(zip(bus_list, dev_prefix)))
        logging.info('Change disk bus to %s' % dest)
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        disks = vmxml.get_disk_all()
        index = 0
        for disk in list(disks.values()):
            if disk.get('device') != 'disk':
                continue
            target = disk.find('target')
            target.set('bus', dest)
            target.set('dev', dev_table[dest] + 'd' + string.ascii_lowercase[index])
            disk.remove(disk.find('address'))
            index += 1
        vmxml.sync()

    def change_network_model(model):
        """
        Change network model to $model
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        network_list = vmxml.get_iface_all()
        for node in list(network_list.values()):
            if node.get('type') == 'network':
                node.find('model').set('type', model)
        vmxml.sync()

    def attach_network_card(model):
        """
        Attach network card based on model
        """
        if model not in ('e1000', 'virtio', 'rtl8139'):
            test.error('Network model not support')
        options = {'type': 'network', 'source': 'default', 'model': model}
        line = ''
        for key in options:
            line += ' --' + key + ' ' + options[key]
        line += ' --current'
        logging.debug(virsh.attach_interface(vm_name, option=line))

    def check_multi_netcards(mac_list, virsh_instance):
        """
        Check if number and type of network cards meet expectation
        """
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
            vm_name, virsh_instance=virsh_instance)
        iflist = vmxml.get_iface_all()
        logging.debug('MAC list before v2v: %s' % mac_list)
        logging.debug('MAC list after  v2v: %s' % list(iflist.keys()))
        if set(mac_list).difference(list(iflist.keys())):
            log_fail('Missing network interface')
        for mac in iflist:
            if iflist[mac].find('model').get('type') != 'virtio':
                log_fail('Network not convert to virtio')

    @vm_shell
    def insert_floppy_devicemap(**kwargs):
        """
        Add an entry of floppy to device.map
        """
        session = kwargs['session']
        line = '(fd0)     /dev/fd0'
        devmap = '/boot/grub/device.map'
        if session.cmd_status('ls %s' % devmap):
            devmap = '/boot/grub2/device.map'
        cmd_exist = 'grep \'(fd0)\' %s' % devmap
        cmd_set = 'sed -i \'2i%s\' %s' % (line, devmap)
        if session.cmd_status(cmd_exist):
            session.cmd(cmd_set)

    def make_label(session):
        """
        Label a volume, swap or root volume
        """
        # swaplabel for rhel7 with xfs, e2label for rhel6 or ext*
        cmd_map = {'root': 'e2label %s ROOT',
                   'swap': 'swaplabel -L SWAPPER %s'}
        if not session.cmd_status('swaplabel --help'):
            blk = 'swap'
        elif not session.cmd_status('which e2label'):
            blk = 'root'
        else:
            test.error('No tool to make label')
        entry = session.cmd('blkid|grep %s' % blk).strip()
        path = entry.split()[0].strip(':')
        cmd_label = cmd_map[blk] % path
        if 'LABEL' not in entry:
            session.cmd(cmd_label)
        return blk

    @vm_shell
    def specify_fstab_entry(type, **kwargs):
        """
        Specify entry in fstab file
        """
        type_list = ['cdrom', 'uuid', 'label', 'sr0', 'invalid']
        if type not in type_list:
            test.error('Not support %s in fstab' % type)
        session = kwargs['session']
        # Specify cdrom device
        if type == 'cdrom':
            line = '/dev/cdrom /media/CDROM auto exec'
            if 'grub2' in utils_misc.get_bootloader_cfg(session):
                line += ',nofail'
            line += ' 0 0'
            logging.debug('fstab entry is "%s"', line)
            cmd = [
                'mkdir -p /media/CDROM',
                'mount /dev/cdrom /media/CDROM',
                'echo "%s" >> /etc/fstab' % line
            ]
            for i in range(len(cmd)):
                session.cmd(cmd[i])
        elif type == 'sr0':
            line = params.get('fstab_content')
            session.cmd('echo "%s" >> /etc/fstab' % line)
        elif type == 'invalid':
            line = utils_misc.generate_random_string(6)
            session.cmd('echo "%s" >> /etc/fstab' % line)
        else:
            map = {'uuid': 'UUID', 'label': 'LABEL'}
            logging.info(type)
            if session.cmd_status('cat /etc/fstab|grep %s' % map[type]):
                # Specify device by UUID
                if type == 'uuid':
                    entry = session.cmd(
                        'blkid -s UUID|grep swap').strip().split()
                    # Replace path for UUID
                    origin = entry[0].strip(':')
                    replace = entry[1].replace('"', '')
                # Specify device by label
                elif type == 'label':
                    blk = make_label(session)
                    entry = session.cmd('blkid|grep %s' % blk).strip()
                    # Remove " from LABEL="****"
                    replace = entry.split()[1].strip().replace('"', '')
                    # Replace the original id/path with label
                    origin = entry.split()[0].strip(':')
                cmd_fstab = "sed -i 's|%s|%s|' /etc/fstab" % (origin, replace)
                session.cmd(cmd_fstab)
        fstab = session.cmd_output('cat /etc/fstab')
        logging.debug('Content of /etc/fstab:\n%s', fstab)

    def create_large_file(session, left_space):
        """
        Create a large file to make left space of root less than $left_space MB
        """
        cmd_df = "df -m / --output=avail"
        df_output = session.cmd(cmd_df).strip()
        logging.debug('Command output: %s', df_output)
        avail = int(df_output.strip().split('\n')[-1])
        logging.info('Available space: %dM' % avail)
        if avail > left_space - 1:
            tmp_dir = data_dir.get_tmp_dir()
            if session.cmd_status('ls %s' % tmp_dir) != 0:
                session.cmd('mkdir %s' % tmp_dir)
            large_file = os.path.join(tmp_dir, 'file.large')
            cmd_create = 'dd if=/dev/zero of=%s bs=1M count=%d' % \
                         (large_file, avail - left_space + 2)
            session.cmd(cmd_create, timeout=v2v_timeout)
        logging.info('Available space: %sM' % session.cmd(cmd_df).strip())

    @vm_shell
    def corrupt_rpmdb(**kwargs):
        """
        Corrupt rpm db
        """
        session = kwargs['session']
        # If __db.* exist, remove them, then touch _db.001 to corrupt db.
        if not session.cmd_status('ls /var/lib/rpm/__db.001'):
            session.cmd('rm -f /var/lib/rpm/__db.*')
        session.cmd('touch /var/lib/rpm/__db.001')
        if not session.cmd_status('yum update'):
            test.error('Corrupt rpmdb failed')

    @vm_shell
    def grub_serial_terminal(**kwargs):
        """
        Edit the serial and terminal lines of grub.conf
        """
        session = kwargs['session']
        vm = kwargs['vm']
        grub_file = utils_misc.get_bootloader_cfg(session)
        if 'grub2' in grub_file:
            test.cancel('Skip this case on grub2')
        cmd = "sed -i '1iserial -unit=0 -speed=115200\\n"
        cmd += "terminal -timeout=10 serial console' %s" % grub_file
        session.cmd(cmd)

    @vm_shell
    def set_selinux(value, **kwargs):
        """
        Set selinux stat of guest
        """
        session = kwargs['session']
        current_stat = session.cmd_output('getenforce').strip()
        logging.debug('Current selinux status: %s', current_stat)
        if current_stat != value:
            cmd = "sed -E -i 's/(^SELINUX=).*?/\\1%s/' /etc/selinux/config" % value
            logging.info('Set selinux stat with command %s', cmd)
            session.cmd(cmd)

    @vm_shell
    def get_firewalld_status(**kwargs):
        """
        Return firewalld service status of vm
        """
        session = kwargs['session']
        # Example: Active: active (running) since Fri 2019-03-15 01:03:39 CST; 3min 48s ago
        firewalld_status = session.cmd('systemctl status firewalld.service|grep Active:',
                                       ok_status=[0, 3]).strip()
        # Exclude the time string because time changes if vm restarts
        firewalld_status = re.search('Active:\s\w*\s\(\w*\)', firewalld_status).group()
        logging.info('Status of firewalld: %s', firewalld_status)
        params[checkpoint] = firewalld_status

    def check_firewalld_status(vmcheck, expect_status):
        """
        Check if status of firewalld meets expectation
        """
        firewalld_status = vmcheck.session.cmd('systemctl status '
                                               'firewalld.service|grep Active:',
                                               ok_status=[0, 3]).strip()
        # Exclude the time string because time changes if vm restarts
        firewalld_status = re.search('Active:\s\w*\s\(\w*\)', firewalld_status).group()
        logging.info('Status of firewalld after v2v: %s', firewalld_status)
        if firewalld_status != expect_status:
            log_fail('Status of firewalld changed after conversion')

    @vm_shell
    def vm_cmd(cmd_list, **kwargs):
        """
        Excecute a list of commands on guest.
        """
        session = kwargs['session']
        for cmd in cmd_list:
            logging.info('Send command "%s"', cmd)
            # 'chronyc waitsync' needs more than 2mins to sync clock,
            # We set timeout to 300s will not have side-effects for other
            # commands.
            status, output = session.cmd_status_output(cmd, timeout=300)
            logging.debug('Command output:\n%s', output)
            if status != 0:
                test.error('Command "%s" failed' % cmd)
        logging.info('All commands executed')

    def check_time_keep(vmcheck):
        """
        Check time drift after convertion.
        """
        logging.info('Check time drift')
        output = vmcheck.session.cmd('chronyc tracking')
        logging.debug(output)
        if 'Not synchronised' in output:
            log_fail('Time not synchronised')
        lst_offset = re.search('Last offset *?: *(.*) ', output).group(1)
        drift = abs(float(lst_offset))
        logging.debug('Time drift is: %f', drift)
        if drift > 3:
            log_fail('Time drift exceeds 3 sec')

    def check_boot():
        """
        Check if guest can boot up after configuration
        """
        try:
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_alive():
                vm.shutdown()
            logging.info('Booting up %s' % vm_name)
            vm.start()
            vm.wait_for_login()
            vm.shutdown()
            logging.info('%s is down' % vm_name)
        except Exception as e:
            test.error('Bootup guest and login failed: %s', str(e))

    def check_result(result, status_error):
        """
        Check virt-v2v command result
        """
        utlv.check_exit_status(result, status_error)
        output = result.stdout + result.stderr
        if skip_check:
            logging.info('Skip checking vm after conversion')
        elif not status_error:
            if output_mode == 'rhev':
                if not utils_v2v.import_vm_to_ovirt(params, address_cache,
                                                    timeout=v2v_timeout):
                    test.fail('Import VM failed')
            if output_mode == 'libvirt':
                try:
                    virsh.start(vm_name, debug=True, ignore_status=False)
                except Exception as e:
                    test.fail('Start vm failed: %s' % str(e))
            # Check guest following the checkpoint document after convertion
            vmchecker = VMChecker(test, params, env)
            params['vmchecker'] = vmchecker
            if params.get('skip_check') != 'yes':
                ret = vmchecker.run()
                if len(ret) == 0:
                    logging.info("All common checkpoints passed")
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=vmchecker.virsh_instance)
            logging.debug(vmxml)
            if checkpoint == 'multi_kernel':
                check_boot_kernel(vmchecker.checker)
                check_vmlinuz_initramfs(output)
            if checkpoint == 'floppy':
                # Convert to rhv will remove all removeable devices(floppy, cdrom)
                if output_mode in ['local', 'libvirt']:
                    check_floppy_exist(vmchecker.checker)
            if checkpoint == 'multi_disks':
                check_disks(vmchecker.checker)
            if checkpoint == 'multi_netcards':
                check_multi_netcards(params['mac_address'],
                                     vmchecker.virsh_instance)
            if checkpoint.startswith(('spice', 'vnc')):
                if checkpoint == 'spice_encrypt':
                    vmchecker.check_graphics(params[checkpoint])
                else:
                    graph_type = checkpoint.split('_')[0]
                    vmchecker.check_graphics({'type': graph_type})
                    video_type = vmxml.get_devices('video')[0].model_type
                    if video_type.lower() != 'qxl':
                        log_fail('Video expect QXL, actual %s' % video_type)
            if checkpoint.startswith('listen'):
                listen_type = vmxml.get_devices('graphics')[0].listen_type
                logging.info('listen type is: %s', listen_type)
                if listen_type != checkpoint.split('_')[-1]:
                    log_fail('listen type changed after conversion')
            if checkpoint.startswith('selinux'):
                status = vmchecker.checker.session.cmd(
                    'getenforce').strip().lower()
                logging.info('Selinux status after v2v:%s', status)
                if status != checkpoint[8:]:
                    log_fail('Selinux status not match')
            if checkpoint == 'guest_firewalld_status':
                check_firewalld_status(vmchecker.checker, params[checkpoint])
            if checkpoint in ['ntpd_on', 'sync_ntp']:
                check_time_keep(vmchecker.checker)
            # Merge 2 error lists
            error_list.extend(vmchecker.errors)
        log_check = utils_v2v.check_log(params, output)
        if log_check:
            log_fail(log_check)
        if len(error_list):
            test.fail('%d checkpoints failed: %s' %
                      (len(error_list), error_list))

    try:
        v2v_params = {
            'target': target,
            'hypervisor': hypervisor,
            'main_vm': vm_name,
            'input_mode': input_mode,
            'network': network,
            'bridge': bridge,
            'storage': storage,
            'hostname': source_ip,
            'v2v_opts': v2v_opts,
            'new_name': vm_name + utils_misc.generate_random_string(3)}
        if vpx_dc:
            v2v_params.update({"vpx_dc": vpx_dc})
        if esx_ip:
            v2v_params.update({"esx_ip": esx_ip})
        output_format = params.get('output_format')
        if output_format:
            v2v_params.update({'output_format': output_format})
        # Build rhev related options
        if output_mode == 'rhev':
            # Create different sasl_user name for different job
            params.update({'sasl_user': params.get("sasl_user") +
                           utils_misc.generate_random_string(3)})
            logging.info('sals user name is %s' % params.get("sasl_user"))

            # Create SASL user on the ovirt host
            user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"),
                                           params.get("sasl_pwd"))
            v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd)
            v2v_sasl.server_ip = params.get("remote_ip")
            v2v_sasl.server_user = params.get('remote_user')
            v2v_sasl.server_pwd = params.get('remote_pwd')
            v2v_sasl.setup(remote=True)
        if output_mode == 'local':
            v2v_params['storage'] = data_dir.get_tmp_dir()
        if output_mode == 'libvirt':
            pvt.pre_pool(pool_name, pool_type, pool_target, '')
        # Set libguestfs environment variable
        os.environ['LIBGUESTFS_BACKEND'] = 'direct'

        # Save origin graphic type for result checking if source is KVM
        if hypervisor == 'kvm':
            ori_vm_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            params['ori_graphic'] = ori_vm_xml.xmltreefile.find(
                'devices').find('graphics').get('type')

        backup_xml = None
        # Only kvm guest's xml needs to be backup currently
        if checkpoint in backup_list and hypervisor == 'kvm':
            backup_xml = ori_vm_xml
        if checkpoint == 'multi_disks':
            new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=v2v_virsh)
            disk_count = 0
            for disk in list(new_xml.get_disk_all().values()):
                if disk.get('device') == 'disk':
                    disk_count += 1
            if disk_count <= 1:
                test.error('Not enough disk devices')
            params['ori_disks'] = disk_count
        if checkpoint == 'sata_disk':
            change_disk_bus('sata')
        if checkpoint.startswith('floppy'):
            img_path = data_dir.get_tmp_dir() + '/floppy.img'
            utlv.create_local_disk('floppy', img_path)
            attach_removable_media('floppy', img_path, 'fda')
            if checkpoint == 'floppy_devmap':
                insert_floppy_devicemap()
        if checkpoint.startswith('fstab'):
            if checkpoint == 'fstab_cdrom':
                img_path = data_dir.get_tmp_dir() + '/cdrom.iso'
                utlv.create_local_disk('iso', img_path)
                attach_removable_media('cdrom', img_path, 'hdc')
            specify_fstab_entry(checkpoint[6:])
        if checkpoint == 'running':
            virsh.start(vm_name)
            logging.info('VM state: %s' %
                         virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'paused':
            virsh.start(vm_name, '--paused')
            logging.info('VM state: %s' %
                         virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'serial_terminal':
            grub_serial_terminal()
            check_boot()
        if checkpoint == 'no_space':
            @vm_shell
            def take_space(**kwargs):
                create_large_file(kwargs['session'], 20)
            take_space()
        if checkpoint.startswith('host_no_space'):
            session = aexpect.ShellSession('sh')
            create_large_file(session, 1000)
            if checkpoint == 'host_no_space_setcache':
                logging.info('Set LIBGUESTFS_CACHEDIR=/home')
                os.environ['LIBGUESTFS_CACHEDIR'] = '/home'
        if checkpoint == 'corrupt_rpmdb':
            corrupt_rpmdb()
        if checkpoint.startswith('network'):
            change_network_model(checkpoint[8:])
        if checkpoint == 'multi_netcards':
            params['mac_address'] = []
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=v2v_virsh)
            network_list = vmxml.get_iface_all()
            for mac in network_list:
                if network_list[mac].get('type') in ['bridge', 'network']:
                    params['mac_address'].append(mac)
            if len(params['mac_address']) < 2:
                test.error('Not enough network interface')
            logging.debug('MAC address: %s' % params['mac_address'])
        if checkpoint.startswith(('spice', 'vnc')):
            if checkpoint == 'spice_encrypt':
                spice_passwd = {'type': 'spice',
                                'passwd': params.get('spice_passwd', 'redhat')}
                vm_xml.VMXML.set_graphics_attr(vm_name, spice_passwd)
                params[checkpoint] = {'type': 'spice',
                                      'passwdValidTo': '1970-01-01T00:00:01'}
            else:
                graphic_video = checkpoint.split('_')
                graphic = graphic_video[0]
                logging.info('Set graphic type to %s', graphic)
                vm_xml.VMXML.set_graphics_attr(vm_name, {'type': graphic})
                if len(graphic_video) > 1:
                    video_type = graphic_video[1]
                    logging.info('Set video type to %s', video_type)
                    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
                    video = vmxml.xmltreefile.find(
                        'devices').find('video').find('model')
                    video.set('type', video_type)
                    # cirrus doesn't support 'ram' and 'vgamem' attribute
                    if video_type == 'cirrus':
                        [video.attrib.pop(attr_i) for attr_i in [
                            'ram', 'vgamem'] if attr_i in video.attrib]
                    vmxml.sync()
        if checkpoint.startswith('listen'):
            listen_type = checkpoint.split('_')[-1]
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            listen = vmxml.xmltreefile.find(
                'devices').find('graphics').find('listen')
            listen.set('type', listen_type)
            vmxml.sync()
        if checkpoint == 'host_selinux_on':
            params['selinux_stat'] = utils_selinux.get_status()
            utils_selinux.set_status('enforcing')
        if checkpoint.startswith('selinux'):
            set_selinux(checkpoint[8:])
        if checkpoint.startswith('host_firewalld'):
            service_mgr = service.ServiceManager()
            logging.info('Backing up firewall services status')
            params['bk_firewalld_status'] = service_mgr.status('firewalld')
            if 'start' in checkpoint:
                service_mgr.start('firewalld')
            if 'stop' in checkpoint:
                service_mgr.stop('firewalld')
        if checkpoint == 'guest_firewalld_status':
            get_firewalld_status()
        if checkpoint == 'remove_securetty':
            logging.info('Remove /etc/securetty file from guest')
            cmd = ['rm -f /etc/securetty']
            vm_cmd(cmd)
        if checkpoint == 'ntpd_on':
            logging.info('Set service chronyd on')
            cmd = ['yum -y install chrony',
                   'systemctl start chronyd',
                   'chronyc add server %s' % ntp_server]
            vm_cmd(cmd)
        if checkpoint == 'sync_ntp':
            logging.info('Sync time with %s', ntp_server)
            cmd = ['yum -y install chrony',
                   'systemctl start chronyd',
                   'chronyc add server %s' % ntp_server,
                   'chronyc waitsync']
            vm_cmd(cmd)
        if checkpoint == 'blank_2nd_disk':
            disk_path = os.path.join(data_dir.get_tmp_dir(), 'blank.img')
            logging.info('Create blank disk %s', disk_path)
            process.run('truncate -s 1G %s' % disk_path)
            logging.info('Attach blank disk to vm')
            attach_removable_media('disk', disk_path, 'vdc')
            logging.debug(virsh.dumpxml(vm_name))
        if checkpoint in ['only_net', 'only_br']:
            logging.info('Detatch all networks')
            virsh.detach_interface(vm_name, 'network --current', debug=True)
            logging.info('Detatch all bridges')
            virsh.detach_interface(vm_name, 'bridge --current', debug=True)
        if checkpoint == 'only_net':
            logging.info('Attach network')
            virsh.attach_interface(
                vm_name, 'network default --current', debug=True)
            v2v_params.pop('bridge')
        if checkpoint == 'only_br':
            logging.info('Attatch bridge')
            virsh.attach_interface(
                vm_name, 'bridge virbr0 --current', debug=True)
            v2v_params.pop('network')
        if checkpoint == 'no_libguestfs_backend':
            os.environ.pop('LIBGUESTFS_BACKEND')
        if checkpoint == 'file_image':
            vm = env.get_vm(vm_name)
            disk = vm.get_first_disk_devices()
            logging.info('Disk type is %s', disk['type'])
            if disk['type'] != 'file':
                test.error('Guest is not with file image')
        v2v_result = utils_v2v.v2v_cmd(v2v_params)
        if v2v_params.get('new_name'):
            vm_name = params['main_vm'] = v2v_params['new_name']
        check_result(v2v_result, status_error)
    finally:
        if close_virsh:
            v2v_virsh.close_session()
        if params.get('vmchecker'):
            params['vmchecker'].cleanup()
        if output_mode == 'libvirt':
            pvt.cleanup_pool(pool_name, pool_type, pool_target, '')
        if backup_xml:
            backup_xml.sync()
        if params.get('selinux_stat') and params['selinux_stat'] != 'disabled':
            utils_selinux.set_status(params['selinux_stat'])
        if 'bk_firewalld_status' in params:
            service_mgr = service.ServiceManager()
            if service_mgr.status('firewalld') != params['bk_firewalld_status']:
                if params['bk_firewalld_status']:
                    service_mgr.start('firewalld')
                else:
                    service_mgr.stop('firewalld')
        if checkpoint.startswith('host_no_space'):
            large_file = os.path.join(data_dir.get_tmp_dir(), 'file.large')
            if os.path.isfile(large_file):
                os.remove(large_file)
        # Cleanup constant files
        utils_v2v.cleanup_constant_files(params)
示例#16
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    status_error = "yes" == params.get("status_error", "no")

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source",
                                   "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd",
                                           "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    if not status_error:
        if attach_device and attach_option:
            check_cmds.append(('attach-device', attach_option))
        if attach_iface and attach_option:
            check_cmds.append(('attach-interface', attach_option))
        if (detach_device or stress_test_detach_device) and detach_option:
            check_cmds.append(('detach-device', detach_option))
        if stress_test_detach_interface and detach_option:
            check_cmds.append(('detach-device', detach_option))
    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if attach_device:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            test.cancel(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            test.fail("Failed to attach-device")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac,
                                           'iface_xml': iface_xml_obj})
            elif attach_iface:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name, options,
                                                 ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            test.cancel(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            test.fail("Failed to attach-interface")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac})

            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                vm.cleanup_serial_console()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # Check if interface was attached
            for iface in iface_list:
                if 'mac' in iface:
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                            iface['mac'])
                    if not if_attr:
                        test.fail("Can't see interface in dumpxml")
                    if (if_attr['type'] != iface_type or
                            if_attr['source'] != iface_source['network']):
                        test.fail("Interface attribute doesn't"
                                  " match attachment opitons")
                    # Check interface on guest

                    def get_iface():
                        try:
                            utils_net.get_linux_ifname(session, iface['mac'])
                            return True
                        except Exception:
                            return False
                    if not utils_misc.wait_for(get_iface, timeout=60):
                        test.fail("Can't see interface on guest")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if 'iface_xml' in iface:
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" %
                                   (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if 'mac' in iface:
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                 iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#17
0
def run(test, params, env):
    """
    Test virsh interface related commands.

    (1) If using given exist interface for testing(eg. lo or ethX):
        1.1 Dumpxml for the interface(with --inactive option)
        1.2 Destroy the interface
        1.3 Undefine the interface
    (2) Define an interface from XML file
    (3) List interfaces with '--inactive' option
    (4) Start the interface
    (5) List interfaces with no option
    (6) Dumpxml for the interface
    (7) Get interface MAC address by interface name
    (8) Get interface name by interface MAC address
    (9) Delete interface if not use the exist interface for testing
        9.1 Destroy the interface
        9.2 Undefine the interface

    Caveat, this test may affect the host network, so using the loopback(lo)
    device by default. You can specify the interface which you want, but be
    careful.
    """

    iface_name = params.get("iface_name", "ENTER.BRIDGE.NAME")
    iface_xml = params.get("iface_xml")
    iface_type = params.get("iface_type", "ethernet")
    iface_pro = params.get("iface_pro", "")
    iface_eth = params.get("iface_eth", "")
    iface_tag = params.get("iface_tag", "0")
    if iface_type == "vlan":
        iface_name = iface_eth + "." + iface_tag
    iface_eth_using = "yes" == params.get("iface_eth_using", "no")
    ping_ip = params.get("ping_ip", "localhost")
    use_exist_iface = "yes" == params.get("use_exist_iface", "no")
    status_error = "yes" == params.get("status_error", "no")
    net_restart = "yes" == params.get("iface_net_restart", "no")
    list_dumpxml_acl = "yes" == params.get("list_dumpxml_acl", "no")
    if ping_ip.count("ENTER"):
        test.cancel("Please input a valid ip address")
    if iface_name.count("ENTER"):
        test.cancel("Please input a existing bridge/ethernet name")

    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user', "EXAMPLE")
    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.")

    virsh_dargs = {'debug': True}
    list_dumpxml_dargs = {'debug': True}
    if params.get('setup_libvirt_polkit') == 'yes':
        if not list_dumpxml_acl:
            virsh_dargs['uri'] = uri
            virsh_dargs['unprivileged_user'] = unprivileged_user
        else:
            list_dumpxml_dargs['uri'] = uri
            list_dumpxml_dargs['unprivileged_user'] = unprivileged_user
            list_dumpxml_dargs['ignore_status'] = False

    # acl api negative testing params
    write_save_status_error = "yes" == params.get("write_save_status_error",
                                                  "no")
    start_status_error = "yes" == params.get("start_status_error", "no")
    stop_status_error = "yes" == params.get("stop_status_error", "no")
    delete_status_error = "yes" == params.get("delete_status_error", "no")

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm:
        xml_bak = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(),
                                   "iface-%s.bk" % iface_name)
    net_bridge = utils_net.Bridge()
    if use_exist_iface:
        if iface_type == "bridge":
            if iface_name not in net_bridge.list_br():
                test.error("Bridge '%s' not exists" % iface_name)
            ifaces = net_bridge.get_structure()[iface_name]
            if len(ifaces) < 1:
                # In this situation, dhcp maybe cannot get ip address
                # Unless you use static, we'd better skip such case
                test.cancel("Bridge '%s' has no interface"
                            " bridged, perhaps cannot get"
                            " ipaddress" % iface_name)
    net_iface = utils_net.Interface(name=iface_name)
    iface_is_up = True
    list_option = "--all"
    if use_exist_iface:
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            test.error("Interface '%s' not exists" % iface_name)
        iface_xml = os.path.join(data_dir.get_tmp_dir(), "iface.xml.tmp")
        iface_is_up = net_iface.is_up()
    else:
        # Note, if not use the interface which already exists, iface_name must
        # be equal to the value specified in XML file
        if libvirt.check_iface(iface_name, "exists", "--all"):
            test.error("Interface '%s' already exists" % iface_name)
        if not iface_xml:
            test.error("XML file is needed.")
        iface_xml = os.path.join(data_dir.get_tmp_dir(), iface_xml)
        create_xml_file(iface_xml, params)

    # Stop NetworkManager as which may conflict with virsh iface commands
    try:
        NM = utils_path.find_command("NetworkManager")
    except utils_path.CmdNotFoundError:
        logging.debug("No NetworkManager service.")
        NM = None
    NM_is_running = False
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            NM_service.stop()

    # run test cases
    try:
        if use_exist_iface:
            # back up the interface script
            process.run("cp %s %s" % (iface_script, iface_script_bk),
                        shell=True)
            # step 1.1
            # dumpxml for interface
            if list_dumpxml_acl:
                virsh.iface_list(**list_dumpxml_dargs)
            xml = virsh.iface_dumpxml(iface_name,
                                      "--inactive",
                                      to_file=iface_xml,
                                      **list_dumpxml_dargs)
            # Step 1.2
            # Destroy interface
            if iface_is_up:
                result = virsh.iface_destroy(iface_name, **virsh_dargs)
                if (params.get('setup_libvirt_polkit') == 'yes'
                        and stop_status_error):
                    # acl_test negative test
                    libvirt.check_exit_status(result, stop_status_error)
                    virsh.iface_destroy(iface_name, debug=True)
                else:
                    libvirt.check_exit_status(result, status_error)

            # Step 1.3
            # Undefine interface
            result = virsh.iface_undefine(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes'
                    and delete_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, delete_status_error)
                virsh.iface_undefine(iface_name, debug=True)
            else:
                libvirt.check_exit_status(result, status_error)
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    test.fail("%s is still present." % iface_name)

        # Step 2
        # Define interface
        result = virsh.iface_define(iface_xml, **virsh_dargs)
        if (params.get('setup_libvirt_polkit') == 'yes'
                and write_save_status_error):
            # acl_test negative test
            libvirt.check_exit_status(result, write_save_status_error)
            virsh.iface_define(iface_xml, debug=True)
        elif iface_type == "bond" and not ping_ip:
            libvirt.check_exit_status(result, True)
            return
        else:
            libvirt.check_exit_status(result, status_error)

        if net_restart:
            network = service.Factory.create_service("network")
            network.restart()

        # After network restart, (ethernet)interface will be started
        if (not net_restart and iface_type in ("bridge", "ethernet")) or\
           (not use_exist_iface and iface_type in ("vlan", "bond")):
            # Step 3
            # List inactive interfaces
            list_option = "--inactive"
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    test.fail("Fail to find %s." % iface_name)

            # Step 4
            # Start interface
            result = virsh.iface_start(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes'
                    and start_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, start_status_error)
                virsh.iface_start(iface_name, debug=True)
            elif (not net_restart and not use_exist_iface
                  and (iface_type == "ethernet" and iface_pro in ["", "dhcp"]
                       or iface_type == "bridge" and iface_pro == "dhcp")):
                libvirt.check_exit_status(result, True)
            else:
                libvirt.check_exit_status(result, status_error)
            if not status_error:
                iface_ip = net_iface.get_ip()
                ping_ip = ping_ip if not iface_ip else iface_ip
                if ping_ip:
                    if not libvirt.check_iface(iface_name, "ping", ping_ip):
                        test.fail("Ping %s fail." % ping_ip)

        # Step 5
        # List active interfaces
        if use_exist_iface or\
           (iface_pro != "dhcp" and iface_type == "bridge") or\
           (iface_eth_using and iface_type == "vlan"):
            list_option = ""
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    test.fail("Fail to find %s in active "
                              "interface list" % iface_name)
            if vm:
                if vm.is_alive():
                    vm.destroy()
                iface_index = 0
                iface_mac_list = vm_xml.VMXML.get_iface_dev(vm_name)
                # Before test, detach all interfaces in guest
                for mac in iface_mac_list:
                    iface_info = vm_xml.VMXML.get_iface_by_mac(vm_name, mac)
                    type = iface_info.get('type')
                    virsh.detach_interface(
                        vm_name, "--type %s --mac %s"
                        " --config" % (type, mac))
                    # After detach interface, vm.virtnet also need update, the
                    # easy way is free these mac addresses before start VM
                    vm.free_mac_address(iface_index)
                    iface_index += 1
                virsh.attach_interface(
                    vm_name, "--type %s --source %s"
                    " --config" % (iface_type, iface_name))
                vm.start()
                try:
                    # Test if guest can be login
                    vm.wait_for_login()
                except remote.LoginError:
                    test.fail("Cannot login guest with %s" % iface_name)

        # Step 6
        # Dumpxml for interface
        if list_dumpxml_acl:
            virsh.iface_list(**list_dumpxml_dargs)
        xml = virsh.iface_dumpxml(iface_name,
                                  "",
                                  to_file="",
                                  **list_dumpxml_dargs)
        logging.debug("Interface '%s' XML:\n%s", iface_name, xml)

        # Step 7
        # Get interface MAC address by name
        result = virsh.iface_mac(iface_name, debug=True)
        libvirt.check_exit_status(result, status_error)
        if not status_error and result.stdout.strip():
            if not libvirt.check_iface(iface_name, "mac",
                                       result.stdout.strip()):
                test.fail("Mac address check fail")

        # Step 8
        # Get interface name by MAC address
        # Bridge's Mac equal to bridged interface's mac
        if iface_type not in ("bridge", "vlan") and result.stdout.strip():
            iface_mac = net_iface.get_mac()
            result = virsh.iface_name(iface_mac, debug=True)
            libvirt.check_exit_status(result, status_error)

        # Step 9
        if not use_exist_iface:
            # Step 9.0
            # check if interface's state is active before destroy
            if libvirt.check_iface(iface_name, "state", "--all"):
                # Step 9.1
                # Destroy interface
                result = virsh.iface_destroy(iface_name, **virsh_dargs)
                if (params.get('setup_libvirt_polkit') == 'yes'
                        and stop_status_error):
                    # acl_test negative test
                    libvirt.check_exit_status(result, stop_status_error)
                    virsh.iface_destroy(iface_name, debug=True)
                elif (not net_restart and iface_type == "ethernet"
                      and iface_pro in ["", "dhcp"]
                      or iface_type == "bridge" and iface_pro == "dhcp"):
                    libvirt.check_exit_status(result, True)
                else:
                    libvirt.check_exit_status(result, status_error)

            # Step 9.2
            # Undefine interface
            result = virsh.iface_undefine(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes'
                    and delete_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, delete_status_error)
                virsh.iface_undefine(iface_name, debug=True)
            else:
                libvirt.check_exit_status(result, status_error)
            list_option = "--all"
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    test.fail("%s is still present." % iface_name)
    finally:
        if os.path.exists(iface_xml):
            os.remove(iface_xml)
        if os.path.exists(iface_script):
            os.remove(iface_script)

        if use_exist_iface:
            if not os.path.exists(iface_script):
                process.run("mv %s %s" % (iface_script_bk, iface_script),
                            shell=True)
            if iface_is_up and\
               not libvirt.check_iface(iface_name, "exists", ""):
                # Need reload script
                process.run("ifup %s" % iface_name, shell=True)
            elif not iface_is_up and libvirt.check_iface(
                    iface_name, "exists", ""):
                net_iface.down()
            if vm:
                xml_bak.sync()
        else:
            if libvirt.check_iface(iface_name, "exists", "--all"):
                # Remove the interface
                try:
                    utils_net.bring_down_ifname(iface_name)
                except utils_net.TAPBringDownError:
                    pass
            if iface_type == "bridge":
                if iface_name in net_bridge.list_br():
                    try:
                        net_bridge.del_bridge(iface_name)
                    except IOError:
                        pass
        if NM_is_running:
            NM_service.start()
示例#18
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        if iface_rom:
            iface.rom = eval(iface_rom)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source",
                                   "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    iface_rom = params.get("iface_rom")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd",
                                           "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")
    err_msg_rom = params.get("err_msg_rom")

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True,
                                              debug=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name, options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug("No more pci slots, can't attach more devices")
                        break
                    elif (ret.stderr.count("doesn't support option %s" % attach_option)):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug("option %s is not supported when domain running is %s" % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options and attach_option):
                            test.fail("return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" % attach_option)
                        if not ("--current" in sep_options and len(sep_options) > 1):
                            test.fail("return mutualy exclusive, but it is unexpected")
                    elif err_msg_rom in ret.stderr:
                        logging.debug("Attach failed with expect err msg: %s" % err_msg_rom)
                    else:
                        test.fail("Failed to attach-interface: %s" % ret.stderr.strip())
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        iface_list.append({'mac': mac,
                                           'iface_xml': iface_xml_obj})
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False
            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist, timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                            iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".
                                      format(if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if 'iface_xml' in iface:
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" %
                                   (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if 'mac' in iface:
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                 iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#19
0
def run(test, params, env):
    """
    Test virsh nwfilter-binding-list

    1)Prepare parameters
    2)Run nwfilter_binding_list command
    3)check result
    4)Clean env
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    status_error = "yes" == params.get("status_error")
    new_filter_1 = params.get("newfilter_1")
    new_filter_2 = params.get("newfilter_2")
    time_wait = params.get("time_wait", 10)
    option = params.get("option")
    vmxml_backup = libvirt_xml.vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    # prepare vm filterrfer parameters dict list
    filter_param_list_1 = []
    params_key_1 = []
    filter_param_list_2 = []
    params_key_2 = []
    for i in params.keys():
        if 'parameters_name_' in i:
            params_key_1.append(i)
    params_key_1.sort()
    for i in range(len(params_key_1)):
        params_dict = {}
        params_dict['name'] = params[params_key_1[i]]
        params_dict['value'] = params['parameters_value_%s' % i]
        filter_param_list_1.append(params_dict)
    filterref_dict_1 = {}
    filterref_dict_1['name'] = new_filter_1
    filterref_dict_1['parameters'] = filter_param_list_1

    for i in params.keys():
        if 'parameters_dhcp_' in i:
            params_key_2.append(i)
    params_key_2.sort()
    for i in range(len(params_key_2)):
        params_dict = {}
        params_dict['name'] = params[params_key_2[i]]
        params_dict['value'] = params['dhcp_value_%s' % i]
        filter_param_list_2.append(params_dict)
    filterref_dict_2 = {}
    filterref_dict_2['name'] = new_filter_2
    filterref_dict_2['parameters'] = filter_param_list_2

    utils_package.package_install('libvirt-daemon-config-nwfilter')

    def env_setting(filterref_dict_1, filterref_dict_2):
        ret = virsh.attach_interface(vm_name, option)
        utlv.check_exit_status(ret, status_error)
        vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name)
        devices = vmxml.get_devices('interface')
        iface_xml = devices[0]
        logging.debug("iface_xml : %s" % iface_xml)
        iface_xml_2 = devices[1]
        vmxml.del_device(iface_xml)
        vmxml.del_device(iface_xml_2)
        new_iface_1 = interface.Interface('network')
        logging.debug("new_iface_1 : %s" % new_iface_1)
        new_iface_2 = interface.Interface('network')
        new_iface_1.xml = iface_xml.xml
        new_iface_1.type_name = "network"
        logging.debug("new_iface_1 : %s" % new_iface_1)
        new_iface_2.xml = iface_xml_2.xml

        new_iface_1.source = {'network': "default"}
        new_filterref = new_iface_1.new_filterref(**filterref_dict_1)
        new_iface_1.filterref = new_filterref
        new_filterref = new_iface_2.new_filterref(**filterref_dict_2)
        new_iface_2.filterref = new_filterref
        logging.debug("new interface xml is: %s \n %s" %
                      (new_iface_1, new_iface_2))
        vmxml.add_device(new_iface_1)
        vmxml.add_device(new_iface_2)
        vmxml.sync()
        return new_iface_1, new_iface_2

    def attach_new_device():
        newnet_iface = interface.Interface('network')
        newnet_iface.source = {'network': "default"}
        newnet_iface.model = 'virtio'
        filterref_dict = {}
        filterref_list = [{'name': "CTRL_IP_LEARNING", 'value': "dhcp"}]
        filterref_dict['name'] = "clean-traffic"
        filterref_dict['parameters'] = filterref_list
        newnet_iface.filterref = newnet_iface.new_filterref(**filterref_dict)
        ret = virsh.attach_device(domainarg=vm_name,
                                  filearg=newnet_iface.xml,
                                  debug=True)
        utlv.check_exit_status(ret, status_error)

    try:
        # set env of start vm
        new_iface_1, new_iface_2 = env_setting(filterref_dict_1,
                                               filterref_dict_2)
        # start vm
        virsh.start(vm_name, debug=True)
        # list binding port dev
        logging.debug("check nwfilter binding for 2 interfaces")
        ret = virsh.nwfilter_binding_list(debug=True)
        utlv.check_result(ret, expected_match=[r"vnet\d+\s+clean-traffic"])
        utlv.check_result(ret, expected_match=[r"vnet\d+\s+allow-dhcp-server"])
        # detach a interface
        option = "--type network" + " --mac " + new_iface_1.mac_address
        ret = virsh.detach_interface(vm_name, option, debug=True)
        time.sleep(time_wait)
        utlv.check_exit_status(ret, status_error)
        logging.debug("check nwfilter binding after detach one interface:")
        time.sleep(3)
        ret = virsh.nwfilter_binding_list(debug=True)
        if re.search(r'vnet\d+\s+clean-traffic.*', ret.stdout):
            test.fail(
                "vnet binding clean-traffic still exists after detach the interface!"
            )
        utlv.check_result(ret, expected_match=[r"vnet\d+\s+allow-dhcp-server"])

        # update_device to delete the filter
        iface_dict = {'del_filter': True}
        new_xml = utlv.modify_vm_iface(vm_name, 'get_xml', iface_dict)
        virsh.update_device(domainarg=vm_name, filearg=new_xml, debug=True)
        logging.debug("check nwfilter-binding after delete the only interface")
        ret = virsh.nwfilter_binding_list(debug=True)
        if re.search(r'vnet\d+\s+allow-dhcp-server.*', ret.stdout):
            test.fail(
                "vnet binding allow-dhcp-server still exists after detach the interface!"
            )
        utlv.check_exit_status(ret, status_error)

        # attach new interface
        attach_new_device()
        ret = virsh.nwfilter_binding_list(debug=True)
        logging.debug("Check nwfilter-binding exists after attach device")
        utlv.check_result(ret, expected_match=[r"vnet\d+\s+clean-traffic"])

    finally:
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#20
0
def run(test, params, env):
    """
    Test mtu feature from virtual network
    """
    vm_name = params.get('main_vm')
    vm = env.get_vm(vm_name)
    mtu_type = params.get('mtu_type')
    mtu_size = params.get('mtu_size', '')
    net = params.get('net', DEFAULT_NET)
    net_type = params.get('net_type', '')
    with_iface = 'yes' == params.get('with_iface', 'no')
    with_net = 'yes' == params.get('with_net', 'no')
    status_error = 'yes' == params.get('status_error', 'no')
    check = params.get('check', '')
    error_msg = params.get('error_msg', '')
    bridge_name = 'br_mtu' + utils_misc.generate_random_string(3)
    add_pkg = params.get('add_pkg', '')
    model = params.get('model', 'virtio')

    def set_network(size, net='default'):
        """
        Set mtu size to a certain network
        """
        logging.info('Set mtu size of network "%s" to %s', net, size)
        default_xml = NetworkXML.new_from_net_dumpxml(net)
        default_xml.mtu = size
        default_xml.sync()
        logging.debug(virsh.net_dumpxml(net))

    def set_interface(mtu_size='',
                      source_network='default',
                      iface_type='network',
                      iface_model='virtio'):
        """
        Set mtu size to a certain interface
        """
        interface_type = 'bridge' if iface_type in (
            'bridge', 'openvswitch') else iface_type
        iface_dict = {
            'type': interface_type,
            'source': "{'%s': '%s'}" % (interface_type, source_network),
            'model': iface_model
        }

        if iface_type == 'openvswitch':
            iface_dict.update({'virtualport_type': 'openvswitch'})

        if mtu_size:
            iface_dict.update({'mtu': "{'size': %s}" % mtu_size})

        libvirt.modify_vm_iface(vm_name, 'update_iface', iface_dict)
        logging.debug(virsh.dumpxml(vm_name).stdout)

    def get_default_if():
        """
        Get default interface that is using by vm
        """
        ifaces = utils_net.get_sorted_net_if()
        logging.debug('Interfaces on host: %s', ifaces)
        for iface in ifaces[0]:
            if 'Link detected: yes' in process.run('ethtool %s' %
                                                   iface).stdout_text:
                logging.debug('Found host interface "%s"', iface)
                return iface

    def create_bridge():
        """
        Create a bridge on host for test
        """
        cmd_create_br = 'nmcli con add type bridge con-name %s ifname %s'
        con_name = 'con_' + utils_misc.generate_random_string(3)
        bridge_name = 'br_' + utils_misc.generate_random_string(3)
        process.run(cmd_create_br % (con_name, bridge_name), verbose=True)
        return con_name, bridge_name

    def create_network_xml(name, network_type, base_if='', **kwargs):
        """
        Create a network xml to be defined
        """
        m_net = NetworkXML(name)
        m_net.forward = {'mode': 'bridge'}
        if network_type in ('bridge', 'openvswitch'):
            m_net.bridge = {'name': kwargs['bridge_name']}
        elif network_type == 'macvtap':
            if base_if:
                m_net.forward_interface = [{'dev': base_if}]
        if network_type == 'openvswitch':
            m_net.virtualport_type = 'openvswitch'
        if 'mtu' in kwargs:
            m_net.mtu = kwargs['mtu']
        logging.debug(m_net)
        return m_net.xml

    def create_iface(iface_type, **kwargs):
        """
        Create a interface to be attached to vm
        """
        m_iface = Interface(iface_type)
        m_iface.mac_address = utils_net.generate_mac_address_simple()
        if 'base_if' in kwargs:
            m_iface.source = {'dev': kwargs['base_if'], 'mode': 'vepa'}
        if 'source_net' in kwargs:
            m_iface.source = {'network': kwargs['source_net']}
        if 'mtu' in kwargs:
            m_iface.mtu = {'size': kwargs['mtu']}
        if 'model_net' in kwargs:
            m_iface.model = kwargs['model_net']
        logging.debug(m_iface.get_xml())
        logging.debug(m_iface)
        return m_iface

    def check_mtu(mtu_size, qemu=False):
        """
        Check if mtu meets expectation on host
        """
        error = ''
        live_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_xml = live_vmxml.get_devices('interface')[0]
        logging.debug(iface_xml.target)
        dev = iface_xml.target['dev']
        ifconfig_info = process.run('ifconfig|grep mtu|grep %s' % dev,
                                    shell=True,
                                    verbose=True).stdout_text
        if 'mtu %s' % mtu_size in ifconfig_info:
            logging.info('PASS on ifconfig check for vnet.')
        else:
            error += 'Fail on ifconfig check for vnet.'
        if qemu:
            qemu_mtu_info = process.run('ps aux|grep qemu-kvm',
                                        shell=True,
                                        verbose=True).stdout_text
            if 'host_mtu=%s' % mtu_size in qemu_mtu_info:
                logging.info('PASS on qemu cmd line check.')
            else:
                error += 'Fail on qemu cmd line check.'
        if error:
            test.fail(error)

    def check_mtu_in_vm(fn_login, mtu_size):
        """
        Check if mtu meets expectations in vm
        """
        session = fn_login()
        check_cmd = 'ifconfig'
        output = session.cmd(check_cmd)
        session.close()
        logging.debug(output)
        if 'mtu %s' % mtu_size not in output:
            test.fail('MTU check inside vm failed.')
        else:
            logging.debug("MTU check inside vm passed.")

    try:
        bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
        bk_netxml = NetworkXML.new_from_net_dumpxml(DEFAULT_NET)
        if add_pkg:
            add_pkg = add_pkg.split()
            if 'openvswitch' in add_pkg and shutil.which('ovs-vsctl'):
                new_pkg = add_pkg.copy()
                new_pkg.remove('openvswitch')
            utils_package.package_install(new_pkg)
        if 'openvswitch' in add_pkg:
            br = 'ovsbr0' + utils_misc.generate_random_string(3)
            process.run('systemctl start openvswitch.service',
                        shell=True,
                        verbose=True)
            process.run('ovs-vsctl add-br %s' % br, shell=True, verbose=True)
            process.run('ovs-vsctl show', shell=True, verbose=True)

        if not check or check in ['save', 'managedsave', 'hotplug_save']:
            # Create bridge or network and set mtu
            iface_type = 'network'
            if net_type in ('bridge', 'openvswitch'):
                if net_type == 'bridge':
                    params['con_name'], br = create_bridge()
                if mtu_type == 'network':
                    test_net = create_network_xml(bridge_name,
                                                  net_type,
                                                  bridge_name=br)
                    virsh.net_create(test_net, debug=True)
                    virsh.net_dumpxml(bridge_name, debug=True)
                if mtu_type == 'interface':
                    iface_type = net_type
                    bridge_name = br
            elif net_type == 'network':
                if mtu_type == 'network':
                    set_network(mtu_size)

            iface_mtu = 0
            if mtu_type == 'interface':
                iface_mtu = mtu_size
            if mtu_type == 'network' and with_iface:
                mtu_size = str(int(mtu_size) // 2)
                iface_mtu = mtu_size

            source_net = bridge_name if net_type in (
                'bridge', 'openvswitch') else 'default'

            # set mtu in vm interface
            set_interface(iface_mtu,
                          source_network=source_net,
                          iface_type=iface_type,
                          iface_model=model)
            vm.start()
            vm_login = vm.wait_for_serial_login if net_type in (
                'bridge', 'openvswitch') else vm.wait_for_login
            vm_login().close()
            check_qemu = True if mtu_type == 'interface' else False

            # Test mtu after save vm
            if check in ('save', 'hotplug_save'):
                if check == 'hotplug_save':
                    iface = create_iface('network',
                                         source_net='default',
                                         mtu=mtu_size,
                                         model_net=model)
                    params['mac'] = iface.mac_address
                    virsh.attach_device(vm_name, iface.xml, debug=True)
                    virsh.dumpxml(vm_name, debug=True)
                    dom_xml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    if params['mac'] not in str(dom_xml):
                        test.fail('Failed to attach interface with mtu')
                save_path = os.path.join(data_dir.get_tmp_dir(),
                                         vm_name + '.save')
                virsh.save(vm_name, save_path, debug=True)
                virsh.restore(save_path, debug=True)
            if check == 'managedsave':
                virsh.managedsave(vm_name, debug=True)
                virsh.start(vm_name, debug=True)

            # Check in both host and vm
            check_mtu(mtu_size, check_qemu)
            if mtu_type == 'interface' or with_iface:
                check_mtu_in_vm(vm_login, mtu_size)
                vm_login(timeout=60).close()

            if check == 'hotplug_save':
                virsh.detach_interface(vm_name,
                                       'network %s' % params['mac'],
                                       debug=True)
                time.sleep(5)
                dom_xml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                if params['mac'] in str(dom_xml):
                    test.fail(
                        'Failed to detach interface with mtu after save-restore'
                    )

        else:
            hotplug = 'yes' == params.get('hotplug', 'False')
            if check == 'net_update':
                result = virsh.net_update(DEFAULT_NET,
                                          'modify',
                                          'mtu',
                                          '''"<mtu size='%s'/>"''' % mtu_size,
                                          debug=True)
            if check in ('macvtap', 'bridge_net', 'ovswitch_net'):
                base_if = get_default_if()
                macv_name = 'direct-macvtap' + utils_misc.generate_random_string(
                    3)

                # Test mtu in different type of network
                if mtu_type == 'network':
                    if check == 'macvtap':
                        test_net = create_network_xml(macv_name,
                                                      'macvtap',
                                                      base_if,
                                                      mtu=mtu_size)
                    if check == 'bridge_net':
                        params['con_name'], br = create_bridge()
                        test_net = create_network_xml(bridge_name,
                                                      'bridge',
                                                      mtu=mtu_size,
                                                      bridge_name=br)
                    if check == 'ovswitch_net':
                        test_net = create_network_xml(bridge_name,
                                                      'openvswitch',
                                                      mtu=mtu_size,
                                                      bridge_name=br)
                    if 'net_create' in params['id']:
                        result = virsh.net_create(test_net, debug=True)
                    if 'net_define' in params['id']:
                        result = virsh.net_define(test_net, debug=True)

                # Test mtu with or without a binding network
                elif mtu_type == 'interface':
                    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
                    if with_net:
                        test_net = create_network_xml(macv_name, 'macvtap',
                                                      base_if)
                        virsh.net_create(test_net, debug=True)
                        iface = create_iface('network',
                                             source_net=macv_name,
                                             mtu=mtu_size,
                                             model_net=model)
                        if hotplug:
                            result = virsh.attach_device(vm_name,
                                                         iface.xml,
                                                         debug=True)
                        else:
                            vmxml.add_device(iface)
                            vmxml.sync()
                            result = virsh.start(vm_name)
                    else:
                        iface = create_iface('direct',
                                             base_if=base_if,
                                             mtu=mtu_size,
                                             model_net=model)
                        if hotplug:
                            result = virsh.attach_device(vm_name,
                                                         iface.xml,
                                                         debug=True)
                        else:
                            vmxml.add_device(iface)
                            result = virsh.define(vmxml.xml, debug=True)
            if check == 'invalid_val':
                iface = create_iface('network',
                                     source_net='default',
                                     mtu=mtu_size,
                                     model_net=model)
                result = virsh.attach_device(vm_name, iface.xml, debug=True)

            # Check result
            libvirt.check_exit_status(result, status_error)
            libvirt.check_result(result, [error_msg])

    finally:
        bk_xml.sync()
        bk_netxml.sync()
        if 'test_net' in locals():
            virsh.net_destroy(bridge_name, debug=True)
        if params.get('con_name'):
            process.run('nmcli con del %s' % params['con_name'], verbose=True)
        if add_pkg:
            process.run("ovs-vsctl del-br %s" % br, verbose=True)
            utils_package.package_remove(add_pkg)
示例#21
0
def run(test, params, env):
    """
    Test virsh interface related commands.

    (1) If using given exist interface for testing(eg. lo or ethX):
        1.1 Dumpxml for the interface(with --inactive option)
        1.2 Destroy the interface
        1.3 Undefine the interface
    (2) Define an interface from XML file
    (3) List interfaces with '--inactive' optioin
    (4) Start the interface
    (5) List interfaces with no option
    (6) Dumpxml for the interface
    (7) Get interface MAC address by interface name
    (8) Get interface name by interface MAC address
    (9) Delete interface if not use the exist interface for testing
        9.1 Destroy the interface
        9.2 Undefine the interface

    Caveat, this test may affect the host network, so using the loopback(lo)
    device by default. You can specify the interface which you want, but be
    careful.
    """

    iface_name = params.get("iface_name", "ENTER.BRIDGE.NAME")
    iface_xml = params.get("iface_xml")
    iface_type = params.get("iface_type", "ethernet")
    iface_pro = params.get("iface_pro", "")
    iface_eth = params.get("iface_eth", "")
    iface_tag = params.get("iface_tag", "0")
    if iface_type == "vlan":
        iface_name = iface_eth + "." + iface_tag
    iface_eth_using = "yes" == params.get("iface_eth_using", "no")
    ping_ip = params.get("ping_ip", "localhost")
    use_exist_iface = "yes" == params.get("use_exist_iface", "no")
    status_error = "yes" == params.get("status_error", "no")
    net_restart = "yes" == params.get("iface_net_restart", "no")
    list_dumpxml_acl = "yes" == params.get("list_dumpxml_acl", "no")
    if ping_ip.count("ENTER"):
        raise error.TestNAError("Please input a valid ip address")
    if iface_name.count("ENTER"):
        raise error.TestNAError("Please input a existing bridge/ethernet name")

    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user', "EXAMPLE")
    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.")

    virsh_dargs = {'debug': True}
    list_dumpxml_dargs = {'debug': True}
    if params.get('setup_libvirt_polkit') == 'yes':
        if not list_dumpxml_acl:
            virsh_dargs['uri'] = uri
            virsh_dargs['unprivileged_user'] = unprivileged_user
        else:
            list_dumpxml_dargs['uri'] = uri
            list_dumpxml_dargs['unprivileged_user'] = unprivileged_user
            list_dumpxml_dargs['ignore_status'] = False

    # acl api negative testing params
    write_save_status_error = "yes" == params.get("write_save_status_error",
                                                  "no")
    start_status_error = "yes" == params.get("start_status_error", "no")
    stop_status_error = "yes" == params.get("stop_status_error", "no")
    delete_status_error = "yes" == params.get("delete_status_error", "no")

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm:
        xml_bak = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(test.tmpdir, "iface-%s.bk" % iface_name)
    net_bridge = utils_net.Bridge()
    if use_exist_iface:
        if iface_type == "bridge":
            if iface_name not in net_bridge.list_br():
                raise error.TestError("Bridge '%s' not exists" % iface_name)
            ifaces = net_bridge.get_structure()[iface_name]
            if len(ifaces) < 1:
                # In this situation, dhcp maybe cannot get ip address
                # Unless you use static, we'd better skip such case
                raise error.TestNAError("Bridge '%s' has no interface"
                                        " bridged, perhaps cannot get"
                                        " ipaddress" % iface_name)
    net_iface = utils_net.Interface(name=iface_name)
    iface_is_up = True
    list_option = "--all"
    if use_exist_iface:
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            raise error.TestError("Interface '%s' not exists" % iface_name)
        iface_xml = os.path.join(test.tmpdir, "iface.xml.tmp")
        iface_is_up = net_iface.is_up()
    else:
        # Note, if not use the interface which already exists, iface_name must
        # be equal to the value specified in XML file
        if libvirt.check_iface(iface_name, "exists", "--all"):
            raise error.TestError("Interface '%s' already exists" % iface_name)
        if not iface_xml:
            raise error.TestError("XML file is needed.")
        iface_xml = os.path.join(test.tmpdir, iface_xml)
        create_xml_file(iface_xml, params)

    # Stop NetworkManager as which may conflict with virsh iface commands
    try:
        NM = utils_misc.find_command("NetworkManager")
    except ValueError:
        logging.debug("No NetworkManager service.")
        NM = None
    NM_is_running = False
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            NM_service.stop()

    # run test cases
    try:
        if use_exist_iface:
            # back up the interface script
            utils.run("cp %s %s" % (iface_script, iface_script_bk))
            # step 1.1
            # dumpxml for interface
            if list_dumpxml_acl:
                virsh.iface_list(**list_dumpxml_dargs)
            xml = virsh.iface_dumpxml(iface_name, "--inactive",
                                      to_file=iface_xml,
                                      **list_dumpxml_dargs)
            # Step 1.2
            # Destroy interface
            if iface_is_up:
                result = virsh.iface_destroy(iface_name, **virsh_dargs)
                if (params.get('setup_libvirt_polkit') == 'yes' and
                        stop_status_error):
                    # acl_test negative test
                    libvirt.check_exit_status(result, stop_status_error)
                    virsh.iface_destroy(iface_name, debug=True)
                else:
                    libvirt.check_exit_status(result, status_error)

            # Step 1.3
            # Undefine interface
            result = virsh.iface_undefine(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes' and
                    delete_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, delete_status_error)
                virsh.iface_undefine(iface_name, debug=True)
            else:
                libvirt.check_exit_status(result, status_error)
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("%s is still present." % iface_name)

        # Step 2
        # Define interface
        result = virsh.iface_define(iface_xml, **virsh_dargs)
        if (params.get('setup_libvirt_polkit') == 'yes' and
                write_save_status_error):
            # acl_test negative test
            libvirt.check_exit_status(result, write_save_status_error)
            virsh.iface_define(iface_xml, debug=True)
        elif iface_type == "bond" and not ping_ip:
            libvirt.check_exit_status(result, True)
            return
        else:
            libvirt.check_exit_status(result, status_error)

        if net_restart:
            network = service.Factory.create_service("network")
            network.restart()

        # After network restart, (ethernet)interface will be started
        if (not net_restart and iface_type in ("bridge", "ethernet")) or\
           (not use_exist_iface and iface_type in ("vlan", "bond")):
            # Step 3
            # List inactive interfaces
            list_option = "--inactive"
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("Fail to find %s." % iface_name)

            # Step 4
            # Start interface
            result = virsh.iface_start(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes' and
                    start_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, start_status_error)
                virsh.iface_start(iface_name, debug=True)
            elif (not net_restart and not use_exist_iface and
                    (iface_type == "ethernet" and iface_pro in ["", "dhcp"] or
                        iface_type == "bridge" and iface_pro == "dhcp")):
                libvirt.check_exit_status(result, True)
            else:
                libvirt.check_exit_status(result, status_error)
            if not status_error:
                iface_ip = net_iface.get_ip()
                ping_ip = ping_ip if not iface_ip else iface_ip
                if ping_ip:
                    if not libvirt.check_iface(iface_name, "ping", ping_ip):
                        raise error.TestFail("Ping %s fail." % ping_ip)

        # Step 5
        # List active interfaces
        if use_exist_iface or\
           (iface_pro != "dhcp" and iface_type == "bridge") or\
           (iface_eth_using and iface_type == "vlan"):
            list_option = ""
            if not status_error:
                if not libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("Fail to find %s in active "
                                         "interface list" % iface_name)
            if vm:
                iface_mac_list = vm_xml.VMXML.get_iface_dev(vm_name)
                # Before test, detach all interfaces in guest
                for mac in iface_mac_list:
                    iface_info = vm_xml.VMXML.get_iface_by_mac(vm_name, mac)
                    type = iface_info.get('type')
                    virsh.detach_interface(vm_name,
                                           "--type %s --mac %s"
                                           " --config" % (type, mac))
                virsh.attach_interface(vm_name,
                                       "--type %s --source %s"
                                       " --config" % (iface_type, iface_name))
                vm.start()
                try:
                    # Test if guest can be login
                    vm.wait_for_login()
                except remote.LoginError:
                    raise error.TestFail("Cannot login guest with %s" %
                                         iface_name)

        # Step 6
        # Dumpxml for interface
        if list_dumpxml_acl:
            virsh.iface_list(**list_dumpxml_dargs)
        xml = virsh.iface_dumpxml(iface_name, "", to_file="",
                                  **list_dumpxml_dargs)
        logging.debug("Interface '%s' XML:\n%s", iface_name, xml)

        # Step 7
        # Get interface MAC address by name
        result = virsh.iface_mac(iface_name, debug=True)
        libvirt.check_exit_status(result, status_error)
        if not status_error and result.stdout.strip():
            if not libvirt.check_iface(iface_name, "mac",
                                       result.stdout.strip()):
                raise error.TestFail("Mac address check fail")

        # Step 8
        # Get interface name by MAC address
        # Bridge's Mac equal to bridged interface's mac
        if iface_type not in ("bridge", "vlan") and result.stdout.strip():
            iface_mac = net_iface.get_mac()
            result = virsh.iface_name(iface_mac, debug=True)
            libvirt.check_exit_status(result, status_error)

        # Step 9
        if not use_exist_iface:
            # Step 9.1
            # Destroy interface
            result = virsh.iface_destroy(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes' and
                    stop_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, stop_status_error)
                virsh.iface_destroy(iface_name, debug=True)
            elif (not net_restart and iface_type == "ethernet"
                    and iface_pro in ["", "dhcp"] or iface_type == "bridge"
                    and iface_pro == "dhcp"):
                libvirt.check_exit_status(result, True)
            else:
                libvirt.check_exit_status(result, status_error)

            # Step 9.2
            # Undefine interface
            result = virsh.iface_undefine(iface_name, **virsh_dargs)
            if (params.get('setup_libvirt_polkit') == 'yes' and
                    delete_status_error):
                # acl_test negative test
                libvirt.check_exit_status(result, delete_status_error)
                virsh.iface_undefine(iface_name, debug=True)
            else:
                libvirt.check_exit_status(result, status_error)
            list_option = "--all"
            if not status_error:
                if libvirt.check_iface(iface_name, "exists", list_option):
                    raise error.TestFail("%s is still present." % iface_name)
    finally:
        if os.path.exists(iface_xml):
            os.remove(iface_xml)
        if os.path.exists(iface_script):
            os.remove(iface_script)

        if use_exist_iface:
            if not os.path.exists(iface_script):
                utils.run("mv %s %s" % (iface_script_bk, iface_script))
            if iface_is_up and\
               not libvirt.check_iface(iface_name, "exists", ""):
                # Need reload script
                utils.run("ifup %s" % iface_name)
            elif not iface_is_up and libvirt.check_iface(iface_name,
                                                         "exists", ""):
                net_iface.down()
            if vm:
                xml_bak.sync()
        else:
            if libvirt.check_iface(iface_name, "exists", "--all"):
                # Remove the interface
                try:
                    utils_net.bring_down_ifname(iface_name)
                except utils_net.TAPBringDownError:
                    pass
            if iface_type == "bridge":
                if iface_name in net_bridge.list_br():
                    try:
                        net_bridge.del_bridge(iface_name)
                    except IOError:
                        pass
        if NM_is_running:
            NM_service.start()
示例#22
0
def run(test, params, env):
    """
    Test virsh {at|de}tach-interface command.

    1) Prepare test environment and its parameters
    2) Attach the required interface
    3) According test type(only attach or both attach and detach):
       a.Go on to test detach(if attaching is correct)
       b.Return GOOD or raise TestFail(if attaching is wrong)
    4) Check if attached interface is correct:
       a.Try to catch it in vm's XML file
       b.Try to catch it in vm
    5) Detach the attached interface
    6) Check result
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    vm_ref = params.get("at_detach_iface_vm_ref", "domname")
    options_suffix = params.get("at_detach_iface_options_suffix", "")
    status_error = "yes" == params.get("status_error", "no")
    start_vm = params.get("start_vm")
    # Should attach must be pass for detach test.
    correct_attach = "yes" == params.get("correct_attach", "no")
    readonly = ("yes" == params.get("readonly", "no"))

    # Interface specific attributes.
    iface_type = params.get("at_detach_iface_type", "network")
    iface_source = params.get("at_detach_iface_source", "default")
    iface_mode = params.get("at_detach_iface_mode", "vepa")
    iface_mac = params.get("at_detach_iface_mac", "created")
    iface_target = params.get("at_detach_iface_target")
    iface_model = params.get("at_detach_iface_model")
    iface_inbound = params.get("at_detach_iface_inbound")
    iface_outbound = params.get("at_detach_iface_outbound")
    iface_rom = params.get("at_detach_rom_bar")
    iface_link = params.get("at_detach_link_state")
    iface_boot = params.get("at_detach_boot_order")
    iface_driver = params.get("at_detach_iface_driver")
    iface_driver_host = params.get("at_detach_driver_host")
    iface_driver_guest = params.get("at_detach_driver_guest")
    iface_backend = params.get("at_detach_iface_backend")

    save_restore = params.get("save_restore", "no")
    restart_libvirtd = params.get("restart_libvirtd", "no")
    attach_cmd = params.get("attach_cmd", "attach-interface")
    virsh_dargs = {'ignore_status': True, 'debug': True, 'uri': uri}
    validate_xml_result = "yes" == params.get("check_xml_result", "no")
    paused_after_vm_start = "yes" == params.get("paused_after_vm_start", "no")
    machine_type = params.get("machine_type")

    # Get iface name if iface_type is direct
    if iface_type == "direct":
        iface_source = utils_net.get_net_if(state="UP")[0]
    # Get a bridge name for test if iface_type is bridge.
    # If there is no bridge other than virbr0, try to create one
    # or fail test
    if iface_type == "bridge":
        host_bridge = utils_net.Bridge()
        bridge_list = host_bridge.list_br()
        try:
            bridge_list.remove("virbr0")
        except AttributeError:
            pass  # If no virbr0, just pass is ok
        logging.debug("Useful bridges:%s", bridge_list)
        if len(bridge_list):
            iface_source = bridge_list[0]
        else:
            process.run('ip link add name br0 type bridge',
                        ignore_status=False)
            iface_source = 'br0'
            logging.debug("Added bridge br0")

    # Test both detach and attach, So collect info
    # both of them for result check.
    # When something wrong with interface, set it to 1
    fail_flag = 0
    result_info = []

    # Get a mac address if iface_mac is 'created'.
    if iface_mac == "created" or correct_attach:
        iface_mac = utils_net.generate_mac_address_simple()

    names = locals()
    iface_format = get_formatted_iface_dict(names, params.get("vm_arch_name"))

    # for rtl8139 model, need to add pcie bridge
    if iface_model == "rtl8139" and machine_type == "q35":
        add_pcie_controller(vm_name)
        if start_vm == "yes" and not vm.is_alive():
            vm.start()

    try:
        # Generate xml file if using attach-device command
        if attach_cmd == "attach-device":
            # Change boot order to disk
            libvirt.change_boot_order(vm_name, "disk", "1")
            vm.destroy()
            vm.start()
            # Generate attached xml
            new_iface = Interface(type_name=iface_type)
            xml_file_tmp = libvirt.modify_vm_iface(vm_name, "get_xml",
                                                   iface_format)
            new_iface.xml = xml_file_tmp
            new_iface.del_address()
            xml_file = new_iface.xml

        # To confirm vm's state and make sure os fully started
        if start_vm == "no":
            if vm.is_alive():
                vm.destroy()
        else:
            vm.wait_for_login().close()

        if paused_after_vm_start:
            vm.pause()

        # Set attach-interface domain
        dom_uuid = vm.get_uuid()
        dom_id = vm.get_id()

        if vm_ref == "domname":
            vm_ref = vm_name
        elif vm_ref == "domid":
            vm_ref = dom_id
        elif vm_ref == "domuuid":
            vm_ref = dom_uuid
        elif vm_ref == "hexdomid" and dom_id is not None:
            vm_ref = hex(int(dom_id))

        # Set attach-interface options and Start attach-interface test
        if correct_attach:
            options = set_options("network", "default", iface_mac, "",
                                  "attach", None, iface_model)
            if readonly:
                virsh_dargs.update({'readonly': True, 'debug': True})
            attach_result = virsh.attach_interface(vm_name, options,
                                                   **virsh_dargs)
        else:
            if attach_cmd == "attach-interface":
                options = set_options(iface_type, iface_source, iface_mac,
                                      options_suffix, "attach", iface_target,
                                      iface_model, iface_inbound,
                                      iface_outbound)
                attach_result = virsh.attach_interface(vm_ref, options,
                                                       **virsh_dargs)
            elif attach_cmd == "attach-device":
                attach_result = virsh.attach_device(vm_name,
                                                    xml_file,
                                                    ignore_status=True,
                                                    debug=True)
        attach_status = attach_result.exit_status
        logging.debug(attach_result)

        # If attach interface failed.
        if attach_status:
            if not status_error:
                fail_flag = 1
                result_info.append("Attach Failed: %s" % attach_result.stderr)
            elif status_error:
                # Here we just use it to exit, do not mean test failed
                fail_flag = 1
        # If attach interface succeeded.
        else:
            if status_error and not correct_attach:
                fail_flag = 1
                result_info.append("Attach Success with wrong command.")

        if fail_flag and start_vm == "yes":
            vm.destroy()
            if len(result_info):
                test.fail(result_info)
            else:
                # Exit because it is error_test for attach-interface.
                return

        if "print-xml" in options_suffix:
            iface_obj = Interface(type_name=iface_type)
            iface_obj.xml = attach_result.stdout.strip()
            if (iface_obj.type_name == iface_type
                    and iface_obj.source['dev'] == iface_source
                    and iface_obj.target['dev'] == iface_target
                    and iface_obj.model == iface_model
                    and iface_obj.bandwidth.inbound == eval(
                        iface_format['inbound'])
                    and iface_obj.bandwidth.outbound == eval(
                        iface_format['outbound'])):
                logging.info("Print ml all element check pass")
            else:
                test.fail("Print xml do not show as expected")

        # Check dumpxml file whether the interface is added successfully.
        status, ret = check_dumpxml_iface(vm_name, iface_format)
        if "print-xml" not in options_suffix:
            # Check validate_xml_result flag to determine whether apply check_interface_xml.
            if validate_xml_result:
                # If options_suffix contains config, it need dump inactive xml.
                is_active = True
                if options_suffix.count("config"):
                    is_active = False
                # Check dumping VM xml value.
                if not check_interface_xml(vm_name, iface_type, iface_source,
                                           iface_mac, is_active):
                    test.fail(
                        "Failed to find matched interface values in VM interface xml"
                    )
            if status:
                fail_flag = 1
                result_info.append(ret)
        else:
            if status == 0:
                test.fail(
                    "Attach interface effect in xml with print-xml option")
            else:
                return

        # Login to domain to check new interface.
        if not vm.is_alive():
            vm.start()
        elif vm.state() == "paused":
            vm.resume()
        vm.wait_for_login().close()

        status, ret = login_to_check(vm, iface_mac)
        if status:
            fail_flag = 1
            result_info.append(ret)

        # Check on host for direct type
        if iface_type == 'direct':
            cmd_result = process.run(
                "ip -d link show test").stdout_text.strip()
            logging.info("cmd output is %s", cmd_result)
            check_patten = (
                "%s@%s.*\n.*%s.*\n.*macvtap.*mode.*%s" %
                (iface_target, iface_source, iface_mac, iface_mode))
            logging.info("check patten is %s", check_patten)
            if not re.search(check_patten, cmd_result):
                logging.error("Can not find %s in ip link" % check_patten)
                fail_flag = 1
                result_info.append(cmd_result)

        # Do operation and check again
        if restart_libvirtd == "yes":
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()

        if save_restore == "yes":
            check_save_restore(vm_name)

        status, ret = check_dumpxml_iface(vm_name, iface_format)
        if status:
            fail_flag = 1
            result_info.append(ret)

        # Set detach-interface options
        options = set_options(iface_type, None, iface_mac, options_suffix,
                              "detach")

        # Start detach-interface test
        if save_restore == "yes" and vm_ref == dom_id:
            vm_ref = vm_name
        detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs)
        detach_status = detach_result.exit_status
        detach_msg = detach_result.stderr.strip()

        logging.debug(detach_result)

        if detach_status == 0 and status_error == 0:
            # If command with --config parameter, ignore below checking.
            if options_suffix.count("config"):
                return
            # Check the xml after detach and clean up if needed.
            time.sleep(5)
            status, _ = check_dumpxml_iface(vm_name, iface_format)
            if status == 0:
                detach_status = 1
                detach_msg = "xml still exist after detach"
                cleanup_options = "--type %s --mac %s" % (iface_type,
                                                          iface_mac)
                virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs)
            else:
                logging.info("After detach, the interface xml disappeared")

        # Check results.
        if status_error:
            if detach_status == 0:
                test.fail("Detach Success with wrong command.")
        else:
            if detach_status != 0:
                test.fail("Detach Failed: %s" % detach_msg)
            else:
                if fail_flag:
                    test.fail("Attach-Detach Success but "
                              "something wrong with its "
                              "functional use:%s" % result_info)
    finally:
        if vm.is_alive():
            vm.destroy()
        backup_xml.sync()
示例#23
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    status_error = "yes" == params.get("status_error", "no")

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source",
                                   "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd",
                                           "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    if not status_error:
        if attach_device and attach_option:
            check_cmds.append(('attach-device', attach_option))
        if attach_iface and attach_option:
            check_cmds.append(('attach-interface', attach_option))
        if (detach_device or stress_test_detach_device) and detach_option:
            check_cmds.append(('detach-device', detach_option))
        if stress_test_detach_interface and detach_option:
            check_cmds.append(('detach-device', detach_option))
    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if attach_device:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-device")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac,
                                           'iface_xml': iface_xml_obj})
                # Need sleep here for attachment take effect
                time.sleep(5)
            elif attach_iface:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name, options,
                                                 ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-interface")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac})
                # Need sleep here for attachment take effect
                time.sleep(5)

            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                vm.cleanup_serial_console()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # Check if interface was attached
            for iface in iface_list:
                if iface.has_key('mac'):
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                            iface['mac'])
                    if not if_attr:
                        raise error.TestFail("Can't see interface "
                                             " in dumpxml")
                    if (if_attr['type'] != iface_type or
                            if_attr['source'] != iface_source['network']):
                        raise error.TestFail("Interface attribute doesn't"
                                             " match attachment opitons")
                    # Check interface on guest
                    if not utils_net.get_linux_ifname(session,
                                                      iface['mac']):
                        raise error.TestFail("Can't see interface"
                                             " on guest")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if iface.has_key('iface_xml'):
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" %
                                   (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if iface.has_key('mac'):
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                 iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            raise error.TestFail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#24
0
def run(test, params, env):
    """
    convert specific kvm guest to rhev
    """
    for v in list(params.values()):
        if "V2V_EXAMPLE" in v:
            test.cancel("Please set real value for %s" % v)
    if utils_v2v.V2V_EXEC is None:
        raise ValueError('Missing command: virt-v2v')
    vm_name = params.get('main_vm', 'EXAMPLE')
    target = params.get('target')
    remote_host = params.get('remote_host', 'EXAMPLE')
    output_mode = params.get('output_mode')
    output_format = params.get('output_format')
    output_storage = params.get('output_storage', 'default')
    bridge = params.get('bridge')
    network = params.get('network')
    ntp_server = params.get('ntp_server')
    address_cache = env.get('address_cache')
    pool_name = params.get('pool_name', 'v2v_test')
    pool_type = params.get('pool_type', 'dir')
    pool_target = params.get('pool_target_path', 'v2v_pool')
    pvt = utlv.PoolVolumeTest(test, params)
    v2v_timeout = int(params.get('v2v_timeout', 1200))
    skip_check = 'yes' == params.get('skip_check', 'no')
    status_error = 'yes' == params.get('status_error', 'no')
    checkpoint = params.get('checkpoint', '')
    debug_kernel = 'debug_kernel' == checkpoint
    multi_kernel_list = ['multi_kernel', 'debug_kernel']
    backup_list = [
        'virtio_on', 'virtio_off', 'floppy', 'floppy_devmap', 'fstab_cdrom',
        'fstab_virtio', 'multi_disks', 'sata_disk', 'network_virtio',
        'network_rtl8139', 'network_e1000', 'multi_netcards', 'spice',
        'spice_encrypt', 'spice_qxl', 'spice_cirrus', 'vnc_qxl', 'vnc_cirrus',
        'blank_2nd_disk', 'listen_none', 'listen_socket', 'only_net', 'only_br'
    ]
    error_list = []

    def log_fail(msg):
        """
        Log error and update error list
        """
        logging.error(msg)
        error_list.append(msg)

    def vm_shell(func):
        """
        Decorator of shell session to vm
        """
        def wrapper(*args, **kwargs):
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_dead():
                logging.info('VM is down. Starting it now.')
                vm.start()
            session = vm.wait_for_login()
            kwargs['session'] = session
            kwargs['vm'] = vm
            func(*args, **kwargs)
            if session:
                session.close()
            vm.shutdown()

        return wrapper

    def check_disks(vmcheck):
        """
        Check disk counts inside the VM
        """
        # Initialize windows boot up
        os_type = params.get("os_type", "linux")
        expected_disks = int(params.get("ori_disks", "1"))
        logging.debug("Expect %s disks im VM after convert", expected_disks)
        # Get disk counts
        if os_type == "linux":
            cmd = "lsblk |grep disk |wc -l"
            disks = int(vmcheck.session.cmd(cmd).strip())
        else:
            cmd = r"echo list disk > C:\list_disk.txt"
            vmcheck.session.cmd(cmd)
            cmd = r"diskpart /s C:\list_disk.txt"
            output = vmcheck.session.cmd(cmd).strip()
            logging.debug("Disks in VM: %s", output)
            disks = len(re.findall('Disk\s\d', output))
        logging.debug("Find %s disks in VM after convert", disks)
        if disks == expected_disks:
            logging.info("Disk counts is expected")
        else:
            log_fail("Disk counts is wrong")

    @vm_shell
    def check_vmlinuz_initramfs(v2v_result):
        """
        Check if vmlinuz matches initramfs on multi-kernel case
        """
        logging.info('Checking if vmlinuz matches initramfs')
        kernels = re.search(
            'kernel packages in this guest:.*?(\(kernel.*?\).*?){2,}',
            v2v_result, re.DOTALL)
        try:
            lines = kernels.group(0)
            kernel_list = re.findall('\((.*?)\)', lines)
            for kernel in kernel_list:
                vmlinuz = re.search(r'/boot/vmlinuz-(.*?),', kernel).group(1)
                initramfs = \
                    re.search(r'/boot/initramfs-(.*?)\.img', kernel).group(1)
                logging.debug('vmlinuz version is: %s' % vmlinuz)
                logging.debug('initramfs version is: %s' % initramfs)
                if vmlinuz != initramfs:
                    log_fail('vmlinuz not match with initramfs')
        except Exception as e:
            test.error('Error on find kernel info \n %s' % str(e))

    def check_boot_kernel(vmcheck):
        """
        Check if converted vm use the latest kernel
        """
        current_kernel = vmcheck.session.cmd('uname -r').strip()
        logging.debug('Current kernel: %s' % current_kernel)
        if current_kernel == '3.10.0-799.el7.x86_64':
            logging.debug('The kernel is the latest kernel')
        else:
            log_fail('VM should choose lastest kernel not %s' % current_kernel)

    def check_floppy_exist(vmcheck):
        """
        Check if floppy exists after convertion
        """
        blk = vmcheck.session.cmd('lsblk')
        logging.info(blk)
        if not re.search('fd0', blk):
            log_fail('Floppy not found')

    def attach_removable_media(type, source, dev):
        bus = {'cdrom': 'ide', 'floppy': 'fdc', 'disk': 'virtio'}
        args = {
            'driver': 'qemu',
            'subdriver': 'raw',
            'sourcetype': 'file',
            'type': type,
            'targetbus': bus[type]
        }
        if type == 'cdrom':
            args.update({'mode': 'readonly'})
        config = ''
        # Join all options together to get command line
        for key in list(args.keys()):
            config += ' --%s %s' % (key, args[key])
        config += ' --current'
        virsh.attach_disk(vm_name, source, dev, extra=config)

    def change_disk_bus(dest):
        """
        Change all disks' bus type to $dest
        """
        bus_list = ['ide', 'sata', 'virtio']
        if dest not in bus_list:
            test.error('Bus type not support')
        dev_prefix = ['h', 's', 'v']
        dev_table = dict(list(zip(bus_list, dev_prefix)))
        logging.info('Change disk bus to %s' % dest)
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        disks = vmxml.get_disk_all()
        index = 0
        for disk in list(disks.values()):
            if disk.get('device') != 'disk':
                continue
            target = disk.find('target')
            target.set('bus', dest)
            target.set('dev',
                       dev_table[dest] + 'd' + string.ascii_lowercase[index])
            disk.remove(disk.find('address'))
            index += 1
        vmxml.sync()

    def change_network_model(model):
        """
        Change network model to $model
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        network_list = vmxml.get_iface_all()
        for node in list(network_list.values()):
            if node.get('type') == 'network':
                node.find('model').set('type', model)
        vmxml.sync()

    def attach_network_card(model):
        """
        Attach network card based on model
        """
        if model not in ('e1000', 'virtio', 'rtl8139'):
            test.error('Network model not support')
        options = {'type': 'network', 'source': 'default', 'model': model}
        line = ''
        for key in options:
            line += ' --' + key + ' ' + options[key]
        line += ' --current'
        logging.debug(virsh.attach_interface(vm_name, option=line))

    def check_multi_netcards(mac_list, virsh_instance):
        """
        Check if number and type of network cards meet expectation
        """
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
            vm_name, virsh_instance=virsh_instance)
        iflist = vmxml.get_iface_all()
        logging.debug('MAC list before v2v: %s' % mac_list)
        logging.debug('MAC list after  v2v: %s' % list(iflist.keys()))
        if set(mac_list).difference(list(iflist.keys())):
            log_fail('Missing network interface')
        for mac in iflist:
            if iflist[mac].find('model').get('type') != 'virtio':
                log_fail('Network not convert to virtio')

    @vm_shell
    def insert_floppy_devicemap(**kwargs):
        """
        Add an entry of floppy to device.map
        """
        session = kwargs['session']
        line = '(fd0)     /dev/fd0'
        devmap = '/boot/grub/device.map'
        if session.cmd_status('ls %s' % devmap):
            devmap = '/boot/grub2/device.map'
        cmd_exist = 'grep \'(fd0)\' %s' % devmap
        cmd_set = 'sed -i \'2i%s\' %s' % (line, devmap)
        if session.cmd_status(cmd_exist):
            session.cmd(cmd_set)

    def make_label(session):
        """
        Label a volume, swap or root volume
        """
        # swaplabel for rhel7 with xfs, e2label for rhel6 or ext*
        cmd_map = {
            'root': 'e2label %s ROOT',
            'swap': 'swaplabel -L SWAPPER %s'
        }
        if not session.cmd_status('swaplabel --help'):
            blk = 'swap'
        elif not session.cmd_status('which e2label'):
            blk = 'root'
        else:
            test.error('No tool to make label')
        entry = session.cmd('blkid|grep %s' % blk).strip()
        path = entry.split()[0].strip(':')
        cmd_label = cmd_map[blk] % path
        if 'LABEL' not in entry:
            session.cmd(cmd_label)
        return blk

    @vm_shell
    def specify_fstab_entry(type, **kwargs):
        """
        Specify entry in fstab file
        """
        type_list = ['cdrom', 'uuid', 'label', 'virtio', 'sr0', 'invalid']
        if type not in type_list:
            test.error('Not support %s in fstab' % type)
        session = kwargs['session']
        # Specify cdrom device
        if type == 'cdrom':
            line = '/dev/cdrom /media/CDROM auto exec'
            if 'grub2' in utils_misc.get_bootloader_cfg(session):
                line += ',nofail'
            line += ' 0 0'
            logging.debug('fstab entry is "%s"', line)
            cmd = [
                'mkdir -p /media/CDROM', 'mount /dev/cdrom /media/CDROM',
                'echo "%s" >> /etc/fstab' % line
            ]
            for i in range(len(cmd)):
                session.cmd(cmd[i])
        elif type == 'sr0':
            line = params.get('fstab_content')
            session.cmd('echo "%s" >> /etc/fstab' % line)
        elif type == 'invalid':
            line = utils_misc.generate_random_string(6)
            session.cmd('echo "%s" >> /etc/fstab' % line)
        else:
            map = {'uuid': 'UUID', 'label': 'LABEL', 'virtio': '/vd'}
            logging.info(type)
            if session.cmd_status('cat /etc/fstab|grep %s' % map[type]):
                # Specify device by UUID
                if type == 'uuid':
                    entry = session.cmd(
                        'blkid -s UUID|grep swap').strip().split()
                    # Replace path for UUID
                    origin = entry[0].strip(':')
                    replace = entry[1].replace('"', '')
                # Specify virtio device
                elif type == 'virtio':
                    entry = session.cmd('cat /etc/fstab|grep /boot').strip()
                    # Get the ID (no matter what, usually UUID)
                    origin = entry.split()[0]
                    key = origin.split('=')[1]
                    blkinfo = session.cmd('blkid|grep %s' % key).strip()
                    # Replace with virtio disk path
                    replace = blkinfo.split()[0].strip(':')
                # Specify device by label
                elif type == 'label':
                    blk = make_label(session)
                    entry = session.cmd('blkid|grep %s' % blk).strip()
                    # Remove " from LABEL="****"
                    replace = entry.split()[1].strip().replace('"', '')
                    # Replace the original id/path with label
                    origin = entry.split()[0].strip(':')
                cmd_fstab = "sed -i 's|%s|%s|' /etc/fstab" % (origin, replace)
                session.cmd(cmd_fstab)
        fstab = session.cmd_output('cat /etc/fstab')
        logging.debug('Content of /etc/fstab:\n%s', fstab)

    def create_large_file(session, left_space):
        """
        Create a large file to make left space of root less than $left_space MB
        """
        cmd_df = "df -m / --output=avail"
        df_output = session.cmd(cmd_df).strip()
        logging.debug('Command output: %s', df_output)
        avail = int(df_output.strip().split('\n')[-1])
        logging.info('Available space: %dM' % avail)
        if avail > left_space - 1:
            tmp_dir = data_dir.get_tmp_dir()
            if session.cmd_status('ls %s' % tmp_dir) != 0:
                session.cmd('mkdir %s' % tmp_dir)
            large_file = os.path.join(tmp_dir, 'file.large')
            cmd_create = 'dd if=/dev/zero of=%s bs=1M count=%d' % \
                         (large_file, avail - left_space + 2)
            session.cmd(cmd_create, timeout=v2v_timeout)
        logging.info('Available space: %sM' % session.cmd(cmd_df).strip())

    @vm_shell
    def corrupt_rpmdb(**kwargs):
        """
        Corrupt rpm db
        """
        session = kwargs['session']
        # If __db.* exist, remove them, then touch _db.001 to corrupt db.
        if not session.cmd_status('ls /var/lib/rpm/__db.001'):
            session.cmd('rm -f /var/lib/rpm/__db.*')
        session.cmd('touch /var/lib/rpm/__db.001')
        if not session.cmd_status('yum update'):
            test.error('Corrupt rpmdb failed')

    @vm_shell
    def grub_serial_terminal(**kwargs):
        """
        Edit the serial and terminal lines of grub.conf
        """
        session = kwargs['session']
        vm = kwargs['vm']
        grub_file = utils_misc.get_bootloader_cfg(session)
        if 'grub2' in grub_file:
            test.cancel('Skip this case on grub2')
        cmd = "sed -i '1iserial -unit=0 -speed=115200\\n"
        cmd += "terminal -timeout=10 serial console' %s" % grub_file
        session.cmd(cmd)

    @vm_shell
    def set_selinux(value, **kwargs):
        """
        Set selinux stat of guest
        """
        session = kwargs['session']
        current_stat = session.cmd_output('getenforce').strip()
        logging.debug('Current selinux status: %s', current_stat)
        if current_stat != value:
            cmd = "sed -E -i 's/(^SELINUX=).*?/\\1%s/' /etc/selinux/config" % value
            logging.info('Set selinux stat with command %s', cmd)
            session.cmd(cmd)

    @vm_shell
    def get_firewalld_status(**kwargs):
        """
        Return firewalld service status of vm
        """
        session = kwargs['session']
        firewalld_status = session.cmd(
            'systemctl status firewalld.service|grep Active:',
            ok_status=[0, 3]).strip()
        logging.info('Status of firewalld: %s', firewalld_status)
        params[checkpoint] = firewalld_status

    def check_firewalld_status(vmcheck, expect_status):
        """
        Check if status of firewalld meets expectation
        """
        firewalld_status = vmcheck.session.cmd(
            'systemctl status '
            'firewalld.service|grep Active:',
            ok_status=[0, 3]).strip()
        logging.info('Status of firewalld after v2v: %s', firewalld_status)
        if firewalld_status != expect_status:
            log_fail('Status of firewalld changed after conversion')

    @vm_shell
    def vm_cmd(cmd_list, **kwargs):
        """
        Excecute a list of commands on guest.
        """
        session = kwargs['session']
        for cmd in cmd_list:
            logging.info('Send command "%s"', cmd)
            status, output = session.cmd_status_output(cmd)
            logging.debug('Command output:\n%s', output)
            if status != 0:
                test.error('Command "%s" failed' % cmd)
        logging.info('All commands executed')

    def check_time_keep(vmcheck):
        """
        Check time drift after convertion.
        """
        logging.info('Check time drift')
        output = vmcheck.session.cmd('ntpdate -q %s' % ntp_server)
        logging.debug(output)
        drift = abs(float(output.split()[-2]))
        logging.debug('Time drift is: %f', drift)
        if drift > 3:
            log_fail('Time drift exceeds 3 sec')

    def check_boot():
        """
        Check if guest can boot up after configuration
        """
        try:
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_alive():
                vm.shutdown()
            logging.info('Booting up %s' % vm_name)
            vm.start()
            vm.wait_for_login()
            vm.shutdown()
            logging.info('%s is down' % vm_name)
        except Exception as e:
            test.error('Bootup guest and login failed: %s', str(e))

    def check_result(result, status_error):
        """
        Check virt-v2v command result
        """
        utlv.check_exit_status(result, status_error)
        output = result.stdout + result.stderr
        if skip_check:
            logging.info('Skip checking vm after conversion')
        elif not status_error:
            if output_mode == 'rhev':
                if not utils_v2v.import_vm_to_ovirt(
                        params, address_cache, timeout=v2v_timeout):
                    test.fail('Import VM failed')
            if output_mode == 'libvirt':
                try:
                    virsh.start(vm_name, debug=True, ignore_status=False)
                except Exception as e:
                    test.fail('Start vm failed: %s' % str(e))
            # Check guest following the checkpoint document after convertion
            vmchecker = VMChecker(test, params, env)
            params['vmchecker'] = vmchecker
            if params.get('skip_check') != 'yes':
                ret = vmchecker.run()
                if len(ret) == 0:
                    logging.info("All common checkpoints passed")
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=vmchecker.virsh_instance)
            logging.debug(vmxml)
            if checkpoint == 'multi_kernel':
                check_boot_kernel(vmchecker.checker)
            if checkpoint == 'floppy':
                check_floppy_exist(vmchecker.checker)
            if checkpoint == 'multi_disks':
                check_disks(vmchecker.checker)
            if checkpoint == 'multi_netcards':
                check_multi_netcards(params['mac_address'],
                                     vmchecker.virsh_instance)
            if checkpoint.startswith(('spice', 'vnc')):
                if checkpoint == 'spice_encrypt':
                    vmchecker.check_graphics(params[checkpoint])
                else:
                    graph_type = checkpoint.split('_')[0]
                    vmchecker.check_graphics({'type': graph_type})
                    video_type = vmxml.get_devices('video')[0].model_type
                    if video_type.lower() != 'qxl':
                        log_fail('Video expect QXL, actual %s' % video_type)
            if checkpoint.startswith('listen'):
                listen_type = vmxml.get_devices('graphics')[0].listen_type
                logging.info('listen type is: %s', listen_type)
                if listen_type != checkpoint.split('_')[-1]:
                    log_fail('listen type changed after conversion')
            if checkpoint.startswith('selinux'):
                status = vmchecker.checker.session.cmd(
                    'getenforce').strip().lower()
                logging.info('Selinux status after v2v:%s', status)
                if status != checkpoint[8:]:
                    log_fail('Selinux status not match')
            if checkpoint == 'guest_firewalld_status':
                check_firewalld_status(vmchecker.checker, params[checkpoint])
            if checkpoint in ['ntpd_on', 'sync_ntp']:
                check_time_keep(vmchecker.checker)
            # Merge 2 error lists
            error_list.extend(vmchecker.errors)
        log_check = utils_v2v.check_log(params, output)
        if log_check:
            log_fail(log_check)
        if len(error_list):
            test.fail('%d checkpoints failed: %s' %
                      (len(error_list), error_list))

    try:
        v2v_params = {
            'hostname': remote_host,
            'hypervisor': 'kvm',
            'v2v_opts': '-v -x',
            'storage': output_storage,
            'network': network,
            'bridge': bridge,
            'target': target,
            'main_vm': vm_name,
            'input_mode': 'libvirt',
            'new_name': vm_name + '_' + utils_misc.generate_random_string(3)
        }
        if output_format:
            v2v_params.update({'output_format': output_format})
        # Build rhev related options
        if output_mode == 'rhev':
            # Create SASL user on the ovirt host
            user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"),
                                           params.get("sasl_pwd"))
            v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd)
            v2v_sasl.server_ip = params.get("remote_ip")
            v2v_sasl.server_user = params.get('remote_user')
            v2v_sasl.server_pwd = params.get('remote_pwd')
            v2v_sasl.setup(remote=True)
        if output_mode == 'local':
            v2v_params['storage'] = data_dir.get_tmp_dir()
        if output_mode == 'libvirt':
            pvt.pre_pool(pool_name, pool_type, pool_target, '')
        # Set libguestfs environment variable
        os.environ['LIBGUESTFS_BACKEND'] = 'direct'

        backup_xml = None
        if checkpoint in backup_list:
            backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
        if checkpoint == 'multi_disks':
            attach_disk_path = os.path.join(data_dir.get_tmp_dir(),
                                            'attach_disks')
            utlv.attach_disks(env.get_vm(vm_name), attach_disk_path, None,
                              params)
            new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            disk_count = 0
            for disk in list(new_xml.get_disk_all().values()):
                if disk.get('device') == 'disk':
                    disk_count += 1
            params['ori_disks'] = disk_count
        if checkpoint == 'virtio_on':
            change_disk_bus('virtio')
        if checkpoint == 'virtio_off':
            change_disk_bus('ide')
        if checkpoint == 'sata_disk':
            change_disk_bus('sata')
        if checkpoint.startswith('floppy'):
            img_path = data_dir.get_tmp_dir() + '/floppy.img'
            utlv.create_local_disk('floppy', img_path)
            attach_removable_media('floppy', img_path, 'fda')
            if checkpoint == 'floppy_devmap':
                insert_floppy_devicemap()
        if checkpoint.startswith('fstab'):
            if checkpoint == 'fstab_cdrom':
                img_path = data_dir.get_tmp_dir() + '/cdrom.iso'
                utlv.create_local_disk('iso', img_path)
                attach_removable_media('cdrom', img_path, 'hdc')
            if checkpoint == 'fstab_virtio':
                change_disk_bus('virtio')
            specify_fstab_entry(checkpoint[6:])
        if checkpoint == 'running':
            virsh.start(vm_name)
            logging.info('VM state: %s' %
                         virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'paused':
            virsh.start(vm_name, '--paused')
            logging.info('VM state: %s' %
                         virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'serial_terminal':
            grub_serial_terminal()
            check_boot()
        if checkpoint == 'no_space':

            @vm_shell
            def take_space(**kwargs):
                create_large_file(kwargs['session'], 20)

            take_space()
        if checkpoint.startswith('host_no_space'):
            session = aexpect.ShellSession('sh')
            create_large_file(session, 1000)
            if checkpoint == 'host_no_space_setcache':
                logging.info('Set LIBGUESTFS_CACHEDIR=/home')
                os.environ['LIBGUESTFS_CACHEDIR'] = '/home'
        if checkpoint == 'corrupt_rpmdb':
            corrupt_rpmdb()
        if checkpoint.startswith('network'):
            change_network_model(checkpoint[8:])
        if checkpoint == 'multi_netcards':
            attach_network_card('virtio')
            attach_network_card('e1000')
            params['mac_address'] = []
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            network_list = vmxml.get_iface_all()
            for mac in network_list:
                if network_list[mac].get('type') == 'network':
                    params['mac_address'].append(mac)
            if len(params['mac_address']) < 2:
                test.error('Not enough network interface')
            logging.debug('MAC address: %s' % params['mac_address'])
        if checkpoint.startswith(('spice', 'vnc')):
            if checkpoint == 'spice_encrypt':
                spice_passwd = {
                    'type': 'spice',
                    'passwd': params.get('spice_passwd', 'redhat')
                }
                vm_xml.VMXML.set_graphics_attr(vm_name, spice_passwd)
                params[checkpoint] = {
                    'type': 'spice',
                    'passwdValidTo': '1970-01-01T00:00:01'
                }
            else:
                graphic_video = checkpoint.split('_')
                graphic = graphic_video[0]
                logging.info('Set graphic type to %s', graphic)
                vm_xml.VMXML.set_graphics_attr(vm_name, {'type': graphic})
                if len(graphic_video) > 1:
                    video_type = graphic_video[1]
                    logging.info('Set video type to %s', video_type)
                    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
                    video = vmxml.xmltreefile.find('devices').find(
                        'video').find('model')
                    video.set('type', video_type)
                    vmxml.sync()
        if checkpoint.startswith('listen'):
            listen_type = checkpoint.split('_')[-1]
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            listen = vmxml.xmltreefile.find('devices').find('graphics').find(
                'listen')
            listen.set('type', listen_type)
            vmxml.sync()
        if checkpoint == 'host_selinux_on':
            params['selinux_stat'] = utils_selinux.get_status()
            utils_selinux.set_status('enforcing')
        if checkpoint.startswith('selinux'):
            set_selinux(checkpoint[8:])
        if checkpoint.startswith('host_firewalld'):
            service_mgr = service.ServiceManager()
            logging.info('Backing up firewall services status')
            params['bk_firewalld_status'] = service_mgr.status('firewalld')
            if 'start' in checkpoint:
                service_mgr.start('firewalld')
            if 'stop' in checkpoint:
                service_mgr.stop('firewalld')
        if checkpoint == 'guest_firewalld_status':
            get_firewalld_status()
        if checkpoint == 'remove_securetty':
            logging.info('Remove /etc/securetty file from guest')
            cmd = ['rm -f /etc/securetty']
            vm_cmd(cmd)
        if checkpoint == 'ntpd_on':
            logging.info('Set service ntpd on')
            cmd = ['yum -y install ntp', 'systemctl start ntpd']
            vm_cmd(cmd)
        if checkpoint == 'sync_ntp':
            logging.info('Sync time with %s', ntp_server)
            cmd = ['yum -y install ntpdate', 'ntpdate %s' % ntp_server]
            vm_cmd(cmd)
        if checkpoint == 'blank_2nd_disk':
            disk_path = os.path.join(data_dir.get_tmp_dir(), 'blank.img')
            logging.info('Create blank disk %s', disk_path)
            process.run('truncate -s 1G %s' % disk_path)
            logging.info('Attach blank disk to vm')
            attach_removable_media('disk', disk_path, 'vdc')
            logging.debug(virsh.dumpxml(vm_name))
        if checkpoint in ['only_net', 'only_br']:
            logging.info('Detatch all networks')
            virsh.detach_interface(vm_name, 'network --current', debug=True)
            logging.info('Detatch all bridges')
            virsh.detach_interface(vm_name, 'bridge --current', debug=True)
        if checkpoint == 'only_net':
            logging.info('Attach network')
            virsh.attach_interface(vm_name,
                                   'network default --current',
                                   debug=True)
            v2v_params.pop('bridge')
        if checkpoint == 'only_br':
            logging.info('Attatch bridge')
            virsh.attach_interface(vm_name,
                                   'bridge virbr0 --current',
                                   debug=True)
            v2v_params.pop('network')
        if checkpoint == 'no_libguestfs_backend':
            os.environ.pop('LIBGUESTFS_BACKEND')
        if checkpoint == 'file_image':
            vm = env.get_vm(vm_name)
            disk = vm.get_first_disk_devices()
            logging.info('Disk type is %s', disk['type'])
            if disk['type'] != 'file':
                test.error('Guest is not with file image')
        virsh.dumpxml(vm_name, debug=True)
        v2v_result = utils_v2v.v2v_cmd(v2v_params)
        if v2v_params.get('new_name'):
            vm_name = params['main_vm'] = v2v_params['new_name']
        check_result(v2v_result, status_error)
    finally:
        if params.get('vmchecker'):
            params['vmchecker'].cleanup()
        if output_mode == 'libvirt':
            pvt.cleanup_pool(pool_name, pool_type, pool_target, '')
        if backup_xml:
            backup_xml.sync()
        if params.get('selinux_stat') and params['selinux_stat'] != 'disabled':
            utils_selinux.set_status(params['selinux_stat'])
        if 'bk_firewalld_status' in params:
            service_mgr = service.ServiceManager()
            if service_mgr.status(
                    'firewalld') != params['bk_firewalld_status']:
                if params['bk_firewalld_status']:
                    service_mgr.start('firewalld')
                else:
                    service_mgr.stop('firewalld')
        if checkpoint.startswith('host_no_space'):
            large_file = os.path.join(data_dir.get_tmp_dir(), 'file.large')
            if os.path.isfile(large_file):
                os.remove(large_file)
示例#25
0
     cmd = ['yum -y install ntp', 'systemctl start ntpd']
     vm_cmd(cmd)
 if checkpoint == 'sync_ntp':
     logging.info('Sync time with %s', ntp_server)
     cmd = ['yum -y install ntpdate', 'ntpdate %s' % ntp_server]
     vm_cmd(cmd)
 if checkpoint == 'blank_2nd_disk':
     disk_path = os.path.join(data_dir.get_tmp_dir(), 'blank.img')
     logging.info('Create blank disk %s', disk_path)
     process.run('truncate -s 1G %s' % disk_path)
     logging.info('Attach blank disk to vm')
     attach_removable_media('disk', disk_path, 'vdc')
     logging.debug(virsh.dumpxml(vm_name))
 if checkpoint in ['only_net', 'only_br']:
     logging.info('Detatch all networks')
     virsh.detach_interface(vm_name, 'network --current', debug=True)
     logging.info('Detatch all bridges')
     virsh.detach_interface(vm_name, 'bridge --current', debug=True)
 if checkpoint == 'only_net':
     logging.info('Attach network')
     virsh.attach_interface(vm_name,
                            'network default --current',
                            debug=True)
     v2v_params.pop('bridge')
 if checkpoint == 'only_br':
     logging.info('Attatch bridge')
     virsh.attach_interface(vm_name,
                            'bridge virbr0 --current',
                            debug=True)
     v2v_params.pop('network')
 if checkpoint == 'no_libguestfs_backend':
示例#26
0
 def vm_stress_events(self, event, vm):
     """
     Stress events
     :param event: event name
     :param vm: vm object
     """
     dargs = {'ignore_status': True, 'debug': True}
     for itr in range(self.iterations):
         if "vcpupin" in event:
             for vcpu in range(int(self.current_vcpu)):
                 result = virsh.vcpupin(vm.name, vcpu,
                                        random.choice(self.host_cpu_list),
                                        **dargs)
                 if not self.ignore_status:
                     libvirt.check_exit_status(result)
         elif "emulatorpin" in event:
             for vcpu in range(int(self.current_vcpu)):
                 result = virsh.emulatorpin(vm.name,
                                            random.choice(
                                                self.host_cpu_list),
                                            **dargs)
                 if not self.ignore_status:
                     libvirt.check_exit_status(result)
         elif "suspend" in event:
             result = virsh.suspend(vm.name, **dargs)
             if not self.ignore_status:
                 libvirt.check_exit_status(result)
             time.sleep(self.event_sleep_time)
             result = virsh.resume(vm.name, **dargs)
             if not self.ignore_status:
                 libvirt.check_exit_status(result)
         elif "cpuhotplug" in event:
             result = virsh.setvcpus(vm.name, self.max_vcpu, "--live",
                                     **dargs)
             if not self.ignore_status:
                 libvirt.check_exit_status(result)
                 exp_vcpu = {'max_config': self.max_vcpu,
                             'max_live': self.max_vcpu,
                             'cur_config': self.current_vcpu,
                             'cur_live': self.max_vcpu,
                             'guest_live': self.max_vcpu}
                 utils_hotplug.check_vcpu_value(
                     vm, exp_vcpu, option="--live")
             time.sleep(self.event_sleep_time)
             result = virsh.setvcpus(vm.name, self.current_vcpu, "--live",
                                     **dargs)
             if not self.ignore_status:
                 libvirt.check_exit_status(result)
                 exp_vcpu = {'max_config': self.max_vcpu,
                             'max_live': self.max_vcpu,
                             'cur_config': self.current_vcpu,
                             'cur_live': self.current_vcpu,
                             'guest_live': self.current_vcpu}
                 utils_hotplug.check_vcpu_value(
                     vm, exp_vcpu, option="--live")
         elif "reboot" in event:
             vm.reboot()
         elif "nethotplug" in event:
             for iface_num in range(int(self.iface_num)):
                 logging.debug("Try to attach interface %d" % iface_num)
                 mac = utils_net.generate_mac_address_simple()
                 options = ("%s %s --model %s --mac %s %s" %
                            (self.iface_type, self.iface_source['network'],
                             self.iface_model, mac, self.attach_option))
                 logging.debug("VM name: %s , Options for Network attach: %s", vm.name, options)
                 ret = virsh.attach_interface(vm.name, options,
                                              ignore_status=True)
                 time.sleep(self.event_sleep_time)
                 if not self.ignore_status:
                     libvirt.check_exit_status(ret)
                 if self.detach_option:
                     options = ("--type %s --mac %s %s" %
                                (self.iface_type, mac, self.detach_option))
                     logging.debug("VM name: %s , Options for Network detach: %s", vm.name, options)
                     ret = virsh.detach_interface(vm.name, options,
                                                  ignore_status=True)
                     if not self.ignore_status:
                         libvirt.check_exit_status(ret)
         elif "diskhotplug" in event:
             for disk_num in range(len(self.device_source_names)):
                 disk = {}
                 disk_attach_error = False
                 disk_name = os.path.join(self.path, vm.name, self.device_source_names[disk_num])
                 device_source = libvirt.create_local_disk(
                     self.disk_type, disk_name, self.disk_size, disk_format=self.disk_format)
                 disk.update({"format": self.disk_format,
                              "source": device_source})
                 disk_xml = Disk(self.disk_type)
                 disk_xml.device = self.disk_device
                 disk_xml.driver = {"name": self.disk_driver, "type": self.disk_format}
                 ret = virsh.attach_disk(vm.name, disk["source"], self.device_target[disk_num], self.attach_option, debug=True)
                 if not self.ignore_status:
                     libvirt.check_exit_status(ret, disk_attach_error)
                 if self.detach_option:
                     ret = virsh.detach_disk(vm.name, self.device_target[disk_num], extra=self.detach_option)
                     if not self.ignore_status:
                         libvirt.check_exit_status(ret)
                     libvirt.delete_local_disk(self.disk_type, disk_name)
         else:
             raise NotImplementedError
示例#27
0
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()
示例#28
0
def run(test, params, env):
    """
    Test interface xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac=None):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        if mac:
            iface.mac_address = mac
        if iface_rom:
            iface.rom = eval(iface_rom)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    def get_all_mac_in_vm():
        """
        get the mac address list of all the interfaces from a running vm os

        return: a list of the mac addresses
        """
        mac_list = []
        interface_list = vm.get_interfaces()
        for iface_ in interface_list:
            mac_ = vm.get_interface_mac(iface_)
            mac_list.append(mac_)
        return mac_list

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source", "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    iface_rom = params.get("iface_rom")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")
    err_msg_rom = params.get("err_msg_rom")
    del_pci = "yes" == params.get("del_pci", "no")
    del_mac = "yes" == params.get("del_mac", "no")
    del_alias = "yes" == params.get("del_alias", "no")
    set_pci = "yes" == params.get("set_pci", "no")
    set_mac = "yes" == params.get("set_mac", "no")
    set_alias = "yes" == params.get("set_alias", "no")
    status_error = "yes" == params.get("status_error", "no")
    pci_addr = params.get("pci")
    check_mac = "yes" == params.get("check_mac", "no")
    vnet_mac = params.get("vnet_mac", None)
    customer_alias = "yes" == params.get("customer_alias", "no")
    detach_error = params.get("detach_error", None)

    libvirt_version.is_libvirt_feature_supported(params)
    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                        iface_xml_obj = create_iface_xml(mac)
                    elif check_mac:
                        iface_xml_obj = create_iface_xml()
                    else:
                        mac = utils_net.generate_mac_address_simple()
                        iface_xml_obj = create_iface_xml(mac)
                    if customer_alias:
                        random_id = process.run(
                            "uuidgen", ignore_status=True,
                            shell=True).stdout_text.strip()
                        alias_str = "ua-" + random_id
                        iface_xml_obj.alias = {"name": alias_str}
                        logging.debug("Update number %s interface xml: %s", i,
                                      iface_xml_obj)
                    iface_xml_obj.xmltreefile.write()
                    if check_mac:
                        mac_bef = get_all_mac_in_vm()
                    ret = virsh.attach_device(vm_name,
                                              iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True,
                                              debug=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name,
                                                 options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug(
                            "No more pci slots, can't attach more devices")
                        break
                    elif ret.stderr.count("doesn't support option %s" %
                                          attach_option):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug(
                            "option %s is not supported when domain running is %s"
                            % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options
                                        and attach_option):
                            test.fail(
                                "return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" %
                                      attach_option)
                        if not ("--current" in sep_options
                                and len(sep_options) > 1):
                            test.fail(
                                "return mutualy exclusive, but it is unexpected"
                            )
                    elif err_msg_rom and err_msg_rom in ret.stderr:
                        logging.debug("Attach failed with expect err msg: %s" %
                                      err_msg_rom)
                    else:
                        test.fail("Failed to attach-interface: %s" %
                                  ret.stderr.strip())
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        if check_mac:
                            mac_aft = get_all_mac_in_vm()
                            add_mac = list(
                                set(mac_aft).difference(set(mac_bef)))
                            try:
                                mac = add_mac[0]
                                logging.debug(
                                    "The mac address of the attached interface is %s"
                                    % mac)
                            except IndexError:
                                test.fail(
                                    "Can not find the new added interface in the guest os!"
                                )
                        iface_list.append({
                            'mac': mac,
                            'iface_xml': iface_xml_obj
                        })
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False

            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist,
                                                       timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(
                        vm_name, iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".format(
                            if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")
                    if vnet_mac:
                        # get the name of the backend tap device
                        iface_params = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, mac)
                        target_name = iface_params['target']['dev']
                        # check the tap device mac on host
                        tap_info = process.run("ip l show %s" % target_name,
                                               shell=True,
                                               ignore_status=True).stdout_text
                        logging.debug("vnet_mac should be %s" % vnet_mac)
                        logging.debug(
                            "check on host for the details of tap device %s: %s"
                            % (target_name, tap_info))
                        if vnet_mac not in tap_info:
                            test.fail(
                                "The mac address of the tap device do not match!"
                            )
            # Detach hot/cold-plugged interface at last
            if detach_device:
                logging.debug("detach interface here:")
                if attach_device:
                    vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    iface_xml_ls = vmxml.get_devices("interface")
                    iface_xml_ls_det = iface_xml_ls[1:]
                    for iface_xml_det in iface_xml_ls_det:
                        if del_mac:
                            iface_xml_det.del_mac_address()
                        if del_pci:
                            iface_xml_det.del_address()
                        if del_alias:
                            iface_xml_det.del_alias()
                        if set_mac:
                            mac = utils_net.generate_mac_address_simple()
                            iface_xml_det.set_mac_address(mac)
                        if set_pci:
                            pci_dict = ast.literal_eval(pci_addr)
                            addr = iface_xml_det.new_iface_address(
                                **{"attrs": pci_dict})
                            iface_xml_det.set_address(addr)
                        if set_alias:
                            random_id = process.run(
                                "uuidgen", ignore_status=True,
                                shell=True).stdout_text.strip()
                            alias_str = "ua-" + random_id
                            iface_xml_det.set_alias({"name": alias_str})
                        ori_pid_libvirtd = process.getoutput("pidof libvirtd")
                        logging.debug(
                            "The xml of the interface to detach is %s",
                            iface_xml_det)
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_det.xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret, status_error)
                        if detach_device and status_error and detach_error:
                            if not ret.stderr.count(detach_error):
                                test.error(
                                    "Detach fail as expected, but the error msg %s can not match!"
                                    % ret.stderr)
                        aft_pid_libvirtd = process.getoutput("pidof libvirtd")
                        if not utils_libvirtd.Libvirtd.is_running or ori_pid_libvirtd != aft_pid_libvirtd:
                            test.fail(
                                "Libvirtd crash after detach non-exists interface"
                            )
                else:
                    for iface in iface_list:
                        options = ("%s --mac %s" % (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                if not status_error:
                    for iface in iface_list:
                        if 'mac' in iface:
                            polltime = time.time() + poll_timeout
                            while True:
                                # Check interface in dumpxml output
                                if not vm_xml.VMXML.get_iface_by_mac(
                                        vm_name, iface['mac']):
                                    break
                                else:
                                    time.sleep(2)
                                    if time.time() > polltime:
                                        test.fail("Interface still "
                                                  "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#29
0
def run(test, params, env):
    """
    convert specific kvm guest to rhev
    """
    for v in list(params.values()):
        if "V2V_EXAMPLE" in v:
            test.cancel("Please set real value for %s" % v)
    if utils_v2v.V2V_EXEC is None:
        raise ValueError('Missing command: virt-v2v')
    enable_legacy_policy = params_get(params, "enable_legacy_policy") == 'yes'
    hypervisor = params.get("hypervisor")
    vm_name = params.get('main_vm', 'EXAMPLE')
    target = params.get('target')
    remote_host = params.get('remote_host', 'EXAMPLE')
    input_mode = params.get("input_mode")
    output_mode = params.get('output_mode')
    output_format = params.get('output_format')
    source_user = params.get("username", "root")
    os_pool = storage = params.get('output_storage')
    bridge = params.get('bridge')
    network = params.get('network')
    ntp_server = params.get('ntp_server')
    vpx_dc = params.get("vpx_dc")
    esx_ip = params.get("esx_hostname")
    address_cache = env.get('address_cache')
    pool_name = params.get('pool_name', 'v2v_test')
    pool_type = params.get('pool_type', 'dir')
    pool_target = params.get('pool_target_path', 'v2v_pool')
    pvt = utlv.PoolVolumeTest(test, params)
    v2v_opts = '-v -x' if params.get('v2v_debug', 'on') in ['on', 'force_on'
                                                            ] else ''
    if params.get("v2v_opts"):
        # Add a blank by force
        v2v_opts += ' ' + params.get("v2v_opts")
    v2v_timeout = int(params.get('v2v_timeout', 3600))
    skip_vm_check = params.get('skip_vm_check', 'no')
    status_error = 'yes' == params.get('status_error', 'no')
    checkpoint = params.get('checkpoint', '')
    debug_kernel = 'debug_kernel' == checkpoint
    backup_list = [
        'floppy', 'floppy_devmap', 'fstab_cdrom', 'sata_disk',
        'network_rtl8139', 'network_e1000', 'spice', 'spice_encrypt',
        'spice_qxl', 'spice_cirrus', 'vnc_qxl', 'vnc_cirrus', 'blank_2nd_disk',
        'listen_none', 'listen_socket', 'only_net', 'only_br'
    ]
    error_list = []

    # For construct rhv-upload option in v2v cmd
    output_method = params.get("output_method")
    rhv_upload_opts = params.get("rhv_upload_opts")
    storage_name = params.get('storage_name')
    # for get ca.crt file from ovirt engine
    rhv_passwd = params.get("rhv_upload_passwd")
    rhv_passwd_file = params.get("rhv_upload_passwd_file")
    ovirt_engine_passwd = params.get("ovirt_engine_password")
    ovirt_hostname = params.get("ovirt_engine_url").split(
        '/')[2] if params.get("ovirt_engine_url") else None
    ovirt_ca_file_path = params.get("ovirt_ca_file_path")
    local_ca_file_path = params.get("local_ca_file_path")

    # For VDDK
    input_transport = params.get("input_transport")
    vddk_libdir = params.get('vddk_libdir')
    # nfs mount source
    vddk_libdir_src = params.get('vddk_libdir_src')
    vddk_thumbprint = params.get('vddk_thumbprint')

    # Prepare step for different hypervisor
    if enable_legacy_policy:
        update_crypto_policy("LEGACY")

    if hypervisor == "esx":
        source_ip = params.get("vpx_hostname")
        source_pwd = params.get("vpx_password")
        vpx_passwd_file = params.get("vpx_passwd_file")
        # Create password file to access ESX hypervisor
        with open(vpx_passwd_file, 'w') as f:
            f.write(source_pwd)
    elif hypervisor == "xen":
        source_ip = params.get("xen_hostname")
        source_pwd = params.get("xen_host_passwd")
        # Set up ssh access using ssh-agent and authorized_keys
        xen_pubkey, xen_session = utils_v2v.v2v_setup_ssh_key(source_ip,
                                                              source_user,
                                                              source_pwd,
                                                              auto_close=False)
        try:
            utils_misc.add_identities_into_ssh_agent()
        except Exception as e:
            process.run("ssh-agent -k")
            test.error("Fail to setup ssh-agent \n %s" % str(e))
    elif hypervisor == "kvm":
        source_ip = None
        source_pwd = None
    else:
        test.cancel("Unsupported hypervisor: %s" % hypervisor)

    # Create libvirt URI
    v2v_uri = utils_v2v.Uri(hypervisor)
    remote_uri = v2v_uri.get_uri(source_ip, vpx_dc, esx_ip)
    LOG.debug("libvirt URI for converting: %s", remote_uri)

    # Make sure the VM exist before convert
    v2v_virsh = None
    close_virsh = False
    if hypervisor == 'kvm':
        v2v_virsh = virsh
    else:
        virsh_dargs = {
            'uri': remote_uri,
            'remote_ip': source_ip,
            'remote_user': source_user,
            'remote_pwd': source_pwd,
            'auto_close': True,
            'debug': True
        }
        v2v_virsh = virsh.VirshPersistent(**virsh_dargs)
        LOG.debug('a new virsh session %s was created', v2v_virsh)
        close_virsh = True
    if not v2v_virsh.domain_exists(vm_name):
        test.error("VM '%s' not exist" % vm_name)

    def log_fail(msg):
        """
        Log error and update error list
        """
        LOG.error(msg)
        error_list.append(msg)

    def vm_shell(func):
        """
        Decorator of shell session to vm
        """
        def wrapper(*args, **kwargs):
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_dead():
                LOG.info('VM is down. Starting it now.')
                vm.start()
            session = vm.wait_for_login()
            kwargs['session'] = session
            kwargs['vm'] = vm
            func(*args, **kwargs)
            if session:
                session.close()
            vm.shutdown()

        return wrapper

    def check_disks(vmcheck):
        """
        Check disk counts inside the VM
        """
        # Initialize windows boot up
        os_type = params.get("os_type", "linux")
        expected_disks = int(params.get("ori_disks", "1"))
        LOG.debug("Expect %s disks im VM after convert", expected_disks)
        # Get disk counts
        if os_type == "linux":
            cmd = "lsblk |grep disk |wc -l"
            disks = int(vmcheck.session.cmd(cmd).strip())
        else:
            cmd = r"echo list disk > C:\list_disk.txt"
            vmcheck.session.cmd(cmd)
            cmd = r"diskpart /s C:\list_disk.txt"
            output = vmcheck.session.cmd(cmd).strip()
            LOG.debug("Disks in VM: %s", output)
            disks = len(re.findall(r'Disk\s\d', output))
        LOG.debug("Find %s disks in VM after convert", disks)
        if disks == expected_disks:
            LOG.info("Disk counts is expected")
        else:
            log_fail("Disk counts is wrong")

    def check_vmlinuz_initramfs(v2v_output):
        """
        Check if vmlinuz matches initramfs on multi-kernel case
        """
        LOG.debug('Checking if vmlinuz matches initramfs')
        kernel_strs = re.findall(r'(\* kernel.*?\/boot\/config){1,}',
                                 v2v_output, re.DOTALL)
        if len(kernel_strs) == 0:
            test.error("Not find kernel information")

        # Remove duplicate items by set
        LOG.debug('Boots and kernel info: %s' % set(kernel_strs))
        for str_i in set(kernel_strs):
            # Fine all versions
            kernel_vers = re.findall(r'((?:\d+\.){1,}\d+-(?:\d+\.){1,}\w+)',
                                     str_i)
            LOG.debug('kernel related versions: %s' % kernel_vers)
            # kernel_vers = [kernel, vmlinuz, initramfs] and they should be
            # same
            if len(kernel_vers) < 3 or len(set(kernel_vers)) != 1:
                log_fail("kernel versions does not match: %s" % kernel_vers)

    def check_boot_kernel(vmcheck):
        """
        Check if converted vm use the latest kernel
        """
        _, current_kernel = vmcheck.run_cmd('uname -r')

        if 'debug' in current_kernel:
            log_fail('Current kernel is a debug kernel: %s' % current_kernel)

        # 'sort -V' can satisfy our testing, even though it's not strictly perfect.
        # The last one is always the latest kernel version
        kernel_normal_list = vmcheck.run_cmd(
            'rpm -q kernel | sort -V')[1].strip().splitlines()
        status, kernel_debug = vmcheck.run_cmd('rpm -q kernel-debug')
        if status != 0:
            test.error('Not found kernel-debug package')
        all_kernel_list = kernel_normal_list + kernel_debug.strip().splitlines(
        )
        LOG.debug('All kernels: %s' % all_kernel_list)
        if len(all_kernel_list) < 3:
            test.error(
                'Needs at least 2 normal kernels and 1 debug kernel in VM')

        # The latest non-debug kernel must be kernel_normal_list[-1]
        if current_kernel.strip() != kernel_normal_list[-1].lstrip('kernel-'):
            log_fail('Check boot kernel failed')

    def check_floppy_exist(vmcheck):
        """
        Check if floppy exists after conversion
        """
        blk = vmcheck.session.cmd('lsblk')
        LOG.info(blk)
        if not re.search('fd0', blk):
            log_fail('Floppy not found')

    def attach_removable_media(type, source, dev):
        bus = {'cdrom': 'ide', 'floppy': 'fdc', 'disk': 'virtio'}
        args = {
            'driver': 'qemu',
            'subdriver': 'raw',
            'sourcetype': 'file',
            'type': type,
            'targetbus': bus[type]
        }
        if type == 'cdrom':
            args.update({'mode': 'readonly'})
        config = ''
        # Join all options together to get command line
        for key in list(args.keys()):
            config += ' --%s %s' % (key, args[key])
        config += ' --current'
        virsh.attach_disk(vm_name, source, dev, extra=config)

    def change_disk_bus(dest):
        """
        Change all disks' bus type to $dest
        """
        bus_list = ['ide', 'sata', 'virtio']
        if dest not in bus_list:
            test.error('Bus type not support')
        dev_prefix = ['h', 's', 'v']
        dev_table = dict(list(zip(bus_list, dev_prefix)))
        LOG.info('Change disk bus to %s' % dest)
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        disks = vmxml.get_disk_all_by_expr('device==disk')
        index = 0
        for disk in list(disks.values()):
            if disk.get('device') != 'disk':
                continue
            target = disk.find('target')
            target.set('bus', dest)
            target.set('dev',
                       dev_table[dest] + 'd' + string.ascii_lowercase[index])
            disk.remove(disk.find('address'))
            index += 1
        vmxml.sync()

    def change_network_model(model):
        """
        Change network model to $model
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        network_list = vmxml.get_iface_all()
        for node in list(network_list.values()):
            if node.get('type') == 'network':
                node.find('model').set('type', model)
        vmxml.sync()

    def attach_network_card(model):
        """
        Attach network card based on model
        """
        if model not in ('e1000', 'virtio', 'rtl8139'):
            test.error('Network model not support')
        options = {'type': 'network', 'source': 'default', 'model': model}
        line = ''
        for key in options:
            line += ' --' + key + ' ' + options[key]
        line += ' --current'
        LOG.debug(virsh.attach_interface(vm_name, option=line))

    def check_multi_netcards(mac_list, vmxml):
        """
        Check if number and type of network cards meet expectation
        """
        xmltree = xml_utils.XMLTreeFile(vmxml)
        iface_nodes = xmltree.find('devices').findall('interface')
        iflist = {}
        for node in iface_nodes:
            mac_addr = node.find('mac').get('address')
            iflist[mac_addr] = node

        LOG.debug('MAC list before v2v: %s' % mac_list)
        LOG.debug('MAC list after  v2v: %s' % list(iflist.keys()))
        if set(mac_list).difference(list(iflist.keys())):
            log_fail('Missing network interface')
        for mac in iflist:
            if iflist[mac].find('model').get('type') != 'virtio':
                log_fail('Network not convert to virtio')

    @vm_shell
    def insert_floppy_devicemap(**kwargs):
        """
        Add an entry of floppy to device.map
        """
        session = kwargs['session']
        line = '(fd0)     /dev/fd0'
        devmap = '/boot/grub/device.map'
        if session.cmd_status('ls %s' % devmap):
            devmap = '/boot/grub2/device.map'
        cmd_exist = 'grep \'(fd0)\' %s' % devmap
        cmd_set = 'sed -i \'2i%s\' %s' % (line, devmap)
        if session.cmd_status(cmd_exist):
            session.cmd(cmd_set)

    def make_label(session):
        """
        Label a volume, swap or root volume
        """
        # swaplabel for rhel7 with xfs, e2label for rhel6 or ext*
        cmd_map = {
            'root': 'e2label %s ROOT',
            'swap': 'swaplabel -L SWAPPER %s'
        }
        if not session.cmd_status('swaplabel --help'):
            blk = 'swap'
        elif not session.cmd_status('which e2label'):
            blk = 'root'
        else:
            test.error('No tool to make label')
        entry = session.cmd('blkid|grep %s' % blk).strip()
        path = entry.split()[0].strip(':')
        cmd_label = cmd_map[blk] % path
        if 'LABEL' not in entry:
            session.cmd(cmd_label)
        return blk

    @vm_shell
    def specify_fstab_entry(type, **kwargs):
        """
        Specify entry in fstab file
        """
        type_list = ['cdrom', 'uuid', 'label', 'sr0', 'invalid']
        if type not in type_list:
            test.error('Not support %s in fstab' % type)
        session = kwargs['session']
        # Specify cdrom device
        if type == 'cdrom':
            line = '/dev/cdrom /media/CDROM auto exec'
            if 'grub2' in utils_misc.get_bootloader_cfg(session):
                line += ',nofail'
            line += ' 0 0'
            LOG.debug('fstab entry is "%s"', line)
            cmd = [
                'mkdir -p /media/CDROM', 'mount /dev/cdrom /media/CDROM',
                'echo "%s" >> /etc/fstab' % line
            ]
            for i in range(len(cmd)):
                session.cmd(cmd[i])
        elif type == 'sr0':
            line = params.get('fstab_content')
            session.cmd('echo "%s" >> /etc/fstab' % line)
        elif type == 'invalid':
            line = utils_misc.generate_random_string(6)
            session.cmd('echo "%s" >> /etc/fstab' % line)
        else:
            map = {'uuid': 'UUID', 'label': 'LABEL'}
            LOG.info(type)
            if session.cmd_status('cat /etc/fstab|grep %s' % map[type]):
                # Specify device by UUID
                if type == 'uuid':
                    entry = session.cmd(
                        'blkid -s UUID|grep swap').strip().split()
                    # Replace path for UUID
                    origin = entry[0].strip(':')
                    replace = entry[1].replace('"', '')
                # Specify device by label
                elif type == 'label':
                    blk = make_label(session)
                    entry = session.cmd('blkid|grep %s' % blk).strip()
                    # Remove " from LABEL="****"
                    replace = entry.split()[1].strip().replace('"', '')
                    # Replace the original id/path with label
                    origin = entry.split()[0].strip(':')
                cmd_fstab = "sed -i 's|%s|%s|' /etc/fstab" % (origin, replace)
                session.cmd(cmd_fstab)
        fstab = session.cmd_output('cat /etc/fstab')
        LOG.debug('Content of /etc/fstab:\n%s', fstab)

    def create_large_file(session, left_space):
        """
        Create a large file to make left space of root less than $left_space MB
        """
        cmd_guestfish = "guestfish get-cachedir"
        tmp_dir = session.cmd_output(cmd_guestfish).split()[-1]
        LOG.debug('Command output of tmp_dir: %s', tmp_dir)
        cmd_df = "df -m %s --output=avail" % tmp_dir
        df_output = session.cmd(cmd_df).strip()
        LOG.debug('Command output: %s', df_output)
        avail = int(df_output.strip().split('\n')[-1])
        LOG.info('Available space: %dM' % avail)
        if avail <= left_space - 1:
            return None
        if not os.path.exists(tmp_dir):
            os.mkdir(tmp_dir)
        large_file = os.path.join(tmp_dir, 'file.large')
        cmd_create = 'dd if=/dev/zero of=%s bs=1M count=%d' % \
                     (large_file, avail - left_space + 2)
        session.cmd(cmd_create, timeout=v2v_timeout)
        newAvail = int(session.cmd(cmd_df).strip().split('\n')[-1])
        LOG.info('New Available space: %sM' % newAvail)
        return large_file

    @vm_shell
    def corrupt_rpmdb(**kwargs):
        """
        Corrupt rpm db
        """
        session = kwargs['session']
        # If __db.* exist, remove them, then touch _db.001 to corrupt db.
        if not session.cmd_status('ls /var/lib/rpm/__db.001'):
            session.cmd('rm -f /var/lib/rpm/__db.*')
        session.cmd('touch /var/lib/rpm/__db.001')
        if not session.cmd_status('yum update'):
            test.error('Corrupt rpmdb failed')

    @vm_shell
    def grub_serial_terminal(**kwargs):
        """
        Edit the serial and terminal lines of grub.conf
        """
        session = kwargs['session']
        vm = kwargs['vm']
        grub_file = utils_misc.get_bootloader_cfg(session)
        if 'grub2' in grub_file:
            test.cancel('Skip this case on grub2')
        cmd = "sed -i '1iserial -unit=0 -speed=115200\\n"
        cmd += "terminal -timeout=10 serial console' %s" % grub_file
        session.cmd(cmd)

    @vm_shell
    def set_selinux(value, **kwargs):
        """
        Set selinux stat of guest
        """
        session = kwargs['session']
        current_stat = session.cmd_output('getenforce').strip()
        LOG.debug('Current selinux status: %s', current_stat)
        if current_stat != value:
            cmd = "sed -E -i 's/(^SELINUX=).*?/\\1%s/' /etc/selinux/config" % value
            LOG.info('Set selinux stat with command %s', cmd)
            session.cmd(cmd)

    @vm_shell
    def get_firewalld_status(**kwargs):
        """
        Return firewalld service status of vm
        """
        session = kwargs['session']
        # Example: Active: active (running) since Fri 2019-03-15 01:03:39 CST;
        # 3min 48s ago
        firewalld_status = session.cmd(
            'systemctl status firewalld.service|grep Active:',
            ok_status=[0, 3]).strip()
        # Exclude the time string because time changes if vm restarts
        firewalld_status = re.search(r'Active:\s\w*\s\(\w*\)',
                                     firewalld_status).group()
        LOG.info('Status of firewalld: %s', firewalld_status)
        params[checkpoint] = firewalld_status

    def check_firewalld_status(vmcheck, expect_status):
        """
        Check if status of firewalld meets expectation
        """
        firewalld_status = vmcheck.session.cmd(
            'systemctl status '
            'firewalld.service|grep Active:',
            ok_status=[0, 3]).strip()
        # Exclude the time string because time changes if vm restarts
        firewalld_status = re.search(r'Active:\s\w*\s\(\w*\)',
                                     firewalld_status).group()
        LOG.info('Status of firewalld after v2v: %s', firewalld_status)
        if firewalld_status != expect_status:
            log_fail('Status of firewalld changed after conversion')

    @vm_shell
    def vm_cmd(cmd_list, **kwargs):
        """
        Execute a list of commands on guest.
        """
        session = kwargs['session']
        for cmd in cmd_list:
            LOG.info('Send command "%s"', cmd)
            # 'chronyc waitsync' needs more than 2mins to sync clock,
            # We set timeout to 300s will not have side-effects for other
            # commands.
            status, output = session.cmd_status_output(cmd, timeout=300)
            LOG.debug('Command output:\n%s', output)
            if status != 0:
                test.error('Command "%s" failed' % cmd)
        LOG.info('All commands executed')

    def check_time_keep(vmcheck):
        """
        Check time drift after conversion.
        """
        LOG.info('Check time drift')
        output = vmcheck.session.cmd('chronyc tracking')
        LOG.debug(output)
        if 'Not synchronised' in output:
            log_fail('Time not synchronised')
        lst_offset = re.search('Last offset *?: *(.*) ', output).group(1)
        drift = abs(float(lst_offset))
        LOG.debug('Time drift is: %f', drift)
        if drift > 3:
            log_fail('Time drift exceeds 3 sec')

    def check_boot():
        """
        Check if guest can boot up after configuration
        """
        try:
            vm = libvirt_vm.VM(vm_name, params, test.bindir,
                               env.get('address_cache'))
            if vm.is_alive():
                vm.shutdown()
            LOG.info('Booting up %s' % vm_name)
            vm.start()
            vm.wait_for_login()
            vm.shutdown()
            LOG.info('%s is down' % vm_name)
        except Exception as e:
            test.error('Bootup guest and login failed: %s' % str(e))

    def check_result(result, status_error):
        """
        Check virt-v2v command result
        """
        utlv.check_exit_status(result, status_error)
        output = result.stdout_text + result.stderr_text
        if not status_error:
            if output_mode == 'json' and not check_json_output(params):
                test.fail('check json output failed')
            if output_mode == 'local' and not check_local_output(params):
                test.fail('check local output failed')
            if output_mode in ['null', 'json', 'local']:
                return

            vmchecker = VMChecker(test, params, env)
            params['vmchecker'] = vmchecker
            if output_mode == 'rhev':
                if not utils_v2v.import_vm_to_ovirt(
                        params, address_cache, timeout=v2v_timeout):
                    test.fail('Import VM failed')
            if output_mode == 'libvirt':
                try:
                    virsh.start(vm_name, debug=True, ignore_status=False)
                except Exception as e:
                    test.fail('Start vm failed: %s' % str(e))
            # Check guest following the checkpoint document after conversion
            if params.get('skip_vm_check') != 'yes':
                ret = vmchecker.run()
                if len(ret) == 0:
                    LOG.info("All common checkpoints passed")
            LOG.debug(vmchecker.vmxml)
            if checkpoint == 'multi_kernel':
                check_boot_kernel(vmchecker.checker)
                check_vmlinuz_initramfs(output)
            if checkpoint == 'floppy':
                # Convert to rhv will remove all removable devices(floppy,
                # cdrom)
                if output_mode in ['local', 'libvirt']:
                    check_floppy_exist(vmchecker.checker)
            if checkpoint == 'multi_disks':
                check_disks(vmchecker.checker)
            if checkpoint == 'multi_netcards':
                check_multi_netcards(params['mac_address'], vmchecker.vmxml)
            if checkpoint.startswith(('spice', 'vnc')):
                if checkpoint == 'spice_encrypt':
                    vmchecker.check_graphics(params[checkpoint])
                else:
                    graph_type = checkpoint.split('_')[0]
                    vmchecker.check_graphics({'type': graph_type})
                    video_type = vmchecker.xmltree.find(
                        './devices/video/model').get('type')
                    if utils_v2v.multiple_versions_compare(
                            V2V_ADAPTE_SPICE_REMOVAL_VER):
                        expect_video_type = 'vga'
                    else:
                        expect_video_type = 'qxl'

                    if video_type.lower() != expect_video_type:
                        log_fail('Video expect %s, actual %s' %
                                 (expect_video_type, video_type))
            if checkpoint.startswith('listen'):
                listen_type = vmchecker.xmltree.find(
                    './devices/graphics/listen').get('type')
                LOG.info('listen type is: %s', listen_type)
                if listen_type != checkpoint.split('_')[-1]:
                    log_fail('listen type changed after conversion')
            if checkpoint.startswith('selinux'):
                status = vmchecker.checker.session.cmd(
                    'getenforce').strip().lower()
                LOG.info('Selinux status after v2v:%s', status)
                if status != checkpoint[8:]:
                    log_fail('Selinux status not match')
            if checkpoint == 'check_selinuxtype':
                expect_output = vmchecker.checker.session.cmd(
                    'cat /etc/selinux/config')
                expect_selinuxtype = re.search(r'^SELINUXTYPE=\s*(\S+)$',
                                               expect_output,
                                               re.MULTILINE).group(1)
                actual_output = vmchecker.checker.session.cmd('sestatus')
                actual_selinuxtype = re.search(
                    r'^Loaded policy name:\s*(\S+)$', actual_output,
                    re.MULTILINE).group(1)
                if actual_selinuxtype != expect_selinuxtype:
                    log_fail('Seliunx type not match')
            if checkpoint == 'guest_firewalld_status':
                check_firewalld_status(vmchecker.checker, params[checkpoint])
            if checkpoint in ['ntpd_on', 'sync_ntp']:
                check_time_keep(vmchecker.checker)
            # Merge 2 error lists
            error_list.extend(vmchecker.errors)
        log_check = utils_v2v.check_log(params, output)
        if log_check:
            log_fail(log_check)
        if len(error_list):
            test.fail('%d checkpoints failed: %s' %
                      (len(error_list), error_list))

    try:
        v2v_sasl = None

        v2v_params = {
            'target': target,
            'hypervisor': hypervisor,
            'main_vm': vm_name,
            'input_mode': input_mode,
            'network': network,
            'bridge': bridge,
            'os_storage': storage,
            'os_pool': os_pool,
            'hostname': source_ip,
            'password': source_pwd,
            'v2v_opts': v2v_opts,
            'new_name': vm_name + utils_misc.generate_random_string(3),
            'output_method': output_method,
            'os_storage_name': storage_name,
            'rhv_upload_opts': rhv_upload_opts,
            'input_transport': input_transport,
            'vcenter_host': source_ip,
            'vcenter_password': source_pwd,
            'vddk_thumbprint': vddk_thumbprint,
            'vddk_libdir': vddk_libdir,
            'vddk_libdir_src': vddk_libdir_src,
            'params': params,
        }
        if vpx_dc:
            v2v_params.update({"vpx_dc": vpx_dc})
        if esx_ip:
            v2v_params.update({"esx_ip": esx_ip})
        output_format = params.get('output_format')
        if output_format:
            v2v_params.update({'of_format': output_format})
        # Build rhev related options
        if output_mode == 'rhev':
            # Create different sasl_user name for different job
            params.update({
                'sasl_user':
                params.get("sasl_user") + utils_misc.generate_random_string(3)
            })
            LOG.info('sals user name is %s' % params.get("sasl_user"))

            # Create SASL user on the ovirt host
            user_pwd = "[['%s', '%s']]" % (params.get("sasl_user"),
                                           params.get("sasl_pwd"))
            v2v_sasl = utils_sasl.SASL(sasl_user_pwd=user_pwd)
            v2v_sasl.server_ip = params.get("remote_ip")
            v2v_sasl.server_user = params.get('remote_user')
            v2v_sasl.server_pwd = params.get('remote_pwd')
            v2v_sasl.setup(remote=True)
            LOG.debug('A SASL session %s was created', v2v_sasl)
            if output_method == 'rhv_upload':
                # Create password file for '-o rhv_upload' to connect to ovirt
                with open(rhv_passwd_file, 'w') as f:
                    f.write(rhv_passwd)
                # Copy ca file from ovirt to local
                remote.scp_from_remote(ovirt_hostname, 22, 'root',
                                       ovirt_engine_passwd, ovirt_ca_file_path,
                                       local_ca_file_path)
        if output_mode == 'local':
            v2v_params['os_directory'] = data_dir.get_tmp_dir()
        if output_mode == 'libvirt':
            pvt.pre_pool(pool_name, pool_type, pool_target, '')
        # Set libguestfs environment variable
        utils_v2v.set_libguestfs_backend(params)

        # Save origin graphic type for result checking if source is KVM
        if hypervisor == 'kvm':
            ori_vm_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            params['ori_graphic'] = ori_vm_xml.xmltreefile.find(
                'devices').find('graphics').get('type')
            params['vm_machine'] = ori_vm_xml.xmltreefile.find(
                './os/type').get('machine')

        backup_xml = None
        # Only kvm guest's xml needs to be backup currently
        if checkpoint in backup_list and hypervisor == 'kvm':
            backup_xml = ori_vm_xml
        if checkpoint == 'multi_disks':
            new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=v2v_virsh)
            disk_count = len(new_xml.get_disk_all_by_expr('device==disk'))
            if disk_count <= 1:
                test.error('Not enough disk devices')
            params['ori_disks'] = disk_count
        if checkpoint == 'sata_disk':
            change_disk_bus('sata')
        if checkpoint.startswith('floppy'):
            if params['vm_machine'] and 'q35' in params['vm_machine'] and int(
                    re.search(r'pc-q35-rhel(\d+)\.',
                              params['vm_machine']).group(1)) >= 8:
                test.cancel(
                    'Device isa-fdc is not supported with machine type %s' %
                    params['vm_machine'])
            img_path = data_dir.get_tmp_dir() + '/floppy.img'
            utlv.create_local_disk('floppy', img_path)
            attach_removable_media('floppy', img_path, 'fda')
            if checkpoint == 'floppy_devmap':
                insert_floppy_devicemap()
        if checkpoint.startswith('fstab'):
            if checkpoint == 'fstab_cdrom':
                img_path = data_dir.get_tmp_dir() + '/cdrom.iso'
                utlv.create_local_disk('iso', img_path)
                attach_removable_media('cdrom', img_path, 'hdc')
            specify_fstab_entry(checkpoint[6:])
        if checkpoint == 'running':
            virsh.start(vm_name)
            LOG.info('VM state: %s' % virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'paused':
            virsh.start(vm_name, '--paused')
            LOG.info('VM state: %s' % virsh.domstate(vm_name).stdout.strip())
        if checkpoint == 'serial_terminal':
            grub_serial_terminal()
            check_boot()
        if checkpoint.startswith('host_no_space'):
            session = aexpect.ShellSession('sh')
            large_file = create_large_file(session, 800)
            if checkpoint == 'host_no_space_setcache':
                LOG.info('Set LIBGUESTFS_CACHEDIR=/home')
                os.environ['LIBGUESTFS_CACHEDIR'] = '/home'
        if checkpoint == 'corrupt_rpmdb':
            corrupt_rpmdb()
        if checkpoint.startswith('network'):
            change_network_model(checkpoint[8:])
        if checkpoint == 'multi_netcards':
            params['mac_address'] = []
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(
                vm_name, virsh_instance=v2v_virsh)
            network_list = vmxml.get_iface_all()
            for mac in network_list:
                if network_list[mac].get('type') in ['bridge', 'network']:
                    params['mac_address'].append(mac)
            if len(params['mac_address']) < 2:
                test.error('Not enough network interface')
            LOG.debug('MAC address: %s' % params['mac_address'])
        if checkpoint.startswith(('spice', 'vnc')):
            if checkpoint == 'spice_encrypt':
                spice_passwd = {
                    'type': 'spice',
                    'passwd': params.get('spice_passwd', 'redhat')
                }
                vm_xml.VMXML.set_graphics_attr(vm_name, spice_passwd)
                params[checkpoint] = {
                    'type': 'spice',
                    'passwdValidTo': '1970-01-01T00:00:01'
                }
            else:
                graphic_video = checkpoint.split('_')
                graphic = graphic_video[0]
                LOG.info('Set graphic type to %s', graphic)
                vm_xml.VMXML.set_graphics_attr(vm_name, {'type': graphic})
                if len(graphic_video) > 1:
                    video_type = graphic_video[1]
                    LOG.info('Set video type to %s', video_type)
                    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
                    video = vmxml.xmltreefile.find('devices').find(
                        'video').find('model')
                    video.set('type', video_type)
                    # cirrus doesn't support 'ram' and 'vgamem' attribute
                    if video_type == 'cirrus':
                        [
                            video.attrib.pop(attr_i)
                            for attr_i in ['ram', 'vgamem']
                            if attr_i in video.attrib
                        ]
                    vmxml.sync()
        if checkpoint.startswith('listen'):
            listen_type = checkpoint.split('_')[-1]
            vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            listen = vmxml.xmltreefile.find('devices').find('graphics').find(
                'listen')
            listen.set('type', listen_type)
            vmxml.sync()
        if checkpoint == 'host_selinux_on':
            params['selinux_stat'] = utils_selinux.get_status()
            utils_selinux.set_status('enforcing')
        if checkpoint.startswith('selinux'):
            set_selinux(checkpoint[8:])
        if checkpoint.startswith('host_firewalld'):
            service_mgr = service.ServiceManager()
            LOG.info('Backing up firewall services status')
            params['bk_firewalld_status'] = service_mgr.status('firewalld')
            if 'start' in checkpoint:
                service_mgr.start('firewalld')
            if 'stop' in checkpoint:
                service_mgr.stop('firewalld')
        if checkpoint == 'guest_firewalld_status':
            get_firewalld_status()
        if checkpoint == 'remove_securetty':
            LOG.info('Remove /etc/securetty file from guest')
            cmd = ['rm -f /etc/securetty']
            vm_cmd(cmd)
        if checkpoint == 'ntpd_on':
            LOG.info('Set service chronyd on')
            cmd = [
                'yum -y install chrony', 'systemctl start chronyd',
                'chronyc add server %s' % ntp_server
            ]
            vm_cmd(cmd)
        if checkpoint == 'sync_ntp':
            LOG.info('Sync time with %s', ntp_server)
            cmd = [
                'yum -y install chrony', 'systemctl start chronyd',
                'chronyc add server %s' % ntp_server, 'chronyc waitsync'
            ]
            vm_cmd(cmd)
        if checkpoint == 'blank_2nd_disk':
            disk_path = os.path.join(data_dir.get_tmp_dir(), 'blank.img')
            LOG.info('Create blank disk %s', disk_path)
            process.run('truncate -s 1G %s' % disk_path)
            LOG.info('Attach blank disk to vm')
            attach_removable_media('disk', disk_path, 'vdc')
            LOG.debug(virsh.dumpxml(vm_name))
        if checkpoint in ['only_net', 'only_br']:
            LOG.info('Detatch all networks')
            virsh.detach_interface(vm_name, 'network --current', debug=True)
            LOG.info('Detatch all bridges')
            virsh.detach_interface(vm_name, 'bridge --current', debug=True)
        if checkpoint == 'only_net':
            LOG.info('Attach network')
            virsh.attach_interface(vm_name,
                                   'network default --current',
                                   debug=True)
        if checkpoint == 'only_br':
            LOG.info('Attatch bridge')
            virsh.attach_interface(vm_name,
                                   'bridge virbr0 --current',
                                   debug=True)
        if checkpoint == 'no_libguestfs_backend':
            os.environ.pop('LIBGUESTFS_BACKEND')
        if checkpoint == 'file_image':
            vm = env.get_vm(vm_name)
            disk = vm.get_first_disk_devices()
            LOG.info('Disk type is %s', disk['type'])
            if disk['type'] != 'file':
                test.error('Guest is not with file image')
        v2v_result = utils_v2v.v2v_cmd(v2v_params)
        if v2v_params.get('new_name'):
            vm_name = params['main_vm'] = v2v_params['new_name']
        check_result(v2v_result, status_error)
    finally:
        if close_virsh and v2v_virsh:
            LOG.debug('virsh session %s is closing', v2v_virsh)
            v2v_virsh.close_session()
        if params.get('vmchecker'):
            params['vmchecker'].cleanup()
        if enable_legacy_policy:
            update_crypto_policy()
        if hypervisor == "xen":
            utils_v2v.v2v_setup_ssh_key_cleanup(xen_session, xen_pubkey)
            process.run('ssh-agent -k')
        if output_mode == 'rhev' and v2v_sasl:
            v2v_sasl.cleanup()
            LOG.debug('SASL session %s is closing', v2v_sasl)
            v2v_sasl.close_session()
        if output_mode == 'libvirt':
            pvt.cleanup_pool(pool_name, pool_type, pool_target, '')
        if backup_xml:
            backup_xml.sync()
        if params.get('selinux_stat') and params['selinux_stat'] != 'disabled':
            utils_selinux.set_status(params['selinux_stat'])
        if 'bk_firewalld_status' in params:
            service_mgr = service.ServiceManager()
            if service_mgr.status(
                    'firewalld') != params['bk_firewalld_status']:
                if params['bk_firewalld_status']:
                    service_mgr.start('firewalld')
                else:
                    service_mgr.stop('firewalld')
        if checkpoint.startswith('host_no_space'):
            if large_file and os.path.isfile(large_file):
                os.remove(large_file)
        # Cleanup constant files
        utils_v2v.cleanup_constant_files(params)
示例#30
0
    def attach_nic():  # pylint: disable=W0611
        """
        Attach interface, by xml or cmd, for both hot and cold plug
        """
        def create_iface_xml(mac):
            """
            Create interface xml file

            :param mac: The mac address of nic device
            """
            iface = Interface(type_name='network')
            iface.source = iface_source
            iface.model = iface_model
            iface.mac_address = mac
            logging.debug("Create new interface xml: %s", iface)
            return iface

        plug_method = params.get('plug_method', 'interface')
        cold_plug = params.get('cold_plug', 'no')
        mac = utils_net.generate_mac_address_simple()
        iface_source = {'network': 'default'}
        iface_model = params["virtio_model"]
        options = ("network %s --model %s --mac %s" %
                   (iface_source['network'], iface_model, mac))
        nic_params = {
            'mac': mac,
            'nettype': params['nettype'],
            'ip_version': 'ipv4'
        }
        if cold_plug == "yes":
            options += ' --config'
        if plug_method == 'interface':  # Hotplug nic vir attach-interface
            ret = virsh.attach_interface(vm_name, options, ignore_status=True)
        else:  # Hotplug nic via attach-device
            nic_xml = create_iface_xml(mac)
            nic_xml.xmltreefile.write()
            xml_file = nic_xml.xml
            with open(xml_file) as nic_file:
                logging.debug("Attach device by XML: %s", nic_file.read())
            ret = virsh.attach_device(domainarg=vm_name,
                                      filearg=xml_file,
                                      debug=True)
        libvirt.check_exit_status(ret)
        if cold_plug == "yes":
            reboot()  # Reboot guest if it is cold plug test
        detect_new_nic(mac)
        if plug_method == 'interface' and cold_plug == 'no':
            check_plug_to_pci_bridge(vm_name, mac)
        session = vm.wait_for_login(serial=True)
        # Add nic to VM object for further check
        nic_name = vm.add_nic(**nic_params)["nic_name"]
        nic = vm.virtnet[nic_name]
        # Config ip inside guest for new added nic
        if not utils_misc.wait_for(
                lambda: get_hotplug_nic_ip(vm, nic, session, guest_os_type),
                timeout=30):
            test.fail("Does not find plugged nic %s in guest" % mac)
        options = ("network %s" % mac)
        if cold_plug == "yes":
            options += ' --config'
        # Detach nic device
        if plug_method == 'interface':
            ret = virsh.detach_interface(vm_name, options, ignore_status=True)
        else:
            with open(xml_file) as nic_file:
                logging.debug("Detach device by XML: %s", nic_file.read())
            ret = virsh.detach_device(domainarg=vm_name,
                                      filearg=xml_file,
                                      debug=True)
        libvirt.check_exit_status(ret)
        if cold_plug == "yes":
            session = reboot()  # Reboot guest if it is cold plug test
        # Check if nic is removed from guest
        if not utils_misc.wait_for(lambda: check_nic_removed(mac, session),
                                   timeout=30):
            test.fail("The nic %s still exist in guest after being unplugged" %
                      nic_name)
def run(test, params, env):
    """
    Test virsh {at|de}tach-interface command.

    1) Prepare test environment and its parameters
    2) Attach the required interface
    3) According test type(only attach or both attach and detach):
       a.Go on to test detach(if attaching is correct)
       b.Return GOOD or raise TestFail(if attaching is wrong)
    4) Check if attached interface is correct:
       a.Try to catch it in vm's XML file
       b.Try to catch it in vm
    5) Detach the attached interface
    6) Check result
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    vm_ref = params.get("at_detach_iface_vm_ref", "domname")
    options_suffix = params.get("at_detach_iface_options_suffix", "")
    status_error = "yes" == params.get("status_error", "no")
    start_vm = params.get("start_vm")
    # Should attach must be pass for detach test.
    correct_attach = "yes" == params.get("correct_attach", "no")
    readonly = ("yes" == params.get("readonly", "no"))

    # Interface specific attributes.
    iface_type = params.get("at_detach_iface_type", "network")
    if iface_type == "bridge":
        try:
            utils_path.find_command("brctl")
        except utils_path.CmdNotFoundError:
            test.cancel("Command 'brctl' is missing. You must "
                        "install it.")

    iface_source = params.get("at_detach_iface_source", "default")
    iface_mode = params.get("at_detach_iface_mode", "vepa")
    iface_mac = params.get("at_detach_iface_mac", "created")
    iface_target = params.get("at_detach_iface_target")
    iface_model = params.get("at_detach_iface_model")
    iface_inbound = params.get("at_detach_iface_inbound")
    iface_outbound = params.get("at_detach_iface_outbound")
    iface_rom = params.get("at_detach_rom_bar")
    iface_link = params.get("at_detach_link_state")
    iface_boot = params.get("at_detach_boot_order")
    iface_driver = params.get("at_detach_iface_driver")
    iface_driver_host = params.get("at_detach_driver_host")
    iface_driver_guest = params.get("at_detach_driver_guest")
    iface_backend = params.get("at_detach_iface_backend")

    save_restore = params.get("save_restore", "no")
    restart_libvirtd = params.get("restart_libvirtd", "no")
    attach_cmd = params.get("attach_cmd", "attach-interface")
    virsh_dargs = {'ignore_status': True, 'debug': True, 'uri': uri}

    # Get iface name if iface_type is direct
    if iface_type == "direct":
        iface_source = utils_net.get_net_if(state="UP")[0]
    # Get a bridge name for test if iface_type is bridge.
    # If there is no bridge other than virbr0, raise TestCancel
    if iface_type == "bridge":
        host_bridge = utils_net.Bridge()
        bridge_list = host_bridge.list_br()
        try:
            bridge_list.remove("virbr0")
        except AttributeError:
            pass  # If no virbr0, just pass is ok
        logging.debug("Useful bridges:%s", bridge_list)
        # just choosing one bridge on host.
        if len(bridge_list):
            iface_source = bridge_list[0]
        else:
            test.cancel("No useful bridge on host "
                        "other than 'virbr0'.")

    # Test both detach and attach, So collect info
    # both of them for result check.
    # When something wrong with interface, set it to 1
    fail_flag = 0
    result_info = []

    # Get a mac address if iface_mac is 'created'.
    if iface_mac == "created" or correct_attach:
        iface_mac = utils_net.generate_mac_address_simple()

    # Record all iface parameters in iface_dict
    iface_dict = {}
    update_list = [
        "driver", "driver_host", "driver_guest", "model", "rom",
        "inbound", "outbound", "link", "target", "mac", "source",
        "boot", "backend", "type", "mode"
        ]
    names = locals()
    for update_item in update_list:
        if names["iface_"+update_item]:
            iface_dict.update({update_item: names["iface_"+update_item]})
        else:
            iface_dict.update({update_item: None})
    logging.info("iface_dict is %s", iface_dict)

    # Format the params
    iface_format = format_param(iface_dict)
    logging.info("iface_format is %s", iface_format)

    try:
        # Generate xml file if using attach-device command
        if attach_cmd == "attach-device":
            # Change boot order to disk
            libvirt.change_boot_order(vm_name, "disk", "1")
            vm.destroy()
            vm.start()
            # Generate attached xml
            xml_file_tmp = libvirt.modify_vm_iface(vm_name, "get_xml", iface_format)
            new_iface = Interface(type_name=iface_type)
            new_iface.xml = xml_file_tmp
            new_iface.del_address()
            xml_file = new_iface.xml

        # To confirm vm's state and make sure os fully started
        if start_vm == "no":
            if vm.is_alive():
                vm.destroy()
        else:
            vm.wait_for_login().close()

        # Set attach-interface domain
        dom_uuid = vm.get_uuid()
        dom_id = vm.get_id()

        if vm_ref == "domname":
            vm_ref = vm_name
        elif vm_ref == "domid":
            vm_ref = dom_id
        elif vm_ref == "domuuid":
            vm_ref = dom_uuid
        elif vm_ref == "hexdomid" and dom_id is not None:
            vm_ref = hex(int(dom_id))

        # Set attach-interface options and Start attach-interface test
        if correct_attach:
            options = set_options("network", "default", iface_mac, "", "attach")
            if readonly:
                virsh_dargs.update({'readonly': True, 'debug': True})
            attach_result = virsh.attach_interface(vm_name, options,
                                                   **virsh_dargs)
        else:
            if attach_cmd == "attach-interface":
                options = set_options(iface_type, iface_source, iface_mac,
                                      options_suffix, "attach", iface_target,
                                      iface_model, iface_inbound, iface_outbound)
                attach_result = virsh.attach_interface(vm_ref, options, **virsh_dargs)
            elif attach_cmd == "attach-device":
                attach_result = virsh.attach_device(vm_name, xml_file,
                                                    ignore_status=True, debug=True)
        attach_status = attach_result.exit_status
        logging.debug(attach_result)

        # If attach interface failed.
        if attach_status:
            if not status_error:
                fail_flag = 1
                result_info.append("Attach Failed: %s" % attach_result.stderr)
            elif status_error:
                # Here we just use it to exit, do not mean test failed
                fail_flag = 1
        # If attach interface succeeded.
        else:
            if status_error and not correct_attach:
                fail_flag = 1
                result_info.append("Attach Success with wrong command.")

        if fail_flag and start_vm == "yes":
            vm.destroy()
            if len(result_info):
                test.fail(result_info)
            else:
                # Exit because it is error_test for attach-interface.
                return

        if "print-xml" in options_suffix:
            iface_obj = Interface(type_name=iface_type)
            iface_obj.xml = attach_result.stdout.strip()
            if (iface_obj.type_name == iface_type
                    and iface_obj.source['dev'] == iface_source
                    and iface_obj.target['dev'] == iface_target
                    and iface_obj.model == iface_model
                    and iface_obj.bandwidth.inbound == eval(iface_format['inbound'])
                    and iface_obj.bandwidth.outbound == eval(iface_format['outbound'])):
                logging.info("Print ml all element check pass")
            else:
                test.fail("Print xml do not show as expected")

        # Check dumpxml file whether the interface is added successfully.
        status, ret = check_dumpxml_iface(vm_name, iface_format)
        if "print-xml" not in options_suffix:
            if status:
                fail_flag = 1
                result_info.append(ret)
        else:
            if status == 0:
                test.fail("Attach interface effect in xml with print-xml option")
            else:
                return

        # Login to domain to check new interface.
        if not vm.is_alive():
            vm.start()
        elif vm.state() == "paused":
            vm.resume()

        status, ret = login_to_check(vm, iface_mac)
        if status:
            fail_flag = 1
            result_info.append(ret)

        # Check on host for direct type
        if iface_type == 'direct':
            cmd_result = process.run("ip -d link show test").stdout_text.strip()
            logging.info("cmd output is %s", cmd_result)
            check_patten = ("%s@%s.*\n.*%s.*\n.*macvtap.*mode.*%s"
                            % (iface_target, iface_source, iface_mac, iface_mode))
            logging.info("check patten is %s", check_patten)
            if not re.search(check_patten, cmd_result):
                logging.error("Can not find %s in ip link" % check_patten)
                fail_flag = 1
                result_info.append(cmd_result)

        # Do operation and check again
        if restart_libvirtd == "yes":
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()

        if save_restore == "yes":
            check_save_restore(vm_name)

        status, ret = check_dumpxml_iface(vm_name, iface_format)
        if status:
            fail_flag = 1
            result_info.append(ret)

        # Set detach-interface options
        options = set_options(iface_type, None, iface_mac,
                              options_suffix, "detach")

        # Start detach-interface test
        if save_restore == "yes" and vm_ref == dom_id:
            vm_ref = vm_name
        detach_result = virsh.detach_interface(vm_ref, options, **virsh_dargs)
        detach_status = detach_result.exit_status
        detach_msg = detach_result.stderr.strip()

        logging.debug(detach_result)

        if detach_status == 0 and status_error == 0:
            # Check the xml after detach and clean up if needed.
            time.sleep(5)
            status, _ = check_dumpxml_iface(vm_name, iface_format)
            if status == 0:
                detach_status = 1
                detach_msg = "xml still exist after detach"
                cleanup_options = "--type %s --mac %s" % (iface_type, iface_mac)
                virsh.detach_interface(vm_ref, cleanup_options, **virsh_dargs)
            else:
                logging.info("After detach, the interface xml disappeared")

        # Check results.
        if status_error:
            if detach_status == 0:
                test.fail("Detach Success with wrong command.")
        else:
            if detach_status != 0:
                test.fail("Detach Failed: %s" % detach_msg)
            else:
                if fail_flag:
                    test.fail("Attach-Detach Success but "
                              "something wrong with its "
                              "functional use:%s" % result_info)
    finally:
        if vm.is_alive():
            vm.destroy()
        backup_xml.sync()
示例#32
0
def run(test, params, env):
    """
    Test virsh {at|de}tach-interface command.

    1) Prepare test environment and its parameters
    2) Attach the required interface
    3) Perform attach and detach operation
    4) Check if attached interface is correct
    5) Detach the attached interface
    """

    def is_attached(vmxml_devices, iface_type, iface_source, iface_mac):
        """
        Check attached interface exist or not.

        :param vmxml_devices: VMXMLDevices instance
        :param iface_type: interface device type
        :param iface_source : interface source
        :param iface_mac : interface MAC address
        :return: True/False if backing file and interface found
        """
        ifaces = vmxml_devices.by_device_tag('interface')
        for iface in ifaces:
            if iface.type_name != iface_type:
                continue
            if iface.mac_address != iface_mac:
                continue
            if iface_source is not None:
                if iface.xmltreefile.find('source') is not None:
                    if iface.source['network'] != iface_source:
                        continue
                else:
                    continue
            # All three conditions met
            logging.debug("Find %s in given iface XML", iface_mac)
            return True
        logging.debug("Not find %s in given iface XML", iface_mac)
        return False

    def check_result(vm_name, iface_source, iface_type, iface_mac,
                     flags, vm_state, attach=True):
        """
        Check the test result of attach/detach-device command.
        """
        active_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        if not attach:
            utils_misc.wait_for(lambda: not is_attached(active_vmxml.devices,
                                                        iface_type, iface_source, iface_mac), 20)
        active_attached = is_attached(active_vmxml.devices, iface_type,
                                      iface_source, iface_mac)
        if vm_state != "transient":
            inactive_vmxml = vm_xml.VMXML.new_from_dumpxml(
                vm_name, options="--inactive")
            inactive_attached = is_attached(inactive_vmxml.devices,
                                            iface_type, iface_source,
                                            iface_mac)

        if flags.count("config"):
            if vm_state != "transient":
                if attach:
                    if not inactive_attached:
                        raise exceptions.TestFail("Inactive domain XML not"
                                                  " updated when --config "
                                                  "options used for attachment")
                else:
                    if inactive_attached:
                        raise exceptions.TestFail("Inactive domain XML not"
                                                  " updated when --config "
                                                  "options used for detachment")
        if flags.count("live"):
            if attach:
                if vm_state in ["paused", "running", "transient"]:
                    if not active_attached:
                        raise exceptions.TestFail("Active domain XML not updated"
                                                  " when --live options used for"
                                                  " attachment")
            else:
                if vm_state in ["paused", "running", "transient"]:
                    if active_attached:
                        raise exceptions.TestFail("Active domain XML not updated"
                                                  " when --live options used for"
                                                  " detachment")
        if flags.count("current") or flags == "":
            if attach:
                if vm_state in ["paused", "running", "transient"]:
                    if not active_attached:
                        raise exceptions.TestFail("Active domain XML not updated"
                                                  " when --current options used "
                                                  "for attachment")
                elif vm_state == "shutoff" and not inactive_attached:
                    raise exceptions.TestFail("Inactive domain XML not updated"
                                              " when --current options used for"
                                              " attachment")
            else:
                if vm_state in ["paused", "running", "transient"]:
                    if active_attached:
                        raise exceptions.TestFail("Active domain XML not updated"
                                                  " when --current options used "
                                                  "for detachment")
                elif vm_state == "shutoff" and inactive_attached:
                    raise exceptions.TestFail("Inactive domain XML not updated "
                                              "when --current options used for "
                                              "detachment")

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    # Test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    vm_ref = params.get("at_detach_iface_vm_ref", "domname")
    at_options_suffix = params.get("at_dt_iface_at_options", "")
    dt_options_suffix = params.get("at_dt_iface_dt_options", "")
    at_status_error = "yes" == params.get("at_status_error", "no")
    dt_status_error = "yes" == params.get("dt_status_error", "no")
    pre_vm_state = params.get("at_dt_iface_pre_vm_state")

    # Skip if libvirt doesn't support --live/--current.
    if (at_options_suffix.count("--live") or
            dt_options_suffix.count("--live")):
        if not libvirt_version.version_compare(1, 0, 5):
            raise exceptions.TestSkipError("update-device doesn't"
                                           " support --live")
    if (at_options_suffix.count("--current") or
            dt_options_suffix.count("--current")):
        if not libvirt_version.version_compare(1, 0, 5):
            raise exceptions.TestSkipError("virsh update-device "
                                           "doesn't support --current")

    # Interface specific attributes.
    iface_type = params.get("at_detach_iface_type", "network")
    if iface_type == "bridge":
        try:
            utils_misc.find_command("brctl")
        except ValueError:
            raise exceptions.TestSkipError("Command 'brctl' is missing."
                                           " You must install it.")

    iface_source = params.get("at_detach_iface_source", "default")
    iface_mac = params.get("at_detach_iface_mac", "created")
    virsh_dargs = {'ignore_status': True, 'uri': uri, 'debug': True}

    # Check host version.
    rhel6_host = False
    if not process.run("grep 'Red Hat Enterprise Linux Server "
                       "release 6' /etc/redhat-release",
                       ignore_status=True, shell=True).exit_status:
        rhel6_host = True

    # Back up xml file.
    if vm.is_alive():
        vm.destroy(gracefully=False)
    backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Get a bridge name for test if iface_type is bridge.
    # If there is no bridge other than virbr0, raise TestSkipError
    if iface_type == "bridge":
        host_bridge = utils_net.Bridge()
        bridge_list = host_bridge.list_br()
        try:
            bridge_list.remove("virbr0")
        except AttributeError:
            pass  # If no virbr0, just pass is ok
        logging.debug("Useful bridges:%s", bridge_list)
        # just choosing one bridge on host.
        if len(bridge_list):
            iface_source = bridge_list[0]
        else:
            raise exceptions.TestSkipError("No useful bridge on host "
                                           "other than 'virbr0'.")

    # Turn VM into certain state.
    if pre_vm_state == "running":
        if (rhel6_host and at_options_suffix == "--config" and
                dt_options_suffix == ""):
            raise exceptions.TestSkipError("For bug921407, "
                                           "won't fix on rhel6 host")
        logging.info("Starting %s..." % vm_name)
        if vm.is_dead():
            vm.start()
            vm.wait_for_login().close()
    elif pre_vm_state == "shutoff":
        logging.info("Shuting down %s..." % vm_name)
        if vm.is_alive():
            vm.destroy(gracefully=False)
    elif pre_vm_state == "paused":
        if (rhel6_host and at_options_suffix == "--config" and
                dt_options_suffix == ""):
            raise exceptions.TestSkipError("For bug921407, "
                                           "won't fix on rhel6 host")
        logging.info("Pausing %s..." % vm_name)
        if vm.is_dead():
            vm.start()
            vm.wait_for_login().close()
        if not vm.pause():
            raise exceptions.TestSkipError("Cann't pause the domain")
    elif pre_vm_state == "transient":
        logging.info("Creating %s..." % vm_name)
        vm.undefine()
        if virsh.create(backup_xml.xml,
                        **virsh_dargs).exit_status:
            backup_xml.define()
            raise exceptions.TestSkipError("Cann't create the domain")

    dom_uuid = vm.get_uuid()
    dom_id = vm.get_id()

    # Set attach-interface domain
    if vm_ref == "domname":
        vm_ref = vm_name
    elif vm_ref == "domid":
        vm_ref = dom_id
    elif vm_ref == "domuuid":
        vm_ref = dom_uuid
    elif vm_ref == "hexdomid" and dom_id is not None:
        vm_ref = hex(int(dom_id))

    # Get a mac address if iface_mac is 'created'.
    if iface_mac == "created":
        iface_mac = utils_net.generate_mac_address_simple()

    try:
        # Set attach-interface options and
        # start attach-interface test
        options = set_options(iface_type, iface_source,
                              iface_mac, at_options_suffix,
                              "attach")
        ret = virsh.attach_interface(vm_name, options,
                                     **virsh_dargs)
        libvirt.check_exit_status(ret, at_status_error)
        # Check if the command take effect in vm
        # or config file.
        if vm.is_paused():
            vm.resume()
            vm.wait_for_login().close()
        #Sleep a while for vm is stable
        time.sleep(3)
        if not ret.exit_status:
            check_result(vm_name, iface_source,
                         iface_type, iface_mac,
                         at_options_suffix, pre_vm_state)

        # Set detach-interface options
        options = set_options(iface_type, None, iface_mac,
                              dt_options_suffix, "detach")

        # Sleep for a while
        time.sleep(10)
        # Start detach-interface test
        if pre_vm_state == "paused":
            if not vm.pause():
                raise exceptions.TestFail("Cann't pause the domain")
        ret = virsh.detach_interface(vm_ref, options,
                                     **virsh_dargs)
        if rhel6_host and pre_vm_state in ['paused', 'running']:
            if (at_options_suffix == "--config" and
                    dt_options_suffix == "--config"):
                dt_status_error = True
        libvirt.check_exit_status(ret, dt_status_error)
        # Check if the command take effect
        # in vm or config file.
        if vm.is_paused():
            vm.resume()
            vm.wait_for_login().close()
        #Sleep a while for vm is stable
        time.sleep(10)
        if not ret.exit_status:
            check_result(vm_name, iface_source,
                         iface_type, iface_mac,
                         dt_options_suffix,
                         pre_vm_state, False)

    finally:
        # Restore the vm
        if vm.is_alive():
            vm.destroy(gracefully=False, free_mac_addresses=False)
        backup_xml.sync()
示例#33
0
    def network_hook():
        """
        Check network hooks.
        """
        # Set interface to use default network
        net_name = params.get("net_name", "default")
        edit_iface(net_name)
        prepare_hook_file(hook_script % (net_name, hook_log))
        try:
            # destroy the network
            ret = virsh.net_destroy(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " stopped end -"
            assert check_hooks(hook_str)

            # start network
            ret = virsh.net_start(net_name, **virsh_dargs)
            libvirt.check_exit_status(ret)
            hook_str = hook_file + " " + net_name + " start begin -"
            assert check_hooks(hook_str)
            hook_str = hook_file + " " + net_name + " started begin -"
            assert check_hooks(hook_str)
            if vm.is_alive():
                vm.destroy(gracefully=False)

            # Remove all controllers, interfaces and addresses in vm dumpxml
            vm_inactive_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            vm_inactive_xml.remove_all_device_by_type('controller')
            type_dict = {'address': '/devices/*/address'}
            try:
                for elem in vm_inactive_xml.xmltreefile.findall(
                        type_dict['address']):
                    vm_inactive_xml.xmltreefile.remove(elem)
            except (AttributeError, TypeError) as details:
                test.fail("Fail to remove address.")
            vm_inactive_xml.xmltreefile.write()
            machine_list = vm_inactive_xml.os.machine.split("-")

            # Modify machine type according to the requirements and Add controllers to VM according to machine type

            def generate_controller(controller_dict):
                controller_xml = Controller("controller")
                controller_xml.model = controller_dict['model']
                controller_xml.type = controller_dict['type']
                controller_xml.index = controller_dict['index']
                return controller_xml

            if machine_type == 'pc':
                vm_inactive_xml.set_os_attrs(
                    **{
                        "machine": machine_list[0] + "-i440fx-" +
                        machine_list[2]
                    })
                pc_Dict0 = {'model': 'pci-root', 'type': 'pci', 'index': 0}
                pc_Dict1 = {'model': 'pci-bridge', 'type': 'pci', 'index': 1}
                vm_inactive_xml.add_device(generate_controller(pc_Dict0))
                vm_inactive_xml.add_device(generate_controller(pc_Dict1))
            elif machine_type == 'q35':
                vm_inactive_xml.set_os_attrs(
                    **{"machine": machine_list[0] + "-q35-" + machine_list[2]})
                q35_Dict0 = {'model': 'pcie-root', 'type': 'pci', 'index': 0}
                q35_Dict1 = {
                    'model': 'pcie-root-port',
                    'type': 'pci',
                    'index': 1
                }
                q35_Dict2 = {
                    'model': 'pcie-to-pci-bridge',
                    'type': 'pci',
                    'index': 2
                }
                vm_inactive_xml.add_device(generate_controller(q35_Dict0))
                vm_inactive_xml.add_device(generate_controller(q35_Dict1))
                vm_inactive_xml.add_device(generate_controller(q35_Dict2))
            vm_inactive_xml.sync()

            # Plug a interface and Unplug the interface
            vm.start()
            vm.wait_for_login().close()
            interface_num = len(
                vm_xml.VMXML.new_from_dumpxml(vm_name).get_devices(
                    "interface"))
            mac_addr = "52:54:00:9a:53:a9"
            logging.debug(vm_xml.VMXML.new_from_dumpxml(vm_name))

            def is_attached_interface():
                return len(
                    vm_xml.VMXML.new_from_dumpxml(vm_name).get_devices(
                        "interface")) == interface_num + 1

            ret = virsh.attach_interface(vm_name, ("network %s --mac %s" %
                                                   (net_name, mac_addr)))
            libvirt.check_exit_status(ret)
            if utils_misc.wait_for(is_attached_interface,
                                   timeout=20) is not True:
                test.fail("Attaching interface failed.")
            if libvirt_version.version_compare(6, 0, 0):
                hook_str = hook_file + " " + net_name + " port-created begin -"
            else:
                hook_str = hook_file + " " + net_name + " plugged begin -"
            assert check_hooks(hook_str)

            def is_detached_interface():
                return len(
                    vm_xml.VMXML.new_from_dumpxml(vm_name).get_devices(
                        "interface")) == interface_num

            ret = virsh.detach_interface(vm_name,
                                         "network --mac %s" % mac_addr)
            libvirt.check_exit_status(ret)
            utils_misc.wait_for(is_detached_interface, timeout=50)
            # Wait for timeout and if not succeeded, detach again (during testing, detaching interface failed from q35 VM for the first time when using this function)
            if len(
                    vm_xml.VMXML.new_from_dumpxml(vm_name).get_devices(
                        "interface")) != interface_num:
                ret = virsh.detach_interface(vm_name,
                                             "network --mac %s" % mac_addr)
                libvirt.check_exit_status(ret)
            if utils_misc.wait_for(is_detached_interface,
                                   timeout=50) is not True:
                test.fail("Detaching interface failed.")
            if libvirt_version.version_compare(6, 0, 0):
                hook_str = hook_file + " " + net_name + " port-deleted begin -"
            else:
                hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
            # remove the log file
            if os.path.exists(hook_log):
                os.remove(hook_log)
            # destroy the domain
            vm.destroy()
            if libvirt_version.version_compare(6, 0, 0):
                hook_str = hook_file + " " + net_name + " port-deleted begin -"
            else:
                hook_str = hook_file + " " + net_name + " unplugged begin -"
            assert check_hooks(hook_str)
        except AssertionError:
            utils_misc.log_last_traceback()
            test.fail("Failed to check network hooks")
示例#34
0
def run(test, params, env):
    """
    Test mtu feature from virtual network
    """
    vm_name = params.get('main_vm')
    vm = env.get_vm(vm_name)
    mtu_type = params.get('mtu_type')
    mtu_size = params.get('mtu_size', '')
    net = params.get('net', DEFAULT_NET)
    net_type = params.get('net_type', '')
    with_iface = 'yes' == params.get('with_iface', 'no')
    with_net = 'yes' == params.get('with_net', 'no')
    status_error = 'yes' == params.get('status_error', 'no')
    check = params.get('check', '')
    error_msg = params.get('error_msg', '')
    bridge_name = 'br_mtu' + utils_misc.generate_random_string(3)
    add_pkg = params.get('add_pkg', '')
    model = params.get('model', 'virtio')

    def set_network(size, net='default'):
        """
        Set mtu size to a certain network
        """
        logging.info('Set mtu size of network "%s" to %s', net, size)
        default_xml = NetworkXML.new_from_net_dumpxml(net)
        default_xml.mtu = size
        default_xml.sync()
        logging.debug(virsh.net_dumpxml(net))

    def set_interface(mtu_size='', source_network='default',
                      iface_type='network', iface_model='virtio'):
        """
        Set mtu size to a certain interface
        """
        interface_type = 'bridge' if iface_type in ('bridge', 'openvswitch') else iface_type
        iface_dict = {
            'type': interface_type,
            'source': "{'%s': '%s'}" % (interface_type, source_network),
            'model': iface_model
        }

        if iface_type == 'openvswitch':
            iface_dict.update({'virtualport_type': 'openvswitch'})

        if mtu_size:
            iface_dict.update({'mtu': "{'size': %s}" % mtu_size})

        libvirt.modify_vm_iface(vm_name, 'update_iface', iface_dict)
        logging.debug(virsh.dumpxml(vm_name).stdout)

    def get_default_if():
        """
        Get default interface that is using by vm
        """
        ifaces = utils_net.get_sorted_net_if()
        logging.debug('Interfaces on host: %s', ifaces)
        for iface in ifaces[0]:
            if 'Link detected: yes' in process.run('ethtool %s' % iface).stdout_text:
                logging.debug('Found host interface "%s"', iface)
                return iface

    def create_bridge():
        """
        Create a bridge on host for test
        """
        cmd_create_br = 'nmcli con add type bridge con-name %s ifname %s'
        con_name = 'con_' + utils_misc.generate_random_string(3)
        bridge_name = 'br_' + utils_misc.generate_random_string(3)
        process.run(cmd_create_br % (con_name, bridge_name), verbose=True)
        return con_name, bridge_name

    def create_network_xml(name, network_type, base_if='', **kwargs):
        """
        Create a network xml to be defined
        """
        m_net = NetworkXML(name)
        m_net.forward = {'mode': 'bridge'}
        if network_type in ('bridge', 'openvswitch'):
            m_net.bridge = {'name': kwargs['bridge_name']}
        elif network_type == 'macvtap':
            if base_if:
                m_net.forward_interface = [{'dev': base_if}]
        if network_type == 'openvswitch':
            m_net.virtualport_type = 'openvswitch'
        if 'mtu' in kwargs:
            m_net.mtu = kwargs['mtu']
        logging.debug(m_net)
        return m_net.xml

    def create_iface(iface_type, **kwargs):
        """
        Create a interface to be attached to vm
        """
        m_iface = Interface(iface_type)
        m_iface.mac_address = utils_net.generate_mac_address_simple()
        if 'base_if' in kwargs:
            m_iface.source = {'dev': kwargs['base_if'],
                              'mode': 'vepa'}
        if 'source_net' in kwargs:
            m_iface.source = {'network': kwargs['source_net']}
        if 'mtu' in kwargs:
            m_iface.mtu = {'size': kwargs['mtu']}
        if 'model_net' in kwargs:
            m_iface.model = kwargs['model_net']
        logging.debug(m_iface.get_xml())
        logging.debug(m_iface)
        return m_iface

    def check_mtu(mtu_size, qemu=False):
        """
        Check if mtu meets expectation on host
        """
        error = ''
        live_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_xml = live_vmxml.get_devices('interface')[0]
        logging.debug(iface_xml.target)
        dev = iface_xml.target['dev']
        ifconfig_info = process.run('ifconfig|grep mtu|grep %s' % dev,
                                    shell=True, verbose=True).stdout_text
        if 'mtu %s' % mtu_size in ifconfig_info:
            logging.info('PASS on ifconfig check for vnet.')
        else:
            error += 'Fail on ifconfig check for vnet.'
        if qemu:
            qemu_mtu_info = process.run('ps aux|grep qemu-kvm',
                                        shell=True, verbose=True).stdout_text
            if 'host_mtu=%s' % mtu_size in qemu_mtu_info:
                logging.info('PASS on qemu cmd line check.')
            else:
                error += 'Fail on qemu cmd line check.'
        if error:
            test.fail(error)

    def check_mtu_in_vm(fn_login, mtu_size):
        """
        Check if mtu meets expectations in vm
        """
        session = fn_login()
        check_cmd = 'ifconfig'
        output = session.cmd(check_cmd)
        session.close()
        logging.debug(output)
        if 'mtu %s' % mtu_size not in output:
            test.fail('MTU check inside vm failed.')
        else:
            logging.debug("MTU check inside vm passed.")

    try:
        bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
        bk_netxml = NetworkXML.new_from_net_dumpxml(DEFAULT_NET)
        if add_pkg:
            add_pkg = add_pkg.split()
            utils_package.package_install(add_pkg)
        if 'openvswitch' in add_pkg:
            br = 'ovsbr0' + utils_misc.generate_random_string(3)
            process.run('systemctl start openvswitch.service', shell=True, verbose=True)
            process.run('ovs-vsctl add-br %s' % br, shell=True, verbose=True)
            process.run('ovs-vsctl show', shell=True, verbose=True)

        if not check or check in ['save', 'managedsave', 'hotplug_save']:
            # Create bridge or network and set mtu
            iface_type = 'network'
            if net_type in ('bridge', 'openvswitch'):
                if net_type == 'bridge':
                    params['con_name'], br = create_bridge()
                if mtu_type == 'network':
                    test_net = create_network_xml(
                        bridge_name, net_type,
                        bridge_name=br
                    )
                    virsh.net_create(test_net, debug=True)
                    virsh.net_dumpxml(bridge_name, debug=True)
                if mtu_type == 'interface':
                    iface_type = net_type
                    bridge_name = br
            elif net_type == 'network':
                if mtu_type == 'network':
                    set_network(mtu_size)

            iface_mtu = 0
            if mtu_type == 'interface':
                iface_mtu = mtu_size
            if mtu_type == 'network' and with_iface:
                mtu_size = str(int(mtu_size)//2)
                iface_mtu = mtu_size

            source_net = bridge_name if net_type in ('bridge', 'openvswitch') else 'default'

            # set mtu in vm interface
            set_interface(iface_mtu, source_network=source_net, iface_type=iface_type, iface_model=model)
            vm.start()
            vm_login = vm.wait_for_serial_login if net_type in ('bridge', 'openvswitch') else vm.wait_for_login
            vm_login().close()
            check_qemu = True if mtu_type == 'interface' else False

            # Test mtu after save vm
            if check in ('save', 'hotplug_save'):
                if check == 'hotplug_save':
                    iface = create_iface('network', source_net='default',
                                         mtu=mtu_size, model_net=model)
                    params['mac'] = iface.mac_address
                    virsh.attach_device(vm_name, iface.xml, debug=True)
                    virsh.dumpxml(vm_name, debug=True)
                    dom_xml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    if params['mac'] not in str(dom_xml):
                        test.fail('Failed to attach interface with mtu')
                save_path = os.path.join(data_dir.get_tmp_dir(), vm_name + '.save')
                virsh.save(vm_name, save_path, debug=True)
                virsh.restore(save_path, debug=True)
            if check == 'managedsave':
                virsh.managedsave(vm_name, debug=True)
                virsh.start(vm_name, debug=True)

            # Check in both host and vm
            check_mtu(mtu_size, check_qemu)
            check_mtu_in_vm(vm_login, mtu_size)
            vm_login(timeout=60).close()

            if check == 'hotplug_save':
                virsh.detach_interface(vm_name, 'network %s' % params['mac'], debug=True)
                time.sleep(5)
                dom_xml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                if params['mac'] in str(dom_xml):
                    test.fail('Failed to detach interface with mtu after save-restore')

        else:
            hotplug = 'yes' == params.get('hotplug', 'False')
            if check == 'net_update':
                result = virsh.net_update(
                    DEFAULT_NET, 'modify', 'mtu',
                    '''"<mtu size='%s'/>"''' % mtu_size,
                    debug=True
                )
            if check in ('macvtap', 'bridge_net', 'ovswitch_net'):
                base_if = get_default_if()
                macv_name = 'direct-macvtap' + utils_misc.generate_random_string(3)

                # Test mtu in different type of network
                if mtu_type == 'network':
                    if check == 'macvtap':
                        test_net = create_network_xml(macv_name, 'macvtap',
                                                      base_if, mtu=mtu_size)
                    if check == 'bridge_net':
                        params['con_name'], br = create_bridge()
                        test_net = create_network_xml(
                            bridge_name, 'bridge', mtu=mtu_size,
                            bridge_name=br
                        )
                    if check == 'ovswitch_net':
                        test_net = create_network_xml(
                            bridge_name, 'openvswitch', mtu=mtu_size,
                            bridge_name=br
                        )
                    if 'net_create' in params['id']:
                        result = virsh.net_create(test_net, debug=True)
                    if 'net_define' in params['id']:
                        result = virsh.net_define(test_net, debug=True)

                # Test mtu with or without a binding network
                elif mtu_type == 'interface':
                    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
                    if with_net:
                        test_net = create_network_xml(macv_name, 'macvtap', base_if)
                        virsh.net_create(test_net, debug=True)
                        iface = create_iface('network', source_net=macv_name, mtu=mtu_size)
                        if hotplug:
                            result = virsh.attach_device(vm_name, iface.xml, debug=True)
                        else:
                            vmxml.add_device(iface)
                            vmxml.sync()
                            result = virsh.start(vm_name)
                    else:
                        iface = create_iface('direct', base_if=base_if, mtu=mtu_size)
                        if hotplug:
                            result = virsh.attach_device(vm_name, iface.xml, debug=True)
                        else:
                            vmxml.add_device(iface)
                            result = virsh.define(vmxml.xml, debug=True)
            if check == 'invalid_val':
                iface = create_iface('network', source_net='default', mtu=mtu_size)
                result = virsh.attach_device(vm_name, iface.xml, debug=True)

            # Check result
            libvirt.check_exit_status(result, status_error)
            libvirt.check_result(result, [error_msg])

    finally:
        bk_xml.sync()
        bk_netxml.sync()
        if 'test_net' in locals():
            virsh.net_destroy(bridge_name, debug=True)
        if params.get('con_name'):
            process.run('nmcli con del %s' % params['con_name'], verbose=True)
        if add_pkg:
            process.run("ovs-vsctl del-br %s" % br, verbose=True)
            utils_package.package_remove(add_pkg)
示例#35
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source", "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name,
                                              iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name,
                                                 options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug(
                            "No more pci slots, can't attach more devices")
                        break
                    elif (ret.stderr.count("doesn't support option %s" %
                                           attach_option)):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug(
                            "option %s is not supported when domain running is %s"
                            % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options
                                        and attach_option):
                            test.fail(
                                "return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" %
                                      attach_option)
                        if not ("--current" in sep_options
                                and len(sep_options) > 1):
                            test.fail(
                                "return mutualy exclusive, but it is unexpected"
                            )
                    else:
                        logging.error("Command output %s" % ret.stdout.strip())
                        test.fail("Failed to attach-interface")
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        iface_list.append({
                            'mac': mac,
                            'iface_xml': iface_xml_obj
                        })
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False

            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist,
                                                       timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(
                        vm_name, iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".format(
                            if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if 'iface_xml' in iface:
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" % (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if 'mac' in iface:
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(
                                    vm_name, iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
示例#36
0
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()
示例#37
0
    def vm_stress_events(self, event, vm):
        """
        Stress events

        :param event: event name
        :param vm: vm object
        """
        dargs = {'ignore_status': True, 'debug': True}
        for itr in range(self.iterations):
            if "vcpupin" in event:
                for vcpu in range(int(self.current_vcpu)):
                    result = virsh.vcpupin(vm.name, vcpu,
                                           random.choice(self.host_cpu_list),
                                           **dargs)
                    if not self.ignore_status:
                        libvirt.check_exit_status(result)
            elif "emulatorpin" in event:
                for vcpu in range(int(self.current_vcpu)):
                    result = virsh.emulatorpin(vm.name,
                                               random.choice(
                                                   self.host_cpu_list),
                                               **dargs)
                    if not self.ignore_status:
                        libvirt.check_exit_status(result)
            elif "suspend" in event:
                result = virsh.suspend(vm.name, **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                time.sleep(self.event_sleep_time)
                result = virsh.resume(vm.name, **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
            elif "cpuhotplug" in event:
                result = virsh.setvcpus(vm.name, self.max_vcpu, "--live",
                                        **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                    exp_vcpu = {'max_config': self.max_vcpu,
                                'max_live': self.max_vcpu,
                                'cur_config': self.current_vcpu,
                                'cur_live': self.max_vcpu,
                                'guest_live': self.max_vcpu}
                    utils_hotplug.check_vcpu_value(
                        vm, exp_vcpu, option="--live")
                time.sleep(self.event_sleep_time)
                result = virsh.setvcpus(vm.name, self.current_vcpu, "--live",
                                        **dargs)
                if not self.ignore_status:
                    libvirt.check_exit_status(result)
                    exp_vcpu = {'max_config': self.max_vcpu,
                                'max_live': self.max_vcpu,
                                'cur_config': self.current_vcpu,
                                'cur_live': self.current_vcpu,
                                'guest_live': self.current_vcpu}
                    utils_hotplug.check_vcpu_value(
                        vm, exp_vcpu, option="--live")
            elif "reboot" in event:
                vm.reboot()
            elif "nethotplug" in event:
                for iface_num in range(int(self.iface_num)):
                    logging.debug("Try to attach interface %d" % iface_num)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (self.iface_type, self.iface_source['network'],
                                self.iface_model, mac, self.attach_option))
                    logging.debug("VM name: %s , Options for Network attach: %s", vm.name, options)
                    ret = virsh.attach_interface(vm.name, options,
                                                 ignore_status=True)
                    time.sleep(self.event_sleep_time)
                    if not self.ignore_status:
                        libvirt.check_exit_status(ret)
                    if self.detach_option:
                        options = ("--type %s --mac %s %s" %
                                   (self.iface_type, mac, self.detach_option))
                        logging.debug("VM name: %s , Options for Network detach: %s", vm.name, options)
                        ret = virsh.detach_interface(vm.name, options,
                                                     ignore_status=True)
                        if not self.ignore_status:
                            libvirt.check_exit_status(ret)
            elif "diskhotplug" in event:
                for disk_num in range(len(self.device_source_names)):
                    disk = {}
                    disk_attach_error = False
                    disk_name = os.path.join(self.path, vm.name, self.device_source_names[disk_num])
                    device_source = libvirt.create_local_disk(
                        self.disk_type, disk_name, self.disk_size, disk_format=self.disk_format)
                    disk.update({"format": self.disk_format,
                                 "source": device_source})
                    disk_xml = Disk(self.disk_type)
                    disk_xml.device = self.disk_device
                    disk_xml.driver = {"name": self.disk_driver, "type": self.disk_format}
                    ret = virsh.attach_disk(vm.name, disk["source"], self.device_target[disk_num], self.attach_option, debug=True)
                    if not self.ignore_status:
                        libvirt.check_exit_status(ret, disk_attach_error)
                    if self.detach_option:
                        ret = virsh.detach_disk(vm.name, self.device_target[disk_num], extra=self.detach_option)
                        if not self.ignore_status:
                            libvirt.check_exit_status(ret)
                        libvirt.delete_local_disk(self.disk_type, disk_name)
            else:
                raise NotImplementedError