Signed-off-by: Lucas Meneghel Rodrigues <[email protected]>
---
 client/tests/kvm/tests/pci_hotplug.py              |   6 +-
 client/tests/kvm/tests/physical_resources_check.py |   4 +-
 client/tests/kvm/tests/qemu_img.py                 |   6 +-
 client/virt/env_process.py                         |   4 +-
 client/virt/kvm_qtree.py                           |   4 +-
 client/virt/kvm_storage.py                         |  10 +-
 client/virt/kvm_vm.py                              |   6 +-
 client/virt/libvirt_storage.py                     |   6 +-
 client/virt/libvirt_vm.py                          |   4 +-
 client/virt/storage.py                             | 345 +++++++++++++++++++++
 client/virt/virt_storage.py                        | 345 ---------------------
 client/virt/virt_test_utils.py                     |   6 +-
 12 files changed, 373 insertions(+), 373 deletions(-)
 create mode 100644 client/virt/storage.py
 delete mode 100644 client/virt/virt_storage.py

diff --git a/client/tests/kvm/tests/pci_hotplug.py 
b/client/tests/kvm/tests/pci_hotplug.py
index 725179e..a917f07 100644
--- a/client/tests/kvm/tests/pci_hotplug.py
+++ b/client/tests/kvm/tests/pci_hotplug.py
@@ -1,6 +1,6 @@
 import re
 from autotest.client.shared import error
-from autotest.client.virt import virt_utils, aexpect, virt_storage
+from autotest.client.virt import virt_utils, aexpect, storage
 
 
 def run_pci_hotplug(test, params, env):
@@ -66,7 +66,7 @@ def run_pci_hotplug(test, params, env):
             pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % tested_model
         elif test_type == "block":
             image_params = params.object_params("stg")
-            image_filename = virt_storage.get_image_filename(image_params,
+            image_filename = storage.get_image_filename(image_params,
                                                        test.bindir)
             pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" %
                            (image_filename, tested_model))
@@ -89,7 +89,7 @@ def run_pci_hotplug(test, params, env):
 
         elif test_type == "block":
             image_params = params.object_params("stg")
-            image_filename = virt_storage.get_image_filename(image_params,
+            image_filename = storage.get_image_filename(image_params,
                                                        test.bindir)
             controller_model = None
             if tested_model == "virtio":
diff --git a/client/tests/kvm/tests/physical_resources_check.py 
b/client/tests/kvm/tests/physical_resources_check.py
index 19dc0b4..b81fff5 100644
--- a/client/tests/kvm/tests/physical_resources_check.py
+++ b/client/tests/kvm/tests/physical_resources_check.py
@@ -1,6 +1,6 @@
 import re, string, logging
 from autotest.client.shared import error
-from autotest.client.virt import kvm_monitor, virt_storage
+from autotest.client.virt import kvm_monitor, storage
 
 
 def run_physical_resources_check(test, params, env):
@@ -145,7 +145,7 @@ def run_physical_resources_check(test, params, env):
     n_fail = []
 
     # We will check HDs with the image name
-    image_name = virt_storage.get_image_filename(params, test.bindir)
+    image_name = storage.get_image_filename(params, test.bindir)
 
     # Check cpu count
     logging.info("CPU count check")
diff --git a/client/tests/kvm/tests/qemu_img.py 
b/client/tests/kvm/tests/qemu_img.py
index 32c6b52..d7a6487 100644
--- a/client/tests/kvm/tests/qemu_img.py
+++ b/client/tests/kvm/tests/qemu_img.py
@@ -1,6 +1,6 @@
 import re, os, logging, commands
 from autotest.client.shared import utils, error
-from autotest.client.virt import virt_utils, env_process, virt_storage
+from autotest.client.virt import virt_utils, env_process, storage
 
 
 def run_qemu_img(test, params, env):
@@ -18,7 +18,7 @@ def run_qemu_img(test, params, env):
         raise error.TestError("Binary of 'qemu-img' not found")
     image_format = params.get("image_format")
     image_size = params.get("image_size", "10G")
-    image_name = virt_storage.get_image_filename(params, test.bindir)
+    image_name = storage.get_image_filename(params, test.bindir)
 
 
     def _check(cmd, img):
@@ -402,7 +402,7 @@ def run_qemu_img(test, params, env):
         sn_fmt = params.get("snapshot_format", "qcow2")
         sn1 = params.get("image_name_snapshot1")
         sn1 = virt_utils.get_path(test.bindir, sn1) + ".%s" % sn_fmt
-        base_img = virt_storage.get_image_filename(params, test.bindir)
+        base_img = storage.get_image_filename(params, test.bindir)
         _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format)
 
         # Create snapshot2 based on snapshot1
