Example #1
0
def run(test, params, env):
    """
    Kill libvirt daemon with different signals and check
    whether daemon restart properly and leaving no pid file
    if stopped.
    """
    def get_pid(libvirtd):
        """
        Get the pid of libvirt daemon process.
        """
        pid = int(open(pid_file).read())
        return pid

    def send_signal(pid, signal_name):
        """
        Send signal to a process by pid.
        """
        signal_num = getattr(signal, signal_name)
        os.kill(pid, signal_num)

    pid_file = '/var/run/libvirtd.pid'
    signal_name = params.get("signal", "SIGTERM")
    should_restart = params.get("expect_restart", "yes") == "yes"
    pid_should_change = params.get("expect_pid_change", "yes") == "yes"

    libvirtd = Libvirtd()
    try:
        libvirtd.start()

        pid = get_pid(libvirtd)
        logging.debug("Pid of libvirtd is %d" % pid)

        logging.debug("Killing process %s with %s" % (pid, signal_name))
        send_signal(pid, signal_name)

        # Wait for libvirtd to restart or reload
        time.sleep(1)

        if libvirtd.is_running():
            if not should_restart:
                test.fail("libvirtd should stop running after signal %s" %
                          signal_name)
            new_pid = get_pid(libvirtd)
            logging.debug("New pid of libvirtd is %d" % new_pid)
            if pid == new_pid and pid_should_change:
                test.fail("Pid should have been changed.")
            if pid != new_pid and not pid_should_change:
                test.fail("Pid should not have been changed.")
        else:
            if should_restart:
                test.fail("libvirtd should still running after signal %s" %
                          signal_name)

    finally:
        if not libvirtd.is_running():
            if os.path.exists(pid_file):
                os.remove(pid_file)
                libvirtd.start()
                test.fail("Pid file should not reside")
            libvirtd.start()
Example #2
0
def run(test, params, env):
    """
    Start libvirt daemon with break point inserted.
    And then kill daemon ensure no sigsegv happends.
    """
    signal_name = params.get("signal", "SIGTERM")
    send_signal_at = params.get("send_signal_at", None)

    def _signal_callback(gdb, info, params):
        """
        Callback function when a signal is received by libvirtd.
        """
        params['recieved'] = True
        logging.debug("Signal received:")
        logging.debug(info)

    def _break_callback(gdb, info, params):
        """
        Callback function when a breakpoint is reached.
        """
        for line in gdb.back_trace():
            logging.debug(line)
        gdb.send_signal(signal_name)
        gdb.cont()

    def get_service(send_signal_at):
        """
        Get the name of the service

        :param send_signal_at: The function to set breakpoint
        :return: Service name
        """
        return {
            'netcfStateInitialize': 'virtinterfaced',
            'networkStateInitialize': 'virtnetworkd',
            'nwfilterStateInitialize': 'virtnwfilterd'
        }.get(send_signal_at)

    serv_name = get_service(send_signal_at)
    bundle = {'recieved': False}

    libvirtd = LibvirtdSession(service_name=serv_name, gdb=True)
    try:
        libvirtd.set_callback('break', _break_callback)
        libvirtd.set_callback('signal', _signal_callback, bundle)

        libvirtd.insert_break(send_signal_at)

        libvirtd.start(wait_for_working=False)

        if not utils_misc.wait_for(lambda: bundle['recieved'], 20, 0.5):
            test.fail("Expect receive signal, but not.")
    finally:
        libvirtd.exit()
        # Need to restart libvirtd.socket after starting libvirtd in the foreground
        Libvirtd("libvirtd.socket").restart()
Example #3
0
 def check_version(params):
     """
     Check whether the output is libvirtd version.
     """
     expected_version = params.get('expected_version', 'no') == 'yes'
     is_version = log[0].startswith('{} (libvirt)'.format(
         Libvirtd().service_list[0]))
     if expected_version != is_version:
         test.fail('Expected output version is %s, but get output:\n%s' %
                   (expected_version, '\n'.join(log)))
Example #4
0
def run(test, params, env):
    """
    Run various regression tests and check whether libvirt daemon crashes.
    """
    func_name = 'run_' + params.get("func_name", "default")
    post_func_name = 'post_' + params.get("func_name", "default")
    repeat = int(params.get("repeat", "1"))
    vm_name = params.get("main_vm", "virt-tests-vm1")
    bug_url = params.get("bug_url", None)
    vm = env.get_vm(vm_name)
    # Run virtlogd foreground
    try:
        path.find_command('virtlogd')
        process.run("systemctl stop virtlogd", ignore_status=True)
        process.run("virtlogd -d")
    except path.CmdNotFoundError:
        pass
    libvirtd = LibvirtdSession(gdb=True)
    serv_tmp = "libvirt" if libvirtd.service_exec == "libvirtd" else libvirtd.service_exec
    process.run("rm -rf /var/run/libvirt/%s-*" % serv_tmp,
                shell=True,
                ignore_status=True)
    try:
        libvirtd.start()

        run_func = globals()[func_name]
        for i in xrange(repeat):
            run_func(params, libvirtd, vm)

        stopped = libvirtd.wait_for_stop(timeout=5)
        if stopped:
            logging.debug('Backtrace:')
            for line in libvirtd.back_trace():
                logging.debug(line)

            if bug_url:
                logging.error(
                    "You might met a regression bug. Please reference %s" %
                    bug_url)

            test.fail("Libvirtd stops with %s" % libvirtd.bundle['stop-info'])

        if post_func_name in globals():
            post_func = globals()[post_func_name]
            post_func(params, libvirtd, vm)
    finally:
        try:
            path.find_command('virtlogd')
            process.run('pkill virtlogd', ignore_status=True)
            process.run('systemctl restart virtlogd.socket',
                        ignore_status=True)
            Libvirtd("libvirtd.socket").restart()
        except path.CmdNotFoundError:
            pass
        libvirtd.exit()
Example #5
0
    def check_pid_file():
        """
        Check whether the pid file exists.
        """
        if not os.path.exists(pid_path):
            test.fail("PID file not found at %s" % pid_path)

        with open(pid_path) as pid_file:
            pid = int(pid_file.readline())
        result = process.run('pgrep %s' % Libvirtd().service_list[0],
                             ignore_status=True,
                             shell=True)
        expected_pid = int(result.stdout_text.strip().split()[0])

        if pid != expected_pid:
            test.fail("PID file content mismatch. Expected %s "
                      "but got %s" % (expected_pid, pid))
