class RestorationController(ProcessController): """ The controller used to manage a complete Restoration procedure """ def __init__(self, disk, backup_id, config): super(RestorationController, self).__init__(disk, backup_id, config) self.backupset = self._load_backupset() self._disk_layout = DiskLayout.with_config(self.disk, self.backup_dir, config, self.backupset.disk_layout) self._imager = PartitionImage.with_config(self.disk, self.backup_dir, self.backupset, config) def _load_backupset(self): self.backupset = Backupset.load(self.backup_id) if self.backupset.node == ConfigHelper.config['node']['name']: return self.backupset else: raise Exception('This backup resides on another node, terminating.') def run(self): """ Starts the execution of the backup restoration procedure on a separate thread. :return: None """ self._thread = Thread(target=self._restore) self._thread.start() def _init_status(self): self._status['status'] = constants.STATUS_RUNNING self._status['operation'] = 'Restoration' self._status['start_time'] = datetime.today().strftime(constants.DATE_FORMAT) self._status['path'] = self.backupset.backup_path self._status['layout'] = self.backupset.disk_layout def _restore(self): try: self._init_status() if self.backupset.compressed: self._mount_sqfs() self._disk_layout.restore_layout() self._imager.restore() self._status['status'] = constants.STATUS_FINISHED except Exception as e: self._set_error(e) if self.backupset.compressed: self._imager.kill() finally: self._status['end_time'] = datetime.today().strftime(constants.DATE_FORMAT) if self.backupset.compressed: self._umount_sqfs() def _mount_sqfs(self): self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount() def _umount_sqfs(self): if self.squash_wrapper: if self.squash_wrapper.mounted: self.squash_wrapper.umount()
def _squashfs_mount(self): if not self.squash_wrapper and self.backupset.compressed: self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount()
class MountController(BasicController): """ The controller used to manage mounting and unmounting procedures """ NODE_POOL = NBDPool def __init__(self, backup_id): super(MountController, self).__init__(backup_id) self.nodes = [] self.backupset = Backupset.load(backup_id) self.squash_wrapper = None self.mount_path = ConfigHelper.config['node']['mount_path'] + self.backupset.id + '/' def mount(self): """ Creates the necessary directory structures and system links, followed by mounting of the backup. :return: None """ try: self._squashfs_mount() create_dir(self.mount_path) self._mount_partitions() self._status['status'] = constants.STATUS_RUNNING if not self._is_mounted_correctly(): self._release_nodes() delete_dir(self.mount_path) self._squashfs_umount() except: self._squashfs_umount() raise def unmount(self): """ Unmounts the backup followed by clean up of the directories and system links created by backup function. :return: None """ try: self._release_nodes() delete_dir(self.mount_path) except: raise finally: self._squashfs_umount() def _squashfs_mount(self): if not self.squash_wrapper and self.backupset.compressed: self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount() def _squashfs_umount(self): if self.backupset.compressed and self.squash_wrapper and self.squash_wrapper.mounted: self.squash_wrapper.umount() def _mount_partitions(self): for partition in self.backupset.partitions: node = self.NODE_POOL.acquire() image_path = self._get_image_path(partition) image_mount_path = self._get_image_mount_path(partition) create_dir(image_mount_path) node.mount(image_path, partition.file_system, image_mount_path) self.nodes.append(node) def _get_image_path(self, partition): return self.backupset.backup_path + constants.PARTITION_FILE_PREFIX + partition.id + \ constants.PARTITION_FILE_SUFFIX def _get_image_mount_path(self, partition): return self.mount_path + constants.PARTITION_FILE_PREFIX + partition.id + '/' def _is_mounted_correctly(self): error_detected = False for node in self.nodes: if node.error and not error_detected: error_detected = True self._set_error("Error detected duirng the mount operation on backup " + str(self.backupset.id)) return not error_detected def _release_nodes(self): for node in self.nodes: node.unmount() self.NODE_POOL.release(node) del self.nodes[:]
def _mount_sqfs(self): self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount()
class MountController(BasicController): """ The controller used to manage mounting and unmounting procedures """ NODE_POOL = NBDPool def __init__(self, backup_id): super(MountController, self).__init__(backup_id) self.nodes = [] self.backupset = Backupset.load(backup_id) self.squash_wrapper = None self.mount_path = ConfigHelper.config['node'][ 'mount_path'] + self.backupset.id + '/' def mount(self): """ Creates the necessary directory structures and system links, followed by mounting of the backup. :return: None """ try: self._squashfs_mount() create_dir(self.mount_path) self._mount_partitions() self._status['status'] = constants.STATUS_RUNNING if not self._is_mounted_correctly(): self._release_nodes() delete_dir(self.mount_path) self._squashfs_umount() except: self._squashfs_umount() raise def unmount(self): """ Unmounts the backup followed by clean up of the directories and system links created by backup function. :return: None """ try: self._release_nodes() delete_dir(self.mount_path) except: raise finally: self._squashfs_umount() def _squashfs_mount(self): if not self.squash_wrapper and self.backupset.compressed: self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount() def _squashfs_umount(self): if self.backupset.compressed and self.squash_wrapper and self.squash_wrapper.mounted: self.squash_wrapper.umount() def _mount_partitions(self): for partition in self.backupset.partitions: node = self.NODE_POOL.acquire() image_path = self._get_image_path(partition) image_mount_path = self._get_image_mount_path(partition) create_dir(image_mount_path) node.mount(image_path, partition.file_system, image_mount_path) self.nodes.append(node) def _get_image_path(self, partition): return self.backupset.backup_path + constants.PARTITION_FILE_PREFIX + partition.id + \ constants.PARTITION_FILE_SUFFIX def _get_image_mount_path(self, partition): return self.mount_path + constants.PARTITION_FILE_PREFIX + partition.id + '/' def _is_mounted_correctly(self): error_detected = False for node in self.nodes: if node.error and not error_detected: error_detected = True self._set_error( "Error detected duirng the mount operation on backup " + str(self.backupset.id)) return not error_detected def _release_nodes(self): for node in self.nodes: node.unmount() self.NODE_POOL.release(node) del self.nodes[:]
class RestorationController(ProcessController): """ The controller used to manage a complete Restoration procedure """ def __init__(self, disk, backup_id, config): super(RestorationController, self).__init__(disk, backup_id, config) self.backupset = self._load_backupset() self._disk_layout = DiskLayout.with_config(self.disk, self.backup_dir, config, self.backupset.disk_layout) self._imager = PartitionImage.with_config(self.disk, self.backup_dir, self.backupset, config) def _load_backupset(self): self.backupset = Backupset.load(self.backup_id) if self.backupset.node == ConfigHelper.config['node']['name']: return self.backupset else: raise Exception( 'This backup resides on another node, terminating.') def run(self): """ Starts the execution of the backup restoration procedure on a separate thread. :return: None """ self._thread = Thread(target=self._restore) self._thread.start() def _init_status(self): self._status['status'] = constants.STATUS_RUNNING self._status['operation'] = 'Restoration' self._status['start_time'] = datetime.today().strftime( constants.DATE_FORMAT) self._status['path'] = self.backupset.backup_path self._status['layout'] = self.backupset.disk_layout def _restore(self): try: self._init_status() if self.backupset.compressed: self._mount_sqfs() self._disk_layout.restore_layout() self._imager.restore() self._status['status'] = constants.STATUS_FINISHED except Exception as e: self._set_error(e) if self.backupset.compressed: self._imager.kill() finally: self._status['end_time'] = datetime.today().strftime( constants.DATE_FORMAT) if self.backupset.compressed: self._umount_sqfs() def _mount_sqfs(self): self.squash_wrapper = SquashfsWrapper(self.backupset) self.squash_wrapper.mount() def _umount_sqfs(self): if self.squash_wrapper: if self.squash_wrapper.mounted: self.squash_wrapper.umount()