Esempio n. 1
0
    def __init__(self, test, params, image_name, blkdebug_cfg="",
                 prompt=r"qemu-io>\s*$", log_filename=None, io_options="",
                 log_func=None):
        self.type = ""
        if log_filename:
            log_filename += "-" + utils_misc.generate_random_string(4)
            self.output_func = utils_misc.log_line
            self.output_params = (log_filename,)
        else:
            self.output_func = None
            self.output_params = ()
        self.output_prefix = ""
        self.prompt=prompt
        self.blkdebug_cfg=blkdebug_cfg

        base_dir = utils_misc.get_path(data_dir.get_root_dir(),
                                       params.get("vm_type"))
        self.qemu_io_cmd = utils_misc.get_path(base_dir,
                                               params.get("qemu_io_binary",
                                                          "qemu-io"))
        self.io_options = io_options
        self.run_command = False
        self.image_name = image_name
        self.blkdebug_cfg = blkdebug_cfg
        self.log_func = log_func
Esempio n. 2
0
    def __init__(self,
                 test,
                 params,
                 image_name,
                 blkdebug_cfg="",
                 prompt=r"qemu-io>\s*$",
                 log_filename=None,
                 io_options="",
                 log_func=None):
        self.type = ""
        if log_filename:
            log_filename += "-" + utils_misc.generate_random_string(4)
            self.output_func = utils_misc.log_line
            self.output_params = (log_filename, )
        else:
            self.output_func = None
            self.output_params = ()
        self.output_prefix = ""
        self.prompt = prompt
        self.blkdebug_cfg = blkdebug_cfg

        base_dir = utils_misc.get_path(data_dir.get_root_dir(),
                                       params.get("vm_type"))
        self.qemu_io_cmd = utils_misc.get_path(
            base_dir, params.get("qemu_io_binary", "qemu-io"))
        self.io_options = io_options
        self.run_command = False
        self.image_name = image_name
        self.blkdebug_cfg = blkdebug_cfg
        self.log_func = log_func
Esempio n. 3
0
def _store_vm_register(test, params, env):
    global _vm_register_thread_termination_event
    delay = float(params.get("vm_register_delay", 5))
    counter = {}
    while True:
        for vm in env.get_all_vms():
            if not vm.is_alive():
                logging.warn("%s is not alive. Can not query the "
                             "register status" % vm.name)
                continue
            vm_pid = vm.get_pid()
            vr_dir = utils_misc.get_path(
                test.debugdir, "vm_register_%s_%s" % (vm.name, vm_pid))
            try:
                os.makedirs(vr_dir)
            except OSError:
                pass

            if vm not in counter:
                counter[vm] = 1
            vr_filename = utils_misc.get_path(vr_dir, "%04d" % counter[vm])
            stored_log = store_vm_register(vm, vr_filename)
            if stored_log:
                counter[vm] += 1

        if _vm_register_thread_termination_event is not None:
            if _vm_register_thread_termination_event.isSet():
                _vm_register_thread_termination_event = None
                break
            _vm_register_thread_termination_event.wait(delay)
        else:
            # Exit event was deleted, exit this thread
            break
Esempio n. 4
0
def _store_vm_register(test, params, env):
    global _vm_register_thread_termination_event
    delay = float(params.get("vm_register_delay", 5))
    counter = {}
    while True:
        for vm in env.get_all_vms():
            if not vm.is_alive():
                logging.warn("%s is not alive. Can not query the "
                             "register status" % vm.name)
                continue
            vm_pid = vm.get_pid()
            vr_dir = utils_misc.get_path(test.debugdir,
                                         "vm_register_%s_%s" % (vm.name,
                                                                vm_pid))
            try:
                os.makedirs(vr_dir)
            except OSError:
                pass

            if vm not in counter:
                counter[vm] = 1
            vr_filename = utils_misc.get_path(vr_dir, "%04d" % counter[vm])
            stored_log = store_vm_register(vm, vr_filename)
            if stored_log:
                counter[vm] += 1

        if _vm_register_thread_termination_event is not None:
            if _vm_register_thread_termination_event.isSet():
                _vm_register_thread_termination_event = None
                break
            _vm_register_thread_termination_event.wait(delay)
        else:
            # Exit event was deleted, exit this thread
            break
Esempio n. 5
0
def _store_vm_register(test, params, env):
    def report_result(status, results):
        msg = "%s." % status
        for vm_instance in results.keys():
            if results[vm_instance] > 0:
                msg += " Used to failed to get register info from guest"
                msg += " %s for %s times." % (vm_instance,
                                              results[vm_instance])

        if msg != "%s." % status:
            logging.debug(msg)

    global _vm_register_thread_termination_event
    delay = float(params.get("vm_register_delay", 5))
    counter = {}
    vm_register_error_count = {}
    while True:
        for vm in env.get_all_vms():
            if vm.instance not in vm_register_error_count:
                vm_register_error_count[vm.instance] = 0

            if not vm.is_alive():
                if vm_register_error_count[vm.instance] < 1:
                    logging.warn("%s is not alive. Can not query the "
                                 "register status" % vm.name)
                vm_register_error_count[vm.instance] += 1
                continue
            vm_pid = vm.get_pid()
            vr_dir = utils_misc.get_path(
                test.debugdir, "vm_register_%s_%s" % (vm.name, vm_pid))
            try:
                os.makedirs(vr_dir)
            except OSError:
                pass

            if vm.instance not in counter:
                counter[vm.instance] = 1
            vr_filename = utils_misc.get_path(vr_dir,
                                              "%04d" % counter[vm.instance])
            stored_log = store_vm_register(vm, vr_filename)
            if vm_register_error_count[vm.instance] >= 1:
                logging.debug("%s alive now. Used to failed to get register"
                              " info from guest %s"
                              " times" %
                              (vm.name, vm_register_error_count[vm.instance]))
                vm_register_error_count[vm.instance] = 0
            if stored_log:
                counter[vm.instance] += 1

        if _vm_register_thread_termination_event is not None:
            if _vm_register_thread_termination_event.isSet():
                _vm_register_thread_termination_event = None
                report_result("Thread quit", vm_register_error_count)
                break
            _vm_register_thread_termination_event.wait(delay)
        else:
            report_result("Thread quit", vm_register_error_count)
            # Exit event was deleted, exit this thread
            break
Esempio n. 6
0
def _store_vm_register(test, params, env):
    def report_result(status, results):
        msg = "%s." % status
        for vm_instance in results.keys():
            if results[vm_instance] > 0:
                msg += " Used to failed to get register info from guest"
                msg += " %s for %s times." % (vm_instance, results[vm_instance])

        if msg != "%s." % status:
            logging.debug(msg)

    global _vm_register_thread_termination_event
    delay = float(params.get("vm_register_delay", 5))
    counter = {}
    vm_register_error_count = {}
    while True:
        for vm in env.get_all_vms():
            if vm.instance not in vm_register_error_count:
                vm_register_error_count[vm.instance] = 0

            if not vm.is_alive():
                if vm_register_error_count[vm.instance] < 1:
                    logging.warn("%s is not alive. Can not query the "
                                 "register status" % vm.name)
                vm_register_error_count[vm.instance] += 1
                continue
            vm_pid = vm.get_pid()
            vr_dir = utils_misc.get_path(test.debugdir,
                                         "vm_register_%s_%s" % (vm.name,
                                                                vm_pid))
            try:
                os.makedirs(vr_dir)
            except OSError:
                pass

            if vm.instance not in counter:
                counter[vm.instance] = 1
            vr_filename = utils_misc.get_path(vr_dir, "%04d" % counter[vm.instance])
            stored_log = store_vm_register(vm, vr_filename)
            if vm_register_error_count[vm.instance] >= 1:
                logging.debug("%s alive now. Used to failed to get register"
                              " info from guest %s"
                              " times" % (vm.name,
                                          vm_register_error_count[vm.instance]))
                vm_register_error_count[vm.instance] = 0
            if stored_log:
                counter[vm.instance] += 1

        if _vm_register_thread_termination_event is not None:
            if _vm_register_thread_termination_event.isSet():
                _vm_register_thread_termination_event = None
                report_result("Thread quit", vm_register_error_count)
                break
            _vm_register_thread_termination_event.wait(delay)
        else:
            report_result("Thread quit", vm_register_error_count)
            # Exit event was deleted, exit this thread
            break
Esempio n. 7
0
    def verify_kernel_crash(self):
        """
        Find kernel crash message on the VM serial console.

        :raise: VMDeadKernelCrashError, in case a kernel crash message was
                found.
        """
        panic_re = [r"BUG:.*---\[ end trace .* \]---"]
        panic_re.append(r"----------\[ cut here.* BUG .*\[ end trace .* \]---")
        panic_re.append(r"general protection fault:.* RSP.*>")
        panic_re = "|".join(panic_re)
        if self.serial_console is not None:
            data = self.serial_console.get_output()
            match = re.search(panic_re, data, re.DOTALL | re.MULTILINE | re.I)
            if match is not None:
                raise VMDeadKernelCrashError(match.group(0))
        #For windows guest
        if self.params.get("check_guest_bsod", "no") == 'yes':
            try:
                scrdump_file = os.path.join("/tmp", "scrdump-img.ppm")
                ref_img_path = self.params.get("bsod_reference_img", "")
                bsod_base_dir = os.path.join(data_dir.get_deps_dir(),
                                             "bsod_img")
                ref_img = utils_misc.get_path(bsod_base_dir, ref_img_path)
                try:
                    self.screendump(filename=scrdump_file, debug=False)
                except Exception, err:
                    logging.warn("Cannot catch guest screendump, %s" % err)
                    pass
                if (os.path.exists(scrdump_file) and
                    ppm_utils.have_similar_img(scrdump_file, ref_img)):
                    err_msg = "Windows Guest appears to have suffered a BSOD,"
                    err_msg += " please check test video."
                    raise VMDeadKernelCrashError(err_msg)
            finally:
Esempio n. 8
0
    def __init__(self, params, root_dir, tag):
        """
        Init the default value for image object.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.
        @param tag: Image tag defined in parameter images
        """
        storage.QemuImg.__init__(self, params, root_dir, tag)
        self.image_cmd = utils_misc.get_path(
            root_dir, params.get("qemu_img_binary", "qemu-img"))
Esempio n. 9
0
    def __init__(self, params, root_dir, tag):
        """
        Init the default value for image object.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.
        @param tag: Image tag defined in parameter images
        """
        storage.QemuImg.__init__(self, params, root_dir, tag)
        self.image_cmd = utils_misc.get_path(root_dir,
                                 params.get("qemu_img_binary","qemu-img"))
Esempio n. 10
0
 def verify_bsod(self, scrdump_file):
     # For windows guest
     if (os.path.exists(scrdump_file) and
             self.params.get("check_guest_bsod", "no") == 'yes' and
             ppm_utils.Image is not None):
         ref_img_path = self.params.get("bsod_reference_img", "")
         bsod_base_dir = os.path.join(data_dir.get_root_dir(),
                                      "shared", "deps",
                                      "bsod_img")
         ref_img = utils_misc.get_path(bsod_base_dir, ref_img_path)
         if ppm_utils.have_similar_img(scrdump_file, ref_img):
             err_msg = "Windows Guest appears to have suffered a BSOD,"
             err_msg += " please check %s against %s." % (scrdump_file, ref_img)
             raise VMDeadKernelCrashError(err_msg)
Esempio n. 11
0
 def verify_bsod(self, scrdump_file):
     # For windows guest
     if (os.path.exists(scrdump_file)
             and self.params.get("check_guest_bsod", "no") == 'yes'
             and ppm_utils.Image is not None):
         ref_img_path = self.params.get("bsod_reference_img", "")
         bsod_base_dir = os.path.join(data_dir.get_root_dir(), "shared",
                                      "deps", "bsod_img")
         ref_img = utils_misc.get_path(bsod_base_dir, ref_img_path)
         if ppm_utils.have_similar_img(scrdump_file, ref_img):
             err_msg = "Windows Guest appears to have suffered a BSOD,"
             err_msg += " please check %s against %s." % (scrdump_file,
                                                          ref_img)
             raise VMDeadKernelCrashError(err_msg)
Esempio n. 12
0
    def __init__(self, params, root_dir, tag):
        """
        Init the default value for image object.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.
        @param tag: Image tag defined in parameter images
        """
        storage.QemuImg.__init__(self, params, root_dir, tag)
        # qemu img binary can be found in the test dir, not data_dir
        qemu_img_base_dir = os.path.join(data_dir.get_root_dir(),
                                         params.get("vm_type"))
        self.image_cmd = utils_misc.get_path(qemu_img_base_dir,
                                 params.get("qemu_img_binary","qemu-img"))
Esempio n. 13
0
    def __init__(self, params, root_dir, tag):
        """
        Init the default value for image object.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.
        @param tag: Image tag defined in parameter images
        """
        storage.QemuImg.__init__(self, params, root_dir, tag)
        # qemu img binary can be found in the test dir, not data_dir
        qemu_img_base_dir = os.path.join(data_dir.get_root_dir(),
                                         params.get("vm_type"))
        self.image_cmd = utils_misc.get_path(qemu_img_base_dir,
                                 params.get("qemu_img_binary","qemu-img"))
