Ejemplo n.º 1
0
def run(test, params, env):

    net_name = params.get("net_update_net_name", "updatenet")
    net_section = params.get("network_section", "ip-dhcp-range")
    update_command = params.get("update_command", "add-last")

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        test_xml.sync()
    except xcepts.LibvirtXMLError, detail:
        raise error.TestNAError("Failed to define a test network.\n"
                                "Detail: %s." % detail)
Ejemplo n.º 2
0
 def create_network():
     """
     Create a network
     """
     net_ip_addr = params.get("net_ip_addr", "192.168.200.1")
     net_ip_netmask = params.get("net_ip_netmask", "255.255.255.0")
     net_dhcp_start = params.get("net_dhcp_start", "192.168.200.2")
     net_dhcp_end = params.get("net_dhcp_end", "192.168.200.254")
     netxml = network_xml.NetworkXML()
     netxml.name = net_name
     netxml.forward = {'mode': "nat"}
     range = network_xml.RangeXML()
     range.attrs = {'start': net_dhcp_start, "end": net_dhcp_end}
     ipxml = network_xml.IPXML()
     if range_lease:
         range.lease_attrs = range_lease
     ipxml.address = net_ip_addr
     ipxml.netmask = net_ip_netmask
     ipxml.dhcp_ranges = range
     if host:
         new_host = network_xml.DhcpHostXML()
         new_host.attrs = host
         new_host.lease_attrs = host_lease
         ipxml.hosts = [new_host]
     netxml.set_ip(ipxml)
     netxml.create()
Ejemplo n.º 3
0
 def _from_scratch(self):
     netxml = network_xml.NetworkXML(virsh_instance=self.dummy_virsh,
                                     network_name='test0')
     self.assertEqual(netxml.name, 'test0')
     netxml.name = 'test1'
     netxml.uuid = 'test2'
     netxml.bridge = {'test3': 'test4'}
     return netxml
Ejemplo n.º 4
0
def run(test, params, env):

    net_name = params.get("net_update_net_name", "updatenet")
    net_section = params.get("network_section", "ip-dhcp-range")
    update_command = params.get("update_command", "add-last")
    add_portgroup = "yes" == params.get("add_portgroup", "no")
    options = params.get("cmd_options", "")
    net_state = params.get("net_state")

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
      <host mac='52:54:00:5a:a0:8b' ip='192.168.100.152' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    port_group = """
<portgroup name='engineering' default='no'>
  <virtualport type='802.1Qbh'>
    <parameters profileid='test'/>
  </virtualport>
  <bandwidth>
    <inbound average='1000' peak='5000' burst='5120'/>
    <outbound average='1000' peak='5000' burst='5120'/>
  </bandwidth>
</portgroup>
"""
    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        if net_section == "portgroup":
            portgroup_xml = network_xml.PortgroupXML()
            portgroup_xml.xml = port_group
            test_xml.portgroup = portgroup_xml
        elif net_section == "forward-interface":
            test_xml.forward = {'mode': 'passthrough'}
            test_xml.forward_interface = [{'dev': 'eth2'}]
            del test_xml.bridge
            del test_xml.mac
            del test_xml.ip
        test_xml.define()
        if net_state == "active":
            test_xml.start()
        test_xml.debug_xml()
        virsh.net_dumpxml(net_name)
    except xcepts.LibvirtXMLError, detail:
        raise error.TestError("Failed to define a test network.\n"
                              "Detail: %s." % detail)
Ejemplo n.º 5
0
 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()
Ejemplo n.º 6
0
    def _from_scratch(self):
        netxml = network_xml.NetworkXML(network_name='test0',
                                        virsh_instance=self.dummy_virsh)
        self.assertEqual(netxml.name, 'test0')
        netxml.name = 'test1'
        netxml.uuid = 'test2'
        netxml.bridge = {'test3': 'test4'}

        ipxml = network_xml.IPXML()
        ipxml.address = ('address_test')
        ipxml.netmask = ('netmask_test')
        netxml.ip = ipxml
        return netxml
Ejemplo n.º 7
0
 def create_macvtap_network():
     """
     Create macvtap type network xml.
     """
     forward_interface_list = []
     for vf_name in vf_name_list:
         forward_interface = {'dev': vf_name}
         forward_interface_list.append(forward_interface)
     netxml = network_xml.NetworkXML()
     netxml.name = net_name
     netxml.forward = {'dev': vf_name_list[0], 'mode': 'passthrough'}
     netxml.forward_interface = forward_interface_list
     logging.debug(netxml)
     return netxml
Ejemplo n.º 8
0
 def create_bridge_network(br_name, net_name, inbound="{'average':'0'}", outbound="{'average':'0'}"):
     """
     Define and start the bridge type network
     """
     # check if network with the same name already exists
     output_all = virsh.net_list("--all").stdout.strip()
     if re.search(net_name, output_all):
         test.cancel("Network with the same name already exists!")
     test_xml = network_xml.NetworkXML(network_name="%s" % net_name)
     test_xml.forward = {"mode": "bridge"}
     test_xml.bridge = {"name": br_name}
     test_xml.bandwidth_inbound = eval(inbound)
     test_xml.bandwidth_outbound = eval(outbound)
     logging.debug("The network's xml is %s", test_xml)
     test_xml.create()