Example #6
0
def run(test, params, env):
    """
    Kill libvirt daemon with different signals and check
    whether daemon restart properly and leaving no pid file
    if stopped.
    """
    def get_pid(libvirtd):
        """
        Get the pid of libvirt daemon process.
        """
        pid = int(open(pid_file).read())
        return pid

    def send_signal(pid, signal_name):
        """
        Send signal to a process by pid.
        """
        signal_num = getattr(signal, signal_name)
        os.kill(pid, signal_num)

    def start_mark(src_file, dest_file):
        """
        Copy the src_file to a tmp file
        :param src_file: The file should be checked.
        :param dest_file: The temp file to mark the time point.
        """
        # Clean the dest file if existed
        if os.path.exists(dest_file):
            os.remove(dest_file)
        cmdline = 'cp %s %s' % \
                  (src_file, dest_file)
        process.run(cmdline, shell=True)

    pid_file = '/var/run/libvirtd.pid'
    message_src_file = '/var/log/messages'
    message_dest_file = '/tmp/messages_tmp'
    signal_name = params.get("signal", "SIGTERM")
    should_restart = params.get("expect_restart", "yes") == "yes"
    pid_should_change = params.get("expect_pid_change", "yes") == "yes"
    sysconfig = params.get("sysconfig", None)
    check_dmesg = params.get("check_dmesg", None)

    libvirtd = Libvirtd()
    try:
        libvirtd.start()

        if sysconfig:
            config = utils_config.LibvirtdSysConfig()
            setattr(config, sysconfig.split('=')[0], sysconfig.split('=')[1])
            libvirtd.restart()
        if check_dmesg:
            start_mark(message_src_file, message_dest_file)

        pid = get_pid(libvirtd)
        logging.debug("Pid of libvirtd is %d" % pid)

        logging.debug("Killing process %s with %s" % (pid, signal_name))
        send_signal(pid, signal_name)

        # Wait for libvirtd to restart or reload
        time.sleep(1)

        if libvirtd.is_running():
            if not should_restart:
                test.fail("libvirtd should stop running after signal %s" %
                          signal_name)
            new_pid = get_pid(libvirtd)
            logging.debug("New pid of libvirtd is %d" % new_pid)
            if pid == new_pid and pid_should_change:
                test.fail("Pid should have been changed.")
            if pid != new_pid and not pid_should_change:
                test.fail("Pid should not have been changed.")
        else:
            if should_restart:
                test.fail("libvirtd should still running after signal %s" %
                          signal_name)

        if check_dmesg:
            cmdline = 'diff %s %s' % \
                      (message_src_file, message_dest_file)
            res = process.run(cmdline, shell=True,
                              ignore_status=True).stdout_text
            if check_dmesg not in res:
                test.fail('%s should in %s , but not now' %
                          (check_dmesg, message_src_file))

    finally:
        if not libvirtd.is_running():
            if os.path.exists(pid_file):
                os.remove(pid_file)
                libvirtd.start()
                test.fail("Pid file should not reside")
            libvirtd.start()
        if sysconfig:
            config.restore()
            libvirtd.restart()