Esempio n. 14
0
def get_image_filename(params, root_dir):
    """
    Generate an image path from params and root_dir.

    @param params: Dictionary containing the test parameters.
    @param root_dir: Base directory for relative filenames.

    @note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    @raise VMDeviceError: When no matching disk found (in indirect method).
    """
    image_name = params.get("image_name", "image")
    indirect_image_select = params.get("indirect_image_select")
    if indirect_image_select:
        re_name = image_name
        indirect_image_select = int(indirect_image_select)
        matching_images = utils.system_output("ls -1d %s" % re_name)
        matching_images = sorted(matching_images.split('\n'))
        if matching_images[-1] == '':
            matching_images = matching_images[:-1]
        try:
            image_name = matching_images[indirect_image_select]
        except IndexError:
            raise virt_vm.VMDeviceError("No matching disk found for "
                                        "name = '%s', matching = '%s' and "
                                        "selector = '%s'" %
                                        (re_name, matching_images,
                                         indirect_image_select))
        for protected in params.get('indirect_image_blacklist', '').split(' '):
            if re.match(protected, image_name):
                raise virt_vm.VMDeviceError("Matching disk is in blacklist. "
                                            "name = '%s', matching = '%s' and "
                                            "selector = '%s'" %
                                            (re_name, matching_images,
                                             indirect_image_select))
    image_format = params.get("image_format", "qcow2")
    if params.get("image_raw_device") == "yes":
        return image_name
    if image_format:
        image_filename = "%s.%s" % (image_name, image_format)
    else:
        image_filename = image_name
    image_filename = utils_misc.get_path(root_dir, image_filename)
    return image_filename
Esempio n. 15
0
def get_image_filename(params, root_dir):
    """
    Generate an image path from params and root_dir.

    @param params: Dictionary containing the test parameters.
    @param root_dir: Base directory for relative filenames.

    @note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    @raise VMDeviceError: When no matching disk found (in indirect method).
    """
    image_name = params.get("image_name", "image")
    indirect_image_select = params.get("indirect_image_select")
    if indirect_image_select:
        re_name = image_name
        indirect_image_select = int(indirect_image_select)
        matching_images = utils.system_output("ls -1d %s" % re_name)
        matching_images = sorted(matching_images.split('\n'))
        if matching_images[-1] == '':
            matching_images = matching_images[:-1]
        try:
            image_name = matching_images[indirect_image_select]
        except IndexError:
            raise virt_vm.VMDeviceError("No matching disk found for "
                                        "name = '%s', matching = '%s' and "
                                        "selector = '%s'" %
                                        (re_name, matching_images,
                                         indirect_image_select))
        for protected in params.get('indirect_image_blacklist', '').split(' '):
            if re.match(protected, image_name):
                raise virt_vm.VMDeviceError("Matching disk is in blacklist. "
                                            "name = '%s', matching = '%s' and "
                                            "selector = '%s'" %
                                            (re_name, matching_images,
                                             indirect_image_select))
    image_format = params.get("image_format", "qcow2")
    if params.get("image_raw_device") == "yes":
        return image_name
    if image_format:
        image_filename = "%s.%s" % (image_name, image_format)
    else:
        image_filename = image_name
    image_filename = utils_misc.get_path(root_dir, image_filename)
    return image_filename
Esempio n. 16
0
def get_image_blkdebug_filename(params, root_dir):
    """
    Generate an blkdebug file path from params and root_dir.

    blkdebug files allow error injection in the block subsystem.

    :param params: Dictionary containing the test parameters.
    :param root_dir: Base directory for relative filenames.

    :note: params should contain:
           blkdebug -- the name of the debug file.
    """
    blkdebug_name = params.get("drive_blkdebug", None)
    if blkdebug_name is not None:
        blkdebug_filename = utils_misc.get_path(root_dir, blkdebug_name)
    else:
        blkdebug_filename = None
    return blkdebug_filename
Esempio n. 17
0
def get_image_blkdebug_filename(params, root_dir):
    """
    Generate an blkdebug file path from params and root_dir.

    blkdebug files allow error injection in the block subsystem.

    :param params: Dictionary containing the test parameters.
    :param root_dir: Base directory for relative filenames.

    :note: params should contain:
           blkdebug -- the name of the debug file.
    """
    blkdebug_name = params.get("drive_blkdebug", None)
    if blkdebug_name is not None:
        blkdebug_filename = utils_misc.get_path(root_dir, blkdebug_name)
    else:
        blkdebug_filename = None
    return blkdebug_filename
Esempio n. 18
0
def preprocess(test, params, env):
    """
    Preprocess all VMs and images according to the instructions in params.
    Also, collect some host information, such as the KVM version.

    @param test: An Autotest test object.
    @param params: A dict containing all VM and image parameters.
    @param env: The environment (a dict-like object).
    """
    error.context("preprocessing")
    port = params.get('shell_port')
    prompt = params.get('shell_prompt')
    address = params.get('ovirt_node_address')
    username = params.get('ovirt_node_user')
    password = params.get('ovirt_node_password')

    # Start tcpdump if it isn't already running
    if "address_cache" not in env:
        env["address_cache"] = {}
    if "tcpdump" in env and not env["tcpdump"].is_alive():
        env["tcpdump"].close()
        del env["tcpdump"]
    if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
        cmd = "%s -npvi any 'dst port 68'" % utils_misc.find_command("tcpdump")
        if params.get("remote_preprocess") == "yes":
            login_cmd = ("ssh -o UserKnownHostsFile=/dev/null -o \
                         PreferredAuthentications=password -p %s %s@%s" %
                         (port, username, address))
            env["tcpdump"] = aexpect.ShellSession(
                login_cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"], ))
            remote._remote_login(env["tcpdump"], username, password, prompt)
            env["tcpdump"].sendline(cmd)
        else:
            env["tcpdump"] = aexpect.Tail(
                command=cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"], ))

        if utils_misc.wait_for(lambda: not env["tcpdump"].is_alive(), 0.1, 0.1,
                               1.0):
            logging.warn("Could not start tcpdump")
            logging.warn("Status: %s" % env["tcpdump"].get_status())
            logging.warn(
                "Output:" +
                utils_misc.format_str_for_message(env["tcpdump"].get_output()))

    # Destroy and remove VMs that are no longer needed in the environment
    requested_vms = params.objects("vms")
    for key in env.keys():
        vm = env[key]
        if not utils_misc.is_vm(vm):
            continue
        if not vm.name in requested_vms:
            vm.destroy()
            del env[key]

    # Get Host cpu type
    if params.get("auto_cpu_model") == "yes":
        if not env.get("cpu_model"):
            env["cpu_model"] = utils_misc.get_cpu_model()
        params["cpu_model"] = env.get("cpu_model")

    kvm_ver_cmd = params.get("kvm_ver_cmd", "")

    if kvm_ver_cmd:
        try:
            cmd_result = utils.run(kvm_ver_cmd)
            kvm_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_version = "Unknown"
    else:
        # Get the KVM kernel module version and write it as a keyval
        if os.path.exists("/dev/kvm"):
            try:
                kvm_version = open("/sys/module/kvm/version").read().strip()
            except Exception:
                kvm_version = os.uname()[2]
        else:
            logging.warning("KVM module not loaded")
            kvm_version = "Unknown"

    logging.debug("KVM version: %s" % kvm_version)
    test.write_test_keyval({"kvm_version": kvm_version})

    # Get the KVM userspace version and write it as a keyval
    kvm_userspace_ver_cmd = params.get("kvm_userspace_ver_cmd", "")

    if kvm_userspace_ver_cmd:
        try:
            cmd_result = utils.run(kvm_userspace_ver_cmd)
            kvm_userspace_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_userspace_version = "Unknown"
    else:
        qemu_path = utils_misc.get_path(test.bindir,
                                        params.get("qemu_binary", "qemu"))
        version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
        matches = re.findall("[Vv]ersion .*?,", version_line)
        if matches:
            kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
        else:
            kvm_userspace_version = "Unknown"

    logging.debug("KVM userspace version: %s" % kvm_userspace_version)
    test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})

    if params.get("setup_hugepages") == "yes":
        h = test_setup.HugePageConfig(params)
        h.setup()
        if params.get("vm_type") == "libvirt":
            libvirt_vm.libvirtd_restart()

    if params.get("setup_thp") == "yes":
        thp = test_setup.TransparentHugePageConfig(test, params)
        thp.setup()

    # Execute any pre_commands
    if params.get("pre_command"):
        process_command(test, params, env, params.get("pre_command"),
                        int(params.get("pre_command_timeout", "600")),
                        params.get("pre_command_noncritical") == "yes")

    #Clone master image from vms.
    if params.get("master_images_clone"):
        for vm_name in params.get("vms").split():
            vm = env.get_vm(vm_name)
            if vm:
                vm.destroy(free_mac_addresses=False)
                env.unregister_vm(vm_name)

            vm_params = params.object_params(vm_name)
            for image in vm_params.get("master_images_clone").split():
                image_obj = kvm_storage.QemuImg(params, test.bindir, image)
                image_obj.clone_image(params, vm_name, image, test.bindir)

    # Preprocess all VMs and images
    if params.get("not_preprocess", "no") == "no":
        process(test, params, env, preprocess_image, preprocess_vm)

    # Start the screendump thread
    if params.get("take_regular_screendumps") == "yes":
        global _screendump_thread, _screendump_thread_termination_event
        _screendump_thread_termination_event = threading.Event()
        _screendump_thread = threading.Thread(target=_take_screendumps,
                                              args=(test, params, env))
        _screendump_thread.start()
Esempio n. 19
0
    def backup_image(self, params, root_dir, action, good=True):
        """
        Backup or restore a disk image, depending on the action chosen.

        @param params: Dictionary containing the test parameters.
        @param root_dir: Base directory for relative filenames.
        @param action: Whether we want to backup or restore the image.
        @param good: If we are backing up a good image(we want to restore it)
            or a bad image (we are saving a bad image for posterior analysis).

        @note: params should contain:
               image_name -- the name of the image file, without extension
               image_format -- the format of the image (qcow2, raw etc)
        """
        def backup_raw_device(src, dst):
            utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))

        def backup_image_file(src, dst):
            logging.debug("Copying %s -> %s", src, dst)
            shutil.copy(src, dst)

        def get_backup_name(filename, backup_dir, good):
            if not os.path.isdir(backup_dir):
                os.makedirs(backup_dir)
            basename = os.path.basename(filename)
            if good:
                backup_filename = "%s.backup" % basename
            else:
                backup_filename = ("%s.bad.%s" %
                                   (basename,
                                    utils_misc.generate_random_string(4)))
            return os.path.join(backup_dir, backup_filename)


        image_filename = self.image_filename
        backup_dir = params.get("backup_dir")
        if params.get('image_raw_device') == 'yes':
            iname = "raw_device"
            iformat = params.get("image_format", "qcow2")
            ifilename = "%s.%s" % (iname, iformat)
            ifilename = utils_misc.get_path(root_dir, ifilename)
            image_filename_backup = get_backup_name(ifilename, backup_dir, good)
            backup_func = backup_raw_device
        else:
            image_filename_backup = get_backup_name(image_filename, backup_dir,
                                                    good)
            backup_func = backup_image_file

        if action == 'backup':
            image_dir = os.path.dirname(image_filename)
            image_dir_disk_free = utils.freespace(image_dir)
            image_filename_size = os.path.getsize(image_filename)
            image_filename_backup_size = 0
            if os.path.isfile(image_filename_backup):
                image_filename_backup_size = os.path.getsize(
                                                        image_filename_backup)
            disk_free = image_dir_disk_free + image_filename_backup_size
            minimum_disk_free = 1.2 * image_filename_size
            if disk_free < minimum_disk_free:
                image_dir_disk_free_gb = float(image_dir_disk_free) / 10**9
                minimum_disk_free_gb = float(minimum_disk_free) / 10**9
                logging.error("Dir %s has %.1f GB free, less than the minimum "
                              "required to store a backup, defined to be 120%% "
                              "of the backup size, %.1f GB. Skipping backup...",
                              image_dir, image_dir_disk_free_gb,
                              minimum_disk_free_gb)
                return
            if good:
                # In case of qemu-img check return 1, we will make 2 backups,
                # one for investigation and other, to use as a 'pristine'
                # image for further tests
                state = 'good'
            else:
                state = 'bad'
            logging.info("Backing up %s image file %s", state, image_filename)
            src, dst = image_filename, image_filename_backup
        elif action == 'restore':
            if not os.path.isfile(image_filename_backup):
                logging.error('Image backup %s not found, skipping restore...',
                              image_filename_backup)
                return
            logging.info("Restoring image file %s from backup",
                         image_filename)
            src, dst = image_filename_backup, image_filename

        backup_func(src, dst)
Esempio n. 20
0
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = utils_misc.get_path(test.bindir,
                                      params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
                                 utils_misc.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))

    cache = {}
    counter = {}

    while True:
        for vm in env.get_all_vms():
            if vm not in counter.keys():
                counter[vm] = 0
            if not vm.is_alive():
                continue
            try:
                vm.screendump(filename=temp_filename, debug=False)
            except kvm_monitor.MonitorError, e:
                logging.warn(e)
                continue
            except AttributeError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(test.debugdir,
                                          "screendumps_%s" % vm.name)
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            counter[vm] += 1
            screendump_filename = os.path.join(screendump_dir, "%04d.jpg" %
                                               counter[vm])
            hsh = utils.hash_file(temp_filename)
            if hsh in cache:
                try:
                    os.link(cache[hsh], screendump_filename)
                except OSError:
                    pass
            else:
                try:
                    try:
                        image = PIL.Image.open(temp_filename)
                        image.save(screendump_filename, format="JPEG",
                                   quality=quality)
                        cache[hsh] = screendump_filename
                    except IOError, error_detail:
                        logging.warning("VM '%s' failed to produce a "
                                        "screendump: %s", vm.name, error_detail)
                        # Decrement the counter as we in fact failed to
                        # produce a converted screendump
                        counter[vm] -= 1
                except NameError:
                    pass
            os.unlink(temp_filename)