Ejemplo n.º 9
0
def run(test, params, env):
    """
    Test command: virsh net-autostart.
    """
    # Gather test parameters
    status_error = "yes" == params.get("status_error", "no")
    net_ref = params.get("net_autostart_net_ref", "netname")
    disable = "yes" == params.get("net_autostart_disable", "no")
    extra = params.get("net_autostart_extra", "")  # extra cmd-line params.
    net_name = params.get("net_autostart_net_name", "autotest")

    # Prepare environment and record current net_state_dict
    backup = network_xml.NetworkXML.new_all_networks_dict()
    backup_state = virsh.net_state_dict()
    logging.debug("Backed up network(s): %s", backup_state)

    # Generate our own bridge
    # First check if a bridge of this name already exists
    try:
        _ = backup[net_name]
    except (KeyError, AttributeError):
        pass  # Not found - good
    else:
        raise error.TestNAError("Found network bridge '%s' - skipping" %
                                (net_name))

    # Define a very bare bones bridge, don't provide UUID - use whatever
    # libvirt ends up generating.  We need to define a persistent network
    # since we'll be looking to restart libvirtd as part of this test.
    #
    # This test cannot use the 'default' bridge (virbr0) since undefining
    # it causes issues for libvirtd restart since it's expected that a
    # default network is defined
    #
    temp_bridge = """
<network>
   <name>%s</name>
   <bridge name="vir%sbr0"/>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = temp_bridge
        test_xml.define()
    except xcepts.LibvirtXMLError, detail:
        raise error.TestNAError("Failed to define a test network.\n"
                                "Detail: %s." % detail)
Ejemplo n.º 10
0
 def create_network():
     """
     Create a network
     """
     net_ip_addr = params.get("net_ip_addr", "192.168.200.1")
     net_ip_netmask = params.get("net_ip_netmask", "255.255.255.0")
     net_dhcp_start = params.get("net_dhcp_start", "192.168.200.2")
     net_dhcp_end = params.get("net_dhcp_end", "192.168.200.254")
     netxml = network_xml.NetworkXML()
     netxml.name = net_name
     netxml.forward = {'mode': "nat"}
     ipxml = network_xml.IPXML()
     ipxml.address = net_ip_addr
     ipxml.netmask = net_ip_netmask
     ipxml.dhcp_ranges = {'start': net_dhcp_start, "end": net_dhcp_end}
     netxml.set_ip(ipxml)
     netxml.create()
Ejemplo n.º 11
0
 def create_hostdev_network():
     """
         Create hostdev type with vf pool network xml.
     """
     vf_addr_list = []
     netxml = network_xml.NetworkXML()
     if vf_pool_source == "vf_list":
         for vf in vf_list:
             attrs = create_address_dict(vf)
             new_vf = netxml.new_vf_address(**{'attrs': attrs})
             vf_addr_list.append(new_vf)
         netxml.driver = {'name': 'vfio'}
         netxml.forward = {"mode": "hostdev", "managed": managed}
         netxml.vf_list = vf_addr_list
     else:
         netxml.pf = {"dev": pf_name}
         netxml.forward = {"mode": "hostdev", "managed": managed}
     netxml.name = net_name
     logging.debug(netxml)
     return netxml
def get_network_xml_instance(virsh_dargs, test_xml, net_name, net_uuid,
                             bridge):
    test_netxml = network_xml.NetworkXML(virsh_instance=virsh.Virsh(
        **virsh_dargs))
    test_netxml.xml = test_xml.name

    # modify XML if called for
    if net_name is not "":
        test_netxml.name = net_name
    else:
        test_netxml.name = "default"
    if net_uuid is not "":
        test_netxml.uuid = net_uuid
    else:
        del test_netxml.uuid  # let libvirt auto-generate
    if bridge is not None:
        test_netxml.bridge = bridge

    # TODO: Test other network parameters

    logging.debug("Modified XML:")
    test_netxml.debug_xml()
    return test_netxml
Ejemplo n.º 13
0
def run(test, params, env):
    """
    Test command: virsh net-list.

    The command returns list of networks.
    1.Get all parameters from configuration.
    2.Get current network's status(State, Autostart).
    3.Do some prepare works for testing.
    4.Perform virsh net-list operation.
    5.Recover network status.
    6.Confirm the result.
    """
    option = params.get("net_list_option", "")
    extra = params.get("net_list_extra", "")
    status_error = params.get("status_error", "no")
    set_status = params.get("set_status", "active")
    set_persistent = params.get("set_persistent", "persistent")
    set_autostart = params.get("set_autostart", "autostart")
    error_msg = params.get("error_msg", "")

    net_name = params.get("net_name", "net-br")
    net_xml = network_xml.NetworkXML(network_name=net_name)

    # acl polkit params
    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user')
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            raise exceptions.TestSkipError("API acl test not supported"
                                           " in current libvirt version.")

    # Record current net_state_dict
    net_backup = network_xml.NetworkXML.new_all_networks_dict()
    net_backup_state = virsh.net_state_dict()
    logging.debug("Backed up network(s): %s", net_backup_state)

    # Check the network name is not duplicated
    try:
        _ = net_backup[net_name]
    except (KeyError, AttributeError):
        pass
    else:
        raise exceptions.TestSkipError("Duplicated network name: '%s'" %
                                       net_name)
    # Default the network is persistent, active, autostart
    # Create a persistent/transient network.
    if set_persistent == "persistent":
        net_xml.define()
        logging.debug("Created persistent network")
    else:
        net_xml.create()
        logging.debug("Created transient network")

    # Prepare an active/inactive network
    # For the new defined network, it's inactive by default
    if set_status == "active" and set_persistent == "persistent":
        net_xml.start()

    # Prepare an autostart/no-autostart network
    # For the new create network, it's no-autostart by default
    if set_autostart == "autostart":
        net_xml.set_autostart(True)

    try:
        virsh_dargs = {'ignore_status': True, 'debug': True}
        if params.get('setup_libvirt_polkit') == 'yes':
            virsh_dargs['unprivileged_user'] = unprivileged_user
            virsh_dargs['uri'] = uri
        ret = virsh.net_list(option, extra, **virsh_dargs)
        output = ret.stdout.strip()

        # Check test results
        if status_error == "yes":
            # Check the results with error parameter
            if error_msg:
                libvirt.check_result(ret, error_msg)
            # Check the results with correct option but inconsistent network status
            else:
                libvirt.check_exit_status(ret)
                if re.search(net_name, output):
                    raise exceptions.TestFail(
                        "virsh net-list %s get wrong results" % option)

        # Check the results with correct option and consistent network status
        else:
            libvirt.check_exit_status(ret)
            if option == "--uuid":
                uuid = virsh.net_uuid(net_name).stdout.strip()
                if not re.search(uuid, output):
                    raise exceptions.TestFail(
                        "Failed to find network: '%s' with:"
                        "virsh net-list '%s'." % (net_name, option))
            else:
                if not re.search(net_name, output):
                    raise exceptions.TestFail(
                        "Failed to find network: '%s' with:"
                        "virsh net-list '%s'." % (net_name, option))
    finally:
        # Recover network
        try:
            if set_status == "active":
                net_xml.del_active()
            if set_persistent == "persistent":
                net_xml.del_defined()
        except Exception:
            virsh.net_undefine()
Ejemplo n.º 14
0
    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        if test_create:
            test_xml.create()
        else:
            test_xml.define()
    except xcepts.LibvirtXMLError, detail:
        raise error.TestNAError("Failed to define a test network.\n"
                                "Detail: %s." % detail)

    # Run test case
    try:
        libvirtd = utils_libvirtd.Libvirtd()
        if test_create:
            # Restart libvirtd and check state
            libvirtd.restart()
Ejemplo n.º 15
0
def run(test, params, env):
    """
    Test command: virsh net-autostart.
    """
    # Gather test parameters
    status_error = "yes" == params.get("status_error", "no")
    net_ref = params.get("net_autostart_net_ref", "netname")
    disable = "yes" == params.get("net_autostart_disable", "no")
    extra = params.get("net_autostart_extra", "")  # extra cmd-line params.
    net_name = params.get("net_autostart_net_name", "autotest")
    net_transient = "yes" == params.get("net_transient", "no")
    readonly = ("yes" == params.get("readonly", "no"))
    sim_reboot = "yes" == params.get("sim_reboot", "no")

    # Prepare environment and record current net_state_dict
    backup = network_xml.NetworkXML.new_all_networks_dict()
    backup_state = virsh.net_state_dict()
    logging.debug("Backed up network(s): %s", backup_state)

    # Generate our own bridge
    # First check if a bridge of this name already exists
    try:
        _ = backup[net_name]
    except (KeyError, AttributeError):
        pass  # Not found - good
    else:
        test.cancel("Found network bridge '%s' - skipping" % net_name)

    # Define a very bare bones bridge, don't provide UUID - use whatever
    # libvirt ends up generating.  We need to define a persistent network
    # since we'll be looking to restart libvirtd as part of this test.
    #
    # This test cannot use the 'default' bridge (virbr0) since undefining
    # it causes issues for libvirtd restart since it's expected that a
    # default network is defined
    #
    temp_bridge = """
