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