Esempio n. 21
0
File: lvm.py Progetto: ypu/virt-test
 def get_emulate_image_name(self):
     img_path = self.params.get("emulated_image")
     if img_path is None:
         img_path = self.generate_id(self.params)
     return utils_misc.get_path(self.data_dir, img_path)
Esempio n. 22
0
 def check_disk_params(self, params):
     """
     Check gathered info from qtree/block with params
     @param params: autotest params
     @return: number of errors
     """
     err = 0
     disks = {}
     for disk in self.disks:
         if isinstance(disk, QtreeDisk):
             disks[disk.get_qname()] = disk.get_params().copy()
     # We don't have the params name so we need to map file_names instead
     qname = None
     for name in params.objects('cdroms'):
         image_name = utils_misc.get_path(
             data_dir.get_data_dir(),
             params.object_params(name).get('cdrom', ''))
         image_name = os.path.realpath(image_name)
         for (qname, disk) in disks.iteritems():
             if disk.get('image_name') == image_name:
                 break
         else:
             continue  # Not /proc/scsi cdrom device
         disks.pop(qname)
     for name in params.objects('images'):
         current = None
         image_params = params.object_params(name)
         image_name = os.path.realpath(
             storage.get_image_filename(image_params,
                                        data_dir.get_data_dir()))
         for (qname, disk) in disks.iteritems():
             if disk.get('image_name') == image_name:
                 current = disk
                 # autotest params might use relative path
                 current['image_name'] = image_params.get('image_name')
                 break
         if not current:
             logging.error("Disk %s is not in qtree but is in params.",
                           name)
             err += 1
             continue
         for prop in current.iterkeys():
             handled = False
             if prop == "drive_format":
                 # HOOK: ahci disk is ide-* disk
                 if (image_params.get(prop) == 'ahci'
                         and current.get(prop).startswith('ide-')):
                     handled = True
                 # HOOK: params to qemu translation
                 elif current.get(prop).startswith(image_params.get(prop)):
                     handled = True
             elif (image_params.get(prop)
                   and image_params.get(prop) == current.get(prop)):
                 handled = True
             if not handled:
                 logging.error(
                     "Disk %s property %s=%s doesn't match params"
                     " %s", qname, prop, current.get(prop),
                     image_params.get(prop))
                 err += 1
         disks.pop(qname)
     if disks:
         logging.error(
             'Some disks were in qtree but not in autotest params'
             ': %s', disks)
         err += 1
     return err
Esempio n. 23
0
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = utils_misc.get_path(test.bindir,
                                       params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(
        temp_dir, "scrdump-%s.ppm" % utils_misc.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))

    cache = {}
    counter = {}

    while True:
        for vm in env.get_all_vms():
            if vm not in counter.keys():
                counter[vm] = 0
            if not vm.is_alive():
                continue
            try:
                vm.screendump(filename=temp_filename, debug=False)
            except kvm_monitor.MonitorError, e:
                logging.warn(e)
                continue
            except AttributeError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(test.debugdir,
                                          "screendumps_%s" % vm.name)
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            counter[vm] += 1
            screendump_filename = os.path.join(screendump_dir,
                                               "%04d.jpg" % counter[vm])
            hsh = utils.hash_file(temp_filename)
            if hsh in cache:
                try:
                    os.link(cache[hsh], screendump_filename)
                except OSError:
                    pass
            else:
                try:
                    try:
                        image = PIL.Image.open(temp_filename)
                        image.save(screendump_filename,
                                   format="JPEG",
                                   quality=quality)
                        cache[hsh] = screendump_filename
                    except IOError, error_detail:
                        logging.warning(
                            "VM '%s' failed to produce a "
                            "screendump: %s", vm.name, error_detail)
                        # Decrement the counter as we in fact failed to
                        # produce a converted screendump
                        counter[vm] -= 1
                except NameError:
                    pass
            os.unlink(temp_filename)
Esempio n. 24
0
    def backup_image(self,
                     params,
                     root_dir,
                     action,
                     good=True,
                     skip_existing=False):
        """
        Backup or restore a disk image, depending on the action chosen.

        :param params: Dictionary containing the test parameters.
        :param root_dir: Base directory for relative filenames.
        :param action: Whether we want to backup or restore the image.
        :param good: If we are backing up a good image(we want to restore it)
            or a bad image (we are saving a bad image for posterior analysis).

        :note: params should contain:
               image_name -- the name of the image file, without extension
               image_format -- the format of the image (qcow2, raw etc)
        """
        def backup_raw_device(src, dst):
            if os.path.exists(src):
                utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))
            else:
                logging.info("No source %s, skipping dd...", src)

        def backup_image_file(src, dst):
            logging.debug("Copying %s -> %s", src, dst)
            if os.path.isfile(dst) and os.path.isfile(src):
                os.unlink(dst)
            if os.path.isfile(src):
                shutil.copy(src, dst)
            else:
                logging.info("No source file %s, skipping copy...", src)

        def get_backup_set(filename, backup_dir, action, good):
            """
            Get all sources and destinations required for each backup.
            """
            if not os.path.isdir(backup_dir):
                os.makedirs(backup_dir)
            basename = os.path.basename(filename)
            bkp_set = []
            if good:
                src = filename
                dst = os.path.join(backup_dir, "%s.backup" % basename)
                if action == 'backup':
                    bkp_set = [[src, dst]]
                elif action == 'restore':
                    bkp_set = [[dst, src]]
            else:
                # We have to make 2 backups, one of the bad image, another one
                # of the good image
                src_bad = filename
                src_good = os.path.join(backup_dir, "%s.backup" % basename)
                hsh = utils_misc.generate_random_string(4)
                dst_bad = (os.path.join(backup_dir,
                                        "%s.bad.%s" % (basename, hsh)))
                dst_good = (os.path.join(backup_dir,
                                         "%s.good.%s" % (basename, hsh)))
                if action == 'backup':
                    bkp_set = [[src_bad, dst_bad], [src_good, dst_good]]
                elif action == 'restore':
                    bkp_set = [[src_good, src_bad]]

            if not bkp_set:
                logging.error("No backup sets for action: %s, state: %s",
                              action, good)

            return bkp_set

        image_filename = self.image_filename
        backup_dir = params.get("backup_dir", "")
        if not os.path.isabs(backup_dir):
            backup_dir = os.path.join(root_dir, backup_dir)
        if params.get('image_raw_device') == 'yes':
            iname = "raw_device"
            iformat = params.get("image_format", "qcow2")
            ifilename = "%s.%s" % (iname, iformat)
            ifilename = utils_misc.get_path(root_dir, ifilename)
            backup_set = get_backup_set(ifilename, backup_dir, action, good)
            backup_func = backup_raw_device
        else:
            backup_set = get_backup_set(image_filename, backup_dir, action,
                                        good)
            backup_func = backup_image_file

        if action == 'backup':
            image_dir = os.path.dirname(image_filename)
            image_dir_disk_free = utils.freespace(image_dir)

            backup_size = 0
            for src, dst in backup_set:
                if os.path.isfile(src):
                    backup_size += os.path.getsize(src)

            minimum_disk_free = 1.2 * backup_size
            if image_dir_disk_free < minimum_disk_free:
                image_dir_disk_free_gb = float(image_dir_disk_free) / 10**9
                backup_size_gb = float(backup_size) / 10**9
                minimum_disk_free_gb = float(minimum_disk_free) / 10**9
                logging.error("Free space on %s: %.1f GB", image_dir,
                              image_dir_disk_free_gb)
                logging.error("Backup size: %.1f GB", backup_size_gb)
                logging.error("Minimum free space acceptable: %.1f GB",
                              minimum_disk_free_gb)
                logging.error("Available disk space is not sufficient for a"
                              "full backup. Skipping backup...")
                return

        for src, dst in backup_set:
            if action == 'backup' and skip_existing and os.path.exists(dst):
                continue
            backup_func(src, dst)
Esempio n. 25
0
def get_image_filename_filesytem(params, root_dir):
    """
    Generate an image path from params and root_dir.

    :param params: Dictionary containing the test parameters.
    :param root_dir: Base directory for relative filenames.

    :note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    :raise VMDeviceError: When no matching disk found (in indirect method).
    """
    def sort_cmp(first, second):
        """
        This function used for sort to suit for this test, first sort by len
        then by value.
        """
        first_contains_digit = re.findall(r'[vhs]d[a-z]*[\d]+', first)
        second_contains_digit = re.findall(r'[vhs]d[a-z]*[\d]+', second)

        if not first_contains_digit and not second_contains_digit:
            if len(first) > len(second):
                return 1
            elif len(first) < len(second):
                return -1
        if len(first) == len(second):
            if first_contains_digit and second_contains_digit:
                return cmp(first, second)
            elif first_contains_digit:
                return -1
            elif second_contains_digit:
                return 1
        return cmp(first, second)

    image_name = params.get("image_name", "image")
    indirect_image_select = params.get("indirect_image_select")
    if indirect_image_select:
        re_name = image_name
        indirect_image_select = int(indirect_image_select)
        matching_images = utils.system_output("ls -1d %s" % re_name)
        matching_images = sorted(matching_images.split('\n'), cmp=sort_cmp)
        if matching_images[-1] == '':
            matching_images = matching_images[:-1]
        try:
            image_name = matching_images[indirect_image_select]
        except IndexError:
            raise virt_vm.VMDeviceError(
                "No matching disk found for "
                "name = '%s', matching = '%s' and "
                "selector = '%s'" %
                (re_name, matching_images, indirect_image_select))
        for protected in params.get('indirect_image_blacklist', '').split(' '):
            match_image = re.match(protected, image_name)
            if match_image and match_image.group(0) == image_name:
                # We just need raise an error if it is totally match, such as
                # sda sda1 and so on, but sdaa should not raise an error.
                raise virt_vm.VMDeviceError(
                    "Matching disk is in blacklist. "
                    "name = '%s', matching = '%s' and "
                    "selector = '%s'" %
                    (re_name, matching_images, indirect_image_select))

    image_format = params.get("image_format", "qcow2")
    if params.get("image_raw_device") == "yes":
        return image_name
    if image_format:
        image_filename = "%s.%s" % (image_name, image_format)
    else:
        image_filename = image_name

    image_filename = utils_misc.get_path(root_dir, image_filename)
    return image_filename
Esempio n. 26
0
    def backup_image(self, params, root_dir, action, good=True,
                     skip_existing=False):
        """
        Backup or restore a disk image, depending on the action chosen.

        :param params: Dictionary containing the test parameters.
        :param root_dir: Base directory for relative filenames.
        :param action: Whether we want to backup or restore the image.
        :param good: If we are backing up a good image(we want to restore it)
            or a bad image (we are saving a bad image for posterior analysis).

        :note: params should contain:
               image_name -- the name of the image file, without extension
               image_format -- the format of the image (qcow2, raw etc)
        """
        def backup_raw_device(src, dst):
            if os.path.exists(src):
                utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))
            else:
                logging.info("No source %s, skipping dd...", src)

        def backup_image_file(src, dst):
            logging.debug("Copying %s -> %s", src, dst)
            if os.path.isfile(dst) and os.path.isfile(src):
                os.unlink(dst)
            if os.path.isfile(src):
                shutil.copy(src, dst)
            else:
                logging.info("No source file %s, skipping copy...", src)

        def get_backup_set(filename, backup_dir, action, good):
            """
            Get all sources and destinations required for each backup.
            """
            if not os.path.isdir(backup_dir):
                os.makedirs(backup_dir)
            basename = os.path.basename(filename)
            bkp_set = []
            if good:
                src = filename
                dst = os.path.join(backup_dir, "%s.backup" % basename)
                if action == 'backup':
                    bkp_set = [[src, dst]]
                elif action == 'restore':
                    bkp_set = [[dst, src]]
            else:
                # We have to make 2 backups, one of the bad image, another one
                # of the good image
                src_bad = filename
                src_good = os.path.join(backup_dir, "%s.backup" % basename)
                hsh = utils_misc.generate_random_string(4)
                dst_bad = (os.path.join(backup_dir, "%s.bad.%s" %
                                        (basename, hsh)))
                dst_good = (os.path.join(backup_dir, "%s.good.%s" %
                                         (basename, hsh)))
                if action == 'backup':
                    bkp_set = [[src_bad, dst_bad], [src_good, dst_good]]
                elif action == 'restore':
                    bkp_set = [[src_good, src_bad]]

            if not bkp_set:
                logging.error("No backup sets for action: %s, state: %s",
                              action, good)

            return bkp_set

        image_filename = self.image_filename
        backup_dir = params.get("backup_dir", "")
        if not os.path.isabs(backup_dir):
            backup_dir = os.path.join(root_dir, backup_dir)
        if params.get('image_raw_device') == 'yes':
            iname = "raw_device"
            iformat = params.get("image_format", "qcow2")
            ifilename = "%s.%s" % (iname, iformat)
            ifilename = utils_misc.get_path(root_dir, ifilename)
            backup_set = get_backup_set(ifilename, backup_dir, action, good)
            backup_func = backup_raw_device
        else:
            backup_set = get_backup_set(image_filename, backup_dir, action,
                                        good)
            backup_func = backup_image_file

        if action == 'backup':
            image_dir = os.path.dirname(image_filename)
            image_dir_disk_free = utils.freespace(image_dir)

            backup_size = 0
            for src, dst in backup_set:
                if os.path.isfile(src):
                    backup_size += os.path.getsize(src)

            minimum_disk_free = 1.2 * backup_size
            if image_dir_disk_free < minimum_disk_free:
                image_dir_disk_free_gb = float(image_dir_disk_free) / 10 ** 9
                backup_size_gb = float(backup_size) / 10 ** 9
                minimum_disk_free_gb = float(minimum_disk_free) / 10 ** 9
                logging.error("Free space on %s: %.1f GB", image_dir,
                              image_dir_disk_free_gb)
                logging.error("Backup size: %.1f GB", backup_size_gb)
                logging.error("Minimum free space acceptable: %.1f GB",
                              minimum_disk_free_gb)
                logging.error("Available disk space is not sufficient for a"
                              "full backup. Skipping backup...")
                return

        for src, dst in backup_set:
            if action == 'backup' and skip_existing and os.path.exists(dst):
                continue
            backup_func(src, dst)
