def run(test, params, env):
    """
    This test virsh domfsfreeze and domfsthaw commands and their options.

    1) Start a guest with/without guest agent configured;
    2) Freeze the guest file systems with domfsfreeze;
    3) Create a file on guest to see command hang;
    4) Thaw the guest file systems with domfsthaw;
    5) Check the file is already created;
    6) Retouch the file the ensure guest file system are not frozen;
    7) Cleanup test environment.
    """
    def check_freeze(session):
        """
        Check whether file system has been frozen by touch a test file
        and see if command will hang.

        :param session: Guest session to be tested.
        """
        try:
            output = session.cmd_output('touch freeze_test',
                                        timeout=10)
            test.fail("Failed to freeze file system. "
                      "Create file succeeded:\n%s" % output)
        except aexpect.ShellTimeoutError:
            pass

    def check_thaw(session):
        """
        Check whether file system has been thawed by check a test file
        prohibited from creation when frozen created and successfully touch
        the file again.

        :param session: Guest session to be tested.
        """
        status, output = session.cmd_status_output('ls freeze_test')
        if status:
            test.fail("Failed to thaw file system. "
                      "Find created file failed:\n%s" % output)

        try:
            output = session.cmd_output('touch freeze_test', timeout=10)
        except aexpect.ShellTimeoutError:
            test.fail("Failed to freeze file system. "
                      "Touch file timeout:\n%s" % output)

    def cleanup(session):
        """
        Clean up the test file used for freeze/thaw test.

        :param session: Guest session to be cleaned up.
        """
        status, output = session.cmd_status_output('rm -f freeze_test')
        if status:
            test.error("Failed to cleanup test file"
                       "Find created file failed:\n%s" % output)

    if not virsh.has_help_command('domfsfreeze'):
        test.cancel("This version of libvirt does not support "
                    "the domfsfreeze/domfsthaw test")

    channel = ("yes" == params.get("prepare_channel", "yes"))
    agent = ("yes" == params.get("start_agent", "yes"))
    mountpoint = params.get("mountpoint", None)
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    xml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    try:
        # Add or remove qemu-agent from guest before test
        vm.prepare_guest_agent(channel=channel, start=agent)
        session = vm.wait_for_login()
        try:
            # Expected fail message patterns
            fail_patts = []
            if not channel:
                fail_patts.append(r"QEMU guest agent is not configured")
            if not agent:
                # For older version
                fail_patts.append(r"Guest agent not available for now")
                # For newer version
                fail_patts.append(r"Guest agent is not responding")
            # Message patterns test should skip when met
            skip_patts = [
                r'The command \S+ has not been found',
                r'specifying mountpoints is not supported',
            ]

            res = virsh.domfsfreeze(vm_name, mountpoint=mountpoint)
            libvirt.check_result(res, fail_patts, skip_patts)
            if not res.exit_status:
                check_freeze(session)

            res = virsh.domfsthaw(vm_name, mountpoint=mountpoint)
            libvirt.check_result(res, fail_patts, skip_patts)
            if not res.exit_status:
                check_thaw(session)

            cleanup(session)
        finally:
            session.close()
    finally:
        xml_backup.sync()