<network>
   <name>%s</name>
   <bridge name="vir%sbr0"/>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = temp_bridge
        test_xml.define()
    except xcepts.LibvirtXMLError as detail:
        test.error("Failed to define a test network.\n" "Detail: %s." % detail)

    # To guarantee cleanup will be executed
    try:
        # Run test case

        # Get the updated list and make sure our new bridge exists
        currents = network_xml.NetworkXML.new_all_networks_dict()
        current_state = virsh.net_state_dict()
        logging.debug("Current network(s): %s", current_state)
        try:
            testbr_xml = currents[net_name]
        except (KeyError, AttributeError):
            test.error("Did not find newly defined bridge '%s'" % net_name)

        # Prepare default property for network
        # Transient network can not be set autostart
        # So confirm persistent is true for test
        testbr_xml['persistent'] = True

        # Set network to inactive
        # Since we do not reboot host to check(instead of restarting libvirtd)
        # If default network is active, we cannot check "--disable".
        # Because active network will not be inactive after restarting libvirtd
        # even we set autostart to False. While inactive network will be active
        # after restarting libvirtd if we set autostart to True
        testbr_xml['active'] = False

        # Prepare options and arguments
        if net_ref == "netname":
            net_ref = testbr_xml.name
        elif net_ref == "netuuid":
            net_ref = testbr_xml.uuid

        if disable:
            net_ref += " --disable"

        if net_transient:
            # make the network to transient and active
            ret = virsh.net_start(net_name)
            libvirt.check_exit_status(ret)
            ret = virsh.net_undefine(net_name)
            libvirt.check_exit_status(ret)
            logging.debug("after make it transistent: %s" %
                          virsh.net_state_dict())

        # Run test case
        # Use function in virsh module directly for both normal and error test
        result = virsh.net_autostart(net_ref, extra, readonly=readonly)
        status = result.exit_status
        if status:
            logging.debug("autostart cmd return:\n%s" % result.stderr.strip())
        else:
            logging.debug("set autostart succeed: %s" % virsh.net_state_dict())

        # Check if autostart or disable is successful with libvirtd restart.
        # TODO: Since autostart is designed for host reboot,
        #       we'd better check it with host reboot.
        autostart_file = '/var/run/libvirt/network/autostarted'
        check_version = libvirt_version.version_compare(5, 6, 0)
        if check_version and os.path.exists(autostart_file):
            logging.debug("the sim_reboot is %s" % sim_reboot)
            if sim_reboot:
                os.unlink(autostart_file)
        utils_libvirtd.libvirtd_restart()

        # Reopen testbr_xml
        currents = network_xml.NetworkXML.new_all_networks_dict()
        current_state = virsh.net_state_dict()
        logging.debug("After libvirtd reboot, current network(s): %s",
                      current_state)
        testbr_xml = currents[net_name]
        is_active = testbr_xml['active']
        # undefine the persistent&autostart network,
        # if "autostart" should change to 'no"
        if not disable and not net_transient:
            logging.debug("undefine the persistent/autostart network:")
            ret = virsh.net_undefine(net_name)
            libvirt.check_exit_status(ret)
            # after undefine, the network can not be "autostart"
            if net_name in virsh.net_list("").stdout.strip():
                current_state = virsh.net_state_dict()[net_name]
                logging.debug("Current network(s): %s", current_state)
                net_autostart_now = current_state['autostart']
                if not status_error and not disable and net_autostart_now:
                    test.fail("transient network can not be autostart")

    finally:
        persistent_net = virsh.net_list("--persistent --all").stdout.strip()
        if net_name in persistent_net:
            virsh.net_undefine(net_name)
        active_net = virsh.net_list("").stdout.strip()
        if net_name in active_net:
            virsh.net_destroy(net_name)

    # Check Result
    if status_error:
        if status == 0:
            test.fail("Run successfully with wrong command!")
    else:
        if disable:
            if status or is_active:
                test.fail("Disable autostart failed.")
        else:
            if status:
                test.fail("The virsh cmd return error when enable autostart!")
            # If host reboot(sim_reboot=True), the network should be active
            # If host do not reboot, restart libvirtd will not start inactive
            # autostart network after libvirt 5.6.0
            if sim_reboot:
                if not is_active:
                    test.fail("Set network autostart failed.")
            else:
                if check_version and is_active:
                    test.fail(
                        "net turn active with libvirtd restart without host reboot!"
                    )