Esempio n. 27
0
    def make_create_command(self, name=None, params=None, root_dir=None):
        """
        Generate a libvirt command line. All parameters are optional. If a
        parameter is not supplied, the corresponding value stored in the
        class attributes is used.

        @param name: The name of the object
        @param params: A dict containing VM params
        @param root_dir: Base directory for relative filenames

        @note: The params dict should contain:
               mem -- memory size in MBs
               cdrom -- ISO filename to use with the qemu -cdrom parameter
               extra_params -- a string to append to the qemu command
               shell_port -- port of the remote shell daemon on the guest
               (SSH, Telnet or the home-made Remote Shell Server)
               shell_client -- client program to use for connecting to the
               remote shell daemon on the guest (ssh, telnet or nc)
               x11_display -- if specified, the DISPLAY environment variable
               will be be set to this value for the qemu process (useful for
               SDL rendering)
               images -- a list of image object names, separated by spaces
               nics -- a list of NIC object names, separated by spaces

               For each image in images:
               drive_format -- string to pass as 'if' parameter for this
               image (e.g. ide, scsi)
               image_snapshot -- if yes, pass 'snapshot=on' to qemu for
               this image
               image_boot -- if yes, pass 'boot=on' to qemu for this image
               In addition, all parameters required by get_image_filename.

               For each NIC in nics:
               nic_model -- string to pass as 'model' parameter for this
               NIC (e.g. e1000)
        """
        # helper function for command line option wrappers
        def has_option(help_text, option):
            return bool(re.search(r"--%s" % option, help_text, re.MULTILINE))

        # Wrappers for all supported libvirt command line parameters.
        # This is meant to allow support for multiple libvirt versions.
        # Each of these functions receives the output of 'libvirt --help' as a
        # parameter, and should add the requested command line option
        # accordingly.

        def add_name(help_text, name):
            return " --name '%s'" % name

        def add_machine_type(help_text, machine_type):
            if has_option(help_text, "machine"):
                return " --machine %s" % machine_type
            else:
                return ""

        def add_hvm_or_pv(help_text, hvm_or_pv):
            if hvm_or_pv == "hvm":
                return " --hvm --accelerate"
            elif hvm_or_pv == "pv":
                return " --paravirt"
            else:
                logging.warning("Unknown virt type hvm_or_pv, using default.")
                return ""

        def add_mem(help_text, mem):
            return " --ram=%s" % mem

        def add_check_cpu(help_text):
            if has_option(help_text, "check-cpu"):
                return " --check-cpu"
            else:
                return ""

        def add_smp(help_text, smp):
            return " --vcpu=%s" % smp

        def add_location(help_text, location):
            if has_option(help_text, "location"):
                return " --location %s" % location
            else:
                return ""

        def add_cdrom(help_text, filename, index=None):
            if has_option(help_text, "cdrom"):
                return " --cdrom %s" % filename
            else:
                return ""

        def add_pxe(help_text):
            if has_option(help_text, "pxe"):
                return " --pxe"
            else:
                return ""

        def add_import(help_text):
            if has_option(help_text, "import"):
                return " --import"
            else:
                return ""

        def add_drive(
            help_text,
            filename,
            pool=None,
            vol=None,
            device=None,
            bus=None,
            perms=None,
            size=None,
            sparse=False,
            cache=None,
            fmt=None,
        ):
            cmd = " --disk"
            if filename:
                cmd += " path=%s" % filename
            elif pool:
                if vol:
                    cmd += " vol=%s/%s" % (pool, vol)
                else:
                    cmd += " pool=%s" % pool
            if device:
                cmd += ",device=%s" % device
            if bus:
                cmd += ",bus=%s" % bus
            if perms:
                cmd += ",%s" % perms
            if size:
                cmd += ",size=%s" % size.rstrip("Gg")
            if sparse:
                cmd += ",sparse=false"
            if fmt:
                cmd += ",format=%s" % fmt
            if cache:
                cmd += ",cache=%s" % cache
            return cmd

        def add_floppy(help_text, filename):
            return " --disk path=%s,device=floppy,ro" % filename

        def add_vnc(help_text, vnc_port=None):
            if vnc_port:
                return " --vnc --vncport=%d" % (vnc_port)
            else:
                return " --vnc"

        def add_vnclisten(help_text, vnclisten):
            if has_option(help_text, "vnclisten"):
                return " --vnclisten=%s" % (vnclisten)
            else:
                return ""

        def add_sdl(help_text):
            if has_option(help_text, "sdl"):
                return " --sdl"
            else:
                return ""

        def add_nographic(help_text):
            return " --nographics"

        def add_video(help_text, video_device):
            if has_option(help_text, "video"):
                return " --video=%s" % (video_device)
            else:
                return ""

        def add_uuid(help_text, uuid):
            if has_option(help_text, "uuid"):
                return " --uuid %s" % uuid
            else:
                return ""

        def add_os_type(help_text, os_type):
            if has_option(help_text, "os-type"):
                return " --os-type %s" % os_type
            else:
                return ""

        def add_os_variant(help_text, os_variant):
            if has_option(help_text, "os-variant"):
                return " --os-variant %s" % os_variant
            else:
                return ""

        def add_pcidevice(help_text, pci_device):
            if has_option(help_text, "host-device"):
                return " --host-device %s" % pci_device
            else:
                return ""

        def add_soundhw(help_text, sound_device):
            if has_option(help_text, "soundhw"):
                return " --soundhw %s" % sound_device
            else:
                return ""

        def add_serial(help_text, filename):
            if has_option(help_text, "serial"):
                return "  --serial file,path=%s --serial pty" % filename
            else:
                self.only_pty = True
                return ""

        def add_kernel_cmdline(help_text, cmdline):
            return " -append %s" % cmdline

        def add_connect_uri(help_text, uri):
            if uri and has_option(help_text, "connect"):
                return " --connect=%s" % uri
            else:
                return ""

        def add_nic(help_text, nic_params):
            """
            Return additional command line params based on dict-like nic_params
            """
            mac = nic_params.get("mac")
            nettype = nic_params.get("nettype")
            netdst = nic_params.get("netdst")
            nic_model = nic_params.get("nic_model")
            if nettype:
                result = " --network=%s" % nettype
            else:
                result = ""
            if has_option(help_text, "bridge"):
                # older libvirt (--network=NATdev --bridge=bridgename --mac=mac)
                if nettype != "user":
                    result += ":%s" % netdst
                if mac:  # possible to specify --mac w/o --network
                    result += " --mac=%s" % mac
            else:
                # newer libvirt (--network=mynet,model=virtio,mac=00:11)
                if nettype != "user":
                    result += "=%s" % netdst
                if nettype and nic_model:  # only supported along with nettype
                    result += ",model=%s" % nic_model
                if nettype and mac:
                    result += ",mac=%s" % mac
                elif mac:  # possible to specify --mac w/o --network
                    result += " --mac=%s" % mac
            logging.debug("vm.make_create_command.add_nic returning: %s" % result)
            return result

        # End of command line option wrappers

        if name is None:
            name = self.name
        if params is None:
            params = self.params
        if root_dir is None:
            root_dir = self.root_dir

        # Clone this VM using the new params
        vm = self.clone(name, params, root_dir, copy_state=True)

        virt_install_binary = utils_misc.get_path(root_dir, params.get("virt_install_binary", "virt-install"))

        help_text = utils.system_output("%s --help" % virt_install_binary)

        # Find all supported machine types, so we can rule out an unsupported
        # machine type option passed in the configuration.
        hvm_or_pv = params.get("hvm_or_pv", "hvm")
        # default to 'uname -m' output
        arch_name = params.get("vm_arch_name", utils.get_current_kernel_arch())
        capabs = libvirt_xml.LibvirtXML()
        support_machine_type = capabs.os_arch_machine_map[hvm_or_pv][arch_name]
        logging.debug("Machine types supported for %s\%s: %s" % (hvm_or_pv, arch_name, support_machine_type))

        # Start constructing the qemu command
        virt_install_cmd = ""
        # Set the X11 display parameter if requested
        if params.get("x11_display"):
            virt_install_cmd += "DISPLAY=%s " % params.get("x11_display")
        # Add the qemu binary
        virt_install_cmd += virt_install_binary

        # set connect uri
        virt_install_cmd += add_connect_uri(help_text, self.connect_uri)

        # hvm or pv specificed by libvirt switch (pv used  by Xen only)
        if hvm_or_pv:
            virt_install_cmd += add_hvm_or_pv(help_text, hvm_or_pv)

        # Add the VM's name
        virt_install_cmd += add_name(help_text, name)

        machine_type = params.get("machine_type")
        if machine_type:
            if machine_type in support_machine_type:
                virt_install_cmd += add_machine_type(help_text, machine_type)
            else:
                raise error.TestNAError("Unsupported machine type %s." % (machine_type))

        mem = params.get("mem")
        if mem:
            virt_install_cmd += add_mem(help_text, mem)

        # TODO: should we do the check before we call ? negative case ?
        check_cpu = params.get("use_check_cpu")
        if check_cpu:
            virt_install_cmd += add_check_cpu(help_text)

        smp = params.get("smp")
        if smp:
            virt_install_cmd += add_smp(help_text, smp)

        # TODO: directory location for vmlinuz/kernel for cdrom install ?
        location = None
        if params.get("medium") == "url":
            location = params.get("url")

        elif params.get("medium") == "kernel_initrd":
            # directory location of kernel/initrd pair (directory layout must
            # be in format libvirt will recognize)
            location = params.get("image_dir")

        elif params.get("medium") == "nfs":
            location = "nfs:%s:%s" % (params.get("nfs_server"), params.get("nfs_dir"))

        elif params.get("medium") == "cdrom":
            if params.get("use_libvirt_cdrom_switch") == "yes":
                virt_install_cmd += add_cdrom(help_text, params.get("cdrom_cd1"))
            elif params.get("unattended_delivery_method") == "integrated":
                virt_install_cmd += add_cdrom(
                    help_text, os.path.join(data_dir.get_data_dir(), params.get("cdrom_unattended"))
                )
            else:
                location = params.get("image_dir")
                kernel_dir = os.path.dirname(params.get("kernel"))
                kernel_parent_dir = os.path.dirname(kernel_dir)
                pxeboot_link = os.path.join(kernel_parent_dir, "pxeboot")
                if os.path.islink(pxeboot_link):
                    os.unlink(pxeboot_link)
                if os.path.isdir(pxeboot_link):
                    logging.info("Removed old %s leftover directory", pxeboot_link)
                    shutil.rmtree(pxeboot_link)
                os.symlink(kernel_dir, pxeboot_link)

        elif params.get("medium") == "import":
            virt_install_cmd += add_import(help_text)

        if location:
            virt_install_cmd += add_location(help_text, location)

        if params.get("display") == "vnc":
            if params.get("vnc_autoport") == "yes":
                vm.vnc_autoport = True
            else:
                vm.vnc_autoport = False
            if not vm.vnc_autoport and params.get("vnc_port"):
                vm.vnc_port = int(params.get("vnc_port"))
            virt_install_cmd += add_vnc(help_text, vm.vnc_port)
            if params.get("vnclisten"):
                vm.vnclisten = params.get("vnclisten")
            virt_install_cmd += add_vnclisten(help_text, vm.vnclisten)
        elif params.get("display") == "sdl":
            virt_install_cmd += add_sdl(help_text)
        elif params.get("display") == "nographic":
            virt_install_cmd += add_nographic(help_text)

        video_device = params.get("video_device")
        if video_device:
            virt_install_cmd += add_video(help_text, video_device)

        sound_device = params.get("sound_device")
        if sound_device:
            virt_install_cmd += add_soundhw(help_text, sound_device)

        # if none is given a random UUID will be generated by libvirt
        if params.get("uuid"):
            virt_install_cmd += add_uuid(help_text, params.get("uuid"))

        # selectable OS type
        if params.get("use_os_type") == "yes":
            virt_install_cmd += add_os_type(help_text, params.get("os_type"))

        # selectable OS variant
        if params.get("use_os_variant") == "yes":
            virt_install_cmd += add_os_variant(help_text, params.get("os_variant"))

        # Add serial console
        virt_install_cmd += add_serial(help_text, self.get_serial_console_filename())

        # If the PCI assignment step went OK, add each one of the PCI assigned
        # devices to the command line.
        if self.pci_devices:
            for pci_id in self.pci_devices:
                virt_install_cmd += add_pcidevice(help_text, pci_id)

        for image_name in params.objects("images"):
            image_params = params.object_params(image_name)
            filename = storage.get_image_filename(image_params, data_dir.get_data_dir())
            if image_params.get("use_storage_pool") == "yes":
                filename = None
                virt_install_cmd += add_drive(
                    help_text,
                    filename,
                    image_params.get("image_pool"),
                    image_params.get("image_vol"),
                    image_params.get("image_device"),
                    image_params.get("image_bus"),
                    image_params.get("image_perms"),
                    image_params.get("image_size"),
                    image_params.get("drive_sparse"),
                    image_params.get("drive_cache"),
                    image_params.get("image_format"),
                )

            if image_params.get("boot_drive") == "no":
                continue
            if filename:
                virt_install_cmd += add_drive(
                    help_text,
                    filename,
                    None,
                    None,
                    None,
                    image_params.get("drive_format"),
                    None,
                    image_params.get("image_size"),
                    image_params.get("drive_sparse"),
                    image_params.get("drive_cache"),
                    image_params.get("image_format"),
                )

        if params.get("unattended_delivery_method") != "integrated" and not (
            self.driver_type == "xen" and params.get("hvm_or_pv") == "pv"
        ):
            for cdrom in params.objects("cdroms"):
                cdrom_params = params.object_params(cdrom)
                iso = cdrom_params.get("cdrom")
                if params.get("use_libvirt_cdrom_switch") == "yes":
                    # we don't want to skip the winutils iso
                    if not cdrom == "winutils":
                        logging.debug("Using --cdrom instead of --disk for install")
                        logging.debug("Skipping CDROM:%s:%s", cdrom, iso)
                        continue
                if params.get("medium") == "cdrom_no_kernel_initrd":
                    if iso == params.get("cdrom_cd1"):
                        logging.debug("Using cdrom or url for install")
                        logging.debug("Skipping CDROM: %s", iso)
                        continue

                if iso:
                    virt_install_cmd += add_drive(
                        help_text,
                        utils_misc.get_path(root_dir, iso),
                        image_params.get("iso_image_pool"),
                        image_params.get("iso_image_vol"),
                        "cdrom",
                        None,
                        None,
                        None,
                        None,
                        None,
                        None,
                    )

        # We may want to add {floppy_otps} parameter for -fda
        # {fat:floppy:}/path/. However vvfat is not usually recommended.
        # Only support to add the main floppy if you want to add the second
        # one please modify this part.
        floppy = params.get("floppy_name")
        if floppy:
            floppy = utils_misc.get_path(data_dir.get_data_dir(), floppy)
            virt_install_cmd += add_drive(help_text, floppy, None, None, "floppy", None, None, None, None, None, None)

        # setup networking parameters
        for nic in vm.virtnet:
            # make_create_command can be called w/o vm.create()
            nic = vm.add_nic(**dict(nic))
            logging.debug("make_create_command() setting up command for" " nic: %s" % str(nic))
            virt_install_cmd += add_nic(help_text, nic)

        if params.get("use_no_reboot") == "yes":
            virt_install_cmd += " --noreboot"

        if params.get("use_autostart") == "yes":
            virt_install_cmd += " --autostart"

        if params.get("virt_install_debug") == "yes":
            virt_install_cmd += " --debug"

        # bz still open, not fully functional yet
        if params.get("use_virt_install_wait") == "yes":
            virt_install_cmd += " --wait %s" % params.get("virt_install_wait_time")

        kernel_params = params.get("kernel_params")
        if kernel_params:
            virt_install_cmd += " --extra-args '%s'" % kernel_params

        virt_install_cmd += " --noautoconsole"

        return virt_install_cmd
