예제 #1
0
def run(test, params, env):
    """
    Test command: virsh managedsave.

    This command can save and destroy a
    running domain, so it can be restarted
    from the same state at a later time.
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    managed_save_file = "/var/lib/libvirt/qemu/save/%s.save" % vm_name
    shutdown_timeout = int(params.get('shutdown_timeout', 60))

    # define function
    def vm_recover_check(option, libvirtd, check_shutdown=False):
        """
        Check if the vm can be recovered correctly.

        :param guest_name : Checked vm's name.
        :param option : managedsave command option.
        """
        # This time vm not be shut down
        if vm.is_alive():
            test.fail("Guest should be inactive")
        # Check vm managed save state.
        ret = virsh.dom_list("--managed-save --inactive", debug=True)
        vm_state1 = re.findall(r".*%s.*" % vm_name,
                               ret.stdout.strip())[0].split()[2]
        ret = virsh.dom_list("--managed-save --all", debug=True)
        vm_state2 = re.findall(r".*%s.*" % vm_name,
                               ret.stdout.strip())[0].split()[2]
        if vm_state1 != "saved" or vm_state2 != "saved":
            test.fail("Guest state should be saved")

        virsh.start(vm_name, debug=True)
        # This time vm should be in the list
        if vm.is_dead():
            test.fail("Guest should be active")
        # Restart libvirtd and check vm status again.
        libvirtd.restart()
        if vm.is_dead():
            test.fail("Guest should be active after" " restarting libvirtd")
        # Check managed save file:
        if os.path.exists(managed_save_file):
            test.fail("Managed save image exist " "after starting the domain")
        if option:
            if option.count("running"):
                if vm.is_dead() or vm.is_paused():
                    test.fail("Guest state should be"
                              " running after started"
                              " because of '--running' option")
            elif option.count("paused"):
                if not vm.is_paused():
                    test.fail("Guest state should be"
                              " paused after started"
                              " because of '--paused' option")
        else:
            if params.get("paused_after_start_vm") == "yes":
                if not vm.is_paused():
                    test.fail("Guest state should be"
                              " paused after started"
                              " because of initia guest state")
        if check_shutdown:
            # Resume the domain.
            if vm.is_paused():
                vm.resume()
            vm.wait_for_login()
            # Shutdown and start the domain,
            # it should be in runing state and can be login.
            vm.shutdown()
            if not vm.wait_for_shutdown(shutdown_timeout):
                test.fail('VM failed to shutdown')
            vm.start()
            vm.wait_for_login()

    def vm_undefine_check(vm_name):
        """
        Check if vm can be undefined with manage-save option
        """
        #backup xml file
        xml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
        if not os.path.exists(managed_save_file):
            test.fail("Can't find managed save image")
        #undefine domain with no options.
        if not virsh.undefine(vm_name, options=None,
                              ignore_status=True).exit_status:
            test.fail("Guest shouldn't be undefined"
                      "while domain managed save image exists")
        #undefine domain with managed-save option.
        if virsh.undefine(vm_name,
                          options="--managed-save",
                          ignore_status=True).exit_status:
            test.fail("Guest can't be undefine with " "managed-save option")

        if os.path.exists(managed_save_file):
            test.fail("Managed save image exists" " after undefining vm")
        #restore and start the vm.
        xml_backup.define()
        vm.start()

    def check_flags_parallel(virsh_cmd, bash_cmd, flags):
        """
        Run the commands parallel and check the output.
        """
        cmd = ("%s & %s" % (virsh_cmd, bash_cmd))
        ret = process.run(cmd,
                          ignore_status=True,
                          shell=True,
                          ignore_bg_processes=True)
        output = ret.stdout_text.strip()
        logging.debug("check flags output: %s" % output)
        lines = re.findall(r"flags:.(\d+)", output, re.M)
        logging.debug("Find all fdinfo flags: %s" % lines)
        lines = [int(i, 8) & flags for i in lines]
        if flags not in lines:
            test.fail("Checking flags %s failed" % flags)

        return ret

    def check_multi_guests(guests, start_delay, libvirt_guests):
        """
        Check start_delay option for multiple guests.
        """
        # Destroy vm first
        if vm.is_alive():
            vm.destroy(gracefully=False)
        # Clone given number of guests
        timeout = params.get("clone_timeout", 360)
        for i in range(int(guests)):
            dst_vm = "%s_%s" % (vm_name, i)
            utils_libguestfs.virt_clone_cmd(vm_name,
                                            dst_vm,
                                            True,
                                            timeout=timeout)
            virsh.start(dst_vm, debug=True)

        # Wait 10 seconds for vm to start
        time.sleep(10)
        is_systemd = process.run("cat /proc/1/comm",
                                 shell=True).stdout_text.count("systemd")
        if is_systemd:
            libvirt_guests.restart()
            pattern = r'(.+ \d\d:\d\d:\d\d).+: Resuming guest.+done'
        else:
            ret = process.run("service libvirt-guests restart | \
                              awk '{ print strftime(\"%b %y %H:%M:%S\"), \
                              $0; fflush(); }'",
                              shell=True)
            pattern = r'(.+ \d\d:\d\d:\d\d)+ Resuming guest.+done'

        # libvirt-guests status command read messages from systemd
        # journal, in cases of messages are not ready in time,
        # add a time wait here.
        def wait_func():
            return libvirt_guests.raw_status().stdout.count("Resuming guest")

        utils_misc.wait_for(wait_func, 5)
        if is_systemd:
            ret = libvirt_guests.raw_status()
        logging.info("status output: %s", ret.stdout_text)
        resume_time = re.findall(pattern, ret.stdout_text, re.M)
        if not resume_time:
            test.fail("Can't see messages of resuming guest")

        # Convert time string to int
        resume_seconds = [
            time.mktime(time.strptime(tm, "%b %y %H:%M:%S"))
            for tm in resume_time
        ]
        logging.info("Resume time in seconds: %s", resume_seconds)
        # Check if start_delay take effect
        for i in range(len(resume_seconds) - 1):
            if resume_seconds[i + 1] - resume_seconds[i] < int(start_delay):
                test.fail("Checking start_delay failed")

    def wait_for_state(vm_state):
        """
        Wait for vm state is ready.
        """
        utils_misc.wait_for(lambda: vm.state() == vm_state, 10)

    def check_guest_flags(bash_cmd, flags):
        """
        Check bypass_cache option for single guest.
        """
        # Drop caches.
        drop_caches()
        # form proper parallel command based on if systemd is used or not
        is_systemd = process.run("cat /proc/1/comm",
                                 shell=True).stdout_text.count("systemd")
        if is_systemd:
            virsh_cmd_stop = "systemctl stop libvirt-guests"
            virsh_cmd_start = "systemctl start libvirt-guests"
        else:
            virsh_cmd_stop = "service libvirt-guests stop"
            virsh_cmd_start = "service libvirt-guests start"

        ret = check_flags_parallel(
            virsh_cmd_stop,
            bash_cmd % (managed_save_file, managed_save_file, "1"), flags)
        if is_systemd:
            ret = libvirt_guests.raw_status()
        logging.info("status output: %s", ret.stdout_text)
        if all([
                "Suspending %s" % vm_name not in ret.stdout_text,
                "stopped, with saved guests" not in ret.stdout_text
        ]):
            test.fail("Can't see messages of suspending vm")
        # status command should return 3.
        if not is_systemd:
            ret = libvirt_guests.raw_status()
        if ret.exit_status != 3:
            test.fail("The exit code %s for libvirt-guests"
                      " status is not correct" % ret)

        # Wait for VM in shut off state
        wait_for_state("shut off")
        check_flags_parallel(
            virsh_cmd_start,
            bash_cmd % (managed_save_file, managed_save_file, "0"), flags)
        # Wait for VM in running state
        wait_for_state("running")

    def vm_msave_remove_check(vm_name):
        """
        Check managed save remove command.
        """
        if not os.path.exists(managed_save_file):
            test.fail("Can't find managed save image")
        virsh.managedsave_remove(vm_name, debug=True)
        if os.path.exists(managed_save_file):
            test.fail("Managed save image still exists")
        virsh.start(vm_name, debug=True)
        # The domain state should be running
        if vm.state() != "running":
            test.fail("Guest state should be" " running after started")

    def vm_managedsave_loop(vm_name, loop_range, libvirtd):
        """
        Run a loop of managedsave command and check its result.
        """
        if vm.is_dead():
            virsh.start(vm_name, debug=True)
        for i in range(int(loop_range)):
            logging.debug("Test loop: %s" % i)
            virsh.managedsave(vm_name, debug=True)
            virsh.start(vm_name, debug=True)
        # Check libvirtd status.
        if not libvirtd.is_running():
            test.fail("libvirtd is stopped after cmd")
        # Check vm status.
        if vm.state() != "running":
            test.fail("Guest isn't in running state")

    def build_vm_xml(vm_name, **dargs):
        """
        Build the new domain xml and define it.
        """
        try:
            # stop vm before doing any change to xml
            if vm.is_alive():
                vm.destroy(gracefully=False)
            vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
            if dargs.get("cpu_mode"):
                if "cpu" in vmxml:
                    del vmxml.cpu
                cpuxml = vm_xml.VMCPUXML()
                cpuxml.mode = params.get("cpu_mode", "host-model")
                cpuxml.match = params.get("cpu_match", "exact")
                cpuxml.fallback = params.get("cpu_fallback", "forbid")
                cpu_topology = {}
                cpu_topology_sockets = params.get("cpu_topology_sockets")
                if cpu_topology_sockets:
                    cpu_topology["sockets"] = cpu_topology_sockets
                cpu_topology_cores = params.get("cpu_topology_cores")
                if cpu_topology_cores:
                    cpu_topology["cores"] = cpu_topology_cores
                cpu_topology_threads = params.get("cpu_topology_threads")
                if cpu_topology_threads:
                    cpu_topology["threads"] = cpu_topology_threads
                if cpu_topology:
                    cpuxml.topology = cpu_topology
                vmxml.cpu = cpuxml
                vmxml.vcpu = int(params.get("vcpu_nums"))
            if dargs.get("sec_driver"):
                seclabel_dict = {
                    "type": "dynamic",
                    "model": "selinux",
                    "relabel": "yes"
                }
                vmxml.set_seclabel([seclabel_dict])

            vmxml.sync()
            vm.start()
        except Exception as e:
            logging.error(str(e))
            test.cancel("Build domain xml failed")

    status_error = ("yes" == params.get("status_error", "no"))
    vm_ref = params.get("managedsave_vm_ref", "name")
    libvirtd_state = params.get("libvirtd", "on")
    extra_param = params.get("managedsave_extra_param", "")
    progress = ("yes" == params.get("managedsave_progress", "no"))
    cpu_mode = "yes" == params.get("managedsave_cpumode", "no")
    test_undefine = "yes" == params.get("managedsave_undefine", "no")
    test_bypass_cache = "yes" == params.get("test_bypass_cache", "no")
    autostart_bypass_cache = params.get("autostart_bypass_cache", "")
    multi_guests = params.get("multi_guests", "")
    test_libvirt_guests = params.get("test_libvirt_guests", "")
    check_flags = "yes" == params.get("check_flags", "no")
    security_driver = params.get("security_driver", "")
    remove_after_cmd = "yes" == params.get("remove_after_cmd", "no")
    option = params.get("managedsave_option", "")
    check_shutdown = "yes" == params.get("shutdown_after_cmd", "no")
    pre_vm_state = params.get("pre_vm_state", "")
    move_saved_file = "yes" == params.get("move_saved_file", "no")
    test_loop_cmd = "yes" == params.get("test_loop_cmd", "no")
    if option:
        if not virsh.has_command_help_match('managedsave', option):
            # Older libvirt does not have this option
            test.cancel("Older libvirt does not"
                        " handle arguments consistently")

    # Backup xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    # Get the libvirtd service
    libvirtd = utils_libvirtd.Libvirtd()
    # Get config files.
    qemu_config = utils_config.LibvirtQemuConfig()
    libvirt_guests_config = utils_config.LibvirtGuestsConfig()
    # Get libvirt-guests service
    libvirt_guests = Factory.create_service("libvirt-guests")

    try:
        # Destroy vm first for setting configuration file
        if vm.state() == "running":
            vm.destroy(gracefully=False)
        # Prepare test environment.
        if libvirtd_state == "off":
            libvirtd.stop()
        if autostart_bypass_cache:
            ret = virsh.autostart(vm_name, "", ignore_status=True, debug=True)
            libvirt.check_exit_status(ret)
            qemu_config.auto_start_bypass_cache = autostart_bypass_cache
            libvirtd.restart()
        if security_driver:
            qemu_config.security_driver = [security_driver]
        if test_libvirt_guests:
            if multi_guests:
                start_delay = params.get("start_delay", "20")
                libvirt_guests_config.START_DELAY = start_delay
            if check_flags:
                libvirt_guests_config.BYPASS_CACHE = "1"
            # The config file format should be "x=y" instead of "x = y"
            process.run(
                "sed -i -e 's/ = /=/g' "
                "/etc/sysconfig/libvirt-guests",
                shell=True)
            libvirt_guests.restart()

        # Change domain xml.
        if cpu_mode:
            build_vm_xml(vm_name, cpu_mode=True)
        if security_driver:
            build_vm_xml(vm_name, sec_driver=True)

        # Turn VM into certain state.
        if pre_vm_state == "transient":
            logging.info("Creating %s..." % vm_name)
            vmxml_for_test = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
            if vm.is_alive():
                vm.destroy(gracefully=False)
            # Wait for VM to be in shut off state
            utils_misc.wait_for(lambda: vm.state() == "shut off", 10)
            vm.undefine()
            if virsh.create(vmxml_for_test.xml, ignore_status=True,
                            debug=True).exit_status:
                vmxml_backup.define()
                test.cancel("Cann't create the domain")

        # Wait for vm in stable state
        if params.get("start_vm") == "yes":
            if vm.state() == "shut off":
                vm.start()
                vm.wait_for_login()

        # run test case
        domid = vm.get_id()
        domuuid = vm.get_uuid()
        if vm_ref == "id":
            vm_ref = domid
        elif vm_ref == "uuid":
            vm_ref = domuuid
        elif vm_ref == "hex_id":
            vm_ref = hex(int(domid))
        elif vm_ref.count("invalid"):
            vm_ref = params.get(vm_ref)
        elif vm_ref == "name":
            vm_ref = vm_name

        # Ignore exception with "ignore_status=True"
        if progress:
            option += " --verbose"
        option += extra_param

        # For bypass_cache test. Run a shell command to check fd flags while
        # excuting managedsave command
        software_mgr = software_manager.SoftwareManager()
        if not software_mgr.check_installed('lsof'):
            logging.info('Installing lsof package:')
            software_mgr.install('lsof')
        bash_cmd = (
            "let i=1; while((i++<400)); do if [ -e %s ]; then (cat /proc"
            "/$(lsof -w %s|awk '/libvirt_i/{print $2}')/fdinfo/%s |"
            "grep 'flags:.*') && break; else sleep 0.05; fi; done;")
        # Flags to check bypass cache take effect
        flags = os.O_DIRECT
        if test_bypass_cache:
            # Drop caches.
            drop_caches()
            virsh_cmd = "virsh managedsave %s %s" % (option, vm_name)
            check_flags_parallel(
                virsh_cmd,
                bash_cmd % (managed_save_file, managed_save_file, "1"), flags)
            # Wait for VM in shut off state
            wait_for_state("shut off")
            virsh_cmd = "virsh start %s %s" % (option, vm_name)
            check_flags_parallel(
                virsh_cmd,
                bash_cmd % (managed_save_file, managed_save_file, "0"), flags)
            # Wait for VM in running state
            wait_for_state("running")
        elif test_libvirt_guests:
            logging.debug("libvirt-guests status: %s", libvirt_guests.status())
            if multi_guests:
                check_multi_guests(multi_guests, start_delay, libvirt_guests)

            if check_flags:
                check_guest_flags(bash_cmd, flags)

        else:
            # Ensure VM is running
            utils_misc.wait_for(lambda: vm.state() == "running", 10)
            ret = virsh.managedsave(vm_ref,
                                    options=option,
                                    ignore_status=True,
                                    debug=True)
            status = ret.exit_status
            # The progress information outputed in error message
            error_msg = ret.stderr.strip()
            if move_saved_file:
                cmd = "echo > %s" % managed_save_file
                process.run(cmd, shell=True)

            # recover libvirtd service start
            if libvirtd_state == "off":
                libvirtd.start()

            if status_error:
                if not status:
                    if libvirtd_state == "off" and libvirt_version.version_compare(
                            5, 6, 0):
                        logging.info(
                            "From libvirt version 5.6.0 libvirtd is restarted "
                            "and command should succeed")
                    else:
                        test.fail("Run successfully with wrong command!")
            else:
                if status:
                    test.fail("Run failed with right command")
                if progress:
                    if not error_msg.count("Managedsave:"):
                        test.fail("Got invalid progress output")
                if remove_after_cmd:
                    vm_msave_remove_check(vm_name)
                elif test_undefine:
                    vm_undefine_check(vm_name)
                elif autostart_bypass_cache:
                    # rhbz#1755303
                    if libvirt_version.version_compare(5, 6, 0):
                        os.remove("/run/libvirt/qemu/autostarted")
                    libvirtd.stop()
                    virsh_cmd = ("(service libvirtd start)")
                    check_flags_parallel(
                        virsh_cmd,
                        bash_cmd % (managed_save_file, managed_save_file, "0"),
                        flags)
                elif test_loop_cmd:
                    loop_range = params.get("loop_range", "20")
                    vm_managedsave_loop(vm_name, loop_range, libvirtd)
                else:
                    vm_recover_check(option, libvirtd, check_shutdown)
    finally:
        # Restore test environment.
        # Restart libvirtd.service
        qemu_config.restore()
        libvirt_guests_config.restore()
        libvirtd.restart()
        if autostart_bypass_cache:
            virsh.autostart(vm_name,
                            "--disable",
                            ignore_status=True,
                            debug=True)
        vm.destroy(gracefully=False)
        virsh.managedsave_remove(vm_name, debug=True)
        vmxml_backup.sync()
        if multi_guests:
            for i in range(int(multi_guests)):
                virsh.remove_domain("%s_%s" % (vm_name, i),
                                    "--remove-all-storage",
                                    debug=True)
예제 #2
0
def run(test, params, env):
    """
    Configuring /etc/sysconfig/libvirt-guests, then check the domains
    status after restarting the libvirt-guests.server,

    1. Set the values in /etc/sysconfig/libvirt-guests
    2. Restart libvirt-guests service
    3. Check the domains states, and the guests' save files
    """
    def get_log():
        """
        Tail output appended data as the file /var/log/messages grows

        :returns: the appended data tailed from /var/log/messages
        """
        tailed_log_file = os.path.join(data_dir.get_tmp_dir(), 'tail_log')
        tailed_messages = aexpect.Tail(command='tail -f /var/log/messages',
                                       output_func=utils_misc.log_line,
                                       output_params=(tailed_log_file))
        return tailed_messages

    def chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output):
        """
        check domains' state when host shutdown, and if parallel_shutdown is set
        to non-zero, check whether the guests have been shutdown correctly.

        :param status_error: positive test if status_error is "no", otherwise
                             negative test
        :param on_shutdown: action taking on host shutdown
        :param parallel_shutdown: the number of parallel_shutdown guests would
                                  be shutdown concurrently on shutdown
        :param output: appended message from /var/log/messages
        """
        if on_shutdown == "shutdown" and on_boot == "start":
            second_boot_time = boot_time()
            logging.debug("The second boot time is %s", second_boot_time)
            if any([i >= j
                    for i, j in zip(first_boot_time, second_boot_time)]):
                test.fail("The second boot time for should be larger"
                          "than its first boot time.")

        expect_msg = expect_shutdown_msg(status_error, on_shutdown)
        logging.debug("The expected messages when host shutdown is: %s ",
                      expect_msg)
        for dom in vms:
            if not re.search(expect_msg[dom.name], output):
                logging.debug("expect_mesg is: %s", expect_msg[dom.name])
                if status_error == "no":
                    test.fail("guest should be %s on shutdown" % on_shutdown)
                else:
                    test.fail("Shutdown of guest should be failed to "
                              "complete in time")

        if (on_shutdown == "shutdown") and int(parallel_shutdown) > 0:
            chk_parallel_shutdown(output, parallel_shutdown)

    def chk_on_boot(status_error, on_boot):
        """
        check domains' state when host booted

        :param status_error: positive test if status_error is "no", otherwise
                             negative test
        :param on_boot: action taking on host booting
        """
        if status_error == "no":
            if on_boot == "start":
                for dom in vms:
                    if not dom.is_alive():
                        test.fail("Since on_boot is setting to 'start', "
                                  "guest should be running after "
                                  "restarting libvirt-guests.")
            else:
                for dom in vms:
                    if dom.is_alive():
                        test.fail("Since on_boot is setting to 'ignore', "
                                  "unless guests are autostart, "
                                  "guest should be shut off after "
                                  "restarting libvirt-guests, ")

    def check_on_shutdown_vm_status():
        for dom in vms:
            result = virsh.domstate(dom.name, "--reason")
            try:
                dom.wait_for_shutdown()
            except Exception as e:
                test.fail('As on_boot is set to "ignore", but guest %s is '
                          'not shutdown. reason: %s ' % (dom.name, e))

    def chk_parallel_shutdown(output, parallel_shutdown):
        """
        check whether the guests has been shut down concurrently
        on host shutdown.
        """
        pattern = r".+ libvirt-guests.sh.*: Starting shutdown on guest: .+"
        shut_start_line_nums = []
        for line_num, line in enumerate(output.splitlines()):
            if re.search(pattern, line):
                shut_start_line_nums.append(line_num)
        logging.debug("the line_numbers contains shutdown messages is: %s ",
                      shut_start_line_nums)

        pattern = r".+ libvirt-guests.sh.*: Shutdown of guest.+complete"
        for line_num, line in enumerate(output.splitlines()):
            if re.search(pattern, line):
                shut_complete_first_line = line_num
                break
        logging.debug(
            "the first line contains shutdown complete messages is: %s ",
            shut_complete_first_line)

        para_shut = int(parallel_shutdown)
        if shut_start_line_nums[para_shut - 1] > shut_complete_first_line:
            test.fail("Since parallel_shutdown is setting to non_zero, "
                      "%s guests should be shutdown concurrently." %
                      parallel_shutdown)
        if shut_start_line_nums[para_shut] < shut_complete_first_line:
            test.fail("The number of guests shutdown concurrently "
                      "should not be exceeded than %s." % parallel_shutdown)

    def expect_shutdown_msg(status_error, on_shutdown):
        """
        the expected messages of each guests when host shutdown
        logged into /var/log/messages
        """
        expect_msg = {}
        for dom in vms:
            if status_error == "no":
                if on_shutdown == "shutdown":
                    expect_msg[dom.name] = ("libvirt-guests.sh.*: "
                                            "Shutdown of guest %s "
                                            "complete" % dom.name)
                else:
                    expect_msg[dom.name] = ("libvirt-guests.sh.*: "
                                            "Suspending %s: done" % dom.name)
            else:
                # Now the negative tests are only about ON_SHUTDOWN=shutdown.
                if on_shutdown == "shutdown":
                    expect_msg[dom.name] = ("libvirt-guests.sh.*: "
                                            "Shutdown of guest %s "
                                            "failed to complete in "
                                            "time" % dom.name)
        return expect_msg

    def chk_save_files(status_error, on_shutdown, on_boot):
        """
        save files should exist when on_shutdown is set to shutdown, and
        on_boot is set to ignore. In other conditions, there should be
        no save files.
        """
        save_files = dict()
        for dom in vms:
            save_files[dom] = ("/var/lib/libvirt/qemu/save/%s.save" % dom.name)
        if status_error == "no":
            if on_shutdown == "shutdown":
                for dom in vms:
                    if os.path.exists(save_files[dom]):
                        test.fail("There should be no save files since "
                                  "guests are shutdown on host shutdown.")
            else:
                if on_boot == "start":
                    for dom in vms:
                        if os.path.exists(save_files[dom]):
                            test.fail("There should be no save files since "
                                      "guests are restored on host shutdown.")
                else:
                    for dom in vms:
                        if not os.path.exists(save_files[dom]):
                            test.fail("Guests are suspended on host shutdown, "
                                      "and been ignored on host boot, there "
                                      "should be save files for the guests.")

    def boot_time():
        booting_time = []
        for vm in vms:
            session = vm.wait_for_login()
            time = session.cmd_output("uptime --since")
            booting_time.append(time)
            session.close()
        return booting_time

    def setup_nfs_backend_guest(vmxml_backup):
        # nfs_server setup
        nfs_server = libvirt.setup_or_cleanup_nfs(True)
        nfs_export_dir = nfs_server['export_dir']
        logging.debug("nfs dir is %s", nfs_export_dir)

        # change the original xml and image path
        for dom in vms:
            vmxml = vm_xml.VMXML.new_from_dumpxml(dom.name)
            vmxml_backup.append(vmxml.copy())
            disk_xml = vmxml.get_devices(device_type="disk")[0]
            orig_image_path_name = disk_xml.source.attrs['file']

            libvirt.update_vm_disk_source(dom.name, nfs_export_dir)
            shutil.copy(orig_image_path_name, nfs_export_dir)

        # set the selinux bool
        if virt_use_nfs:
            result = process.run("setsebool virt_use_nfs 1",
                                 shell=True,
                                 verbose=True)
            if result.exit_status:
                logging.error("Failed to set virt_use_nfs on")

    def cleanup_nfs_backend_guest(vmxml_backup):
        if virt_use_nfs:
            result = process.run("setsebool virt_use_nfs 0",
                                 shell=True,
                                 verbose=True)
            if result.exit_status:
                logging.error("Failed to set virt_use_nfs off")

        # recover the guest xml
        for xml_backup in vmxml_backup:
            xml_backup.sync(options="--managed-save")

        nfs_server = libvirt.setup_or_cleanup_nfs(False)

    main_vm_name = params.get("main_vm")
    main_vm = env.get_vm(main_vm_name)

    on_boot = params.get("on_boot")
    on_shutdown = params.get("on_shutdown")
    nfs_vol = params.get("nfs_vol") == "yes"
    virt_use_nfs = params.get("virt_use_nfs") == "on"
    parallel_shutdown = params.get("parallel_shutdown")
    additional_vms = int(params.get("additional_vms", "0"))
    status_error = params.get("status_error")
    shutdown_timeout = params.get("shutdown_timeout", "300")

    config = utils_config.LibvirtGuestsConfig()
    libvirt_guests_service = service.Factory.create_service("libvirt-guests")
    if not libvirt_guests_service.status():
        libvirt_guests_service.start()

    vms = [main_vm]
    if main_vm.is_alive:
        main_vm.destroy(gracefully=False)

    if not utils_misc.start_rsyslogd():
        test.error("Rsyslogd service start fail")

    try:
        utils_path.find_command("virt-clone")
    except utils_path.CmdNotFoundError:
        test.cancel("No virt-clone command found.")

    # Clone additional vms: avocado-vt-vm2, avocado-vt-vm3.....
    for i in range(additional_vms):
        guest_name = ("%s" % main_vm_name[:-1]) + ("%s" % str(i + 2))
        logging.debug("guest_name : %s", guest_name)
        utils_libguestfs.virt_clone_cmd(main_vm_name,
                                        guest_name,
                                        True,
                                        timeout=360,
                                        ignore_status=False)
        vms.append(main_vm.clone(guest_name))
        logging.debug("Now the vms is: %s", [dom.name for dom in vms])

    if nfs_vol:
        # info collected for clear env finally
        vmxml_backup = []
        setup_nfs_backend_guest(vmxml_backup)

    for dom in vms:
        if not dom.is_alive():
            dom.start()
    for dom in vms:
        dom.wait_for_login()
    first_boot_time = []
    if on_shutdown == "shutdown" and on_boot == "start":
        first_boot_time = boot_time()
        logging.debug("The first boot time is %s", first_boot_time)

    try:
        # Config the libvirt-guests file
        config.ON_BOOT = on_boot
        config.ON_SHUTDOWN = on_shutdown
        config.PARALLEL_SHUTDOWN = parallel_shutdown
        config.SHUTDOWN_TIMEOUT = shutdown_timeout
        process.run("sed -i -e 's/ = /=/g' "
                    "/etc/sysconfig/libvirt-guests",
                    shell=True)

        tail_messages = get_log()
        # Even though libvirt-guests was designed to operate guests when
        # host shutdown. The purpose can also be fulfilled by restart the
        # libvirt-guests service.
        libvirt_guests_service.restart()
        time.sleep(10)
        output = tail_messages.get_output()
        logging.debug("Get messages in /var/log/messages: %s" % output)

        # check the guests state when host shutdown
        chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output)
        # check the guests state when host rebooted
        chk_on_boot(status_error, on_boot)
        # check the guests save files
        chk_save_files(status_error, on_shutdown, on_boot)

        if on_boot == "ignore" and on_shutdown == "shutdown":
            check_on_shutdown_vm_status()

    finally:
        config.restore()

        # Undefine additional vms
        for dom in vms[1:]:
            if dom.is_alive():
                dom.destroy(gracefully=False)
            virsh.remove_domain(dom.name, "--remove-all-storage")

        if nfs_vol:
            cleanup_nfs_backend_guest(vmxml_backup)

        if libvirt_guests_service.status():
            libvirt_guests_service.stop()
예제 #3
0
    pre_vm_state = params.get("pre_vm_state", "")
    move_saved_file = "yes" == params.get("move_saved_file", "no")
    test_loop_cmd = "yes" == params.get("test_loop_cmd", "no")
    if option:
        if not virsh.has_command_help_match('managedsave', option):
            # Older libvirt does not have this option
            raise error.TestNAError("Older libvirt does not"
                                    " handle arguments consistently")

    # Backup xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    # Get the libvirtd service
    libvirtd = utils_libvirtd.Libvirtd()
    # Get config files.
    qemu_config = utils_config.LibvirtQemuConfig()
    libvirt_guests_config = utils_config.LibvirtGuestsConfig()
    # Get libvirt-guests service
    libvirt_guests = Factory.create_service("libvirt-guests")

    try:
        # Destroy vm first for setting configuration file
        if vm.state() == "running":
            vm.destroy(gracefully=False)
        # Prepare test environment.
        if libvirtd_state == "off":
            libvirtd.stop()
        if autostart_bypass_cache:
            ret = virsh.autostart(vm_name, "", ignore_status=True)
            libvirt.check_exit_status(ret)
            qemu_config.auto_start_bypass_cache = autostart_bypass_cache
            libvirtd.restart()
예제 #4
0
def run(test, params, env):
    """
    Configuring /etc/sysconfig/libvirt-guests, then check the domains
    status after restarting the libvirt-guests.server,

    1. Set the values in /etc/sysconfig/libvirt-guests
    2. Restart libvirt-guests service
    3. Check the domains states, and the guests' save files
    """

    def get_log():
        """
        Tail output appended data as the file /var/log/messages grows

        :returns: the appended data tailed from /var/log/messages
        """
        tailed_log_file = os.path.join(data_dir.get_tmp_dir(), 'tail_log')
        tailed_messages = aexpect.Tail(command='tail -f /var/log/messages',
                                       output_func=utils_misc.log_line,
                                       output_params=(tailed_log_file))
        return tailed_messages

    def chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output):
        """
        check domains' state when host shutdown, and if parallel_shutdown is set
        to non-zero, check whether the guests have been shutdown corretly.

        :param status_error: positive test if status_error is "no", otherwise
                             negative test
        :param on_shutdown: action taking on host shutdown
        :param parallel_shutdown: the number of parallel_shutdown guests would
                                  be shutdown concurrently on shutdown
        :param output: apppended message from /var/log/messages
        """
        expect_msg = expect_shutdown_msg(status_error, on_shutdown)
        logging.debug("The expected messages when host shutdown is: %s ", expect_msg)
        for dom in vms:
            if not expect_msg[dom.name] in output:
                logging.debug("expect_mesg is: %s", expect_msg[dom.name])
                if status_error == "no":
                    test.fail("guest should be %s on shutdown" % on_shutdown)
                else:
                    test.fail("Shutdown of guest should be failed to "
                              "complete in time")

        if (on_shutdown == "shutdown") and int(parallel_shutdown) > 0:
            chk_parallel_shutdown(output, parallel_shutdown)

    def chk_on_boot(status_error, on_boot):
        """
        check domains' state when host booted

        :param status_error: positive test if status_error is "no", otherwise
                             negative test
        :param on_boot: action taking on host booting
        """
        if status_error == "no":
            if on_boot == "start":
                for dom in vms:
                    if not dom.is_alive():
                        test.fail("Since on_boot is setting to 'start', "
                                  "guest should be running after "
                                  "restarting libvirt-guests.")
            else:
                for dom in vms:
                    if dom.is_alive():
                        test.fail("Since on_boot is setting to 'ignore', "
                                  "unless guests are autostart, "
                                  "guest should be shut off after "
                                  "restarting libvirt-guests, ")

    def check_on_shutdown_vm_status():
        for dom in vms:
            result = virsh.domstate(dom.name, "--reason")
            try:
                dom.wait_for_shutdown()
            except Exception as e:
                test.fail('As on_boot is set to "ignore", but guest %s is '
                          'not shutdown. reason: %s ' % (dom.name, e))

    def chk_parallel_shutdown(output, parallel_shutdown):
        """
        check whether the guests has been shut down concurrently
        on host shutdown.
        """
        pattern = r".+ libvirt-guests.sh: Starting shutdown on guest: .+"
        shut_start_line_nums = []
        for line_num, line in enumerate(output.splitlines()):
            if re.search(pattern, line):
                shut_start_line_nums.append(line_num)
        logging.debug("the line_numbers contains shutdown messages is: %s ",
                      shut_start_line_nums)

        pattern = r".+ libvirt-guests.sh: Shutdown of guest.+complete"
        for line_num, line in enumerate(output.splitlines()):
            if re.search(pattern, line):
                shut_complete_first_line = line_num
                break
        logging.debug("the first line contains shutdown complete messages is: %s ",
                      shut_complete_first_line)

        para_shut = int(parallel_shutdown)
        if shut_start_line_nums[para_shut-1] > shut_complete_first_line:
            test.fail("Since parallel_shutdown is setting to non_zero, "
                      "%s guests should be shutdown concurrently."
                      % parallel_shutdown)
        if shut_start_line_nums[para_shut] < shut_complete_first_line:
            test.fail("The number of guests shutdown concurrently "
                      "should not be exceeded than %s."
                      % parallel_shutdown)

    def expect_shutdown_msg(status_error, on_shutdown):
        """
        the expected messages of each guests when host shutdown
        logged into /var/log/messages
        """
        expect_msg = {}
        for dom in vms:
            if status_error == "no":
                if on_shutdown == "shutdown":
                    expect_msg[dom.name] = ("libvirt-guests.sh: "
                                            "Shutdown of guest %s "
                                            "complete" % dom.name)
                else:
                    expect_msg[dom.name] = ("libvirt-guests.sh: "
                                            "Suspending %s: done"
                                            % dom.name)
            else:
                # Now the negative tests are only about ON_SHUTDOWN=shutdown.
                if on_shutdown == "shutdown":
                    expect_msg[dom.name] = ("libvirt-guests.sh: "
                                            "Shutdown of guest %s "
                                            "failed to complete in "
                                            "time" % dom.name)
        return expect_msg

    def chk_save_files(status_error, on_shutdown, on_boot):
        """
        save files should exist when on_shutdown is set to shutdown, and
        on_boot is set to ignore. In other conditions, there should be
        no save files.
        """
        save_files = dict()
        for dom in vms:
            save_files[dom] = ("/var/lib/libvirt/qemu/save/%s.save" %
                               dom.name)
        if status_error == "no":
            if on_shutdown == "shutdown":
                for dom in vms:
                    if os.path.exists(save_files[dom]):
                        test.fail("There should be no save files since "
                                  "guests are shutdown on host shutdown.")
            else:
                if on_boot == "start":
                    for dom in vms:
                        if os.path.exists(save_files[dom]):
                            test.fail("There should be no save files since "
                                      "guests are restored on host shutdown.")
                else:
                    for dom in vms:
                        if not os.path.exists(save_files[dom]):
                            test.fail("Guests are suspended on host shutdown, "
                                      "and been ignored on host boot, there "
                                      "should be save files for the guests.")

    main_vm_name = params.get("main_vm")
    main_vm = env.get_vm(main_vm_name)

    on_boot = params.get("on_boot")
    on_shutdown = params.get("on_shutdown")
    parallel_shutdown = params.get("parallel_shutdown")
    additional_vms = int(params.get("additional_vms", "0"))
    status_error = params.get("status_error")
    shutdown_timeout = params.get("shutdown_timeout", "300")

    config = utils_config.LibvirtGuestsConfig()
    libvirt_guests_service = service.Factory.create_service("libvirt-guests")
    if not libvirt_guests_service.status():
        libvirt_guests_service.start()

    vms = [main_vm]
    if main_vm.is_alive:
        main_vm.destroy(gracefully=False)

    try:
        utils_path.find_command("virt-clone")
    except utils_path.CmdNotFoundError:
        test.cancel("No virt-clone command found.")

    # Clone additional vms: avocado-vt-vm2, avocado-vt-vm3.....
    for i in range(additional_vms):
        guest_name = ("%s" % main_vm_name[:-1])+("%s" % str(i+2))
        logging.debug("guest_name : %s", guest_name)
        utils_libguestfs.virt_clone_cmd(main_vm_name, guest_name,
                                        True, timeout=360)
        vms.append(main_vm.clone(guest_name))
        logging.debug("Now the vms is: %s", [dom.name for dom in vms])

    for dom in vms:
        if not dom.is_alive():
            dom.start()
    for dom in vms:
        dom.wait_for_login()

    try:
        # Config the libvirt-guests file
        config.ON_BOOT = on_boot
        config.ON_SHUTDOWN = on_shutdown
        config.PARALLEL_SHUTDOWN = parallel_shutdown
        config.SHUTDOWN_TIMEOUT = shutdown_timeout
        process.run("sed -i -e 's/ = /=/g' "
                    "/etc/sysconfig/libvirt-guests",
                    shell=True)

        tail_messages = get_log()
        # Even though libvirt-guests was designed to operate guests when
        # host shutdown. The purpose can also be fullfilled by restart the
        # libvirt-guests service.
        libvirt_guests_service.restart()
        output = tail_messages.get_output()

        # check the guests state when host shutdown
        chk_on_shutdown(status_error, on_shutdown, parallel_shutdown, output)
        # check the guests state when host rebooted
        chk_on_boot(status_error, on_boot)
        # check the guests save files
        chk_save_files(status_error, on_shutdown, on_boot)

        if on_boot == "ignore" and on_shutdown == "shutdown":
            check_on_shutdown_vm_status()

    finally:
        config.restore()

        # Undefine additional vms
        for dom in vms[1:]:
            if dom.is_alive():
                dom.destroy(gracefully=False)
            virsh.remove_domain(dom.name, "--remove-all-storage")

        if not libvirt_guests_service.status():
            libvirt_guests_service.start()