blockdev_commit_base.py 5.8 KB
Newer Older
A
Aihua Liang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
import logging

from virttest import qemu_storage
from virttest import data_dir
from virttest import utils_disk

from provider import backup_utils
from provider import job_utils

from provider.virt_storage.storage_admin import sp_admin


class BlockDevCommitTest(object):

    def __init__(self, test, params, env):
        self.env = env
        self.test = test
        self.params = params
        self.disks_info = list()
        self.files_info = list()
        self.main_vm = self.prepare_main_vm()

    @staticmethod
    def get_node_name(tag):
        return "drive_%s" % tag

    def prepare_main_vm(self):
        return self.env.get_vm(self.params["main_vm"])

    def get_image_by_tag(self, name):
        image_dir = data_dir.get_data_dir()
        image_params = self.params.object_params(name)
        return qemu_storage.QemuImg(image_params, image_dir, name)

    def prepare_snapshot_file(self, snapshot_tags):
        self.snapshot_images = list(
            map(self.get_image_by_tag, snapshot_tags))
        params = self.params.copy()
        params.setdefault("target_path", data_dir.get_data_dir())
        for tag in snapshot_tags:
            image = sp_admin.volume_define_by_params(tag, params)
            image.hotplug(self.main_vm)

    def verify_data_file(self):
        for info in self.files_info:
            mount_point, filename = info[0], info[1]
            backup_utils.verify_file_md5(
                self.main_vm, mount_point, filename)

    def create_snapshots(self, snapshot_tags, device):
        options = ["node", "overlay"]
        cmd = "blockdev-snapshot"
        for idx, tag in enumerate(snapshot_tags):
            params = self.params.object_params(tag)
            arguments = params.copy_from_keys(options)
            arguments["overlay"] = self.get_node_name(tag)
            if idx == 0:
                arguments["node"] = self.device_node
            else:
                arguments["node"] = self.get_node_name(
                    snapshot_tags[idx - 1])
            self.main_vm.monitor.cmd(cmd, dict(arguments))
            for info in self.disks_info:
                if device in info:
                    self.generate_tempfile(info[1], tag)

    def commit_snapshots(self):
        job_id_list = []
        for device in self.params["device_tag"].split():
            device_params = self.params.object_params(device)
            snapshot_tags = device_params["snapshot_tags"].split()
            self.device_node = self.get_node_name(device)
            options = ["base-node", "top-node", "speed"]
            arguments = self.params.copy_from_keys(options)
            arguments["base-node"] = self.get_node_name(device)
            arguments["top-node"] = self.get_node_name(snapshot_tags[-2])
            device = self.get_node_name(snapshot_tags[-1])
            if len(self.params["device_tag"].split()) == 1:
                backup_utils.block_commit(self.main_vm, device, **arguments)
            else:
                commit_cmd = backup_utils.block_commit_qmp_cmd
                cmd, args = commit_cmd(device, **arguments)
                job_id = args.get("job-id", device)
                job_id_list.append(job_id)
                self.main_vm.monitor.cmd(cmd, args)
        for job_id in job_id_list:
            job_utils.wait_until_block_job_completed(self.main_vm, job_id)

    @staticmethod
    def get_linux_disk_path(session, disk_size):
        disks = utils_disk.get_linux_disks(session, True)
        for kname, attr in disks.items():
            if attr[1] == disk_size and attr[2] == "disk":
                return kname
        return None

    def configure_data_disk(self, tag):
        os_type = self.params["os_type"]
        disk_params = self.params.object_params(tag)
        disk_size = disk_params["image_size"]
        session = self.main_vm.wait_for_login()
        try:
            if os_type != "windows":
                disk_id = self.get_linux_disk_path(session, disk_size)
                assert disk_id, "Disk not found in guest!"
                mount_point = utils_disk.configure_empty_linux_disk(
                    session, disk_id, disk_size)[0]
                self.disks_info.append([
                    r"/dev/%s1" %
                    disk_id, mount_point, tag])
            else:
                disk_id = utils_disk.get_windows_disks_index(
                    session, disk_size)
                driver_letter = utils_disk.configure_empty_windows_disk(
                    session, disk_id, disk_size)[0]
                mount_point = r"%s:\\" % driver_letter
                self.disks_info.append([disk_id, mount_point, tag])
        finally:
            session.close()

    def generate_tempfile(self, root_dir, filename="data",
                          size="10M", timeout=360):
        backup_utils.generate_tempfile(
            self.main_vm, root_dir, filename, size, timeout)
        self.files_info.append([root_dir, filename])

    def pre_test(self):
        if not self.main_vm.is_alive():
            self.main_vm.create()
        self.main_vm.verify_alive()
        for device in self.params["device_tag"].split():
            device_params = self.params.object_params(device)
            snapshot_tags = device_params["snapshot_tags"].split()
            self.device_node = self.get_node_name(device)
            self.configure_data_disk(device)
            self.prepare_snapshot_file(snapshot_tags)
            self.create_snapshots(snapshot_tags, device)

    def post_test(self):
        try:
            self.main_vm.destroy()
            for image in self.snapshot_images:
                image.remove()
        except Exception as error:
            logging.error(str(error))

    def run_test(self):
        self.pre_test()
        try:
            self.commit_snapshots()
            self.verify_data_file()
        finally:
            self.post_test()