Esempio n. 28
0
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = utils_misc.get_path(test.bindir,
                                      params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
                                 utils_misc.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))
    inactivity_treshold = float(params.get("inactivity_treshold", 1800))
    inactivity_watcher = params.get("inactivity_watcher", "log")

    cache = {}
    counter = {}
    inactivity = {}

    while True:
        for vm in env.get_all_vms():
            if vm not in counter.keys():
                counter[vm] = 0
            if vm not in inactivity.keys():
                inactivity[vm] = time.time()
            if not vm.is_alive():
                continue
            try:
                vm.screendump(filename=temp_filename, debug=False)
            except qemu_monitor.MonitorError, e:
                logging.warn(e)
                continue
            except AttributeError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(test.debugdir,
                                          "screendumps_%s" % vm.name)
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            counter[vm] += 1
            screendump_filename = os.path.join(screendump_dir, "%04d.jpg" %
                                               counter[vm])
            image_hash = utils.hash_file(temp_filename)
            if image_hash in cache:
                time_inactive = time.time() - inactivity[vm]
                if time_inactive > inactivity_treshold:
                    msg = ("%s screen is inactive for more than %d s (%d min)" %
                           (vm.name, time_inactive, time_inactive/60))
                    if inactivity_watcher == "error":
                        try:
                            raise virt_vm.VMScreenInactiveError(vm,
                                                                time_inactive)
                        except virt_vm.VMScreenInactiveError:
                            logging.error(msg)
                            # Let's reset the counter
                            inactivity[vm] = time.time()
                            test.background_errors.put(sys.exc_info())
                    elif inactivity_watcher == 'log':
                        logging.debug(msg)
                try:
                    os.link(cache[image_hash], screendump_filename)
                except OSError:
                    pass
            else:
                inactivity[vm] = time.time()
                try:
                    try:
                        image = PIL.Image.open(temp_filename)
                        image.save(screendump_filename, format="JPEG",
                                   quality=quality)
                        cache[image_hash] = screendump_filename
                    except IOError, error_detail:
                        logging.warning("VM '%s' failed to produce a "
                                        "screendump: %s", vm.name, error_detail)
                        # Decrement the counter as we in fact failed to
                        # produce a converted screendump
                        counter[vm] -= 1
                except NameError:
                    pass
            os.unlink(temp_filename)
Esempio n. 29
0
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = utils_misc.get_path(test.bindir,
                                       params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(
        temp_dir, "scrdump-%s.ppm" % utils_misc.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))
    inactivity_treshold = float(params.get("inactivity_treshold", 1800))
    inactivity_watcher = params.get("inactivity_watcher", "log")

    cache = {}
    counter = {}
    inactivity = {}

    while True:
        for vm in env.get_all_vms():
            if vm.instance not in counter.keys():
                counter[vm.instance] = 0
            if vm.instance not in inactivity.keys():
                inactivity[vm.instance] = time.time()
            if not vm.is_alive():
                continue
            vm_pid = vm.get_pid()
            try:
                vm.screendump(filename=temp_filename, debug=False)
            except qemu_monitor.MonitorError, e:
                logging.warn(e)
                continue
            except AttributeError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(
                test.debugdir, "screendumps_%s_%s" % (vm.name, vm_pid))
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            counter[vm.instance] += 1
            screendump_filename = os.path.join(
                screendump_dir, "%04d.jpg" % counter[vm.instance])
            vm.verify_bsod(screendump_filename)
            image_hash = utils.hash_file(temp_filename)
            if image_hash in cache:
                time_inactive = time.time() - inactivity[vm.instance]
                if time_inactive > inactivity_treshold:
                    msg = (
                        "%s screen is inactive for more than %d s (%d min)" %
                        (vm.name, time_inactive, time_inactive / 60))
                    if inactivity_watcher == "error":
                        try:
                            raise virt_vm.VMScreenInactiveError(
                                vm, time_inactive)
                        except virt_vm.VMScreenInactiveError:
                            logging.error(msg)
                            # Let's reset the counter
                            inactivity[vm.instance] = time.time()
                            test.background_errors.put(sys.exc_info())
                    elif inactivity_watcher == 'log':
                        logging.debug(msg)
                try:
                    os.link(cache[image_hash], screendump_filename)
                except OSError:
                    pass
            else:
                inactivity[vm.instance] = time.time()
                try:
                    try:
                        image = PIL.Image.open(temp_filename)
                        image.save(screendump_filename,
                                   format="JPEG",
                                   quality=quality)
                        cache[image_hash] = screendump_filename
                    except IOError, error_detail:
                        logging.warning(
                            "VM '%s' failed to produce a "
                            "screendump: %s", vm.name, error_detail)
                        # Decrement the counter as we in fact failed to
                        # produce a converted screendump
                        counter[vm.instance] -= 1
                except NameError:
                    pass
            os.unlink(temp_filename)
Esempio n. 30
0
def get_image_filename_filesytem(params, root_dir):
    """
    Generate an image path from params and root_dir.

    :param params: Dictionary containing the test parameters.
    :param root_dir: Base directory for relative filenames.

    :note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    :raise VMDeviceError: When no matching disk found (in indirect method).
    """
    def sort_cmp(first, second):
        """
        This function used for sort to suit for this test, first sort by len
        then by value.
        """
        first_contains_digit = re.findall(r'[vhs]d[a-z]*[\d]+', first)
        second_contains_digit = re.findall(r'[vhs]d[a-z]*[\d]+', second)

        if not first_contains_digit and not second_contains_digit:
            if len(first) > len(second):
                return 1
            elif len(first) < len(second):
                return -1
        if len(first) == len(second):
            if first_contains_digit and second_contains_digit:
                return cmp(first, second)
            elif first_contains_digit:
                return -1
            elif second_contains_digit:
                return 1
        return cmp(first, second)

    image_name = params.get("image_name", "image")
    indirect_image_select = params.get("indirect_image_select")
    if indirect_image_select:
        re_name = image_name
        indirect_image_select = int(indirect_image_select)
        matching_images = utils.system_output("ls -1d %s" % re_name)
        matching_images = sorted(matching_images.split('\n'), cmp=sort_cmp)
        if matching_images[-1] == '':
            matching_images = matching_images[:-1]
        try:
            image_name = matching_images[indirect_image_select]
        except IndexError:
            raise virt_vm.VMDeviceError("No matching disk found for "
                                        "name = '%s', matching = '%s' and "
                                        "selector = '%s'" %
                                        (re_name, matching_images,
                                         indirect_image_select))
        for protected in params.get('indirect_image_blacklist', '').split(' '):
            match_image = re.match(protected, image_name)
            if match_image and match_image.group(0) == image_name:
                # We just need raise an error if it is totally match, such as
                # sda sda1 and so on, but sdaa should not raise an error.
                raise virt_vm.VMDeviceError("Matching disk is in blacklist. "
                                            "name = '%s', matching = '%s' and "
                                            "selector = '%s'" %
                                            (re_name, matching_images,
                                             indirect_image_select))

    image_format = params.get("image_format", "qcow2")
    if params.get("image_raw_device") == "yes":
        return image_name
    if image_format:
        image_filename = "%s.%s" % (image_name, image_format)
    else:
        image_filename = image_name

    image_filename = utils_misc.get_path(root_dir, image_filename)
    return image_filename