Example #7
0
def run(test, params, env):
    """
    Test the command virsh metadata

    Run in 4 steps:
    1. Set domain metadata
    2. Get domain metadata
    3. Restart libvirtd then get domain metadata again
    4. Remove domain metadata then get domain metadata again
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    metadata_uri = params.get("metadata_uri")
    metadata_key = params.get("metadata_key")
    metadata_value = params.get("metadata_value", "")
    metadata_option = params.get("metadata_option", "")
    virsh_dargs = {'debug': True, 'ignore_status': True}
    metadata_set = "yes" == params.get("metadata_set", "no")
    metadata_get = "yes" == params.get("metadata_get", "yes")
    metadata_remove = "yes" == params.get("metadata_remove", "no")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    status_error = "yes" == params.get("status_error", "no")
    if not metadata_uri:
        test.error("'uri' is needed")
    vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
    # Start VM
    if vm.state() != "running":
        vm.destroy()
        vm.start()

    def pretty_xml(xml_str):
        return xml.dom.minidom.parseString(xml_str).toprettyxml()

    def check_result(result, expect_status, expect_output=None):
        """
        Check virsh metadata command
        """
        utlv.check_exit_status(result, expect_status)
        if result.exit_status == 0 and expect_output:
            expect_output = pretty_xml(expect_output)
            logging.debug("Expect metadata: %s", expect_output)
            output = result.stdout.strip()
            output = pretty_xml(output)
            logging.debug("Command get metadata: %s", output)
            if output != expect_output:
                test.fail("Metadat is not expected")

    def get_metadata(metadata_option=""):
        """
        Get domain metadata
        """
        option = metadata_option.replace("--edit", "")
        result = virsh.metadata(vm_name,
                                metadata_uri,
                                options=option,
                                key=metadata_key,
                                **virsh_dargs)
        return result

    try:
        # Set metadata XML
        if metadata_set:
            if not metadata_key:
                test.error("'key' is needed")
            if not metadata_value:
                test.error("New metadata is needed")
            # Parse metadata value
            if "--edit" in metadata_option:
                virsh_cmd = r"virsh metadata %s --uri %s --key %s %s"
                virsh_cmd = virsh_cmd % (vm_name, metadata_uri, metadata_key,
                                         metadata_option)
                session = aexpect.ShellSession("sudo -s")
                logging.info("Running command: %s", virsh_cmd)
                try:
                    session.sendline(virsh_cmd)
                    session.sendline(r":insert")
                    session.sendline(metadata_value)
                    session.sendline(".")
                    session.send('ZZ')
                    remote.handle_prompts(session,
                                          None,
                                          None,
                                          r"[\#\$]\s*$",
                                          debug=True,
                                          timeout=CMD_TIMEOUT)
                except Exception as e:
                    logging.error("Error occurred: %s", e)
                session.close()
            else:
                result = virsh.metadata(vm_name,
                                        metadata_uri,
                                        options=metadata_option,
                                        key=metadata_key,
                                        new_metadata=metadata_value,
                                        **virsh_dargs)
                check_result(result, status_error)
        # Get metadata
        for option in metadata_option.split():
            if option == "--config":
                vm.destroy()
                vm.start()
                check_result(get_metadata(metadata_option=option),
                             status_error, metadata_value)
            elif metadata_get:
                check_result(get_metadata(metadata_option=option),
                             status_error, metadata_value)

        # Restart libvirtd:
        if restart_libvirtd:
            libvirtd = Libvirtd()
            libvirtd.restart()
            # Get metadata again
            for option in metadata_option.split():
                check_result(get_metadata(metadata_option=option),
                             status_error, metadata_value)
        # Remove metadata
        if metadata_remove:
            remove_option = metadata_option.replace("--edit", "")
            remove_option += " --remove"
            result = virsh.metadata(vm_name,
                                    metadata_uri,
                                    options=remove_option,
                                    key=metadata_key,
                                    **virsh_dargs)
            check_result(result, status_error)
            # Get metadata again
            for option in metadata_option.split():
                check_result(get_metadata(metadata_option=option), True)
    finally:
        vmxml.sync()
def run(test, params, env):
    """
    Test remote access with TCP, TLS connection
    """

    test_dict = dict(params)
    pattern = test_dict.get("filter_pattern", "")
    if ('@LIBVIRT' in pattern and
            distro.detect().name == 'rhel' and
            int(distro.detect().version) < 8):
        test.cancel("The test {} is not supported on current OS({}{}<8.0) as "
                    "the keyword @LIBVIRT is not supported by gnutls on this "
                    "OS.".format(test.name, distro.detect().name,
                                 distro.detect().version))
    vm_name = test_dict.get("main_vm")
    status_error = test_dict.get("status_error", "no")
    allowed_dn_str = params.get("tls_allowed_dn_list")
    if allowed_dn_str:
        allowed_dn_list = []
        if not libvirt_version.version_compare(1, 0, 0):
            # Reverse the order in the dn list to workaround the
            # feature changes between RHEL 6 and RHEL 7
            dn_list = allowed_dn_str.split(",")
            dn_list.reverse()
            allowed_dn_str = ','.join(dn_list)
        allowed_dn_list.append(allowed_dn_str)
        test_dict['tls_allowed_dn_list'] = allowed_dn_list
    transport = test_dict.get("transport")
    plus = test_dict.get("conn_plus", "+")
    config_ipv6 = test_dict.get("config_ipv6", "no")
    tls_port = test_dict.get("tls_port", "")
    listen_addr = test_dict.get("listen_addr", "0.0.0.0")
    ssh_port = test_dict.get("ssh_port", "")
    tcp_port = test_dict.get("tcp_port", "")
    server_ip = test_dict.get("server_ip")
    server_user = test_dict.get("server_user")
    server_pwd = test_dict.get("server_pwd")
    no_any_config = params.get("no_any_config", "no")
    sasl_type = test_dict.get("sasl_type", "gssapi")
    sasl_user_pwd = test_dict.get("sasl_user_pwd")
    sasl_allowed_users = test_dict.get("sasl_allowed_users")
    server_cn = test_dict.get("server_cn")
    custom_pki_path = test_dict.get("custom_pki_path")
    rm_client_key_cmd = test_dict.get("remove_client_key_cmd")
    rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd")
    ca_cn_new = test_dict.get("ca_cn_new")
    no_verify = test_dict.get("no_verify", "no")
    ipv6_addr_des = test_dict.get("ipv6_addr_des")
    tls_sanity_cert = test_dict.get("tls_sanity_cert")
    restart_libvirtd = test_dict.get("restart_libvirtd", "yes")
    diff_virt_ver = test_dict.get("diff_virt_ver", "no")
    driver = test_dict.get("test_driver", "qemu")
    uri_path = test_dict.get("uri_path", "/system")
    virsh_cmd = params.get("virsh_cmd", "list")
    action = test_dict.get("libvirtd_action", "restart")
    uri_user = test_dict.get("uri_user", "")
    uri_aliases = test_dict.get("uri_aliases", "")
    uri_default = test_dict.get("uri_default", "")
    unix_sock_dir = test_dict.get("unix_sock_dir")
    mkdir_cmd = test_dict.get("mkdir_cmd")
    rmdir_cmd = test_dict.get("rmdir_cmd")
    adduser_cmd = test_dict.get("adduser_cmd")
    deluser_cmd = test_dict.get("deluser_cmd")
    auth_conf = test_dict.get("auth_conf")
    auth_conf_cxt = test_dict.get("auth_conf_cxt")
    polkit_pkla = test_dict.get("polkit_pkla")
    polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt")
    ssh_setup = test_dict.get("ssh_setup", "no")
    tcp_setup = test_dict.get("tcp_setup", "no")
    tls_setup = test_dict.get("tls_setup", "no")
    unix_setup = test_dict.get("unix_setup", "no")
    ssh_recovery = test_dict.get("ssh_auto_recovery", "yes")
    tcp_recovery = test_dict.get("tcp_auto_recovery", "yes")
    tls_recovery = test_dict.get("tls_auto_recovery", "yes")
    unix_recovery = test_dict.get("unix_auto_recovery", "yes")
    sasl_allowed_username_list = test_dict.get("sasl_allowed_username_list")
    auth_unix_rw = test_dict.get("auth_unix_rw")
    kinit_pwd = test_dict.get("kinit_pwd")
    test_alias = test_dict.get("test_alias")

    config_list = []
    port = ""
    # extra URI arguments
    extra_params = ""
    # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later
    objs_list = []
    # redirect LIBVIRT_DEBUG log into test log later
    test_dict["logfile"] = test.logfile

    # Make sure all of parameters are assigned a valid value
    check_parameters(test_dict, test)
    # Make sure libvirtd on remote is running
    server_session = remote.wait_for_login('ssh', server_ip, '22',
                                           server_user, server_pwd,
                                           r"[\#\$]\s*$")

    remote_libvirtd = Libvirtd(session=server_session)
    if not remote_libvirtd.is_running():
        logging.debug("start libvirt on remote")
        res = remote_libvirtd.start()
        if not res:
            status, output = server_session.cmd_status_output("journalctl -xe")
            test.error("Failed to start libvirtd on remote. [status]: %s "
                       "[output]: %s." % (status, output))
    server_session.close()

    if distro.detect().name == 'rhel' and int(distro.detect().version) >= 9:
        # Update crypto policies to legacy for RHEL>=9 per Bug 1931723 or
        # https://libguestfs.org/virt-v2v-input-xen.1.html#ssh-authentication
        crypto_policies = process.run("update-crypto-policies --set LEGACY",
                                      ignore_status=False)

    # only simply connect libvirt daemon then return
    if no_any_config == "yes":
        test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path)
        remote_access(test_dict, test)
        return

    # append extra 'pkipath' argument to URI if exists
    if custom_pki_path:
        extra_params = "?pkipath=%s" % custom_pki_path

    # append extra 'no_verify' argument to URI if exists
    if no_verify == "yes":
        extra_params = "?no_verify=1"

    # append extra 'socket' argument to URI if exists
    if unix_sock_dir:
        extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir

    # generate auth.conf and default under the '/etc/libvirt'
    if auth_conf_cxt and auth_conf:
        cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf)
        process.system(cmd, ignore_status=True, shell=True)

    # generate polkit_pkla and default under the
    # '/etc/polkit-1/localauthority/50-local.d/'
    if polkit_pkla_cxt and polkit_pkla:
        cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla)
        process.system(cmd, ignore_status=True, shell=True)

    # generate remote IP
    if config_ipv6 == "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif config_ipv6 != "yes" and server_cn:
        remote_ip = server_cn
    elif config_ipv6 != "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif server_ip and transport != "unix":
        remote_ip = server_ip
    else:
        remote_ip = ""

    # get URI port
    if tcp_port != "":
        port = ":" + tcp_port

    if tls_port != "":
        port = ":" + tls_port

    if ssh_port != "" and not ipv6_addr_des:
        port = ":" + ssh_port

    # generate URI
    uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                   remote_ip, port, uri_path, extra_params)
    test_dict["uri"] = uri

    logging.debug("The final test dict:\n<%s>", test_dict)

    if virsh_cmd == "start" and transport != "unix":
        session = remote.wait_for_login("ssh", server_ip, "22", "root",
                                        server_pwd, "#")
        cmd = "virsh domstate %s" % vm_name
        status, output = session.cmd_status_output(cmd)
        if status:
            session.close()
            test.cancel(output)

        session.close()

    try:
        # setup IPv6
        if config_ipv6 == "yes":
            ipv6_obj = IPv6Manager(test_dict)
            objs_list.append(ipv6_obj)
            ipv6_obj.setup()

        # compare libvirt version if needs
        if diff_virt_ver == "yes":
            compare_virt_version(server_ip, server_user, server_pwd, test)

        # setup SSH
        if (transport == "ssh" or ssh_setup == "yes") and sasl_type != "plain":
            if not test_dict.get("auth_pwd"):
                ssh_obj = SSHConnection(test_dict)
                if ssh_recovery == "yes":
                    objs_list.append(ssh_obj)
                # setup test environment
                ssh_obj.conn_setup()
            else:
                # To access to server with password,
                # cleanup authorized_keys on remote
                ssh_pubkey_file = "/root/.ssh/id_rsa.pub"
                if (os.path.exists("/root/.ssh/id_rsa") and
                        os.path.exists(ssh_pubkey_file)):
                    remote_file_obj = remote.RemoteFile(address=server_ip,
                                                        client='scp',
                                                        username=server_user,
                                                        password=server_pwd,
                                                        port='22',
                                                        remote_path="/root/.ssh/authorized_keys")
                    with open(ssh_pubkey_file, 'r') as fd:
                        line = fd.read().split()[-1].rstrip('\n')
                    line = ".*" + line
                    remote_file_obj.remove([line])
                    objs_list.append(remote_file_obj)

        # setup TLS
        if transport == "tls" or tls_setup == "yes":
            tls_obj = TLSConnection(test_dict)
            if tls_recovery == "yes":
                objs_list.append(tls_obj)
            # reserve cert path
            tmp_dir = tls_obj.tmp_dir
            # setup test environment
            tls_obj.conn_setup()

        # setup TCP
        if transport == "tcp" or tcp_setup == "yes":
            tcp_obj = TCPConnection(test_dict)
            if tcp_recovery == "yes":
                objs_list.append(tcp_obj)
            # setup test environment
            tcp_obj.conn_setup()

        # create a directory if needs
        if mkdir_cmd:
            process.system(mkdir_cmd, ignore_status=True, shell=True)

        # setup UNIX
        if transport == "unix" or unix_setup == "yes" or sasl_type == "plain":
            unix_obj = UNIXConnection(test_dict)
            if unix_recovery == "yes":
                objs_list.append(unix_obj)
            # setup test environment
            unix_obj.conn_setup()

        # need to restart libvirt service for negative testing
        if restart_libvirtd == "no":
            remotely_control_libvirtd(server_ip, server_user,
                                      server_pwd, action, status_error)
        # check TCP/IP listening by service
        if restart_libvirtd != "no" and transport != "unix":
            service = 'libvirtd'
            if transport == "ssh":
                service = 'ssh'

            check_listening_port_remote_by_service(server_ip, server_user,
                                                   server_pwd, service,
                                                   port, listen_addr)

        # open the tls/tcp listening port on server
        if transport in ["tls", "tcp"]:
            firewalld_port = port[1:]
            server_session = remote.wait_for_login('ssh', server_ip, '22',
                                                   server_user, server_pwd,
                                                   r"[\#\$]\s*$")
            firewall_cmd = utils_iptables.Firewall_cmd(server_session)
            firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True)
            server_session.close()

        if 'inv_transport' in test_dict:
            transport = test_dict['inv_transport']
            uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                           remote_ip, port, uri_path,
                                           extra_params)
            test_dict["uri"] = uri

        config_list = []
        if uri_aliases:
            uri_config = change_libvirtconf_on_client(
                {'uri_aliases': uri_aliases})
            config_list.append(uri_config)
            test_dict["uri"] = test_alias

        if uri_default:
            test_dict["uri"] = ""
            # Delete the default URI environment variable to prevent overriding
            del os.environ['LIBVIRT_DEFAULT_URI']
            uri_config = change_libvirtconf_on_client(
                {'uri_default': uri_default})
            config_list.append(uri_config)
            ret = virsh.command('uri', debug=True)
            if uri_default.strip('"') in ret.stdout_text:
                logging.debug("Virsh output as expected.")
            else:
                test.fail("Expected virsh output: {} not found in:{}".format(
                    uri_default.strip('"'), ret.stdout_text))

        # remove client certifications if exist, only for TLS negative testing
        if rm_client_key_cmd:
            process.system(rm_client_key_cmd, ignore_status=True, shell=True)

        if rm_client_cert_cmd:
            process.system(rm_client_cert_cmd, ignore_status=True, shell=True)

        # add user to specific group
        if adduser_cmd:
            process.system(adduser_cmd, ignore_status=True, shell=True)

        # change /etc/pki/libvirt/servercert.pem then
        # restart libvirt service on the remote host
        if tls_sanity_cert == "no" and ca_cn_new:
            test_dict['ca_cn'] = ca_cn_new
            test_dict['scp_new_cacert'] = 'no'
            tls_obj_new = TLSConnection(test_dict)
            test_dict['tls_obj_new'] = tls_obj_new
            # only setup new CA and server
            tls_obj_new.conn_setup(True, False)

        # obtain and cache a ticket
        if kinit_pwd and sasl_type == 'gssapi' and auth_unix_rw == 'sasl':
            username_list = json.loads(sasl_allowed_username_list)
            for username in username_list:
                kinit_cmd = "echo '%s' | kinit %s" % (kinit_pwd, username)
                process.system(kinit_cmd, ignore_status=True, shell=True)

        # setup SASL certification
        # From libvirt-3.2.0, the default sasl change from
        # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded.
        # More details: https://libvirt.org/auth.html#ACL_server_kerberos
        if sasl_user_pwd and sasl_type in ['digest-md5', 'plain']:
            # covert string tuple and list to python data type
            sasl_user_pwd = eval(sasl_user_pwd)
            if sasl_allowed_users:
                sasl_allowed_users = eval(sasl_allowed_users)

            # create a sasl user
            sasl_obj = SASL(test_dict)
            objs_list.append(sasl_obj)
            sasl_obj.setup()

            for sasl_user, sasl_pwd in sasl_user_pwd:
                # need't authentication if the auth.conf is configured by user
                if not auth_conf:
                    if sasl_type == 'plain':
                        test_dict["auth_pwd"] = server_pwd
                        pass
                    else:
                        test_dict["auth_user"] = sasl_user
                        test_dict["auth_pwd"] = sasl_pwd
                    logging.debug("sasl_user, sasl_pwd = "
                                  "(%s, %s)", sasl_user, sasl_pwd)

                if sasl_allowed_users and sasl_user not in sasl_allowed_users:
                    test_dict["status_error"] = "yes"
                patterns_extra_dict = {"authentication name": sasl_user,
                                       "enter your password": sasl_pwd}
                test_dict["patterns_extra_dict"] = patterns_extra_dict
                remote_access(test_dict, test)
        else:
            if not uri_default:
                remote_access(test_dict, test)

    finally:
        # recovery test environment
        # Destroy the VM after all test are done
        for config in config_list:
            restore_libvirtconf_on_client(config)
        cleanup(objs_list)

        if vm_name:
            vm = env.get_vm(vm_name)
            if vm and vm.is_alive():
                vm.destroy(gracefully=False)

        if transport in ["tcp", "tls"] and 'firewalld_port' in locals():
            server_session = remote.wait_for_login('ssh', server_ip, '22',
                                                   server_user, server_pwd,
                                                   r"[\#\$]\s*$")
            firewall_cmd = utils_iptables.Firewall_cmd(server_session)
            firewall_cmd.remove_port(firewalld_port, 'tcp', permanent=True)
            server_session.close()

        if rmdir_cmd:
            process.system(rmdir_cmd, ignore_status=True, shell=True)

        if deluser_cmd:
            process.system(deluser_cmd, ignore_status=True, shell=True)

        if auth_conf and os.path.isfile(auth_conf):
            os.unlink(auth_conf)

        if polkit_pkla and os.path.isfile(polkit_pkla):
            os.unlink(polkit_pkla)
Example #9
0
def run(test, params, env):
    """
    Test the PCIe controllers' options
    1. Backup guest xml before the tests
    2. Modify guest xml and define the guest
    3. Start guest
    4. Hotplug if needed
    5. Do checking
    6. Destroy guest and restore guest
    """
    def get_disk_bus(disk_dev=None):
        """
        Get the bus list of guest disks

        :param disk_dev: The specified disk device
        :return: list for disks' buses
        """
        disk_bus_list = []

        cur_vm_xml = VMXML.new_from_dumpxml(vm_name)
        disk_dev_list = cur_vm_xml.get_disk_blk(vm_name)
        if disk_dev and disk_dev not in disk_dev_list:
            return disk_bus_list
        for disk_index in range(0, len(disk_dev_list)):
            disk_target = disk_dev if disk_dev else disk_dev_list[disk_index]
            disk_bus = cur_vm_xml.get_disk_attr(vm_name, disk_target,
                                                'address', 'bus')
            disk_bus_list.append(disk_bus)
            if disk_dev:
                break
        logging.debug("Return disk bus list: {}".format(disk_bus_list))
        return disk_bus_list

    def check_guest_disks(ishotplug):
        """
        Check guest disks in different ways

        :param ishotplug: True for hotplug, False for hotunplug
        :raise: test.fail if some errors happen
        """
        def _find_disk_by_cmd():
            """
            Check disk using virsh command

            :return: True if the disk is found, otherwise False
            """
            ret = virsh.domblklist(vm_name, **virsh_options)
            target_disks = re.findall(r"[v,s]d[a-z]", ret.stdout.strip())
            logging.debug(target_disks)

            for one_disk in target_disks:
                if target_dev in one_disk:
                    logging.debug("Found the disk '{}'".format(target_dev))
                    return True
            logging.debug("Can't find the disk '{}'".format(target_dev))
            return False

        def _find_disk_in_xml():
            """
            Check disk in guest xml

            :return: True if the disk is found with right bus
                     False if the disk is not found
            :raise: test.fail if the disk's bus is incorrect
            """
            bus_list = get_disk_bus(target_dev)
            if len(bus_list) == 0:
                return False
            if bus_list[0] != '0x%02x' % int(contr_index):
                test.fail("The found disk's bus is expected to be {}, "
                          "but {} found".format('0x%02x' % int(contr_index),
                                                bus_list[0]))
            return True

        virsh_options.update({'ignore_status': False})
        # Firstly check virsh.domblklist
        found_by_cmd = _find_disk_by_cmd()
        found_in_xml = _find_disk_in_xml()
        msg1 = "Can't find the device with target_dev '{}' by cmd".format(
            target_dev)
        msg2 = "Found the device with target_dev '{}' unexpectedly by cmd".format(
            target_dev)
        msg3 = "The device with target_dev '{}' was not detached successfully in xml".format(
            target_dev)
        msg4 = "The device with target_dev '{}' was detached unexpectedly in xml".format(
            target_dev)
        if ((ishotplug and not status_error and not found_by_cmd)
                or (not ishotplug and status_error and not found_by_cmd)):
            test.fail(msg1)
        if ((ishotplug and status_error and found_by_cmd)
                or (not ishotplug and not status_error and found_by_cmd)):
            test.fail(msg2)
        if ((ishotplug and not status_error and not found_in_xml)
                or (not ishotplug and not status_error and found_in_xml)):
            test.fail(msg3)
        if ((ishotplug and status_error and found_in_xml)
                or (not ishotplug and status_error and not found_in_xml)):
            test.fail(msg4)

    def check_inside_guest(ishotplug):
        """
        Check devices within the guest

        :param ishotplug: True for hotplug, False for hotunplug
        :raise: test.fail if the result is not expected
        """
        def _check_disk_in_guest():
            """
            Compare the disk numbers within the guest

            :return: True if new disk is found, otherwise False
            """
            new_disk_num = len(vm.get_disks())
            if new_disk_num > ori_disk_num:
                logging.debug("New disk is found in vm")
                return True
            logging.debug("New disk is not found in vm")
            return False

        vm_session = vm.wait_for_login()
        status = _check_disk_in_guest()
        vm_session.close()
        msg1 = "Can't find the device in the guest"
        msg2 = "Found the device in the guest unexpectedly"
        if ((ishotplug and not status_error and not status)
                or (not ishotplug and status_error and not status)):
            test.fail(msg1)
        if ((ishotplug and status_error and status)
                or (not ishotplug and not status_error and status)):
            test.fail(msg2)

    def check_guest_contr():
        """
        Check the controller in guest xml

        :raise: test.fail if the controller does not meet the expectation
        """
        cntl = None
        cur_vm_xml = VMXML.new_from_dumpxml(vm_name)
        for cntl in cur_vm_xml.devices.by_device_tag('controller'):
            if (cntl.type == 'pci' and cntl.model == contr_model
                    and cntl.index == contr_index):
                logging.debug(cntl.target)
                cntl_hotplug = cntl.target.get('hotplug')
                logging.debug("Got controller's hotplug:%s", cntl_hotplug)
                if cntl_hotplug != hotplug_option:
                    test.fail("The controller's hotplug option is {}, "
                              "but expect {}".format(cntl_hotplug,
                                                     hotplug_option))
                break
        if not cntl:
            test.fail("The controller with index {} is not found".format(
                contr_index))

    def check_multi_attach(bus_list):
        """
        Check the result of multiple attach devices to the VM

        :param bus_list: List which includes the buses of vm disks
        :raise: test.fail if the result is unexpected
        """
        msg_pattern = "The disk is {} expected to be attached to " \
                      "the controller with index '{}'"
        is_found = False
        if hotplug_option == 'on':
            for one_bus in bus_list:
                is_found = is_found | (one_bus == '0x%02x' % int(contr_index))
            if not is_found:
                test.fail(msg_pattern.format('', contr_index))
            else:
                logging.debug("Found a disk attached to the controller "
                              "with index '{}".format(contr_index))
        else:
            for one_bus in bus_list:
                is_found = one_bus == '0x%02x' % int(contr_index)
                if is_found:
                    test.fail(msg_pattern.format('not', contr_index))
            logging.debug("No disk is found to attach to the "
                          "controller with index '{}'".format(contr_index))

    vm_name = params.get("main_vm", "avocado-vt-vm1")
    setup_controller = params.get("setup_controller", 'yes') == 'yes'
    check_within_guest = params.get("check_within_guest", 'yes') == 'yes'
    check_disk_xml = params.get("check_disk_xml", 'no') == 'yes'
    check_cntl_xml = params.get("check_cntl_xml", 'no') == 'yes'
    contr_model = params.get("controller_model", 'pcie-root-port')
    contr_target = params.get("controller_target")
    hotplug_option = params.get("hotplug_option")
    hotplug = params.get("hotplug", 'yes') == 'yes'
    define_option = params.get("define_option")
    attach_extra = params.get("attach_extra")
    target_dev = params.get("target_dev")
    err_msg = params.get("err_msg")
    status_error = params.get("status_error", "no") == 'yes'
    restart_daemon = params.get("restart_daemon", "no") == 'yes'
    save_restore = params.get("save_restore", "no") == 'yes'
    hotplug_counts = params.get("hotplug_counts")
    addr_twice = params.get("addr_twice", 'no') == 'yes'
    contr_index = None

    virsh_options = {'debug': True, 'ignore_status': False}

    image_path_list = []
    vm = env.get_vm(vm_name)
    vm_xml_obj = VMXML.new_from_inactive_dumpxml(vm_name)
    vm_xml_backup = vm_xml_obj.copy()
    try:
        if check_within_guest:
            if not vm.is_alive():
                virsh.start(vm_name, **virsh_options)
            ori_disk_num = len(vm.get_disks())
            logging.debug("The original disk number in vm is %d", ori_disk_num)
            virsh.destroy(vm_name)

        if setup_controller:
            contr_dict = {
                'controller_type': 'pci',
                'controller_model': contr_model,
                'controller_target': contr_target
            }
            contr_obj = libvirt.create_controller_xml(contr_dict)
            vm_xml_obj.add_device(contr_obj)
            logging.debug("Add a controller: %s" % contr_obj)

        virsh.define(vm_xml_obj.xml, options=define_option, **virsh_options)
        vm_xml = VMXML.new_from_dumpxml(vm_name)
        ret_indexes = libvirt_pcicontr.get_max_contr_indexes(
            vm_xml, 'pci', contr_model)
        if not ret_indexes or len(ret_indexes) < 1:
            test.error("Can't find the controller index for model "
                       "'{}'".format(contr_model))
        contr_index = ret_indexes[0]
        if attach_extra and attach_extra.count('--address '):
            attach_extra = attach_extra % ("%02x" % int(contr_index))
        if err_msg and err_msg.count('%s'):
            err_msg = err_msg % contr_index
        if not save_restore:
            disk_max = int(hotplug_counts) if hotplug_counts else 1
            for disk_inx in range(0, disk_max):
                image_path = os.path.join(data_dir.get_tmp_dir(),
                                          'disk{}.qcow2'.format(disk_inx))
                image_path_list.append(image_path)
                libvirt.create_local_disk("file",
                                          image_path,
                                          '10M',
                                          disk_format='qcow2')
        if not hotplug and not save_restore:
            # Do coldplug before hotunplug to prepare the virtual device
            virsh.attach_disk(vm_name,
                              image_path,
                              target_dev,
                              extra=attach_extra,
                              **virsh_options)
        virsh.start(vm_name, **virsh_options)

        logging.debug("Test VM XML after starting:"
                      "\n%s", VMXML.new_from_dumpxml(vm_name))
        vm.wait_for_login().close()

        if restart_daemon:
            daemon_obj = Libvirtd()
            daemon_obj.restart()

        if save_restore:
            save_path = os.path.join(data_dir.get_tmp_dir(), 'rhel.save')
            virsh.save(vm_name, save_path, **virsh_options)
            time.sleep(10)
            virsh.restore(save_path, **virsh_options)
        # Create virtual device xml
        if hotplug:
            virsh_options.update({'ignore_status': True})
            attach_times = 1 if not hotplug_counts else int(hotplug_counts)

            if attach_times == 1:
                ret = virsh.attach_disk(vm_name,
                                        image_path_list[0],
                                        target_dev,
                                        extra=attach_extra,
                                        **virsh_options)
                libvirt.check_result(ret, expected_fails=err_msg)
            else:
                for attach_inx in range(0, attach_times):
                    disk_dev = 'vd{}'.format(chr(98 + attach_inx))
                    ret = virsh.attach_disk(vm_name,
                                            image_path_list[attach_inx],
                                            disk_dev,
                                            extra=attach_extra,
                                            **virsh_options)
                    if ret.exit_status and not addr_twice:
                        break
                libvirt.check_result(ret, expected_fails=err_msg)
        if not hotplug and check_within_guest:
            virsh_options.update({'ignore_status': True})
            ret = virsh.detach_disk(vm_name, target_dev, **virsh_options)
            libvirt.check_result(ret, expected_fails=err_msg)
        logging.debug(VMXML.new_from_dumpxml(vm_name))
        if check_disk_xml:
            time.sleep(5)
            check_guest_disks(hotplug)
        if check_cntl_xml:
            check_guest_contr()
        if hotplug_counts and not addr_twice:
            check_multi_attach(get_disk_bus())
        if check_within_guest:
            check_inside_guest(hotplug)

    finally:
        vm_xml_backup.sync()
Example #10
0
def run(test, params, env):
    """
    Start libvirt daemon with different options.
    Check socket files.
    """
    log = []

    def _logger(line):
        """
        Callback function to log libvirtd output.
        """
        log.append(line)

    def check_help(params):
        """
        Check whether the output is help and meets expectation
        """
        expected_help = params.get('expected_help', 'no') == 'yes'
        is_help = any(line.startswith('Usage:') for line in log)
        if expected_help != is_help:
            test.fail(
                'Expected output help is %s, but get output:\n%s' %
                (expected_help, '\n'.join(log)))

    def check_version(params):
        """
        Check whether the output is libvirtd version.
        """
        expected_version = params.get('expected_version', 'no') == 'yes'
        is_version = log[0].startswith('{} (libvirt)'.format(daemon_name))
        if expected_version != is_version:
            test.fail(
                'Expected output version is %s, but get output:\n%s' %
                (expected_version, '\n'.join(log)))

    def check_unix_socket_files():
        """
        Check whether the socket file exists.
        """
        rw_sock_path = '/var/run/libvirt/libvirt-sock'
        ro_sock_path = '/var/run/libvirt/libvirt-sock-ro'

        if libvirtd.running or libvirt_version.version_compare(5, 6, 0):
            if not os.path.exists(rw_sock_path):
                test.fail('RW unix socket file not found at %s' %
                          rw_sock_path)
            if not os.path.exists(ro_sock_path):
                test.fail('RO unix socket file not found at %s' %
                          ro_sock_path)
        else:
            if os.path.exists(rw_sock_path) or os.path.exists(ro_sock_path):
                test.fail('Expect unix socket file do not exists '
                          'when libvirtd is stopped')

    def check_pid_file():
        """
        Check whether the pid file exists.
        """
        if not os.path.exists(pid_path):
            test.fail("PID file not found at %s" % pid_path)

        with open(pid_path) as pid_file:
            pid = int(pid_file.readline())
        result = process.run('pgrep %s' % daemon_name,
                             ignore_status=True, shell=True)
        expected_pid = int(result.stdout_text.strip().split()[0])

        if pid != expected_pid:
            test.fail("PID file content mismatch. Expected %s "
                      "but got %s" % (expected_pid, pid))

    def check_config_file():
        """
        Check whether the config file take effects by checking max_clients.
        """
        connect_uri = daemon_name + ":///system"
        vp = virt_admin.VirtadminPersistent(uri=connect_uri)
        result = vp.srv_clients_info(daemon_name, uri=connect_uri, ignore_status=True, debug=True)
        output = result.stdout.strip().splitlines()
        out_split = [item.split(':') for item in output]
        out_dict = dict([[item[0].strip(), item[1].strip()] for item in out_split])
        if int(out_dict["nclients_max"]) != check_max_clients:
            test.fail('Expected max_clients is %s, but got %s' %
                      (check_max_clients, out_dict["nclients_max"]))

    MAX_TIMEOUT = 10
    arg_str = params.get("libvirtd_arg", "")
    time_tolerance = float(params.get("exit_time_tolerance", 1))
    expected_exit_time = float(params.get("expected_exit_time", 'inf'))
    config_path = params.get('expected_config_path', "")
    pid_path = params.get('expected_pid_path', "")
    daemon_name = params.get('daemon_name', "")
    test_config = params.get('test_config', "no") == "yes"
    require_modular_daemon = params.get('require_modular_daemon', "no") == "yes"

    utils_split_daemons.daemon_mode_check(require_modular_daemon)
    if expected_exit_time == float('inf'):
        timeout = MAX_TIMEOUT
    else:
        if expected_exit_time > 0:
            if len(virsh.dom_list('--name').stdout.strip().splitlines()):
                test.cancel('Timeout option will be ignore if '
                            'there exists living domain')
        timeout = expected_exit_time + time_tolerance

    libvirtd = LibvirtdSession(service_name=daemon_name, logging_handler=_logger)

    # Setup config file.
    check_max_clients = int(101)
    if test_config:
        config = utils_config.get_conf_obj(daemon_name)
        logging.debug(config.conf_path)
        config_path = config.conf_path
        config.max_clients = check_max_clients
        arg_str = arg_str + config_path

    try:
        check_unix_socket_files()

        Libvirtd(daemon_name).stop()
        libvirtd.start(arg_str=arg_str, wait_for_working=False)

        start = time.time()
        libvirtd_exited = libvirtd.wait_for_stop(timeout=timeout, step=0.1)
        wait_time = time.time() - start

        if log:
            logging.debug("Libvirtd log:")
            for line in log:
                logging.debug(line)

            check_help(params)
            check_version(params)

        if libvirtd_exited:
            if expected_exit_time == float('inf'):
                test.fail("Expected never stop, but ran %ss" % wait_time)
            elif wait_time < expected_exit_time - time_tolerance:
                test.fail("Expected exit in %ss(+-%ss), but ran %ss" %
                          (expected_exit_time, time_tolerance, wait_time))
        else:
            if expected_exit_time != float('inf'):
                test.fail("Expected exit in %ss(+-%ss), but ran timeout in %ss" %
                          (expected_exit_time, time_tolerance, wait_time))

        not libvirt_version.version_compare(5, 6, 0) and check_unix_socket_files()
        if test_config:
            check_config_file()
        if pid_path:
            check_pid_file()
    finally:
        libvirtd.exit()
        Libvirtd(daemon_name).stop()
        socket_name = daemon_name + ".socket"
        Libvirtd(socket_name).restart()
        Libvirtd(daemon_name).start()

        # Clean up config file
        if test_config:
            config.restore()
        if os.path.exists(pid_path):
            os.remove(pid_path)
Example #11
0
def run(test, params, env):
    """
    Test the command virsh metadata

    Run in 4 steps:
    1. Set domain metadata
    2. Get domain metadata
    3. Restart libvirtd then get domain metadata again
    4. Remove domain metadata then get domain metadata again
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    metadata_uri = params.get("metadata_uri")
    metadata_key = params.get("metadata_key")
    metadata_value = params.get("metadata_value", "")
    metadata_option = params.get("metadata_option", "")
    virsh_dargs = {'debug': True, 'ignore_status': True}
    metadata_set = "yes" == params.get("metadata_set", "no")
    metadata_get = "yes" == params.get("metadata_get", "yes")
    metadata_remove = "yes" == params.get("metadata_remove", "no")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    status_error = "yes" == params.get("status_error", "no")
    if not metadata_uri:
        raise error.TestErrorr("'uri' is needed")
    vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
    # Start VM
    if vm.state() != "running":
        vm.destroy()
        vm.start()

    def pretty_xml(xml_str):
        return xml.dom.minidom.parseString(xml_str).toprettyxml()

    def check_result(result, expect_status, expect_output=None):
        """
        Check virsh metadata command
        """
        utlv.check_exit_status(result, expect_status)
        if result.exit_status == 0 and expect_output:
            expect_output = pretty_xml(expect_output)
            logging.debug("Expect metadata: %s", expect_output)
            output = result.stdout.strip()
            output = pretty_xml(output)
            logging.debug("Command get metadata: %s", output)
            if output != expect_output:
                raise error.TestFail("Metadat is not expected")

    def get_metadata():
        """
        Get domain metadata
        """
        option = metadata_option.replace("--edit", "")
        result = virsh.metadata(vm_name,
                                metadata_uri,
                                options=option,
                                key=metadata_key,
                                **virsh_dargs)
        return result

    try:
        # Set metadata XML
        if metadata_set:
            if not metadata_key:
                raise error.TestErrorr("'key' is needed")
            if not metadata_value:
                raise error.TestErrorr("New metadata is needed")
            # Parse metadata value
            if "--edit" in metadata_option:
                virsh_cmd = r"virsh metadata %s --uri %s --key %s %s"
                virsh_cmd = virsh_cmd % (vm_name, metadata_uri,
                                         metadata_key, metadata_option)
                session = aexpect.ShellSession("sudo -s")
                logging.info("Running command: %s", virsh_cmd)
                try:
                    session.sendline(virsh_cmd)
                    session.sendline(r":insert")
                    session.sendline(metadata_value)
                    session.sendline(".")
                    session.send('ZZ')
                    remote.handle_prompts(session, None, None, r"[\#\$]\s*$",
                                          debug=True)
                except Exception, e:
                    logging.error("Error occured: %s", e)
                session.close()
            else:
                result = virsh.metadata(vm_name,
                                        metadata_uri,
                                        options=metadata_option,
                                        key=metadata_key,
                                        new_metadata=metadata_value,
                                        **virsh_dargs)
                check_result(result, status_error)
            if "--config" in metadata_option:
                vm.destroy()
                vm.start()
                check_result(get_metadata(), status_error, metadata_value)
        # Get metadata
        if metadata_get:
            check_result(get_metadata(), status_error, metadata_value)

        # Restart libvirtd:
        if restart_libvirtd:
            libvirtd = Libvirtd()
            libvirtd.restart()
            # Get metadata again
            check_result(get_metadata(), status_error, metadata_value)
        # Remove metadata
        if metadata_remove:
            remove_option = metadata_option.replace("--edit", "")
            remove_option += " --remove"
            result = virsh.metadata(vm_name,
                                    metadata_uri,
                                    options=remove_option,
                                    key=metadata_key,
                                    **virsh_dargs)
            check_result(result, status_error)
            # Get metadata again
            check_result(get_metadata(), True)