def run(test, params, env):
    """
    Test domfsthaw command, make sure that all supported options work well

    Test scenaries:
    1. fsthaw fs which has been freezed
    2. fsthaw fs which has not been freezed

    Note: --mountpoint still not supported so will not test here
    """

    if not virsh.has_help_command('domfsthaw'):
        raise error.TestNAError("This version of libvirt does not support "
                                "the domfsthaw test")

    vm_name = params.get("main_vm", "avocado-vt-vm1")
    start_vm = ("yes" == params.get("start_vm", "no"))
    no_freeze = ("yes" == params.get("no_freeze", "yes"))
    has_qemu_ga = not ("yes" == params.get("no_qemu_ga", "no"))
    start_qemu_ga = not ("yes" == params.get("no_start_qemu_ga", "no"))
    status_error = ("yes" == params.get("status_error", "no"))
    options = params.get("domfsthaw_options", "")
    vm_ref = params.get("vm_ref", "")

    # Do backup for origin xml
    xml_backup = vm_xml.VMXML.new_from_dumpxml(vm_name)
    try:
        vm = env.get_vm(vm_name)

        vm.destroy()

        if not vm.is_alive():
            vm.start()

        # Firstly, freeze all filesytems
        if not no_freeze:
            # Add channel device for qemu-ga
            vm.prepare_guest_agent()
            cmd_result = virsh.domfsfreeze(vm_name, debug=True)
            if cmd_result.exit_status != 0:
                raise error.TestFail("Fail to do virsh domfsfreeze, error %s" %
                                     cmd_result.stderr)

        if has_qemu_ga:
            vm.prepare_guest_agent(start=start_qemu_ga)
        else:
            # Remove qemu-ga channel
            vm.prepare_guest_agent(channel=has_qemu_ga, start=False)

        if start_vm:
            if not vm.is_alive():
                vm.start()
        else:
            vm.destroy()

        if vm_ref == "none":
            vm_name = " "

        cmd_result = virsh.domfsthaw(vm_name, options=options, debug=True)
        if not status_error:
            if cmd_result.exit_status != 0:
                raise error.TestFail("Fail to do virsh domfsthaw, error %s" %
                                     cmd_result.stderr)
        else:
            if cmd_result.exit_status == 0:
                raise error.TestFail("Command 'virsh domfsthaw' failed ")

    finally:
        # Do domain recovery
        xml_backup.sync()