Ejemplo n.º 16
0
def run(test, params, env):
    """
    Test command: virsh net-start.
    """
    # Gather test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    status_error = "yes" == params.get("status_error", "no")
    inactive_default = "yes" == params.get("net_start_inactive_default", "yes")
    net_ref = params.get("net_start_net_ref", "netname")  # default is tested
    extra = params.get("net_start_options_extra", "")  # extra cmd-line params.
    route_test = "yes" == params.get("route_test", "no")

    # make easy to maintain
    virsh_dargs = {'uri': uri, 'debug': True, 'ignore_status': True}
    virsh_instance = virsh.VirshPersistent(**virsh_dargs)

    # libvirt acl polkit related params
    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            test.cancel("API acl test not supported in current"
                        " libvirt version.")

    virsh_uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user')
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    # Get all network instance
    origin_nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance)

    # Prepare default network for following test.
    try:
        default_netxml = origin_nets['default']
    except KeyError:
        virsh_instance.close_session()
        test.cancel("Test requires default network to exist")
    try:
        # To confirm default network is active
        if not default_netxml.active:
            default_netxml.active = True

        # inactive default according test's need
        if inactive_default:
            logging.info("Stopped default network")
            default_netxml.active = False

        # State before run command
        origin_state = virsh_instance.net_state_dict()
        logging.debug("Origin network(s) state: %s", origin_state)

        if route_test:
            # define a network "def" with route address is "192.168.122.x"
            # 1. start def first then start default
            current_state = virsh_instance.net_state_dict()
            if 'def' in current_state:
                virsh.net_destroy("def", ignore_status=True)
                virsh.net_undefine("def", ignore_status=True)
            expect_fail = "yes" == params.get("expect_start_fail", "no")
            test_xml = network_xml.NetworkXML(network_name="def")
            test_xml.forward = {'mode': 'nat'}
            test_xml.routes = [{
                'address': '192.168.122.0',
                'prefix': '24',
                'gateway': '192.168.100.1'
            }]
            ipxml = IPXML(address='192.168.100.1', netmask='255.255.255.0')
            ipxml.dhcp_ranges = {
                'start': '192.168.100.2',
                'end': '192.168.100.254'
            }
            test_xml.ip = ipxml
            test_xml.define()
            virsh.net_start("def")
            # start default, should fail
            result = virsh.net_start("default")
            logging.debug(result)
            libvirt.check_exit_status(result, expect_error=expect_fail)

            # 2. start default then start def
            virsh.net_destroy("def")
            virsh.net_start("default")
            current_state11 = virsh_instance.net_state_dict()
            logging.debug("before start 2nd network(s) state: %s",
                          current_state11)
            # start def, should fail
            result = virsh.net_start("def")
            logging.debug(result)
            libvirt.check_exit_status(result, expect_error=expect_fail)
            current_state12 = virsh_instance.net_state_dict()
            logging.debug("after start 2nd network(s) state: %s",
                          current_state12)
            # clear the env
            virsh.net_undefine("def")

        else:
            if net_ref == "netname":
                net_ref = default_netxml.name
            elif net_ref == "netuuid":
                net_ref = default_netxml.uuid

            if params.get('setup_libvirt_polkit') == 'yes':
                virsh_dargs = {
                    'uri': virsh_uri,
                    'unprivileged_user': unprivileged_user,
                    'debug': False,
                    'ignore_status': True
                }
            if params.get('net_start_readonly', 'no') == 'yes':
                virsh_dargs = {
                    'uri': uri,
                    'debug': True,
                    'readonly': True,
                    'ignore_status': True
                }

        # Run test case
        if 'unprivileged_user' in virsh_dargs and status_error:
            test_virsh = virsh.VirshPersistent(
                unprivileged_user=virsh_dargs['unprivileged_user'])
            virsh_dargs.pop('unprivileged_user')
            result = test_virsh.net_start(net_ref, extra, **virsh_dargs)
            test_virsh.close_session()
        elif not route_test:
            result = virsh.net_start(net_ref, extra, **virsh_dargs)
        logging.debug(result)
        status = result.exit_status

        # Get current net_stat_dict
        current_state = virsh_instance.net_state_dict()
        logging.debug("Current network(s) state: %s", current_state)
        if 'default' not in current_state:
            test.fail('Network "default" cannot be found')
        # Check status_error
        if status_error:
            if not status:
                test.fail("Run successfully with wrong command!")
        else:
            if status:
                test.fail("Run failed with right command")

            # Get current net_stat_dict
            current_state = virsh_instance.net_state_dict()
            logging.debug("Current network(s) state: %s", current_state)
            is_default_active = current_state['default']['active']
            if not is_default_active:
                test.fail(
                    "Execute cmd successfully but default is inactive actually."
                )
    finally:
        virsh_instance.close_session()
        current_state = virsh_instance.net_state_dict()
        if "def" in current_state:
            virsh.net_destroy("def", ignore_status=True)
            virsh.net_undefine("def", ignore_status=True)
        virsh.net_start('default', debug=True, ignore_status=True)