Example #12
0
def run(test, params, env):
    """
    Kill libvirt daemon with different signals and check
    whether daemon restart properly and leaving no pid file
    if stopped.
    """
    def get_pid(libvirtd):
        """
        Get the pid of libvirt daemon process.
        """
        pid = int(open(pid_file).read())
        return pid

    def send_signal(pid, signal_name):
        """
        Send signal to a process by pid.
        """
        signal_num = getattr(signal, signal_name)
        os.kill(pid, signal_num)

    pid_file = '/var/run/libvirtd.pid'
    signal_name = params.get("signal", "SIGTERM")
    should_restart = params.get("expect_restart", "yes") == "yes"
    pid_should_change = params.get("expect_pid_change", "yes") == "yes"

    libvirtd = Libvirtd()
    try:
        libvirtd.start()

        pid = get_pid(libvirtd)
        logging.debug("Pid of libvirtd is %d" % pid)

        logging.debug("Killing process %s with %s" % (pid, signal_name))
        send_signal(pid, signal_name)

        # Wait for libvirtd to restart or reload
        time.sleep(1)

        if libvirtd.is_running():
            if not should_restart:
                raise error.TestFail(
                    "libvirtd should stop running after signal %s"
                    % signal_name)
            new_pid = get_pid(libvirtd)
            logging.debug("New pid of libvirtd is %d" % new_pid)
            if pid == new_pid and pid_should_change:
                raise error.TestFail("Pid should have been changed.")
            if pid != new_pid and not pid_should_change:
                raise error.TestFail("Pid should not have been changed.")
        else:
            if should_restart:
                raise error.TestFail(
                    "libvirtd should still running after signal %s"
                    % signal_name)

    finally:
        if not libvirtd.is_running():
            if os.path.exists(pid_file):
                os.remove(pid_file)
                libvirtd.start()
                raise error.TestFail("Pid file should not reside")
            libvirtd.start()
