Exemple #1
0
    def load_config(self):
        """Load archive configurations."""
        if not os.path.exists(self.archive_config_path):
            ABUNDANT_LOGGER.error('Archive config not found at %s' % self.archive_config_path)
            raise FileNotFoundError('Archive config not found at %s' % self.archive_config_path)

        with open(self.archive_config_path, mode='r', encoding='utf-8') as raw_archive_config:
            self.archive_config = json.load(raw_archive_config)
        ABUNDANT_LOGGER.debug('Loaded archive config')
Exemple #2
0
 def load_config(self):
     """Load configuration for this version."""
     with get_config(self.version_config_path) as version_config:
         for version in version_config['VersionRecords']:
             if version['UUID'] == self.uuid:
                 self.version_config = dict(version)
                 ABUNDANT_LOGGER.debug('Version record found: %s' % self.uuid)
                 return
     ABUNDANT_LOGGER.error('Cannot find config for version %s' % self.uuid)
     raise FileNotFoundError('Cannot find config for version %s' % self.uuid)
Exemple #3
0
    def export(self, destination_dir: str, exact=False):
        """Export files in this version to destination directory."""
        ABUNDANT_LOGGER.debug('Exporting version %s to %s' % (self.uuid, destination_dir))

        if not os.path.exists(destination_dir):
            ABUNDANT_LOGGER.error('Cannot find destination directory: %s' % destination_dir)
            raise FileNotFoundError('Cannot find destination directory: %s' % destination_dir)

        file_source = self.files if not exact else self.exact_files
        for relative_path, absolute_path in file_source:
            destination_path = os.path.join(destination_dir, relative_path)
            os.makedirs(os.path.dirname(destination_path), exist_ok=True)
            shutil.copy(absolute_path, destination_path)
            ABUNDANT_LOGGER.debug('Copied %s' % destination_path)
        ABUNDANT_LOGGER.info('Exported version %s to %s' % (self.uuid, destination_dir))
Exemple #4
0
def create_archive(archive_record: dict, algorithm: str, max_number_of_versions: int) -> ArchiveAgent:
    """Create an archive according to the archive record.
    No validity check will be performed."""
    source_dir, archive_dir = archive_record['SourceDirectory'], archive_record['ArchiveDirectory']
    uuid = archive_record['UUID']
    archive_content_dir = os.path.join(archive_dir, 'archive')
    archive_meta_dir = os.path.join(archive_dir, 'meta')
    ABUNDANT_LOGGER.debug('Creating archive: %s' % uuid)

    try:
        # create archive and meta directories
        os.mkdir(archive_content_dir)
        os.mkdir(archive_meta_dir)

        # set archive config
        archive_config = dict(ARCHIVE_CONFIG_TEMPLATE)
        archive_config.update({
            'HashAlgorithm': algorithm,
            'SourceDirectory': source_dir,
            'MaxNumberOfVersions': max_number_of_versions,
            'UUID': uuid
        })
        with open(os.path.join(archive_meta_dir, 'archive_config.json'), mode='w', encoding='utf-8') \
                as raw_archive_config:
            json.dump(archive_config, raw_archive_config)
        ABUNDANT_LOGGER.debug('Created archive config: %s' % uuid)

    except OSError as e:
        # OSError on file operations usually indicates insufficient privilege or
        # incorrect configurations
        ABUNDANT_LOGGER.error('Cannot create archive %s, possibly caused by insufficient privilege' %
                              uuid)

        # undo previous change
        if os.path.exists(archive_content_dir):
            os.rmdir(archive_content_dir)
        if os.path.exists(archive_meta_dir):
            os.rmdir(archive_meta_dir)
        ABUNDANT_LOGGER.info('Previous change undone')

        # raise
        raise e
    else:
        ABUNDANT_LOGGER.info('Created archive: %s' % uuid)
        return ArchiveAgent(archive_dir, on_creation_pardon=True)
Exemple #5
0
    def create_archive(self, source_dir: str, archive_dir: str, algorithm: str, max_number_of_versions: int):
        """Create an archive."""
        # validity check
        if not os.path.exists(source_dir):
            ABUNDANT_LOGGER.error('Source directory does not exist: %s' % source_dir)
            raise FileNotFoundError('Source directory does not exist: %s' % source_dir)
        if not os.path.exists(archive_dir):
            ABUNDANT_LOGGER.error('Archive directory does not exist: %s' % archive_dir)
            raise FileNotFoundError('Archive directory does not exist: %s' % archive_dir)
        if self.master_config.get_archive_record(archive_dir=archive_dir):
            ABUNDANT_LOGGER.error('Archive directory has already been used: %s' % archive_dir)
            raise FileNotFoundError('Archive directory has already been used: %s' % archive_dir)
        algorithm = algorithm.lower()
        if algorithm not in VALID_ALGORITHMS:
            ABUNDANT_LOGGER.error('Invalid hash algorithm: %s' % algorithm)
            raise NotImplementedError('Requested algorithm is either invalid or has not been implemented yet: %s'
                                      % algorithm)
        if max_number_of_versions < 0:
            ABUNDANT_LOGGER.error('At least one version should be kept: %s' % max_number_of_versions)
            raise ValueError('At least one version should be kept: %s' % max_number_of_versions)

        # create archive record
        new_archive_record = self.master_config.add_archive_record(source_dir, archive_dir)

        # create archive
        try:
            archive = create_archive(new_archive_record, algorithm, max_number_of_versions)
        except OSError as e:
            # delete the archive record previously created
            self.master_config.remove_archive_record(uuid=new_archive_record['UUID'])
            ABUNDANT_LOGGER.debug('Archive record added removed')

            raise e

        # create base version
        archive.create_base()
        ABUNDANT_LOGGER.info('Created archive %s' % archive.uuid)
        return archive