Ejemplo n.º 17
0
def run(test, params, env):

    net_name = params.get("net_update_net_name", "updatenet")
    net_section = params.get("network_section", "ip-dhcp-range")
    update_command = params.get("update_command", "add-last")
    options = params.get("cmd_options", "")
    net_state = params.get("net_state")

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
      <host mac='52:54:00:5a:a0:8b' ip='192.168.100.152' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    port_group = """
<portgroup name='engineering' default='no'>
  <virtualport type='802.1Qbh'>
    <parameters profileid='test'/>
  </virtualport>
  <bandwidth>
    <inbound average='1000' peak='5000' burst='5120'/>
    <outbound average='1000' peak='5000' burst='5120'/>
  </bandwidth>
</portgroup>
"""
    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        if net_section == "portgroup":
            portgroup_xml = network_xml.PortgroupXML()
            portgroup_xml.xml = port_group
            test_xml.portgroup = portgroup_xml
        elif net_section == "forward-interface":
            test_xml.forward = {'mode': 'passthrough'}
            test_xml.forward_interface = [{'dev': 'eth2'}]
            del test_xml.bridge
            del test_xml.mac
            del test_xml.ip
        test_xml.define()
        if net_state == "active":
            test_xml.start()
        test_xml.debug_xml()
        virsh.net_dumpxml(net_name)
    except xcepts.LibvirtXMLError as detail:
        test.error("Failed to define a test network.\n" "Detail: %s." % detail)

    try:
        # Get a tmp_dir.
        tmp_dir = data_dir.get_tmp_dir()

        # Write new xml into a tempfile
        tmp_file = tempfile.NamedTemporaryFile(prefix=("new_xml_"),
                                               dir=tmp_dir)
        xmlfile = tmp_file.name
        tmp_file.close()

        element = "/%s" % net_section.replace('-', '/')
        section_xml = test_xml.get_section_string(xpath=element)

        flag_list = []
        if update_command == "delete":
            newxml = section_xml
        else:
            if net_section == "bridge":
                new_bridge_name = net_name + "_new"
                flag_list.append(new_bridge_name)
                newxml = section_xml.replace(net_name, new_bridge_name)
                logging.info("The new bridge xml is %s", newxml)

            elif net_section == "forward":
                new_mode = "route"
                flag_list.append(new_mode)
                newxml = section_xml.replace("nat", new_mode)
                logging.info("The new forward xml is %s", newxml)

            elif net_section == "ip":
                new_netmask = "255.255.0.0"
                flag_list.append(new_netmask)
                newxml = section_xml.replace("255.255.255.0", new_netmask)
                logging.info("The new xml of ip section is %s", newxml)

            elif net_section == "ip-dhcp-range":
                new_end_ip = "192.168.100.253"
                flag_list.append(new_end_ip)
                newxml = section_xml.replace("192.168.100.254", new_end_ip)
                logging.info("The new xml of ip-dhcp-range is %s", newxml)
            elif net_section == "portgroup":
                new_inbound_average = "2000"
                flag_list.append(new_inbound_average)
                newxml = section_xml.replace("1000", new_inbound_average)
                newxml = newxml.replace("no", "yes")
                flag_list.append("yes")
                if update_command in ['add-first', 'add-last']:
                    newxml = newxml.replace("engineering", "sales")
                    flag_list.append("sales")
                logging.info("The new xml of portgroup is %s", newxml)
            elif net_section == "forward-interface":
                new_forward_iface = params.get("new_forward_iface", "eth4")
                flag_list.append(new_forward_iface)
                newxml = section_xml.replace("eth2", new_forward_iface)
                logging.info("The new xml of forward-interface is %s", newxml)
            elif net_section == "ip-dhcp-host":
                new_ip_dhcp_host = params.get("new_ip_dhcp_host",
                                              "192.168.100.153")
                flag_list.append(new_ip_dhcp_host)
                newxml = section_xml.replace("192.168.100.152",
                                             new_ip_dhcp_host)
                if update_command in ['add-first', 'add-last']:
                    new_ip_dhcp_mac = params.get("new_ip_dhcp_mac",
                                                 "52:54:00:5a:a0:9b")
                    newxml = newxml.replace("52:54:00:5a:a0:8b",
                                            new_ip_dhcp_mac)
                    flag_list.append(new_ip_dhcp_mac)
                logging.info("The new xml of forward-interface is %s", newxml)
            else:
                test.fail("Unknown network section")

        fd = open(xmlfile, 'w')
        fd.write(newxml)
        fd.close()

        cmd_result = virsh.net_update(net_name,
                                      update_command,
                                      net_section,
                                      xmlfile,
                                      options,
                                      debug=True)

        if cmd_result.exit_status:
            err = cmd_result.stderr.strip()
            if re.search("not supported", err):
                test.cancel("Skip the test: %s" % err)
            else:
                test.fail("Failed to execute " "virsh net-update command")

        # Check the actual xml
        virsh_option = ""
        if options == "--config":
            virsh_option = "--inactive"
        cmd_result = virsh.net_dumpxml(net_name, virsh_option)
        actual_net_xml = cmd_result.stdout.strip()
        logging.info("After net-update, the actual net xml is %s",
                     actual_net_xml)

        if update_command == "delete":
            new_xml_obj = network_xml.NetworkXML.new_from_net_dumpxml(
                net_name, extra=virsh_option)
            try:
                section_str = new_xml_obj.get_section_string(xpath=element)
            except xcepts.LibvirtXMLNotFoundError:
                section_str = None
            if section_str is not None:
                test.fail("The actual net xml is not expected,"
                          "element still exists")

        else:
            for flag_string in flag_list:
                if not re.search(flag_string, actual_net_xml):
                    test.fail("The actual net xml failed to update")

    finally:
        test_xml.undefine()

        if os.path.exists(xmlfile):
            os.remove(xmlfile)
Ejemplo n.º 18
0
def run(test, params, env):
    """
    Test command: virsh net-edit <network>

    1) Define a temp virtual network
    2) Execute virsh net-edit to modify it
    3) Dump its xml then check it
    """
    def edit_net_xml():
        edit_cmd = r":%s /100.254/100.253"

        session = aexpect.ShellSession("sudo -s")
        try:
            logging.info("Execute virsh net-edit %s", net_name)
            session.sendline("virsh net-edit %s" % net_name)

            logging.info("Change the ip value of dhcp end")
            session.sendline(edit_cmd)
            session.send('\x1b')
            session.send('ZZ')
            remote.handle_prompts(session, None, None, r"[\#\$]\s*$")
            session.close()
        except (aexpect.ShellError, aexpect.ExpectError) as details:
            log = session.get_output()
            session.close()
            test.fail("Failed to do net-edit: %s\n%s" % (details, log))

    # Gather test parameters
    net_name = params.get("net_edit_net_name", "editnet")
    test_create = "yes" == params.get("test_create", "no")

    virsh_dargs = {'debug': True, 'ignore_status': True}
    virsh_instance = virsh.VirshPersistent(**virsh_dargs)

    # Get all network instance
    nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance)

    # First check if a bridge of this name already exists
    # Increment suffix integer from 1 then append it to net_name
    # till there is no name conflict.
    if net_name in nets:
        net_name_fmt = net_name + "%d"
        suffix_num = 1
        while ((net_name_fmt % suffix_num) in nets):
            suffix_num += 1

        net_name = net_name_fmt % suffix_num

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        if test_create:
            test_xml.create()
        else:
            test_xml.define()
    except xcepts.LibvirtXMLError as detail:
        test.cancel("Failed to define a test network.\n"
                    "Detail: %s." % detail)

    # Run test case
    try:
        libvirtd = utils_libvirtd.Libvirtd()
        if test_create:
            # Restart libvirtd and check state
            libvirtd.restart()
            net_state = virsh.net_state_dict()
            if (not net_state[net_name]['active']
                    or net_state[net_name]['autostart']
                    or net_state[net_name]['persistent']):
                test.fail("Found wrong network states"
                          " after restarting libvirtd: %s" % net_state)
        else:
            libvirtd.restart()
            net_state = virsh.net_state_dict()
            if (net_state[net_name]['active']
                    or net_state[net_name]['autostart']
                    or not net_state[net_name]['persistent']):
                test.fail("Found wrong network states: %s" % net_state)
            virsh.net_start(net_name)
        edit_net_xml()
        if test_create:
            # Network become persistent after editing
            net_state = virsh.net_state_dict()
            if (not net_state[net_name]['active']
                    or net_state[net_name]['autostart']
                    or not net_state[net_name]['persistent']):
                test.fail("Found wrong network states"
                          " after editing: %s" % net_state)

        cmd_result = virsh.net_dumpxml(net_name, '--inactive', debug=True)
        if cmd_result.exit_status:
            test.fail("Failed to dump xml of virtual network %s" % net_name)

        # The xml should contain the match_string
        match_string = "100.253"
        xml = cmd_result.stdout.strip()
        if not re.search(match_string, xml):
            test.fail("The xml is not expected")
        # The active xml should not contain the match_string
        cmd_result = virsh.net_dumpxml(net_name, debug=True)
        if cmd_result.exit_status:
            test.fail("Failed to dump active xml of virtual network %s" %
                      net_name)
        # The xml should contain the match_string
        match_string = "100.253"
        xml = cmd_result.stdout.strip()
        if re.search(match_string, xml):
            test.fail("The active xml should not change")

    finally:
        test_xml.orbital_nuclear_strike()
