Beispiel #1
0
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()
Beispiel #2
0
 def _squashfs_mount(self):
     if not self.squash_wrapper and self.backupset.compressed:
         self.squash_wrapper = SquashfsWrapper(self.backupset)
         self.squash_wrapper.mount()
Beispiel #3
0
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[:]
Beispiel #4
0
 def _mount_sqfs(self):
     self.squash_wrapper = SquashfsWrapper(self.backupset)
     self.squash_wrapper.mount()
Beispiel #5
0
 def _squashfs_mount(self):
     if not self.squash_wrapper and self.backupset.compressed:
         self.squash_wrapper = SquashfsWrapper(self.backupset)
         self.squash_wrapper.mount()
Beispiel #6
0
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[:]
Beispiel #7
0
 def _mount_sqfs(self):
     self.squash_wrapper = SquashfsWrapper(self.backupset)
     self.squash_wrapper.mount()
Beispiel #8
0
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()