Esempio n. 31
0
    def make_create_command(self, name=None, params=None, root_dir=None):
        """
        Generate a libvirt command line. All parameters are optional. If a
        parameter is not supplied, the corresponding value stored in the
        class attributes is used.

        @param name: The name of the object
        @param params: A dict containing VM params
        @param root_dir: Base directory for relative filenames

        @note: The params dict should contain:
               mem -- memory size in MBs
               cdrom -- ISO filename to use with the qemu -cdrom parameter
               extra_params -- a string to append to the qemu command
               shell_port -- port of the remote shell daemon on the guest
               (SSH, Telnet or the home-made Remote Shell Server)
               shell_client -- client program to use for connecting to the
               remote shell daemon on the guest (ssh, telnet or nc)
               x11_display -- if specified, the DISPLAY environment variable
               will be be set to this value for the qemu process (useful for
               SDL rendering)
               images -- a list of image object names, separated by spaces
               nics -- a list of NIC object names, separated by spaces

               For each image in images:
               drive_format -- string to pass as 'if' parameter for this
               image (e.g. ide, scsi)
               image_snapshot -- if yes, pass 'snapshot=on' to qemu for
               this image
               image_boot -- if yes, pass 'boot=on' to qemu for this image
               In addition, all parameters required by get_image_filename.

               For each NIC in nics:
               nic_model -- string to pass as 'model' parameter for this
               NIC (e.g. e1000)
        """
        # helper function for command line option wrappers
        def has_option(help, option):
            return bool(re.search(r"--%s" % option, help, re.MULTILINE))

        # Wrappers for all supported libvirt command line parameters.
        # This is meant to allow support for multiple libvirt versions.
        # Each of these functions receives the output of 'libvirt --help' as a
        # parameter, and should add the requested command line option
        # accordingly.

        def add_name(help, name):
            return " --name '%s'" % name

        def add_machine_type(help, machine_type):
            if has_option(help, "machine"):
                return " --machine %s" % machine_type
            else:
                return ""

        def add_hvm_or_pv(help, hvm_or_pv):
            if hvm_or_pv == "hvm":
                return " --hvm --accelerate"
            elif hvm_or_pv == "pv":
                return " --paravirt"
            else:
                logging.warning("Unknown virt type hvm_or_pv, using default.")
                return ""

        def add_mem(help, mem):
            return " --ram=%s" % mem

        def add_check_cpu(help):
            if has_option(help, "check-cpu"):
                return " --check-cpu"
            else:
                return ""

        def add_smp(help, smp):
            return " --vcpu=%s" % smp

        def add_location(help, location):
            if has_option(help, "location"):
                return " --location %s" % location
            else:
                return ""

        def add_cdrom(help, filename, index=None):
            if has_option(help, "cdrom"):
                return " --cdrom %s" % filename
            else:
                return ""

        def add_pxe(help):
            if has_option(help, "pxe"):
                return " --pxe"
            else:
                return ""

        def add_import(help):
            if has_option(help, "import"):
                return " --import"
            else:
                return ""

        def add_drive(help, filename, pool=None, vol=None, device=None,
                      bus=None, perms=None, size=None, sparse=False,
                      cache=None, format=None):
            cmd = " --disk"
            if filename:
                cmd += " path=%s" % filename
            elif pool:
                if vol:
                    cmd += " vol=%s/%s" % (pool, vol)
                else:
                    cmd += " pool=%s" % pool
            if device:
                cmd += ",device=%s" % device
            if bus:
                cmd += ",bus=%s" % bus
            if perms:
                cmd += ",%s" % perms
            if size:
                cmd += ",size=%s" % size.rstrip("Gg")
            if sparse:
                cmd += ",sparse=false"
            if format:
                cmd += ",format=%s" % format
            if cache:
                cmd += ",cache=%s" % cache
            return cmd

        def add_floppy(help, filename):
            return " --disk path=%s,device=floppy,ro" % filename

        def add_vnc(help, vnc_port=None):
            if vnc_port:
                return " --vnc --vncport=%d" % (vnc_port)
            else:
                return " --vnc"

        def add_vnclisten(help, vnclisten):
            if has_option(help, "vnclisten"):
                return " --vnclisten=%s" % (vnclisten)
            else:
                return ""

        def add_sdl(help):
            if has_option(help, "sdl"):
                return " --sdl"
            else:
                return ""

        def add_nographic(help):
            return " --nographics"

        def add_video(help, video_device):
            if has_option(help, "video"):
                return " --video=%s" % (video_device)
            else:
                return ""

        def add_uuid(help, uuid):
            if has_option(help, "uuid"):
                return " --uuid %s" % uuid
            else:
                return ""

        def add_os_type(help, os_type):
            if has_option(help, "os-type"):
                return " --os-type %s" % os_type
            else:
                return ""

        def add_os_variant(help, os_variant):
            if has_option(help, "os-variant"):
                return " --os-variant %s" % os_variant
            else:
                return ""

        def add_pcidevice(help, pci_device):
            if has_option(help, "host-device"):
                return " --host-device %s" % pci_device
            else:
                return ""

        def add_soundhw(help, sound_device):
            if has_option(help, "soundhw"):
                return " --soundhw %s" % sound_device
            else:
                return ""

        def add_serial(help, filename):
            if has_option(help, "serial"):
                return "  --serial file,path=%s --serial pty" % filename
            else:
                self.only_pty = True
                return ""

        def add_kernel_cmdline(help, cmdline):
            return " -append %s" % cmdline

        def add_connect_uri(help, uri):
            if uri and has_option(help, "connect"):
                return " --connect=%s" % uri
            else:
                return ""

        def add_nic(help, nic_params):
            """
            Return additional command line params based on dict-like nic_params
            """
            mac = nic_params.get('mac')
            nettype = nic_params.get('nettype')
            netdst = nic_params.get('netdst')
            nic_model = nic_params.get('nic_model')
            if nettype:
                result = " --network=%s" % nettype
            else:
                result = ""
            if has_option(help, "bridge"):
                # older libvirt (--network=NATdev --bridge=bridgename --mac=mac)
                if nettype != 'user':
                    result += ':%s' % netdst
                if mac: # possible to specify --mac w/o --network
                    result += " --mac=%s" % mac
            else:
                # newer libvirt (--network=mynet,model=virtio,mac=00:11)
                if nettype != 'user':
                    result += '=%s' % netdst
                if nettype and nic_model: # only supported along with nettype
                    result += ",model=%s" % nic_model
                if nettype and mac:
                    result += ',mac=%s' % mac
                elif mac: # possible to specify --mac w/o --network
                    result += " --mac=%s" % mac
            logging.debug("vm.make_create_command.add_nic returning: %s"
                             % result)
            return result

        # End of command line option wrappers

        if name is None:
            name = self.name
        if params is None:
            params = self.params
        if root_dir is None:
            root_dir = self.root_dir

        # Clone this VM using the new params
        vm = self.clone(name, params, root_dir, copy_state=True)

        virt_install_binary = utils_misc.get_path(
            root_dir,
            params.get("virt_install_binary",
                       "virt-install"))

        help = utils.system_output("%s --help" % virt_install_binary)

        # Find all supported machine types, so we can rule out an unsupported
        # machine type option passed in the configuration.
        hvm_or_pv = params.get("hvm_or_pv", "hvm")
        # default to 'uname -m' output
        arch_name = params.get("vm_arch_name", utils.get_current_kernel_arch())
        capabs = libvirt_xml.LibvirtXML()
        support_machine_type = capabs.os_arch_machine_map[hvm_or_pv][arch_name]
        logging.debug("Machine types supported for %s\%s: %s" % (hvm_or_pv,
                                              arch_name, support_machine_type))

        # Start constructing the qemu command
        virt_install_cmd = ""
        # Set the X11 display parameter if requested
        if params.get("x11_display"):
            virt_install_cmd += "DISPLAY=%s " % params.get("x11_display")
        # Add the qemu binary
        virt_install_cmd += virt_install_binary

        # set connect uri
        virt_install_cmd += add_connect_uri(help, self.connect_uri)

        # hvm or pv specificed by libvirt switch (pv used  by Xen only)
        if hvm_or_pv:
            virt_install_cmd += add_hvm_or_pv(help, hvm_or_pv)

        # Add the VM's name
        virt_install_cmd += add_name(help, name)

        machine_type = params.get("machine_type")
        if machine_type:
            if machine_type in support_machine_type:
                virt_install_cmd += add_machine_type(help, machine_type)
            else:
                raise error.TestNAError("Unsupported machine type %s." %
                                        (machine_type))

        mem = params.get("mem")
        if mem:
            virt_install_cmd += add_mem(help, mem)

        # TODO: should we do the check before we call ? negative case ?
        check_cpu = params.get("use_check_cpu")
        if check_cpu:
            virt_install_cmd += add_check_cpu(help)

        smp = params.get("smp")
        if smp:
            virt_install_cmd += add_smp(help, smp)

        # TODO: directory location for vmlinuz/kernel for cdrom install ?
        location = None
        if params.get("medium") == 'url':
            location = params.get('url')

        elif params.get("medium") == 'kernel_initrd':
            # directory location of kernel/initrd pair (directory layout must
            # be in format libvirt will recognize)
            location = params.get("image_dir")

        elif params.get("medium") == 'nfs':
            location = "nfs:%s:%s" % (params.get("nfs_server"),
                                      params.get("nfs_dir"))

        elif params.get("medium") == 'cdrom':
            if params.get("use_libvirt_cdrom_switch") == 'yes':
                virt_install_cmd += add_cdrom(help, params.get("cdrom_cd1"))
            elif params.get("unattended_delivery_method") == "integrated":
                virt_install_cmd += add_cdrom(help,
                                              params.get("cdrom_unattended"))
            else:
                location = params.get("image_dir")
                kernel_dir = os.path.dirname(params.get("kernel"))
                kernel_parent_dir = os.path.dirname(kernel_dir)
                pxeboot_link = os.path.join(kernel_parent_dir, "pxeboot")
                if os.path.islink(pxeboot_link):
                    os.unlink(pxeboot_link)
                if os.path.isdir(pxeboot_link):
                    logging.info("Removed old %s leftover directory",
                                 pxeboot_link)
                    shutil.rmtree(pxeboot_link)
                os.symlink(kernel_dir, pxeboot_link)

        elif params.get("medium") == "import":
            virt_install_cmd += add_import(help)

        if location:
            virt_install_cmd += add_location(help, location)

        if params.get("display") == "vnc":
            if params.get("vnc_autoport") == "yes":
                vm.vnc_autoport = True
            else:
                vm.vnc_autoport = False
            if not vm.vnc_autoport and params.get("vnc_port"):
                vm.vnc_port = int(params.get("vnc_port"))
            virt_install_cmd += add_vnc(help, vm.vnc_port)
            if params.get("vnclisten"):
                vm.vnclisten = params.get("vnclisten")
            virt_install_cmd += add_vnclisten(help, vm.vnclisten)
        elif params.get("display") == "sdl":
            virt_install_cmd += add_sdl(help)
        elif params.get("display") == "nographic":
            virt_install_cmd += add_nographic(help)

        video_device = params.get("video_device")
        if video_device:
            virt_install_cmd += add_video(help, video_device)

        sound_device = params.get("sound_device")
        if sound_device:
            virt_install_cmd += add_soundhw(help, sound_device)

        # if none is given a random UUID will be generated by libvirt
        if params.get("uuid"):
            virt_install_cmd += add_uuid(help, params.get("uuid"))

        # selectable OS type
        if params.get("use_os_type") == "yes":
            virt_install_cmd += add_os_type(help, params.get("os_type"))

        # selectable OS variant
        if params.get("use_os_variant") == "yes":
            virt_install_cmd += add_os_variant(help, params.get("os_variant"))

        # Add serial console
        virt_install_cmd += add_serial(help, self.get_serial_console_filename())

        # If the PCI assignment step went OK, add each one of the PCI assigned
        # devices to the command line.
        if self.pci_devices:
            for pci_id in self.pci_devices:
                virt_install_cmd += add_pcidevice(help, pci_id)

        for image_name in params.objects("images"):
            image_params = params.object_params(image_name)
            filename = storage.get_image_filename(image_params,
                                                  data_dir.get_data_dir())
            if image_params.get("use_storage_pool") == "yes":
                filename = None
                virt_install_cmd += add_drive(help,
                                  filename,
                                  image_params.get("image_pool"),
                                  image_params.get("image_vol"),
                                  image_params.get("image_device"),
                                  image_params.get("image_bus"),
                                  image_params.get("image_perms"),
                                  image_params.get("image_size"),
                                  image_params.get("drive_sparse"),
                                  image_params.get("drive_cache"),
                                  image_params.get("image_format"))

            if image_params.get("boot_drive") == "no":
                continue
            if filename:
                virt_install_cmd += add_drive(help,
                                    filename,
                                    None,
                                    None,
                                    None,
                                    image_params.get("drive_format"),
                                    None,
                                    image_params.get("image_size"),
                                    image_params.get("drive_sparse"),
                                    image_params.get("drive_cache"),
                                    image_params.get("image_format"))

        if (params.get('unattended_delivery_method') != 'integrated' and
            not (self.driver_type == 'xen' and params.get('hvm_or_pv') == 'pv')):
            for cdrom in params.objects("cdroms"):
                cdrom_params = params.object_params(cdrom)
                iso = cdrom_params.get("cdrom")
                if params.get("use_libvirt_cdrom_switch") == 'yes':
                    # we don't want to skip the winutils iso
                    if not cdrom == 'winutils':
                        logging.debug("Using --cdrom instead of --disk for install")
                        logging.debug("Skipping CDROM:%s:%s", cdrom, iso)
                        continue
                if params.get("medium") == 'cdrom_no_kernel_initrd':
                    if iso == params.get("cdrom_cd1"):
                        logging.debug("Using cdrom or url for install")
                        logging.debug("Skipping CDROM: %s", iso)
                        continue

                if iso:
                    virt_install_cmd += add_drive(help,
                                      utils_misc.get_path(root_dir, iso),
                                      image_params.get("iso_image_pool"),
                                      image_params.get("iso_image_vol"),
                                      'cdrom',
                                      None,
                                      None,
                                      None,
                                      None,
                                      None,
                                      None)

        # We may want to add {floppy_otps} parameter for -fda
        # {fat:floppy:}/path/. However vvfat is not usually recommended.
        # Only support to add the main floppy if you want to add the second
        # one please modify this part.
        floppy = params.get("floppy_name")
        if floppy:
            floppy = utils_misc.get_path(data_dir.get_data_dir(), floppy)
            virt_install_cmd += add_drive(help, floppy,
                              None,
                              None,
                              'floppy',
                              None,
                              None,
                              None,
                              None,
                              None,
                              None)

        # setup networking parameters
        for nic in vm.virtnet:
            # make_create_command can be called w/o vm.create()
            nic = vm.add_nic(**dict(nic))
            logging.debug("make_create_command() setting up command for"
                          " nic: %s" % str(nic))
            virt_install_cmd += add_nic(help,nic)

        if params.get("use_no_reboot") == "yes":
            virt_install_cmd += " --noreboot"

        if params.get("use_autostart") == "yes":
            virt_install_cmd += " --autostart"

        if params.get("virt_install_debug") == "yes":
            virt_install_cmd += " --debug"

        # bz still open, not fully functional yet
        if params.get("use_virt_install_wait") == "yes":
            virt_install_cmd += (" --wait %s" %
                                 params.get("virt_install_wait_time"))

        kernel_params = params.get("kernel_params")
        if kernel_params:
            virt_install_cmd += " --extra-args '%s'" % kernel_params

        virt_install_cmd += " --noautoconsole"

        return virt_install_cmd