Ejemplo n.º 19
0
def run(test, params, env):
    """
    Test command: virsh net-start.
    """
    # Gather test parameters
    uri = libvirt_vm.normalize_connect_uri(params.get("connect_uri",
                                                      "default"))
    status_error = "yes" == params.get("status_error", "no")
    inactive_default = "yes" == params.get("net_start_inactive_default", "yes")
    net_ref = params.get("net_start_net_ref", "netname")  # default is tested
    extra = params.get("net_start_options_extra", "")  # extra cmd-line params.
    route_test = "yes" == params.get("route_test", "no")
    firewalld_operate = params.get("firewalld_operate", None)

    # make easy to maintain
    virsh_dargs = {'uri': uri, 'debug': True, 'ignore_status': True}
    virsh_instance = virsh.VirshPersistent(**virsh_dargs)

    # libvirt acl polkit related params
    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            test.cancel("API acl test not supported in current"
                        " libvirt version.")

    virsh_uri = params.get("virsh_uri")
    if virsh_uri and not utils_split_daemons.is_modular_daemon():
        virsh_uri = "qemu:///system"
    unprivileged_user = params.get('unprivileged_user')
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    # Get all network instance
    origin_nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance)

    # Prepare default network for following test.
    try:
        default_netxml = origin_nets['default']
    except KeyError:
        virsh_instance.close_session()
        test.cancel("Test requires default network to exist")
    try:
        # To confirm default network is active
        if not default_netxml.active:
            default_netxml.active = True

        # inactive default according test's need
        if inactive_default:
            logging.info("Stopped default network")
            default_netxml.active = False

        # State before run command
        origin_state = virsh_instance.net_state_dict()
        logging.debug("Origin network(s) state: %s", origin_state)

        if route_test:
            # define a network "def" with route address is "192.168.122.x"
            # 1. start def first then start default
            current_state = virsh_instance.net_state_dict()
            if 'def' in current_state:
                virsh.net_destroy("def", ignore_status=True)
                virsh.net_undefine("def", ignore_status=True)
            expect_fail = "yes" == params.get("expect_start_fail", "no")
            test_xml = network_xml.NetworkXML(network_name="def")
            test_xml.forward = {'mode': 'nat'}
            test_xml.routes = [{
                'address': '192.168.122.0',
                'prefix': '24',
                'gateway': '192.168.100.1'
            }]
            ipxml = IPXML(address='192.168.100.1', netmask='255.255.255.0')
            range_4 = network_xml.RangeXML()
            range_4.attrs = {
                'start': '192.168.100.2',
                'end': '192.168.100.254'
            }
            ipxml.dhcp_ranges = range_4
            test_xml.ip = ipxml
            test_xml.define()
            virsh.net_start("def")
            # start default, should fail
            result = virsh.net_start("default")
            logging.debug(result)
            libvirt.check_exit_status(result, expect_error=expect_fail)

            # 2. start default then start def
            virsh.net_destroy("def")
            virsh.net_start("default")
            current_state11 = virsh_instance.net_state_dict()
            logging.debug("before start 2nd network(s) state: %s",
                          current_state11)
            # start def, should fail
            result = virsh.net_start("def")
            logging.debug(result)
            libvirt.check_exit_status(result, expect_error=expect_fail)
            current_state12 = virsh_instance.net_state_dict()
            logging.debug("after start 2nd network(s) state: %s",
                          current_state12)
            # clear the env
            virsh.net_undefine("def")

        else:
            if net_ref == "netname":
                net_ref = default_netxml.name
            elif net_ref == "netuuid":
                net_ref = default_netxml.uuid

            if params.get('setup_libvirt_polkit') == 'yes':
                virsh_dargs = {
                    'uri': virsh_uri,
                    'unprivileged_user': unprivileged_user,
                    'debug': False,
                    'ignore_status': True
                }
            if params.get('net_start_readonly', 'no') == 'yes':
                virsh_dargs = {
                    'uri': uri,
                    'debug': True,
                    'readonly': True,
                    'ignore_status': True
                }

        # Run test case
        if 'unprivileged_user' in virsh_dargs and status_error:
            test_virsh = virsh.VirshPersistent(
                unprivileged_user=virsh_dargs['unprivileged_user'])
            virsh_dargs.pop('unprivileged_user')
            result = test_virsh.net_start(net_ref, extra, **virsh_dargs)
            test_virsh.close_session()
        elif not route_test:
            result = virsh.net_start(net_ref, extra, **virsh_dargs)
        logging.debug(result)
        status = result.exit_status

        # Get current net_stat_dict
        current_state = virsh_instance.net_state_dict()
        logging.debug("Current network(s) state: %s", current_state)
        if 'default' not in current_state:
            test.fail('Network "default" cannot be found')
        if firewalld_operate:
            # current network is active, ensure firewalld is active
            # if not, restart firewalld, then restart libvirtd
            firewalld_service = service.Factory.create_service("firewalld")
            libvirtd_obj = utils_libvirtd.Libvirtd()
            if not firewalld_service.status():
                firewalld_service.start()
                libvirtd_obj.restart()
                virsh_instance = virsh.VirshPersistent(**virsh_dargs)
            if firewalld_operate == "restart":
                # after firewalld restart, destroy and start the network
                firewalld_service.restart()
                time.sleep(5)
                res1 = virsh.net_destroy(net_ref, extra, **virsh_dargs)
                # need to add wait time. As libvirt doesn't know that firewalld has restarted until it gets the
                # dbus message, but that message won't arrive until some time after all of libvirt's chains/rules
                # have already been removed by the firewalld restart. refer to bug 1942805
                time.sleep(5)
                res2 = virsh.net_start(net_ref, extra, **virsh_dargs)
            elif firewalld_operate == "stop_start":
                # start network which has been destroyed before firewalld restart
                res1 = virsh.net_destroy(net_ref, extra, **virsh_dargs)
                firewalld_service.stop()
                firewalld_service.start()
                time.sleep(5)
                res2 = virsh.net_start(net_ref, extra, **virsh_dargs)
            logging.debug(
                "firewalld_operate is %s, result for start network after firewalld restart: %s",
                firewalld_operate, res2)
            status1 = res1.exit_status | res2.exit_status
            if status1:
                test.fail(
                    "Start or destroy network after firewalld restart fail!")
        # Check status_error
        if status_error:
            if not status:
                test.fail("Run successfully with wrong command!")
        else:
            if status:
                test.fail("Run failed with right command")

            # Get current net_stat_dict
            current_state = virsh_instance.net_state_dict()
            logging.debug("Current network(s) state: %s", current_state)
            is_default_active = current_state['default']['active']
            if not is_default_active:
                test.fail(
                    "Execute cmd successfully but default is inactive actually."
                )
    finally:
        virsh_instance.close_session()
        current_state = virsh_instance.net_state_dict()
        if "def" in current_state:
            virsh.net_destroy("def", ignore_status=True)
            virsh.net_undefine("def", ignore_status=True)
        virsh.net_start('default', debug=True, ignore_status=True)