diff --git a/client/virt/env_process.py b/client/virt/env_process.py
index 5ed8996..c49ede6 100644
--- a/client/virt/env_process.py
+++ b/client/virt/env_process.py
@@ -2,7 +2,7 @@ import os, time, commands, re, logging, glob, threading, shutil
 from autotest.client import utils
 from autotest.client.shared import error
 import aexpect, kvm_monitor, ppm_utils, virt_test_setup, virt_vm, kvm_vm
-import libvirt_vm, virt_video_maker, virt_utils, virt_storage, kvm_storage
+import libvirt_vm, virt_video_maker, virt_utils, storage, kvm_storage
 import remote, virt_v2v, ovirt
 
 try:
@@ -29,7 +29,7 @@ def preprocess_image(test, params, image_name):
         iscsidev = kvm_storage.Iscsidev(params, test.bindir, image_name)
         params["image_name"] = iscsidev.setup()
     else:
-        image_filename = virt_storage.get_image_filename(params, test.bindir)
+        image_filename = storage.get_image_filename(params, test.bindir)
 
         create_image = False
 
diff --git a/client/virt/kvm_qtree.py b/client/virt/kvm_qtree.py
index d10d1c8..bddab28 100644
--- a/client/virt/kvm_qtree.py
+++ b/client/virt/kvm_qtree.py
@@ -5,7 +5,7 @@ Utility classes and functions to handle KVM Qtree parsing and 
verification.
 @copyright: 2012 Red Hat Inc.
 """
 import logging, os, re
-import virt_storage
+import storage
 
 OFFSET_PER_LEVEL = 2
 
@@ -473,7 +473,7 @@ class QtreeDisksContainer(object):
             current = None
             image_params = params.object_params(name)
             image_name = os.path.realpath(
-                        virt_storage.get_image_filename(image_params, 
root_dir))
+                        storage.get_image_filename(image_params, root_dir))
             for (qname, disk) in disks.iteritems():
                 if disk.get('image_name') == image_name:
                     current = disk
diff --git a/client/virt/kvm_storage.py b/client/virt/kvm_storage.py
index 918717d..72a4d78 100644
--- a/client/virt/kvm_storage.py
+++ b/client/virt/kvm_storage.py
@@ -8,10 +8,10 @@ This exports:
 import logging, os
 from autotest.client.shared import error
 from autotest.client import utils
-import virt_utils, virt_vm, virt_storage
+import virt_utils, virt_vm, storage
 
 
-class QemuImg(virt_storage.QemuImg):
+class QemuImg(storage.QemuImg):
     """
     KVM class for handling operations of disk/block images.
     """
@@ -23,7 +23,7 @@ class QemuImg(virt_storage.QemuImg):
         @param root_dir: Base directory for relative filenames.
         @param tag: Image tag defined in parameter images
         """
-        virt_storage.QemuImg.__init__(self, params, root_dir, tag)
+        storage.QemuImg.__init__(self, params, root_dir, tag)
         self.image_cmd = virt_utils.get_path(root_dir,
                                  params.get("qemu_img_binary","qemu-img"))
 
@@ -129,7 +129,7 @@ class QemuImg(virt_storage.QemuImg):
         params_convert = {"image_name": convert_image,
                           "image_format": convert_format}
 
-        convert_image_filename = 
virt_storage.get_image_filename(params_convert,
+        convert_image_filename = storage.get_image_filename(params_convert,
                                                                  root_dir)
 
         cmd = self.image_cmd
@@ -346,7 +346,7 @@ class QemuImg(virt_storage.QemuImg):
                               image_filename)
 
 
-class Iscsidev(virt_storage.Iscsidev):
+class Iscsidev(storage.Iscsidev):
     """
     Class for handle iscsi devices for VM
     """
diff --git a/client/virt/kvm_vm.py b/client/virt/kvm_vm.py
index eff1f65..9b025b0 100644
--- a/client/virt/kvm_vm.py
+++ b/client/virt/kvm_vm.py
@@ -7,7 +7,7 @@ Utility classes and functions to handle Virtual Machine 
creation using qemu.
 import time, os, logging, fcntl, re, commands
 from autotest.client.shared import error
 from autotest.client import utils