Example #13
0
def run(test, params, env):
    """
    Start libvirt daemon with different options.
    Check socket files.
    """
    log = []

    def _logger(line):
        """
        Callback function to log libvirtd output.
        """
        log.append(line)

    def check_help(params):
        """
        Check whether the output is help and meets expectation
        """
        expected_help = params.get('expected_help', 'no') == 'yes'
        is_help = any(line.startswith('Usage:') for line in log)
        if expected_help != is_help:
            test.fail('Expected output help is %s, but get output:\n%s' %
                      (expected_help, '\n'.join(log)))

    def check_version(params):
        """
        Check whether the output is libvirtd version.
        """
        expected_version = params.get('expected_version', 'no') == 'yes'
        is_version = log[0].startswith('{} (libvirt)'.format(
            Libvirtd().service_list[0]))
        if expected_version != is_version:
            test.fail('Expected output version is %s, but get output:\n%s' %
                      (expected_version, '\n'.join(log)))

    def check_unix_socket_files():
        """
        Check whether the socket file exists.
        """
        rw_sock_path = '/var/run/libvirt/libvirt-sock'
        ro_sock_path = '/var/run/libvirt/libvirt-sock-ro'

        if libvirtd.running or libvirt_version.version_compare(5, 6, 0):
            if not os.path.exists(rw_sock_path):
                test.fail('RW unix socket file not found at %s' % rw_sock_path)
            if not os.path.exists(ro_sock_path):
                test.fail('RO unix socket file not found at %s' % ro_sock_path)
        else:
            if os.path.exists(rw_sock_path) or os.path.exists(ro_sock_path):
                test.fail('Expect unix socket file do not exists '
                          'when libvirtd is stopped')

    def check_pid_file():
        """
        Check whether the pid file exists.
        """
        if not os.path.exists(pid_path):
            test.fail("PID file not found at %s" % pid_path)

        with open(pid_path) as pid_file:
            pid = int(pid_file.readline())
        result = process.run('pgrep %s' % Libvirtd().service_list[0],
                             ignore_status=True,
                             shell=True)
        expected_pid = int(result.stdout_text.strip().split()[0])

        if pid != expected_pid:
            test.fail("PID file content mismatch. Expected %s "
                      "but got %s" % (expected_pid, pid))

    def check_config_file():
        """
        Check whether the config file take effects by checking UUID.
        """
        cur_uuid = capability_xml.CapabilityXML()['uuid']
        if cur_uuid != check_uuid:
            test.fail('Expected host UUID is %s, but got %s' %
                      (check_uuid, cur_uuid))

    MAX_TIMEOUT = 10
    arg_str = params.get("libvirtd_arg", "")
    time_tolerance = float(params.get("exit_time_tolerance", 1))
    expected_exit_time = float(params.get("expected_exit_time", 'inf'))
    config_path = params.get('expected_config_path', "")
    pid_path = params.get('expected_pid_path', "")

    if expected_exit_time == float('inf'):
        timeout = MAX_TIMEOUT
    else:
        if expected_exit_time > 0:
            if len(virsh.dom_list('--name').stdout.strip().splitlines()):
                test.cancel('Timeout option will be ignore if '
                            'there exists living domain')
        timeout = expected_exit_time + time_tolerance

    libvirtd = LibvirtdSession(logging_handler=_logger, )

    # Setup config file.
    check_uuid = '13371337-1337-1337-1337-133713371337'
    if config_path:
        open(config_path, 'a').close()
        config = utils_config.LibvirtdConfig(config_path)
        config.host_uuid = check_uuid

    try:
        check_unix_socket_files()

        Libvirtd().stop()
        libvirtd.start(arg_str=arg_str, wait_for_working=False)

        start = time.time()
        libvirtd_exited = libvirtd.wait_for_stop(timeout=timeout, step=0.1)
        wait_time = time.time() - start

        if log:
            logging.debug("Libvirtd log:")
            for line in log:
                logging.debug(line)

            check_help(params)
            check_version(params)

        if libvirtd_exited:
            if expected_exit_time == float('inf'):
                test.fail("Expected never stop, but ran %ss" % wait_time)
            elif wait_time < expected_exit_time - time_tolerance:
                test.fail("Expected exit in %ss(+-%ss), but ran %ss" %
                          (expected_exit_time, time_tolerance, wait_time))
        else:
            if expected_exit_time != float('inf'):
                test.fail(
                    "Expected exit in %ss(+-%ss), but ran timeout in %ss" %
                    (expected_exit_time, time_tolerance, wait_time))

        not libvirt_version.version_compare(5, 6,
                                            0) and check_unix_socket_files()
        if config_path:
            check_config_file()
        if pid_path:
            check_pid_file()
    finally:
        libvirtd.exit()
        Libvirtd().stop()
        Libvirtd("libvirtd.socket").restart()
        Libvirtd().start()

        # Clean up config file
        if config_path:
            config.restore()
            if os.path.exists(config_path):
                os.remove(config_path)
        if os.path.exists(pid_path):
            os.remove(pid_path)