def run(test, params, env):
    """
    Test command: domfsinfo [--domain]

    The command gets information of domain's mounted filesystems.
    """
    start_vm = ("yes" == params.get("start_vm", "yes"))
    start_ga = ("yes" == params.get("start_ga", "yes"))
    prepare_channel = ("yes" == params.get("prepare_channel", "yes"))
    status_error = ("yes" == params.get("status_error", "no"))
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    mount_dir = params.get("mount_dir", None)
    quiet_mode = ("yes" == params.get("quiet_mode", False))
    readonly_mode = ("yes" == params.get("readonly_mode", False))
    nfs_mount = ("yes" == params.get("nfs_mount", False))
    domfsfreeze = ("yes" == params.get("domfsfreeze", False))

    # Hotplug and Unplug options
    hotplug_unplug = ("yes" == params.get("hotplug_unplug", False))
    disk_name = params.get("disk_name", "test")
    disk_path = os.path.join(data_dir.get_tmp_dir(), disk_name)
    disk_target = params.get("disk_target", "vdb")
    fs_type = params.get("fs_type", "ext3")
    new_part = ""

    fail_pat = []
    check_point_msg = params.get("check_point_msg", "")
    if check_point_msg:
        for msg in check_point_msg.split(";"):
            fail_pat.append(msg)

    def hotplug_domain_disk(domain, target, source=None, hotplug=True):
        """
        Hot-plug/Hot-unplug disk for domain

        :param domain: Guest name
        :param source: Source of disk device, can leave None if hotplug=False
        :param target: Target of disk device
        :param hotplug: True means hotplug, False means hot-unplug
        :return: Virsh command object
        """
        if hotplug:
            result = virsh.attach_disk(domain,
                                       source,
                                       target,
                                       "--live",
                                       ignore_status=False,
                                       debug=True)
        else:
            session = vm.wait_for_login()
            try:
                session.cmd("umount %s" % mount_dir)
                session.close()
            except:
                test.error(
                    "fail to unmount the disk before unpluging the disk")
            result = virsh.detach_disk(domain,
                                       target,
                                       "--live",
                                       ignore_status=False,
                                       debug=True)
        # It need more time for attachment to take effect
        time.sleep(5)

    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    cleanup_nfs = False
    try:
        reset_kwargs = {
            "start_vm": start_vm,
            "start_ga": start_ga,
            "prepare_channel": prepare_channel
        }
        reset_domain(vm, **reset_kwargs)

        if domfsfreeze:
            result = virsh.domfsfreeze(vm_name, debug=True)
            if result.exit_status:
                test.fail("Failed to execute virsh.domfsfreeze:\n%s" %
                          result.stderr)
        if nfs_mount:
            nfs_device = libvirt.setup_or_cleanup_nfs(True,
                                                      mount_dir=mount_dir,
                                                      is_mount=True)
            if nfs_device:
                cleanup_nfs = True
        if hotplug_unplug:
            session = vm.wait_for_login()
            new_device = libvirt.create_local_disk("file",
                                                   path=disk_path,
                                                   size="1")
            parts_list_before_attach = utils_disk.get_parts_list(session)
            hotplug_domain_disk(vm_name, disk_target, new_device)
            parts_list_after_attach = utils_disk.get_parts_list(session)
            new_part = list(
                set(parts_list_after_attach).difference(
                    set(parts_list_before_attach)))[0]
            logging.debug("The new partition is %s", new_part)
            libvirt.mkfs("/dev/%s" % new_part, fs_type, session=session)
            session.cmd_status(
                "mkdir -p {0} ; mount /dev/{1} {0}; ls {0}".format(
                    mount_dir, new_part))
            session.close()

        # Run test case
        command_dargs = {
            "readonly": readonly_mode,
            "quiet": quiet_mode,
            "debug": True
        }
        result = virsh.domfsinfo(vm_name, **command_dargs)
        if not result.exit_status:
            if fail_pat:
                test.fail("Expected fail with %s, but run succeed:\n%s" %
                          (fail_pat, result))
        else:
            if not fail_pat:
                test.fail("Expected success, but run failed:\n%s" % result)
            else:
                # If not any pattern matches(fail_pat, result.stderr)
                if not any(p in result.stderr for p in fail_pat):
                    test.fail(
                        "Expected fail with one of %s, but failed with:\n%s" %
                        (fail_pat, result))
        # Check virsh.domfsinfo output
        cmd_output = result.stdout.strip()
        if quiet_mode:
            head_pat = "Mountpoint\s+Name\s+Type\s+Target"
            check_output(cmd_output, head_pat, test, expected=False)
        elif nfs_mount:
            check_output(cmd_output, mount_dir, test, expected=False)
        elif hotplug_unplug:
            blk_target = re.findall(r'[a-z]+', new_part)[0]
            disk_pat = "%s\s+%s\s+%s\s+%s" % (mount_dir, new_part, fs_type,
                                              blk_target)
            check_output(cmd_output, disk_pat, test, expected=True)
            # Unplug domain disk
            hotplug_domain_disk(vm_name, target=new_part, hotplug=False)
            result = virsh.domfsinfo(vm_name, **command_dargs)
            if result.exit_status:
                test.fail(
                    "Failed to run virsh.domfsinfo after disk unplug:\n%s" %
                    result.stderr)
            check_output(result.stdout.strip(), disk_pat, test, expected=False)
        else:
            # Verify virsh.domfsinfo consistency
            if not status_error:
                session = vm.wait_for_login(timeout=120)
                domfsinfo = vm.domfsinfo()
                expected_result = get_mount_fs(session)
                if domfsinfo and expected_result:
                    check_domfsinfo(domfsinfo, expected_result, test)
                else:
                    logging.debug("Virsh.domfsinfo output:\n%s", domfsinfo)
                    logging.debug("Expected_result is:\n%s", expected_result)
                    test.error("Command output inconsistent with expected")
                session.close()
    finally:
        if cleanup_nfs:
            libvirt.setup_or_cleanup_nfs(False, mount_dir=mount_dir)
        if vm.is_alive():
            vm.destroy()
        if hotplug_unplug:
            if disk_path:
                cmd = "rm -rf %s" % disk_path
                process.run(cmd)
        vmxml_backup.sync()