Esempio n. 32
0
    def create(self, name=None, params=None, root_dir=None, timeout=5.0,
               migration_mode=None, mac_source=None):
        """
        Start the VM by running a qemu command.
        All parameters are optional. If name, params or root_dir are not
        supplied, the respective values stored as class attributes are used.

        @param name: The name of the object
        @param params: A dict containing VM params
        @param root_dir: Base directory for relative filenames
        @param migration_mode: If supplied, start VM for incoming migration
                using this protocol (either 'tcp', 'unix' or 'exec')
        @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."'
                (e.g. 'gzip -c -d filename') if migration_mode is 'exec'
        @param mac_source: A VM object from which to copy MAC addresses. If not
                specified, new addresses will be generated.

        @raise VMCreateError: If qemu terminates unexpectedly
        @raise VMKVMInitError: If KVM initialization fails
        @raise VMHugePageError: If hugepage initialization fails
        @raise VMImageMissingError: If a CD image is missing
        @raise VMHashMismatchError: If a CD image hash has doesn't match the
                expected hash
        @raise VMBadPATypeError: If an unsupported PCI assignment type is
                requested
        @raise VMPAError: If no PCI assignable devices could be assigned
        """
        error.context("creating '%s'" % self.name)
        self.destroy(free_mac_addresses=False)

        if name is not None:
            self.name = name
        if params is not None:
            self.params = params
        if root_dir is not None:
            self.root_dir = root_dir
        name = self.name
        params = self.params
        root_dir = self.root_dir

        # Verify the md5sum of the ISO images
        for cdrom in params.objects("cdroms"):
            if params.get("medium") == "import":
                break
            cdrom_params = params.object_params(cdrom)
            iso = cdrom_params.get("cdrom")
            if ((self.driver_type == 'xen') and
                (params.get('hvm_or_pv') == 'pv') and
                (os.path.basename(iso) == 'ks.iso')):
                continue
            if iso:
                iso = utils_misc.get_path(data_dir.get_data_dir(), iso)
                if not os.path.exists(iso):
                    raise virt_vm.VMImageMissingError(iso)
                compare = False
                if cdrom_params.get("md5sum_1m"):
                    logging.debug("Comparing expected MD5 sum with MD5 sum of "
                                  "first MB of ISO file...")
                    actual_hash = utils.hash_file(iso, 1048576, method="md5")
                    expected_hash = cdrom_params.get("md5sum_1m")
                    compare = True
                elif cdrom_params.get("md5sum"):
                    logging.debug("Comparing expected MD5 sum with MD5 sum of "
                                  "ISO file...")
                    actual_hash = utils.hash_file(iso, method="md5")
                    expected_hash = cdrom_params.get("md5sum")
                    compare = True
                elif cdrom_params.get("sha1sum"):
                    logging.debug("Comparing expected SHA1 sum with SHA1 sum "
                                  "of ISO file...")
                    actual_hash = utils.hash_file(iso, method="sha1")
                    expected_hash = cdrom_params.get("sha1sum")
                    compare = True
                if compare:
                    if actual_hash == expected_hash:
                        logging.debug("Hashes match")
                    else:
                        raise virt_vm.VMHashMismatchError(actual_hash,
                                                          expected_hash)

        # Make sure the following code is not executed by more than one thread
        # at the same time
        lockfile = open("/tmp/libvirt-autotest-vm-create.lock", "w+")
        fcntl.lockf(lockfile, fcntl.LOCK_EX)

        try:
            # Handle port redirections
            redir_names = params.objects("redirs")
            host_ports = utils_misc.find_free_ports(5000, 6000, len(redir_names))
            self.redirs = {}
            for i in range(len(redir_names)):
                redir_params = params.object_params(redir_names[i])
                guest_port = int(redir_params.get("guest_port"))
                self.redirs[guest_port] = host_ports[i]

            # Find available PCI devices
            self.pci_devices = []
            for device in params.objects("pci_devices"):
                self.pci_devices.append(device)

            # Find available VNC port, if needed
            if params.get("display") == "vnc":
                if params.get("vnc_autoport") == "yes":
                    self.vnc_port = None
                    self.vnc_autoport = True
                else:
                    self.vnc_port = utils_misc.find_free_port(5900, 6100)
                    self.vnc_autoport = False

            # Find available spice port, if needed
            if params.get("spice"):
                self.spice_port = utils_misc.find_free_port(8000, 8100)

            # Find random UUID if specified 'uuid = random' in config file
            if params.get("uuid") == "random":
                f = open("/proc/sys/kernel/random/uuid")
                self.uuid = f.read().strip()
                f.close()

            # Generate or copy MAC addresses for all NICs
            for nic in self.virtnet:
                nic_params = dict(nic)
                if mac_source:
                    # Will raise exception if source doesn't
                    # have cooresponding nic
                    logging.debug("Copying mac for nic %s from VM %s"
                                    % (nic.nic_name, mac_source.nam))
                    nic_params['mac'] = mac_source.get_mac_address(nic.nic_name)
                # make_create_command() calls vm.add_nic (i.e. on a copy)
                nic = self.add_nic(**nic_params)
                logging.debug('VM.create activating nic %s' % nic)
                self.activate_nic(nic.nic_name)

            # Make qemu command
            install_command = self.make_create_command()

            logging.info("Running libvirt command (reformatted):")
            for item in install_command.replace(" -", " \n    -").splitlines():
                logging.info("%s", item)
            utils.run(install_command, verbose=False)
            # Wait for the domain to be created
            utils_misc.wait_for(func=self.is_alive, timeout=60,
                                text=("waiting for domain %s to start" %
                                      self.name))
            self.uuid = virsh.domuuid(self.name, uri=self.connect_uri)

            # Establish a session with the serial console
            if self.only_pty == True:
                self.serial_console = aexpect.ShellSession(
                    "virsh console %s" % self.name,
                    auto_close=False,
                    output_func=utils_misc.log_line,
                    output_params=("serial-%s.log" % name,))
            else:
                self.serial_console = aexpect.ShellSession(
                    "tail -f %s" % self.get_serial_console_filename(),
                    auto_close=False,
                    output_func=utils_misc.log_line,
                    output_params=("serial-%s.log" % name,))

        finally:
            fcntl.lockf(lockfile, fcntl.LOCK_UN)
            lockfile.close()
Esempio n. 33
0
    def check_disk_params(self, params):
        """
        Check gathered info from qtree/block with params
        @param params: autotest params
        @return: number of errors
        """
        err = 0
        disks = {}
        for disk in self.disks:
            if isinstance(disk, QtreeDisk):
                disks[disk.get_qname()] = disk.get_params().copy()
        # We don't have the params name so we need to map file_names instead
        qname = None
        for name in params.objects('cdroms'):
            image_name = utils_misc.get_path(data_dir.get_data_dir(),
                                params.object_params(name).get('cdrom', ''))
            image_name = os.path.realpath(image_name)
            for (qname, disk) in disks.iteritems():
                if disk.get('image_name') == image_name:
                    break
            else:
                continue    # Not /proc/scsi cdrom device
            disks.pop(qname)
        for name in params.objects('images'):
            current = None
            image_params = params.object_params(name)

            base_dir = image_params.get("images_base_dir",
                                        data_dir.get_data_dir())

            image_name = os.path.realpath(
                        storage.get_image_filename(image_params,
                                                   base_dir))
            for (qname, disk) in disks.iteritems():
                if disk.get('image_name') == image_name:
                    current = disk
                    # autotest params might use relative path
                    current['image_name'] = image_params.get('image_name')
                    break
            if not current:
                logging.error("Disk %s is not in qtree but is in params.", name)
                err += 1
                continue
            for prop in current.iterkeys():
                handled = False
                if prop == "drive_format":
                    # HOOK: ahci disk is ide-* disk
                    if (image_params.get(prop) == 'ahci' and
                                current.get(prop).startswith('ide-')):
                        handled = True
                    # HOOK: params to qemu translation
                    elif current.get(prop).startswith(image_params.get(prop)):
                        handled = True
                elif (image_params.get(prop) and
                        image_params.get(prop) == current.get(prop)):
                    handled = True
                if not handled:
                    logging.error("Disk %s property %s=%s doesn't match params"
                                  " %s", qname, prop, current.get(prop),
                                  image_params.get(prop))
                    err += 1
            disks.pop(qname)
        if disks:
            logging.error('Some disks were in qtree but not in autotest params'
                          ': %s', disks)
            err += 1
        return err
Esempio n. 34
0
def preprocess(test, params, env):
    """
    Preprocess all VMs and images according to the instructions in params.
    Also, collect some host information, such as the KVM version.

    @param test: An Autotest test object.
    @param params: A dict containing all VM and image parameters.
    @param env: The environment (a dict-like object).
    """
    error.context("preprocessing")
    # First, let's verify if this test does require root or not. If it
    # does and the test suite is running as a regular user, we shall just
    # throw a TestNAError exception, which will skip the test.
    if params.get('requires_root', 'no') == 'yes':
        utils_test.verify_running_as_root()

    port = params.get('shell_port')
    prompt = params.get('shell_prompt')
    address = params.get('ovirt_node_address')
    username = params.get('ovirt_node_user')
    password = params.get('ovirt_node_password')

    # Start tcpdump if it isn't already running
    if "address_cache" not in env:
        env["address_cache"] = {}
    if "tcpdump" in env and not env["tcpdump"].is_alive():
        env["tcpdump"].close()
        del env["tcpdump"]
    if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
        cmd = "%s -npvi any 'dst port 68'" % utils_misc.find_command("tcpdump")
        if params.get("remote_preprocess") == "yes":
            login_cmd = ("ssh -o UserKnownHostsFile=/dev/null -o \
                         PreferredAuthentications=password -p %s %s@%s" %
                         (port, username, address))
            env["tcpdump"] = aexpect.ShellSession(
                login_cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"],))
            remote._remote_login(env["tcpdump"], username, password, prompt)
            env["tcpdump"].sendline(cmd)
        else:
            env["tcpdump"] = aexpect.Tail(
                command=cmd,
                output_func=_update_address_cache,
                output_params=(env["address_cache"],))

        if utils_misc.wait_for(lambda: not env["tcpdump"].is_alive(),
                              0.1, 0.1, 1.0):
            logging.warn("Could not start tcpdump")
            logging.warn("Status: %s" % env["tcpdump"].get_status())
            logging.warn("Output:" + utils_misc.format_str_for_message(
                env["tcpdump"].get_output()))

    # Destroy and remove VMs that are no longer needed in the environment
    requested_vms = params.objects("vms")
    for key in env.keys():
        vm = env[key]
        if not isinstance(vm, virt_vm.BaseVM):
            continue
        if not vm.name in requested_vms:
            vm.destroy()
            del env[key]

    # Get Host cpu type
    if params.get("auto_cpu_model") == "yes":
        if not env.get("cpu_model"):
            env["cpu_model"] = utils_misc.get_cpu_model()
        params["cpu_model"] = env.get("cpu_model")

    kvm_ver_cmd = params.get("kvm_ver_cmd", "")

    if kvm_ver_cmd:
        try:
            cmd_result = utils.run(kvm_ver_cmd)
            kvm_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_version = "Unknown"
    else:
        # Get the KVM kernel module version and write it as a keyval
        if os.path.exists("/dev/kvm"):
            try:
                kvm_version = open("/sys/module/kvm/version").read().strip()
            except Exception:
                kvm_version = os.uname()[2]
        else:
            logging.warning("KVM module not loaded")
            kvm_version = "Unknown"

    logging.debug("KVM version: %s" % kvm_version)
    test.write_test_keyval({"kvm_version": kvm_version})

    # Get the KVM userspace version and write it as a keyval
    kvm_userspace_ver_cmd = params.get("kvm_userspace_ver_cmd", "")

    if kvm_userspace_ver_cmd:
        try:
            cmd_result = utils.run(kvm_userspace_ver_cmd)
            kvm_userspace_version = cmd_result.stdout.strip()
        except error.CmdError:
            kvm_userspace_version = "Unknown"
    else:
        qemu_path = utils_misc.get_path(test.bindir,
                                        params.get("qemu_binary", "qemu"))
        version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
        matches = re.findall("[Vv]ersion .*?,", version_line)
        if matches:
            kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
        else:
            kvm_userspace_version = "Unknown"

    logging.debug("KVM userspace version: %s" % kvm_userspace_version)
    test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})

    if params.get("setup_hugepages") == "yes":
        h = test_setup.HugePageConfig(params)
        h.setup()
        if params.get("vm_type") == "libvirt":
            libvirt_vm.libvirtd_restart()

    if params.get("setup_thp") == "yes":
        thp = test_setup.TransparentHugePageConfig(test, params)
        thp.setup()

    # Execute any pre_commands
    if params.get("pre_command"):
        process_command(test, params, env, params.get("pre_command"),
                        int(params.get("pre_command_timeout", "600")),
                        params.get("pre_command_noncritical") == "yes")

    #Clone master image from vms.
    base_dir = data_dir.get_data_dir()
    if params.get("master_images_clone"):
        for vm_name in params.get("vms").split():
            vm = env.get_vm(vm_name)
            if vm:
                vm.destroy(free_mac_addresses=False)
                env.unregister_vm(vm_name)

            vm_params = params.object_params(vm_name)
            for image in vm_params.get("master_images_clone").split():
                image_obj = qemu_storage.QemuImg(params, base_dir, image)
                image_obj.clone_image(params, vm_name, image, base_dir)

    # Preprocess all VMs and images
    if params.get("not_preprocess","no") == "no":
        process(test, params, env, preprocess_image, preprocess_vm)

    # Start the screendump thread
    if params.get("take_regular_screendumps") == "yes":
        global _screendump_thread, _screendump_thread_termination_event
        _screendump_thread_termination_event = threading.Event()
        _screendump_thread = threading.Thread(target=_take_screendumps,
                                              args=(test, params, env))
        _screendump_thread.start()