Example #14
0
def run(test, params, env):
    """
    Kill libvirt daemon with different signals and check
    whether daemon restart properly and leaving no pid file
    if stopped.
    """
    def get_pid(libvirtd):
        """
        Get the pid of libvirt daemon process.
        """
        pid = int(open(pid_file).read())
        return pid

    def send_signal(pid, signal_name):
        """
        Send signal to a process by pid.
        """
        signal_num = getattr(signal, signal_name)
        os.kill(pid, signal_num)

    def start_mark(src_file, dest_file):
        """
        Copy the src_file to a tmp file
        :param src_file: The file should be checked.
        :param dest_file: The temp file to mark the time point.
        """
        # Clean the dest file if existed
        if os.path.exists(dest_file):
            os.remove(dest_file)
        cmdline = 'cp %s %s' % \
                  (src_file, dest_file)
        process.run(cmdline, shell=True)

    pid_file = '/var/run/libvirtd.pid'
    if utils_split_daemons.is_modular_daemon():
        pid_file = '/var/run/virtqemud.pid'
    message_src_file = '/var/log/messages'
    message_dest_file = '/tmp/messages_tmp'
    signal_name = params.get("signal", "SIGTERM")
    should_restart = params.get("expect_restart", "yes") == "yes"
    timeout = int(params.get("restart_timeout", 1))
    pid_should_change = params.get("expect_pid_change", "yes") == "yes"
    expect_coredump = params.get("expect_coredump", "no") == "yes"
    check_dmesg = params.get("check_dmesg", None)

    libvirtd = Libvirtd("virtqemud")
    try:
        libvirtd.start()

        if check_dmesg:
            start_mark(message_src_file, message_dest_file)

        pid = get_pid(libvirtd)
        logging.debug("Pid of libvirtd is %d" % pid)

        logging.debug("Killing process %s with %s" % (pid, signal_name))
        send_signal(pid, signal_name)

        # Wait for libvirtd to restart or reload
        time.sleep(timeout)

        if libvirtd.is_running():
            if not should_restart:
                test.fail("libvirtd should stop running after signal %s" %
                          signal_name)
            new_pid = get_pid(libvirtd)
            logging.debug("New pid of libvirtd is %d" % new_pid)
            if pid == new_pid and pid_should_change:
                test.fail("Pid should have been changed.")
            if pid != new_pid and not pid_should_change:
                test.fail("Pid should not have been changed.")
        else:
            if should_restart:
                test.fail("libvirtd should still running after signal %s" %
                          signal_name)

        if check_dmesg:
            cmdline = 'diff %s %s' % \
                      (message_src_file, message_dest_file)
            res = process.run(cmdline, shell=True,
                              ignore_status=True).stdout_text
            if check_dmesg not in res:
                test.fail('%s should in %s , but not now' %
                          (check_dmesg, message_src_file))

    finally:
        # Clear coredump info
        if expect_coredump:
            cmd = 'journalctl --flush;'
            cmd += 'journalctl --rotate; journalctl --vacuum-size=1K; journalctl --vacuum-time=1s'
            process.run(cmd, ignore_status=True, shell=True)
        if not libvirtd.is_running():
            if os.path.exists(pid_file):
                os.remove(pid_file)
                libvirtd.start()
                test.fail("Pid file should not reside")
            libvirtd.start()