-import virt_utils, virt_vm, virt_test_setup, virt_storage, kvm_monitor, aexpect
+import virt_utils, virt_vm, virt_test_setup, storage, kvm_monitor, aexpect
 import kvm_virtio_port
 import remote
 
@@ -1046,7 +1046,7 @@ class VM(virt_vm.BaseVM):
                     virtio_scsi_pcis.append("virtio_scsi_pci%d" % i)
 
             qemu_cmd += add_drive(help,
-                    virt_storage.get_image_filename(image_params, root_dir),
+                    storage.get_image_filename(image_params, root_dir),
                     image_params.get("drive_index"),
                     image_params.get("drive_format"),
                     image_params.get("drive_cache"),
@@ -1055,7 +1055,7 @@ class VM(virt_vm.BaseVM):
                     image_params.get("drive_serial"),
                     image_params.get("image_snapshot"),
                     image_params.get("image_boot"),
-                    virt_storage.get_image_blkdebug_filename(image_params,
+                    storage.get_image_blkdebug_filename(image_params,
                                                            self.virt_dir),
                     bus,
                     port,
diff --git a/client/virt/libvirt_storage.py b/client/virt/libvirt_storage.py
index d7920eb..819e79c 100644
--- a/client/virt/libvirt_storage.py
+++ b/client/virt/libvirt_storage.py
@@ -5,10 +5,10 @@ This exports:
   - two functions for get image/blkdebug filename
   - class for image operates and basic parameters
 """
-import virt_storage
+import storage
 
 
-class QemuImg(virt_storage.QemuImg):
+class QemuImg(storage.QemuImg):
     """
     libvirt class for handling operations of disk/block images.
     """
@@ -20,7 +20,7 @@ class QemuImg(virt_storage.QemuImg):
         @param root_dir: Base directory for relative filenames.
         @param tag: Image tag defined in parameter images.
         """
-        virt_storage.QemuImg(params, root_dir, tag)
+        storage.QemuImg(params, root_dir, tag)
         # Please init image_cmd for libvirt in this class
         # self.image_cmd =
 
diff --git a/client/virt/libvirt_vm.py b/client/virt/libvirt_vm.py
index ba5feb1..9e532c7 100644
--- a/client/virt/libvirt_vm.py
+++ b/client/virt/libvirt_vm.py
@@ -8,7 +8,7 @@ import time, os, logging, fcntl, re, commands, shutil, 
urlparse, tempfile
 from autotest.client.shared import error
 from autotest.client import utils, os_dep
 from xml.dom import minidom
-import virt_utils, virt_vm, virt_storage, aexpect, remote
+import virt_utils, virt_vm, storage, aexpect, remote
 
 DEBUG = False
 try:
@@ -1207,7 +1207,7 @@ class VM(virt_vm.BaseVM):
 
         for image_name in params.objects("images"):
             image_params = params.object_params(image_name)
-            filename = virt_storage.get_image_filename(image_params, root_dir)
+            filename = storage.get_image_filename(image_params, root_dir)
             if image_params.get("use_storage_pool") == "yes":
                 filename = None
                 virt_install_cmd += add_drive(help,
diff --git a/client/virt/storage.py b/client/virt/storage.py
new file mode 100644
index 0000000..cb3482f
--- /dev/null
+++ b/client/virt/storage.py
@@ -0,0 +1,345 @@
+"""
+Classes and functions to handle storage devices.
+
+This exports:
+  - two functions for get image/blkdebug filename
+  - class for image operates and basic parameters
+"""
+import logging, os, shutil, re
+from autotest.client import utils
+from autotest.client.shared import iscsi
+import virt_utils, virt_vm
+
+
+def preprocess_images(bindir, params, env):
+    # Clone master image form vms.
+    for vm_name in params.get("vms").split():
+        vm = env.get_vm(vm_name)
+        if vm:
+            vm.destroy(free_mac_addresses=False)
+        vm_params = params.object_params(vm_name)
+        for image in vm_params.get("master_images_clone").split():
+            image_obj = QemuImg(params, bindir, image)
+            image_obj.clone_image(params, vm_name, image, bindir)
+
+
+def postprocess_images(bindir, params):
+    for vm in params.get("vms").split():
+        vm_params = params.object_params(vm)
+        for image in vm_params.get("master_images_clone").split():
+            image_obj = QemuImg(params, bindir, image)
+            image_obj.rm_cloned_image(params, vm, image, bindir)
+
+
+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 = virt_utils.get_path(root_dir, blkdebug_name)
+    else:
+        blkdebug_filename = None
+    return blkdebug_filename
+
+
+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 = virt_utils.get_path(root_dir, image_filename)
+    return image_filename
+
+
+class OptionMissing(Exception):
+    """
+    Option not found in the odbject
+    """
+    def __init__(self, option):
+        self.option = option
+
+
+    def __str__(self):
+        return "%s is missing. Please check your parameters" % self.option
+
+
+class QemuImg(object):
+    """
+    A basic class for handling operations of disk/block images.
+    """
+    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.
+        """
+        self.image_filename = get_image_filename(params, root_dir)
+        self.image_format = params.get("image_format", "qcow2")
+        self.size = params.get("image_size", "10G")
+        self.check_output = params.get("check_output") == "yes"
+        self.image_blkdebug_filename = get_image_blkdebug_filename(params,
+                                                                   root_dir)
+        image_chain = params.get("image_chain")
+        self.base_tag = None
+        self.snapshot_tag = None
+        if image_chain:
+            image_chain = re.split("\s+", image_chain)
+            if tag in image_chain:
+                index = image_chain.index(tag)
+                if index < len(image_chain) - 1:
+                    self.snapshot_tag = image_chain[index + 1]
+                if index > 0:
+                    self.base_tag = image_chain[index - 1]
+        if self.base_tag:
+            base_params = params.object_params(self.base_tag)
+            self.base_image_filename = get_image_filename(base_params,
+                                                           root_dir)
+            self.base_format = base_params.get("image_format")
+        if self.snapshot_tag:
+            ss_params = params.object_params(self.snapshot_tag)
+            self.snapshot_image_filename = get_image_filename(ss_params,
+                                                               root_dir)
+            self.snapshot_format = ss_params.get("image_format")
+
+
+    def check_option(self, option):
+        """
+        Check if object has the option required.
+
+        @param option: option should be checked
+        """
+        if option not in self.__dict__:
+            raise OptionMissing(option)
+
+
+    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,
+                                    virt_utils.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 = virt_utils.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)
+
+
+    def clone_image(self, params, vm_name, image_name, root_dir):
+        """
+        Clone master image to vm specific file.
+
+        @param params: Dictionary containing the test parameters.
+        @param vm_name: Vm name.
+        @param image_name: Master image name.
+        @param root_dir: Base directory for relative filenames.
+        """
+        if not params.get("image_name_%s_%s" % (image_name, vm_name)):
+            m_image_name = params.get("image_name", "image")
+            vm_image_name = "%s_%s" % (m_image_name, vm_name)
+            if params.get("clone_master", "yes") == "yes":
+                image_params = params.object_params(image_name)
+                image_params["image_name"] = vm_image_name
+
+                m_image_fn = get_image_filename(params, root_dir)
+                image_fn = get_image_filename(image_params, root_dir)
+
+                logging.info("Clone master image for vms.")
+                utils.run(params.get("image_clone_commnad") % (m_image_fn,
+                                                               image_fn))
+
+            params["image_name_%s_%s" % (image_name, vm_name)] = vm_image_name
+
+
+    def rm_cloned_image(self, params, vm_name, image_name, root_dir):
+        """
+        Remove vm specific file.
+
+        @param params: Dictionary containing the test parameters.
+        @param vm_name: Vm name.
+        @param image_name: Master image name.
+        @param root_dir: Base directory for relative filenames.
+        """
+        if params.get("image_name_%s_%s" % (image_name, vm_name)):
+            m_image_name = params.get("image_name", "image")
+            vm_image_name = "%s_%s" % (m_image_name, vm_name)
+            if params.get("clone_master", "yes") == "yes":
+                image_params = params.object_params(image_name)
+                image_params["image_name"] = vm_image_name
+
+                image_fn = get_image_filename(image_params, root_dir)
+
+                logging.debug("Removing vm specific image file %s", image_fn)
+                if os.path.exists(image_fn):
+                    utils.run(params.get("image_remove_commnad") % (image_fn))
+                else:
+                    logging.debug("Image file %s not found", image_fn)
+
+
+class Rawdev(object):
+    """
+    Base class for rew storage devices such as iscsi and local disks
+    """
+    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
+        """
+        host_set_flag = params.get("host_setup_flag")
+        if host_set_flag is not None:
+            self.cleanup = host_set_flag & 2 == 2
+        else:
+            self.cleanup = False
+        if params.get("force_cleanup") == "yes":
+            self.cleanup = True
+        self.image_name = tag
+
+
+class Iscsidev(Rawdev):
+    """
+    Class for handle iscsi devices for VM
+    """
+    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
+        """
+        Rawdev.__init__(self, params, root_dir, tag)
+        self.emulated_file_remove = False
+        self.emulated_image = params.get("emulated_image")
+        if self.emulated_image:
+            if params.get("emulated_file_remove", "no") == "yes":
+                self.emulated_file_remove = True
+        params["iscsi_thread_id"] = self.image_name
+        self.iscsidevice = iscsi.Iscsi(params, root_dir=root_dir)
+        self.device_id = params.get("device_id")
diff --git a/client/virt/virt_storage.py b/client/virt/virt_storage.py
deleted file mode 100644
index cb3482f..0000000
--- a/client/virt/virt_storage.py
+++ /dev/null
@@ -1,345 +0,0 @@
-"""
-Classes and functions to handle storage devices.
-
-This exports:
-  - two functions for get image/blkdebug filename
-  - class for image operates and basic parameters
-"""
-import logging, os, shutil, re
-from autotest.client import utils
-from autotest.client.shared import iscsi
-import virt_utils, virt_vm
-
-
-def preprocess_images(bindir, params, env):
-    # Clone master image form vms.
-    for vm_name in params.get("vms").split():
-        vm = env.get_vm(vm_name)
-        if vm:
-            vm.destroy(free_mac_addresses=False)
-        vm_params = params.object_params(vm_name)
-        for image in vm_params.get("master_images_clone").split():
-            image_obj = QemuImg(params, bindir, image)
-            image_obj.clone_image(params, vm_name, image, bindir)
-
-
-def postprocess_images(bindir, params):
-    for vm in params.get("vms").split():
-        vm_params = params.object_params(vm)
-        for image in vm_params.get("master_images_clone").split():
-            image_obj = QemuImg(params, bindir, image)
-            image_obj.rm_cloned_image(params, vm, image, bindir)
-
-
-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 = virt_utils.get_path(root_dir, blkdebug_name)
-    else:
-        blkdebug_filename = None
-    return blkdebug_filename
-
-
-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 = virt_utils.get_path(root_dir, image_filename)
-    return image_filename
-
-
-class OptionMissing(Exception):
-    """
-    Option not found in the odbject
-    """
-    def __init__(self, option):
-        self.option = option
-
-
-    def __str__(self):
-        return "%s is missing. Please check your parameters" % self.option
-
-
-class QemuImg(object):
-    """
-    A basic class for handling operations of disk/block images.
-    """
-    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.
-        """
-        self.image_filename = get_image_filename(params, root_dir)
-        self.image_format = params.get("image_format", "qcow2")
-        self.size = params.get("image_size", "10G")
-        self.check_output = params.get("check_output") == "yes"
-        self.image_blkdebug_filename = get_image_blkdebug_filename(params,
-                                                                   root_dir)
-        image_chain = params.get("image_chain")
-        self.base_tag = None
-        self.snapshot_tag = None
-        if image_chain:
-            image_chain = re.split("\s+", image_chain)
-            if tag in image_chain:
-                index = image_chain.index(tag)
-                if index < len(image_chain) - 1:
-                    self.snapshot_tag = image_chain[index + 1]
-                if index > 0:
-                    self.base_tag = image_chain[index - 1]
-        if self.base_tag:
-            base_params = params.object_params(self.base_tag)
-            self.base_image_filename = get_image_filename(base_params,
-                                                           root_dir)
-            self.base_format = base_params.get("image_format")
-        if self.snapshot_tag:
-            ss_params = params.object_params(self.snapshot_tag)
-            self.snapshot_image_filename = get_image_filename(ss_params,
-                                                               root_dir)
-            self.snapshot_format = ss_params.get("image_format")
-
-
-    def check_option(self, option):
-        """
-        Check if object has the option required.
-
-        @param option: option should be checked
-        """
-        if option not in self.__dict__:
-            raise OptionMissing(option)
-
-
-    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,
-                                    virt_utils.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 = virt_utils.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)
-
-
-    def clone_image(self, params, vm_name, image_name, root_dir):
-        """
-        Clone master image to vm specific file.
-
-        @param params: Dictionary containing the test parameters.
-        @param vm_name: Vm name.
-        @param image_name: Master image name.
-        @param root_dir: Base directory for relative filenames.
-        """
-        if not params.get("image_name_%s_%s" % (image_name, vm_name)):
-            m_image_name = params.get("image_name", "image")
-            vm_image_name = "%s_%s" % (m_image_name, vm_name)
-            if params.get("clone_master", "yes") == "yes":
-                image_params = params.object_params(image_name)
-                image_params["image_name"] = vm_image_name
-
-                m_image_fn = get_image_filename(params, root_dir)
-                image_fn = get_image_filename(image_params, root_dir)
-
-                logging.info("Clone master image for vms.")
-                utils.run(params.get("image_clone_commnad") % (m_image_fn,
-                                                               image_fn))
-
-            params["image_name_%s_%s" % (image_name, vm_name)] = vm_image_name
-
-
-    def rm_cloned_image(self, params, vm_name, image_name, root_dir):
-        """
-        Remove vm specific file.
-
-        @param params: Dictionary containing the test parameters.
-        @param vm_name: Vm name.
-        @param image_name: Master image name.
-        @param root_dir: Base directory for relative filenames.
-        """
-        if params.get("image_name_%s_%s" % (image_name, vm_name)):
-            m_image_name = params.get("image_name", "image")
-            vm_image_name = "%s_%s" % (m_image_name, vm_name)
-            if params.get("clone_master", "yes") == "yes":
-                image_params = params.object_params(image_name)
-                image_params["image_name"] = vm_image_name
-
-                image_fn = get_image_filename(image_params, root_dir)
-
-                logging.debug("Removing vm specific image file %s", image_fn)
-                if os.path.exists(image_fn):
-                    utils.run(params.get("image_remove_commnad") % (image_fn))
-                else:
-                    logging.debug("Image file %s not found", image_fn)
-
-
-class Rawdev(object):
-    """
-    Base class for rew storage devices such as iscsi and local disks
-    """
-    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
-        """
-        host_set_flag = params.get("host_setup_flag")
-        if host_set_flag is not None:
-            self.cleanup = host_set_flag & 2 == 2
-        else:
-            self.cleanup = False
-        if params.get("force_cleanup") == "yes":
-            self.cleanup = True
-        self.image_name = tag
-
-
-class Iscsidev(Rawdev):
-    """
-    Class for handle iscsi devices for VM
-    """
-    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
-        """
-        Rawdev.__init__(self, params, root_dir, tag)
-        self.emulated_file_remove = False
-        self.emulated_image = params.get("emulated_image")
-        if self.emulated_image:
-            if params.get("emulated_file_remove", "no") == "yes":
-                self.emulated_file_remove = True
-        params["iscsi_thread_id"] = self.image_name
-        self.iscsidevice = iscsi.Iscsi(params, root_dir=root_dir)
-        self.device_id = params.get("device_id")
diff --git a/client/virt/virt_test_utils.py b/client/virt/virt_test_utils.py
index 6521ab6..7f7b0f8 100644
--- a/client/virt/virt_test_utils.py
+++ b/client/virt/virt_test_utils.py
@@ -28,7 +28,7 @@ from autotest.client.shared import error, global_config
 from autotest.client import utils
 from autotest.client.tools import scan_results
 from autotest.client.shared.syncdata import SyncData, SyncListenServer
-import aexpect, virt_utils, virt_vm, remote, virt_storage, env_process
+import aexpect, virt_utils, virt_vm, remote, storage, env_process
 
 GLOBAL_CONFIG = global_config.global_config
 
@@ -552,7 +552,7 @@ class MultihostMigration(object):
         """
         Prepare env to start vms.
         """
-        virt_storage.preprocess_images(self.test.bindir, self.params, self.env)
+        storage.preprocess_images(self.test.bindir, self.params, self.env)
 
 
     def _check_vms_source(self, mig_data):
@@ -667,7 +667,7 @@ class MultihostMigration(object):
         """
         Kill vms and delete cloned images.
         """
-        virt_storage.postprocess_images(self.test.bindir, self.params)
+        storage.postprocess_images(self.test.bindir, self.params)
 
 
     def migrate(self, vms_name, srchost, dsthost, start_work=None,
-- 
1.7.11.2

_______________________________________________
Autotest-kernel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/autotest-kernel

Reply via email to