Ejemplo n.º 20
0
def run(test, params, env):
    """
    Test command: virsh net-edit <network>

    1) Define a temp virtual network
    2) Execute virsh net-edit to modify it
    3) Dump its xml then check it
    """
    def edit_net_xml(edit_cmd, expect_error, **dargs):
        """
        Edit net xml with virsh net-edit

        :params edit_cmd: The edit cmd to execute
        :params expect_error: Boolean, expect success or not
        :params **dargs: The virsh edit's option
        """
        logging.debug("edit_cmd: %s", edit_cmd)
        readonly = dargs.get("readonly", False)
        session = aexpect.ShellSession("sudo -s")
        try:
            logging.info("Execute virsh net-edit %s", net_name)
            virsh_cmd = "virsh net-edit %s" % net_name
            if readonly:
                virsh_cmd = "virsh -r net-edit %s" % net_name
            logging.debug("virsh_cmd: %s", virsh_cmd)
            session.sendline(virsh_cmd)
            session.sendline(edit_cmd)
            session.send('\x1b')
            session.send('ZZ')
            remote.handle_prompts(session, None, None, r"[\#\$]\s*$")
            session.close()
        except (aexpect.ShellError, aexpect.ExpectError,
                remote.LoginTimeoutError) as details:
            log = session.get_output()
            session.close()
            if not expect_error:
                test.fail("Failed to do net-edit: %s\n%s" % (details, log))
            logging.debug("Expected error: %s" % log)
            if readonly and "read only" not in log:
                test.fail("Not expected error")

    # Gather test parameters
    net_name = params.get("net_edit_net_name", "editnet")
    test_create = "yes" == params.get("test_create", "no")

    virsh_dargs = {'debug': True, 'ignore_status': True}
    virsh_instance = virsh.VirshPersistent(**virsh_dargs)

    change_attribute = params.get("attribute", None)
    old_value = params.get("old_value", None)
    new_value = params.get("new_value", None)
    edit_type = params.get("edit_type", "modify")
    status_error = (params.get("status_error", "no") == "yes")
    readonly = (params.get("net_edit_readonly", "no") == "yes")

    # Get all network instance
    nets = network_xml.NetworkXML.new_all_networks_dict(virsh_instance)

    # First check if a bridge of this name already exists
    # Increment suffix integer from 1 then append it to net_name
    # till there is no name conflict.
    if net_name in nets:
        net_name_fmt = net_name + "%d"
        suffix_num = 1
        while ((net_name_fmt % suffix_num) in nets):
            suffix_num += 1

        net_name = net_name_fmt % suffix_num

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254' />
    </dhcp>
  </ip>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = virtual_net
        if test_create:
            test_xml.create()
        else:
            test_xml.define()
    except xcepts.LibvirtXMLError as detail:
        test.cancel("Failed to define a test network.\n"
                    "Detail: %s." % detail)

    # Run test case
    try:
        libvirtd = utils_libvirtd.Libvirtd()
        if change_attribute == "uuid":
            # if the attribute need to change is uuid, the old uuid should get
            # from current network, and new uuid can generate by uuidgen
            new_value = process.run("uuidgen", shell=True).stdout[:-1]
            old_value = virsh.net_uuid(net_name).stdout.strip()
        if test_create:
            # Restart libvirtd and check state
            libvirtd.restart()
            net_state = virsh.net_state_dict()
            if (not net_state[net_name]['active']
                    or net_state[net_name]['autostart']
                    or net_state[net_name]['persistent']):
                test.fail("Found wrong network states"
                          " after restarting libvirtd: %s" % net_state)
        else:
            libvirtd.restart()
            net_state = virsh.net_state_dict()
            if (net_state[net_name]['active']
                    or net_state[net_name]['autostart']
                    or not net_state[net_name]['persistent']):
                test.fail("Found wrong network states: %s" % net_state)
            result = virsh.net_start(net_name)
            logging.debug("start the persistent network return: %s", result)

        if edit_type == "modify":
            edit_cmd = r":%%s/%s=\'%s\'/%s=\'%s\'" % (
                change_attribute, old_value, change_attribute, new_value)
            match_string = "%s=\'%s\'" % (change_attribute, new_value)

        if edit_type == "delete":
            match_string = "%s" % change_attribute
            # Pattern to be more accurate
            if old_value and change_attribute != 'uuid':
                match_string = "%s=\'%s\'" % (change_attribute, old_value)
            else:
                match_string = old_value
            edit_cmd = r":/%s/d" % match_string

        edit_net_xml(edit_cmd, status_error, readonly=readonly)

        net_state = virsh.net_state_dict()
        # transient Network become persistent after editing
        if not status_error and (not net_state[net_name]['active']
                                 or net_state[net_name]['autostart']
                                 or not net_state[net_name]['persistent']):
            test.fail("Found wrong network states"
                      " after editing: %s" % net_state)

        cmd_result = virsh.net_dumpxml(net_name, '--inactive', debug=True)
        if cmd_result.exit_status:
            test.fail("Failed to dump xml of virtual network %s" % net_name)

        # The inactive xml should contain the match string
        xml = cmd_result.stdout.strip()
        if edit_type == "modify":
            if not status_error and not re.search(match_string, xml):
                test.fail("The inactive xml should contain the change '%s'" %
                          match_string)
            if status_error and re.search(match_string, xml):
                test.fail("Expect to modify failure but run success")

        if edit_type == "delete":
            if not status_error and re.search(match_string, xml):
                test.fail("The inactive xml should delete the change '%s'" %
                          match_string)
            if status_error and not re.search(match_string, xml):
                test.fail("Expect to delete failure but run success")

        # The active xml should not contain the match string
        if net_state[net_name]['active']:
            if not status_error:
                cmd_result = virsh.net_dumpxml(net_name, debug=True)
                if cmd_result.exit_status:
                    test.fail(
                        "Failed to dump active xml of virtual network %s" %
                        net_name)
                xml = cmd_result.stdout.strip()
                if edit_type == "modify" and re.search(match_string, xml):
                    test.fail(
                        "The active xml should not contain the change '%s'" %
                        match_string)
                if edit_type == "delete" and not re.search(match_string, xml):
                    test.fail(
                        "The active xml should not delete the change '%s'" %
                        match_string)
    finally:
        test_xml.orbital_nuclear_strike()