def run(test, params, env):
    """
    Test domfsfreeze command, make sure that all supported options work well

    Test scenaries:
    1. fsfreeze all fs without options
    2. fsfreeze a mountpoint with --mountpoint
    3. fsfreeze a mountpoint without --mountpoint
    """
    def check_freeze(session):
        """
        Check whether file system has been frozen by touch a test file
        and see if command will hang.

        :param session: Guest session to be tested.
        """
        try:
            output = session.cmd_output('touch freeze_test', timeout=10)
            test.fail("Failed to freeze file system. "
                      "Create file succeeded:%s\n" % output)
        except aexpect.ShellTimeoutError:
            pass

    if not virsh.has_help_command('domfsfreeze'):
        test.cancel("This version of libvirt does not support "
                    "the domfsfreeze test")

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

    vm_ref = params.get("vm_ref", "name")
    vm_name = params.get("main_vm", "virt-tests-vm1")
    mountpoint = params.get("domfsfreeze_mnt", None)
    options = params.get("domfsfreeze_options", "")
    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user')
    start_vm = ("yes" == params.get("start_vm", "yes"))
    has_channel = ("no" == params.get("no_qemu_ga", "no"))
    start_qemu_ga = ("no" == params.get("no_start_qemu_ga", "no"))
    status_error = ("yes" == params.get("status_error", "no"))

    # Do backup for origin xml
    xml_backup = vm_xml.VMXML.new_from_dumpxml(vm_name)
    try:
        vm = env.get_vm(vm_name)
        if vm.is_alive():
            vm.destroy()

        if has_channel:
            # Add channel device for qemu-ga
            vm.prepare_guest_agent(start=start_qemu_ga)
        else:
            # Remove qemu-ga channel
            vm.prepare_guest_agent(channel=False, start=False)

        if start_vm:
            if not vm.is_alive():
                vm.start()
            domid = vm.get_id()
            session = vm.wait_for_login()
        else:
            vm.destroy()

        domuuid = vm.get_uuid()
        if vm_ref == "id":
            vm_ref = domid
        elif vm_ref == "uuid":
            vm_ref = domuuid
        elif vm_ref.count("invalid"):
            vm_ref = uuid.uuid1()
        elif vm_ref == "none":
            vm_ref = ""
        elif vm_ref == "name":
            vm_ref = vm_name

        result = virsh.domfsfreeze(vm_ref,
                                   mountpoint=mountpoint,
                                   options=options,
                                   unprivileged_user=unprivileged_user,
                                   uri=uri,
                                   debug=True)
        libvirt.check_exit_status(result, status_error)
        if not result.exit_status:
            check_freeze(session)

    finally:
        # Do domain recovery
        xml_backup.sync()
