def set_root(params, object=None): """ Set a root state to provide object existence. All arguments match the base class. Create a ramdisk, virtual group, thin pool and logical volume for each object (all off). """ vm_name = params["vms"] mount_loc = LVMBackend._get_images_mount_loc(params) logging.info("Creating original logical volume for %s", vm_name) lv_utils.vg_ramdisk(None, params["vg_name"], params["ramdisk_vg_size"], params["ramdisk_basedir"], params["ramdisk_sparse_filename"], params["use_tmpfs"] == "yes") lv_utils.lv_create( params["vg_name"], params["lv_name"], params["lv_size"], # NOTE: call by key to keep good argument order which wasn't # accepted upstream for backward API compatibility pool_name=params["pool_name"], pool_size=params["pool_size"]) lv_utils.lv_take_snapshot(params["vg_name"], params["lv_name"], params["lv_pointer_name"]) if mount_loc: if not os.path.exists(mount_loc): os.mkdir(mount_loc) lv_utils.lv_mount(params["vg_name"], params["lv_pointer_name"], mount_loc, create_filesystem="ext4") super(LVMBackend, LVMBackend).set_root(params, object)
def get(cls, params, object=None): """ Retrieve a state disregarding the current changes. All arguments match the base class. """ vm_name = params["vms"] mount_loc = cls._get_image_mount_loc(params) params["lv_snapshot_name"] = params["get_state"] if mount_loc: # mount to avoid not-mounted errors try: lv_utils.lv_mount(params["vg_name"], params["lv_pointer_name"], mount_loc) except lv_utils.LVException: pass lv_utils.lv_umount(params["vg_name"], params["lv_pointer_name"]) try: logging.info("Restoring %s to state %s", vm_name, params["get_state"]) lv_utils.lv_remove(params["vg_name"], params["lv_pointer_name"]) lv_utils.lv_take_snapshot(params["vg_name"], params["lv_snapshot_name"], params["lv_pointer_name"]) finally: if mount_loc: lv_utils.lv_mount(params["vg_name"], params["lv_pointer_name"], mount_loc)
def set_root(run_params): """ Create a ramdisk, virtual group, thin pool and logical volume for each vm (all offline). :param run_params: configuration parameters :type run_params: {str, str} :raises: :py:class:`exceptions.TestError` if the root state already exists """ vms = run_params.objects("vms") for vm_name in vms: vm_params = run_params.object_params(vm_name) if lv_utils.vg_check(vm_params["vg_name"]): if vm_params.get("force_create", "no") == "yes": logging.info("Removing the previously created %s", vm_name) if vm_params.get("image_raw_device", "yes") == "no": mount_loc = os.path.dirname(vm_params["image_name"]) try: lv_utils.lv_umount(vm_params["vg_name"], vm_params["lv_pointer_name"]) except lv_utils.LVException: pass logging.debug("Removing previous volume group of %s", vm_name) lv_utils.vg_ramdisk_cleanup(vm_params["ramdisk_sparse_filename"], os.path.join(vm_params["ramdisk_basedir"], vm_params["vg_name"]), vm_params["vg_name"], None, vm_params["use_tmpfs"] == "yes") else: raise exceptions.TestError("The root state of %s already exists" % vm_name) logging.info("Preparing original logical volume for %s", vm_name) lv_utils.vg_ramdisk(None, vm_params["vg_name"], vm_params["ramdisk_vg_size"], vm_params["ramdisk_basedir"], vm_params["ramdisk_sparse_filename"], vm_params["use_tmpfs"] == "yes") lv_utils.lv_create(vm_params["vg_name"], vm_params["lv_name"], vm_params["lv_size"], # NOTE: call by key to keep good argument order which wasn't # accepted upstream for backward API compatibility pool_name=vm_params["pool_name"], pool_size=vm_params["pool_size"]) lv_utils.lv_take_snapshot(vm_params["vg_name"], vm_params["lv_name"], vm_params["lv_pointer_name"]) if vm_params.get("image_raw_device", "yes") == "no": mount_loc = os.path.dirname(vm_params["image_name"]) if not os.path.exists(mount_loc): os.mkdir(mount_loc) lv_utils.lv_mount(vm_params["vg_name"], vm_params["lv_pointer_name"], mount_loc, create_filesystem="ext4")
def test_lv_snapshot(self): """ Takes a snapshot from the logical and merges snapshot with the logical volume. """ self.create_lv() lv_utils.lv_take_snapshot(self.vg_name, self.lv_name, self.lv_snapshot_name, self.lv_snapshot_size) lv_utils.lv_revert(self.vg_name, self.lv_name, self.lv_snapshot_name) self.mount_unmount_lv()
def set(cls, params, object=None): """ Store a state saving the current changes. All arguments match the base class. """ vm_name = params["vms"] params["lv_snapshot_name"] = params["set_state"] logging.info("Taking a snapshot '%s' of %s", params["set_state"], vm_name) lv_utils.lv_take_snapshot(params["vg_name"], params["lv_pointer_name"], params["lv_snapshot_name"])
def test_lv_snapshot(self): """ Takes a snapshot from the logical and merges snapshot with the logical volume. """ self.create_lv() lv_utils.lv_mount(self.vg_name, self.lv_name, self.mount_loc, create_filesystem=self.fs_name) lv_utils.lv_umount(self.vg_name, self.lv_name) lv_utils.lv_take_snapshot(self.vg_name, self.lv_name, self.lv_snap_name, self.lv_snapshot_size) lv_utils.lv_revert(self.vg_name, self.lv_name, self.lv_snap_name) self.mount_unmount_lv() self.delete_lv()
def test_snapshot(self): """ General logical volume setup. A volume group with given name is created in the ramdisk. It then creates a logical volume. Takes a snapshot from the logical and merges snapshot with the logical volume. """ self.ramdisks.append(lv_utils.vg_ramdisk(self.disk, self.vg_name, self.ramdisk_vg_size, self.ramdisk_basedir, self.ramdisk_sparse_filename)) lv_utils.lv_create(self.vg_name, self.lv_name, self.lv_size) lv_utils.lv_take_snapshot(self.vg_name, self.lv_name, self.lv_snapshot_name, self.lv_snapshot_size) lv_utils.lv_revert(self.vg_name, self.lv_name, self.lv_snapshot_name)
def _get_state(vm, vm_params): """ Get to an online/offline state of a vm object. We use LVM for offline snapshots and QCOW2 for online snapshots. """ vm_name = vm_params["vms"] if vm_params["get_state"] in OFFLINE_ROOTS + ONLINE_ROOTS: # reusing root states (offline root and online boot) is analogical to not doing anything return if vm_params["get_type"] == "offline": vm_params["lv_snapshot_name"] = vm_params["get_state"] if vm_params.get("image_raw_device", "yes") == "no": mount_loc = os.path.dirname(vm_params["image_name"]) try: lv_utils.lv_umount(vm_params["vg_name"], vm_params["lv_pointer_name"]) except lv_utils.LVException: pass try: logging.info("Restoring %s to state %s", vm_name, vm_params["get_state"]) lv_utils.lv_remove(vm_params["vg_name"], vm_params["lv_pointer_name"]) lv_utils.lv_take_snapshot(vm_params["vg_name"], vm_params["lv_snapshot_name"], vm_params["lv_pointer_name"]) finally: if vm_params.get("image_raw_device", "yes") == "no": mount_loc = os.path.dirname(vm_params["image_name"]) lv_utils.lv_mount(vm_params["vg_name"], vm_params["lv_pointer_name"], mount_loc) else: logging.info("Reusing online state '%s' of %s", vm_params["get_state"], vm_name) vm.pause() # NOTE: second online type is available and still supported but not recommended if vm_params["get_type"] != "ramfile": vm.loadvm(vm_params["get_state"]) else: state_dir = vm_params.get("image_name", "") state_dir = os.path.dirname(state_dir) state_file = os.path.join(state_dir, vm_params["get_state"]) state_file = "%s.state" % state_file vm.restore_from_file(state_file) vm.resume()
def test_snapshot(self): """ General logical volume setup. A volume group with given name is created in the ramdisk. It then creates a logical volume. Takes a snapshot from the logical and merges snapshot with the logical volume. """ self.ramdisks.append(lv_utils.vg_ramdisk(self.disk, self.vg_name, self.ramdisk_vg_size, self.ramdisk_basedir, self.ramdisk_sparse_filename)) lv_utils.lv_create(self.vg_name, self.lv_name, self.lv_size) lv_utils.lv_mount(self.vg_name, self.lv_name, self.mount_loc, create_filesystem=self.fs_name) lv_utils.lv_umount(self.vg_name, self.lv_name) lv_utils.lv_take_snapshot(self.vg_name, self.lv_name, self.lv_snapshot_name, self.lv_snapshot_size) lv_utils.lv_revert(self.vg_name, self.lv_name, self.lv_snapshot_name)
def _set_state(vm, vm_params): """ Set an online/offline state of a vm object. We use LVM for offline snapshots and QCOW2 for online snapshots. """ vm_name = vm_params["vms"] if vm_params["set_state"] in OFFLINE_ROOTS: # vm_params["vms"] = vm_name vm_params["main_vm"] = vm_name set_root(vm_params) elif vm_params["set_type"] == "offline": vm_params["lv_snapshot_name"] = vm_params["set_state"] logging.info("Taking a snapshot '%s' of %s", vm_params["set_state"], vm_name) lv_utils.lv_take_snapshot(vm_params["vg_name"], vm_params["lv_pointer_name"], vm_params["lv_snapshot_name"]) elif vm_params["set_state"] in ONLINE_ROOTS: # set boot state if vm is None or not vm.is_alive(): vm.create() else: logging.info("Setting online state '%s' of %s", vm_params["set_state"], vm_name) vm.pause() # NOTE: second online type is available and still supported but not recommended if vm_params["set_type"] != "ramfile": vm.savevm(vm_params["set_state"]) else: state_dir = vm_params.get("image_name", "") state_dir = os.path.dirname(state_dir) state_file = os.path.join(state_dir, vm_params["set_state"]) state_file = "%s.state" % state_file vm.save_to_file(state_file) # BUG: because the built-in functionality uses system_reset # which leads to unclean file systems in some cases it is # better to restore from the saved state vm.restore_from_file(state_file) vm.resume()
def set_root(cls, params, object=None): """ Set a root state to provide object existence. All arguments match the base class. Create a disk, virtual group, thin pool and logical volume for each object. """ vm_name = params["vms"] mount_loc = cls._get_image_mount_loc(params) logging.info("Creating original logical volume for %s", vm_name) vg_setup(params["vg_name"], params["disk_vg_size"], params["disk_basedir"], params["disk_sparse_filename"], params["use_tmpfs"] == "yes") lv_utils.lv_create( params["vg_name"], params["lv_name"], params["lv_size"], # NOTE: call by key to keep good argument order which wasn't # accepted upstream for backward API compatibility pool_name=params["lv_pool_name"], pool_size=params["lv_pool_size"]) lv_utils.lv_take_snapshot(params["vg_name"], params["lv_name"], params["lv_pointer_name"]) if mount_loc: if not os.path.exists(mount_loc): os.mkdir(mount_loc) lv_utils.lv_mount(params["vg_name"], params["lv_pointer_name"], mount_loc, create_filesystem="ext4") # TODO: it is not correct for the LVM backend to expect QCOW2 images # but at the moment we have no better way to provide on states with # base image to take snapshots of super(LVMBackend, LVMBackend).set_root(params, object)