Esempio n. 35
0
    def check_disk_params(self, params):
        """
        Check gathered info from qtree/block with params
        :param params: autotest params
        :return: number of errors
        """
        def check_drive_format(node, params):
            """ checks the drive format according to qtree info """
            expected = params.get('drive_format')
            if expected == 'scsi':
                if arch.ARCH == 'ppc64':
                    expected = 'spapr-vscsi'
                else:
                    expected = 'lsi53c895a'
            elif expected.startswith('scsi'):
                expected = params.get('scsi_hba', 'virtio-scsi-pci')
            elif expected.startswith('usb'):
                expected = 'usb-storage'
            try:
                if expected == 'virtio':
                    actual = node.qtree['type']
                else:
                    actual = node.parent.parent.qtree.get('type')
            except AttributeError:
                logging.error("Failed to check drive format, can't get parent"
                              "of:\n%s", node)
            if actual == 'virtio-scsi-device':  # new name for virtio-scsi
                actual = 'virtio-scsi-pci'
            if expected not in actual:
                return ("drive format in qemu is %s, in autotest %s"
                        % (actual, expected))

        err = 0
        disks = {}
        for disk in self.disks:
            if isinstance(disk, QtreeDisk):
                disks[disk.get_qname()] = (disk.get_params().copy(), disk)
        # We don't have the params name so we need to map file_names instead
        qname = None
        for name in params.objects('cdroms'):
            image_name = utils_misc.get_path(data_dir.get_data_dir(),
                                             params.object_params(name).get('cdrom', ''))
            image_name = os.path.realpath(image_name)
            for (qname, disk) in disks.iteritems():
                if disk[0].get('image_name') == image_name:
                    break
            else:
                continue    # Not /proc/scsi cdrom device
            disks.pop(qname)
        for name in params.objects('images'):
            current = None
            image_params = params.object_params(name)

            base_dir = image_params.get("images_base_dir",
                                        data_dir.get_data_dir())

            image_name = os.path.realpath(
                storage.get_image_filename(image_params,
                                           base_dir))
            for (qname, disk) in disks.iteritems():
                if disk[0].get('image_name') == image_name:
                    current = disk[0]
                    current_node = disk[1]
                    # autotest params might use relative path
                    current['image_name'] = image_params.get('image_name')
                    break
            if not current:
                logging.error("Disk %s is not in qtree but is in params.",
                              name)
                err += 1
                continue
            for prop in current.iterkeys():
                handled = False
                if prop == "drive_format":
                    out = check_drive_format(current_node, image_params)
                    if out:
                        logging.error("Disk %s %s", qname, out)
                        err += 1
                    handled = True
                elif (image_params.get(prop) and
                        image_params.get(prop) == current.get(prop)):
                    handled = True
                if not handled:
                    logging.error("Disk %s property %s=%s doesn't match params"
                                  " %s", qname, prop, current.get(prop),
                                  image_params.get(prop))
                    err += 1
            disks.pop(qname)
        if disks:
            logging.error('Some disks were in qtree but not in autotest params'
                          ': %s', disks)
            err += 1
        return err
Esempio n. 36
0
    def check_disk_params(self, params):
        """
        Check gathered info from qtree/block with params
        :param params: autotest params
        :return: number of errors
        """
        def check_drive_format(node, params):
            """ checks the drive format according to qtree info """
            expected = params.get('drive_format')
            if expected == 'scsi':
                if arch.ARCH == 'ppc64':
                    expected = 'spapr-vscsi'
                else:
                    expected = 'lsi53c895a'
            elif expected.startswith('scsi'):
                expected = params.get('scsi_hba', 'virtio-scsi-pci')
            elif expected.startswith('usb'):
                expected = 'usb-storage'
            try:
                if expected == 'virtio':
                    actual = node.qtree['type']
                else:
                    actual = node.parent.parent.qtree.get('type')
            except AttributeError:
                logging.error(
                    "Failed to check drive format, can't get parent"
                    "of:\n%s", node)
            if actual == 'virtio-scsi-device':  # new name for virtio-scsi
                actual = 'virtio-scsi-pci'
            if expected not in actual:
                return ("drive format in qemu is %s, in autotest %s" %
                        (actual, expected))

        err = 0
        disks = {}
        for disk in self.disks:
            if isinstance(disk, QtreeDisk):
                disks[disk.get_qname()] = (disk.get_params().copy(), disk)
        # We don't have the params name so we need to map file_names instead
        qname = None
        for name in params.objects('cdroms'):
            image_name = utils_misc.get_path(
                data_dir.get_data_dir(),
                params.object_params(name).get('cdrom', ''))
            image_name = os.path.realpath(image_name)
            for (qname, disk) in disks.iteritems():
                if disk[0].get('image_name') == image_name:
                    break
            else:
                continue  # Not /proc/scsi cdrom device
            disks.pop(qname)
        for name in params.objects('images'):
            current = None
            image_params = params.object_params(name)

            base_dir = image_params.get("images_base_dir",
                                        data_dir.get_data_dir())

            image_name = os.path.realpath(
                storage.get_image_filename(image_params, base_dir))
            for (qname, disk) in disks.iteritems():
                if disk[0].get('image_name') == image_name:
                    current = disk[0]
                    current_node = disk[1]
                    # autotest params might use relative path
                    current['image_name'] = image_params.get('image_name')
                    break
            if not current:
                logging.error("Disk %s is not in qtree but is in params.",
                              name)
                err += 1
                continue
            for prop in current.iterkeys():
                handled = False
                if prop == "drive_format":
                    out = check_drive_format(current_node, image_params)
                    if out:
                        logging.error("Disk %s %s", qname, out)
                        err += 1
                    handled = True
                elif (image_params.get(prop)
                      and image_params.get(prop) == current.get(prop)):
                    handled = True
                if not handled:
                    logging.error(
                        "Disk %s property %s=%s doesn't match params"
                        " %s", qname, prop, current.get(prop),
                        image_params.get(prop))
                    err += 1
            disks.pop(qname)
        if disks:
            logging.error(
                'Some disks were in qtree but not in autotest params'
                ': %s', disks)
            err += 1
        return err
Esempio n. 37
0
 def get_emulate_image_name(self):
     img_path = self.params.get("emulated_image")
     if img_path is None:
         img_path = self.generate_id(self.params)
     return utils_misc.get_path(self.data_dir, img_path)
Esempio n. 38
0
    def create(self, name=None, params=None, root_dir=None, timeout=5.0, migration_mode=None, mac_source=None):
        """
        Start the VM by running a qemu command.
        All parameters are optional. If name, params or root_dir are not
        supplied, the respective values stored as class attributes are used.

        @param name: The name of the object
        @param params: A dict containing VM params
        @param root_dir: Base directory for relative filenames
        @param migration_mode: If supplied, start VM for incoming migration
                using this protocol (either 'tcp', 'unix' or 'exec')
        @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."'
                (e.g. 'gzip -c -d filename') if migration_mode is 'exec'
        @param mac_source: A VM object from which to copy MAC addresses. If not
                specified, new addresses will be generated.

        @raise VMCreateError: If qemu terminates unexpectedly
        @raise VMKVMInitError: If KVM initialization fails
        @raise VMHugePageError: If hugepage initialization fails
        @raise VMImageMissingError: If a CD image is missing
        @raise VMHashMismatchError: If a CD image hash has doesn't match the
                expected hash
        @raise VMBadPATypeError: If an unsupported PCI assignment type is
                requested
        @raise VMPAError: If no PCI assignable devices could be assigned
        """
        error.context("creating '%s'" % self.name)
        self.destroy(free_mac_addresses=False)

        if name is not None:
            self.name = name
        if params is not None:
            self.params = params
        if root_dir is not None:
            self.root_dir = root_dir
        name = self.name
        params = self.params
        root_dir = self.root_dir

        # Verify the md5sum of the ISO images
        for cdrom in params.objects("cdroms"):
            if params.get("medium") == "import":
                break
            cdrom_params = params.object_params(cdrom)
            iso = cdrom_params.get("cdrom")
            if (
                (self.driver_type == "xen")
                and (params.get("hvm_or_pv") == "pv")
                and (os.path.basename(iso) == "ks.iso")
            ):
                continue
            if iso:
                iso = utils_misc.get_path(data_dir.get_data_dir(), iso)
                if not os.path.exists(iso):
                    raise virt_vm.VMImageMissingError(iso)
                compare = False
                if cdrom_params.get("md5sum_1m"):
                    logging.debug("Comparing expected MD5 sum with MD5 sum of " "first MB of ISO file...")
                    actual_hash = utils.hash_file(iso, 1048576, method="md5")
                    expected_hash = cdrom_params.get("md5sum_1m")
                    compare = True
                elif cdrom_params.get("md5sum"):
                    logging.debug("Comparing expected MD5 sum with MD5 sum of " "ISO file...")
                    actual_hash = utils.hash_file(iso, method="md5")
                    expected_hash = cdrom_params.get("md5sum")
                    compare = True
                elif cdrom_params.get("sha1sum"):
                    logging.debug("Comparing expected SHA1 sum with SHA1 sum " "of ISO file...")
                    actual_hash = utils.hash_file(iso, method="sha1")
                    expected_hash = cdrom_params.get("sha1sum")
                    compare = True
                if compare:
                    if actual_hash == expected_hash:
                        logging.debug("Hashes match")
                    else:
                        raise virt_vm.VMHashMismatchError(actual_hash, expected_hash)

        # Make sure the following code is not executed by more than one thread
        # at the same time
        lockfile = open("/tmp/libvirt-autotest-vm-create.lock", "w+")
        fcntl.lockf(lockfile, fcntl.LOCK_EX)

        try:
            # Handle port redirections
            redir_names = params.objects("redirs")
            host_ports = utils_misc.find_free_ports(5000, 6000, len(redir_names))
            self.redirs = {}
            for i in range(len(redir_names)):
                redir_params = params.object_params(redir_names[i])
                guest_port = int(redir_params.get("guest_port"))
                self.redirs[guest_port] = host_ports[i]

            # Find available PCI devices
            self.pci_devices = []
            for device in params.objects("pci_devices"):
                self.pci_devices.append(device)

            # Find available VNC port, if needed
            if params.get("display") == "vnc":
                if params.get("vnc_autoport") == "yes":
                    self.vnc_port = None
                    self.vnc_autoport = True
                else:
                    self.vnc_port = utils_misc.find_free_port(5900, 6100)
                    self.vnc_autoport = False

            # Find available spice port, if needed
            if params.get("spice"):
                self.spice_port = utils_misc.find_free_port(8000, 8100)

            # Find random UUID if specified 'uuid = random' in config file
            if params.get("uuid") == "random":
                f = open("/proc/sys/kernel/random/uuid")
                self.uuid = f.read().strip()
                f.close()

            # Generate or copy MAC addresses for all NICs
            for nic in self.virtnet:
                nic_params = dict(nic)
                if mac_source:
                    # Will raise exception if source doesn't
                    # have cooresponding nic
                    logging.debug("Copying mac for nic %s from VM %s" % (nic.nic_name, mac_source.nam))
                    nic_params["mac"] = mac_source.get_mac_address(nic.nic_name)
                # make_create_command() calls vm.add_nic (i.e. on a copy)
                nic = self.add_nic(**nic_params)
                logging.debug("VM.create activating nic %s" % nic)
                self.activate_nic(nic.nic_name)

            # Make qemu command
            install_command = self.make_create_command()

            logging.info("Running libvirt command (reformatted):")
            for item in install_command.replace(" -", " \n    -").splitlines():
                logging.info("%s", item)
            utils.run(install_command, verbose=False)
            # Wait for the domain to be created
            utils_misc.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s to start" % self.name))
            self.uuid = virsh.domuuid(self.name, uri=self.connect_uri)

            # Establish a session with the serial console
            if self.only_pty == True:
                self.serial_console = aexpect.ShellSession(
                    "virsh console %s" % self.name,
                    auto_close=False,
                    output_func=utils_misc.log_line,
                    output_params=("serial-%s.log" % name,),
                )
            else:
                self.serial_console = aexpect.ShellSession(
                    "tail -f %s" % self.get_serial_console_filename(),
                    auto_close=False,
                    output_func=utils_misc.log_line,
                    output_params=("serial-%s.log" % name,),
                )

        finally:
            fcntl.lockf(lockfile, fcntl.LOCK_UN)
            lockfile.close()
Esempio n. 39
0
            kvm_version = "Unknown"

    logging.debug("KVM version: %s" % kvm_version)
    test.write_test_keyval({"kvm_version": kvm_version})

    # Get the KVM userspace version and write it as a keyval
    kvm_userspace_ver_cmd = params.get("kvm_userspace_ver_cmd", "")

    if kvm_userspace_ver_cmd:
        try:
            cmd_result = utils.run(kvm_userspace_ver_cmd)
            kvm_userspace_version = cmd_result.stdout.strip()
        except error.CmdError, e:
            kvm_userspace_version = "Unknown"
    else:
        qemu_path = utils_misc.get_path(test.bindir, params.get("qemu_binary", "qemu"))
        version_line = commands.getoutput("%s -help | head -n 1" % qemu_path)
        matches = re.findall("[Vv]ersion .*?,", version_line)
        if matches:
            kvm_userspace_version = " ".join(matches[0].split()[1:]).strip(",")
        else:
            kvm_userspace_version = "Unknown"

    logging.debug("KVM userspace version: %s" % kvm_userspace_version)
    test.write_test_keyval({"kvm_userspace_version": kvm_userspace_version})

    if params.get("setup_hugepages") == "yes":
        h = test_setup.HugePageConfig(params)
        h.setup()
        if params.get("vm_type") == "libvirt":
            libvirt_vm.libvirtd_restart()