def run(test, params, env):
    """
    Test domfsfreeze command, make sure that all supported options work well

    Test scenaries:
    1. fsfreeze all fs without options
    2. fsfreeze a mountpoint with --mountpoint
    3. fsfreeze a mountpoint without --mountpoint
    """

    def check_freeze(session):
        """
        Check whether file system has been frozen by touch a test file
        and see if command will hang.

        :param session: Guest session to be tested.
        """
        try:
            output = session.cmd_output('touch freeze_test',
                                        timeout=10)
            test.fail("Failed to freeze file system. "
                      "Create file succeeded:%s\n" % output)
        except aexpect.ShellTimeoutError:
            pass

    if not virsh.has_help_command('domfsfreeze'):
        test.cancel("This version of libvirt does not support "
                    "the domfsfreeze test")

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

    vm_ref = params.get("vm_ref", "name")
    vm_name = params.get("main_vm", "virt-tests-vm1")
    mountpoint = params.get("domfsfreeze_mnt", None)
    options = params.get("domfsfreeze_options", "")
    uri = params.get("virsh_uri")
    unprivileged_user = params.get('unprivileged_user')
    start_vm = ("yes" == params.get("start_vm", "yes"))
    has_channel = ("no" == params.get("no_qemu_ga", "no"))
    start_qemu_ga = ("no" == params.get("no_start_qemu_ga", "no"))
    status_error = ("yes" == params.get("status_error", "no"))

    # Do backup for origin xml
    xml_backup = vm_xml.VMXML.new_from_dumpxml(vm_name)
    try:
        vm = env.get_vm(vm_name)
        if vm.is_alive():
            vm.destroy()

        if has_channel:
            # Add channel device for qemu-ga
            vm.prepare_guest_agent(start=start_qemu_ga)
        else:
            # Remove qemu-ga channel
            vm.prepare_guest_agent(channel=False, start=False)

        if start_vm:
            if not vm.is_alive():
                vm.start()
            domid = vm.get_id()
            session = vm.wait_for_login()
        else:
            vm.destroy()

        domuuid = vm.get_uuid()
        if vm_ref == "id":
            vm_ref = domid
        elif vm_ref == "uuid":
            vm_ref = domuuid
        elif vm_ref.count("invalid"):
            vm_ref = uuid.uuid1()
        elif vm_ref == "none":
            vm_ref = ""
        elif vm_ref == "name":
            vm_ref = vm_name

        result = virsh.domfsfreeze(vm_ref, mountpoint=mountpoint,
                                   options=options,
                                   unprivileged_user=unprivileged_user,
                                   uri=uri, debug=True)
        libvirt.check_exit_status(result, status_error)
        if not result.exit_status:
            check_freeze(session)

    finally:
        # Do domain recovery
        xml_backup.sync()
def run(test, params, env):
    """
    Test domfsthaw command, make sure that all supported options work well

    Test scenaries:
    1. fsthaw fs which has been freezed
    2. fsthaw fs which has not been freezed

    Note: --mountpoint still not supported so will not test here
    """

    if not virsh.has_help_command('domfsthaw'):
        raise error.TestNAError("This version of libvirt does not support "
                                "the domfsthaw test")

    vm_name = params.get("main_vm", "virt-tests-vm1")
    start_vm = ("yes" == params.get("start_vm", "no"))
    no_freeze = ("yes" == params.get("no_freeze", "yes"))
    has_qemu_ga = not ("yes" == params.get("no_qemu_ga", "no"))
    start_qemu_ga = not ("yes" == params.get("no_start_qemu_ga", "no"))
    status_error = ("yes" == params.get("status_error", "no"))
    options = params.get("domfsthaw_options", "")
    vm_ref = params.get("vm_ref", "")

    # Do backup for origin xml
    xml_backup = vm_xml.VMXML.new_from_dumpxml(vm_name)
    try:
        vm = env.get_vm(vm_name)

        vm.destroy()

        if not vm.is_alive():
            vm.start()

        # Firstly, freeze all filesytems
        if not no_freeze:
            # Add channel device for qemu-ga
            vm.prepare_guest_agent()
            cmd_result = virsh.domfsfreeze(vm_name, debug=True)
            if cmd_result.exit_status != 0:
                raise error.TestFail("Fail to do virsh domfsfreeze, error %s" %
                                     cmd_result.stderr)

        if has_qemu_ga:
            vm.prepare_guest_agent(start=start_qemu_ga)
        else:
            # Remove qemu-ga channel
            vm.prepare_guest_agent(channel=has_qemu_ga, start=False)

        if start_vm:
            if not vm.is_alive():
                vm.start()
        else:
            vm.destroy()

        if vm_ref == "none":
            vm_name = " "

        cmd_result = virsh.domfsthaw(vm_name, options=options, debug=True)
        if not status_error:
            if cmd_result.exit_status != 0:
                raise error.TestFail("Fail to do virsh domfsthaw, error %s" %
                                     cmd_result.stderr)
        else:
            if cmd_result.exit_status == 0:
                raise error.TestFail("Command 'virsh domfsthaw' failed ")

    finally:
        # Do domain recovery
        xml_backup.sync()