Ejemplo n.º 21
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()
Ejemplo n.º 22
0
def run(test, params, env):
    """
    Test command: virsh net-autostart.
    """
    # Gather test parameters
    status_error = "yes" == params.get("status_error", "no")
    net_ref = params.get("net_autostart_net_ref", "netname")
    disable = "yes" == params.get("net_autostart_disable", "no")
    extra = params.get("net_autostart_extra", "")  # extra cmd-line params.
    net_name = params.get("net_autostart_net_name", "autotest")

    # Prepare environment and record current net_state_dict
    backup = network_xml.NetworkXML.new_all_networks_dict()
    backup_state = virsh.net_state_dict()
    logging.debug("Backed up network(s): %s", backup_state)

    # Generate our own bridge
    # First check if a bridge of this name already exists
    try:
        _ = backup[net_name]
    except (KeyError, AttributeError):
        pass  # Not found - good
    else:
        test.cancel("Found network bridge '%s' - skipping" % net_name)

    # Define a very bare bones bridge, don't provide UUID - use whatever
    # libvirt ends up generating.  We need to define a persistent network
    # since we'll be looking to restart libvirtd as part of this test.
    #
    # This test cannot use the 'default' bridge (virbr0) since undefining
    # it causes issues for libvirtd restart since it's expected that a
    # default network is defined
    #
    temp_bridge = """
<network>
   <name>%s</name>
   <bridge name="vir%sbr0"/>
</network>
""" % (net_name, net_name)

    try:
        test_xml = network_xml.NetworkXML(network_name=net_name)
        test_xml.xml = temp_bridge
        test_xml.define()
    except xcepts.LibvirtXMLError as detail:
        test.error("Failed to define a test network.\n" "Detail: %s." % detail)

    # To guarantee cleanup will be executed
    try:
        # Run test case

        # Get the updated list and make sure our new bridge exists
        currents = network_xml.NetworkXML.new_all_networks_dict()
        current_state = virsh.net_state_dict()
        logging.debug("Current network(s): %s", current_state)
        try:
            testbr_xml = currents[net_name]
        except (KeyError, AttributeError):
            test.error("Did not find newly defined bridge '%s'" % net_name)

        # Prepare default property for network
        # Transient network can not be set autostart
        # So confirm persistent is true for test
        testbr_xml['persistent'] = True

        # Set network to inactive
        # Since we do not reboot host to check(instead of restarting libvirtd)
        # If default network is active, we cannot check "--disable".
        # Because active network will not be inactive after restarting libvirtd
        # even we set autostart to False. While inactive network will be active
        # after restarting libvirtd if we set autostart to True
        testbr_xml['active'] = False

        # Prepare options and arguments
        if net_ref == "netname":
            net_ref = testbr_xml.name
        elif net_ref == "netuuid":
            net_ref = testbr_xml.uuid

        if disable:
            net_ref += " --disable"

        # Run test case
        # Use function in virsh module directly for both normal and error test
        result = virsh.net_autostart(net_ref, extra)
        logging.debug(result)
        status = result.exit_status

        # Check if autostart or disable is successful with libvirtd restart.
        # TODO: Since autostart is designed for host reboot,
        #       we'd better check it with host reboot.
        utils_libvirtd.libvirtd_restart()

        # Reopen testbr_xml
        currents = network_xml.NetworkXML.new_all_networks_dict()
        current_state = virsh.net_state_dict()
        logging.debug("Current network(s): %s", current_state)
        testbr_xml = currents[net_name]
        is_active = testbr_xml['active']

    finally:
        test_xml.undefine()

    # Check Result
    if status_error:
        if status == 0:
            test.fail("Run successfully with wrong command!")
    else:
        if disable:
            if status or is_active:
                test.fail("Disable autostart failed.")
        else:
            if status or (not is_active):
                test.fail("Set network autostart failed.")