From 9f5b826078288a370bf794247d81361c1712fd0d Mon Sep 17 00:00:00 2001 From: ljf Date: Tue, 1 Jan 2019 16:42:48 +0100 Subject: [PATCH] [wip] Work on borg local repo --- src/yunohost/backup.py | 26 ++++- src/yunohost/repository.py | 208 ++++++++++++++++++------------------- 2 files changed, 128 insertions(+), 106 deletions(-) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 687d02258..62c3e32ce 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -1888,13 +1888,37 @@ class TarBackupMethod(BackupMethod): class BorgBackupMethod(BackupMethod): + def __init__(self, repo=None): + super(TarBackupMethod, self).__init__(repo) + if not self.repo.domain: + filesystem.mkdir(self.repo.path, parent=True) + else: + #Todo Initialize remote repo + pass + @property def method_name(self): return 'borg' def backup(self): """ Backup prepared files with borg """ - super(CopyBackupMethod, self).backup() + super(BorgBackupMethod, self).backup() + + for path in self.manager.paths_to_backup: + source = path['source'] + dest = os.path.join(self.repo.path, path['dest']) + if source == dest: + logger.debug("Files already copyed") + return + + dest_parent = os.path.dirname(dest) + if not os.path.exists(dest_parent): + filesystem.mkdir(dest_parent, 0o750, True, uid='admin') + + if os.path.isdir(source): + shutil.copytree(source, dest) + else: + shutil.copy(source, dest) # TODO run borg create command raise YunohostError('backup_borg_not_implemented') diff --git a/src/yunohost/repository.py b/src/yunohost/repository.py index 2b3fce6cd..08cabb42a 100644 --- a/src/yunohost/repository.py +++ b/src/yunohost/repository.py @@ -91,7 +91,7 @@ class BackupRepository(object): except Exception as e: raise YunohostError('backup_cant_save_repositories_file', reason=e) - def __init__(self, created=True, location, name=None, description=None, method=None, + def __init__(self, created, location, name=None, description=None, method=None, encryption=None, quota=None): self.location = location @@ -126,127 +126,125 @@ class BackupRepository(object): repositories.pop(self.name) - BackupRepository.save() + BackupRepository.save() - if purge: - self.purge() + if purge: + self.purge() - def save(self): - BackupRepository.reposirories[self.name] = self.__dict__ - BackupRepository.save() + def save(self): + BackupRepository.reposirories[self.name] = self.__dict__ + BackupRepository.save() - def _split_location(self): - """ - Split a repository location into protocol, user, domain and path - """ - location_regex = r'^((?Pssh://)?(?P[^@ ]+)@(?P[^: ]+:))?(?P[^\0]+)$' - location_match = re.match(location_regex, self.location) - - if location_match is None: - raise YunohostError('backup_repositories_invalid_location', - location=location) - - self.protocol = location_match.group('protocol') - self.user = location_match.group('user') - self.domain = location_match.group('domain') - self.path = location_match.group('path') - - - def backup_repository_list(name, full=False): + def _split_location(self): """ - List available repositories where put archives + Split a repository location into protocol, user, domain and path """ - repositories = BackupRepository.load() + location_regex = r'^((?Pssh://)?(?P[^@ ]+)@(?P[^: ]+:))?(?P[^\0]+)$' + location_match = re.match(location_regex, self.location) - if full: - return repositories - else: - return repositories.keys() + if location_match is None: + raise YunohostError('backup_repositories_invalid_location', + location=location) + + self.protocol = location_match.group('protocol') + self.user = location_match.group('user') + self.domain = location_match.group('domain') + self.path = location_match.group('path') + +def backup_repository_list(name, full=False): + """ + List available repositories where put archives + """ + repositories = BackupRepository.load() + + if full: + return repositories + else: + return repositories.keys() + +def backup_repository_info(name, human_readable=True, space_used=False): + """ + Show info about a repository + + Keyword arguments: + name -- Name of the backup repository + """ + repository = BackupRepository.get(name) + + if space_used: + repository.compute_space_used() + + repository = repository.__dict__ + if human_readable: + if 'quota' in repository: + repository['quota'] = binary_to_human(repository['quota']) + if 'used' in repository and isinstance(repository['used'], int): + repository['used'] = binary_to_human(repository['used']) + + return repository - def backup_repository_info(name, human_readable=True, space_used=False): - """ - Show info about a repository +@is_unit_operation() +def backup_repository_add(operation_logger, location, name, description=None, + methods=None, quota=None, encryption="passphrase"): + """ + Add a backup repository - Keyword arguments: - name -- Name of the backup repository - """ - repository = BackupRepository.get(name) + Keyword arguments: + location -- Location of the repository (could be a remote location) + name -- Name of the backup repository + description -- An optionnal description + quota -- Maximum size quota of the repository + encryption -- If available, the kind of encryption to use + """ + repository = BackupRepository( + location, name, description, methods, quota, encryption) - if space_used: - repository.compute_space_used() + try: + repository.save() + except MoulinetteError: + raise YunohostError('backup_repository_add_failed', + repository=name, location=location) - repository = repository.__dict__ - if human_readable: - if 'quota' in repository: - repository['quota'] = binary_to_human(repository['quota']) - if 'used' in repository and isinstance(repository['used'], int): - repository['used'] = binary_to_human(repository['used']) - - return repository + logger.success(m18n.n('backup_repository_added', + repository=name, location=location)) - @is_unit_operation() - def backup_repository_add(operation_logger, location, name, description=None, - methods=None, quota=None, encryption="passphrase"): - """ - Add a backup repository +@is_unit_operation() +def backup_repository_update(operation_logger, name, description=None, + quota=None, password=None): + """ + Update a backup repository - Keyword arguments: - location -- Location of the repository (could be a remote location) - name -- Name of the backup repository - description -- An optionnal description - quota -- Maximum size quota of the repository - encryption -- If available, the kind of encryption to use - """ - repository = BackupRepository( - location, name, description, methods, quota, encryption) + Keyword arguments: + name -- Name of the backup repository + """ + repository = BackupRepository.get(name) - try: - repository.save() - except MoulinetteError: - raise YunohostError('backup_repository_add_failed', - repository=name, location=location) + if description is not None: + repository.description = description - logger.success(m18n.n('backup_repository_added', - repository=name, location=location)) + if quota is not None: + repository.quota = quota + + try: + repository.save() + except MoulinetteError: + raise YunohostError('backup_repository_update_failed', repository=name) + logger.success(m18n.n('backup_repository_updated', repository=name, + location=repository['location'])) - @is_unit_operation() - def backup_repository_update(operation_logger, name, description=None, - quota=None, password=None): - """ - Update a backup repository +@is_unit_operation() +def backup_repository_remove(operation_logger, name, purge=False): + """ + Remove a backup repository - Keyword arguments: - name -- Name of the backup repository - """ - repository = BackupRepository.get(name) + Keyword arguments: + name -- Name of the backup repository to remove - if description is not None: - repository.description = description - - if quota is not None: - repository.quota = quota - - try: - repository.save() - except MoulinetteError: - raise YunohostError('backup_repository_update_failed', repository=name) - logger.success(m18n.n('backup_repository_updated', repository=name, - location=repository['location'])) - - - @is_unit_operation() - def backup_repository_remove(operation_logger, name, purge=False): - """ - Remove a backup repository - - Keyword arguments: - name -- Name of the backup repository to remove - - """ - repository = BackupRepository.get(name) - repository.delete(purge) - logger.success(m18n.n('backup_repository_removed', repository=name, - path=repository['path'])) + """ + repository = BackupRepository.get(name) + repository.delete(purge) + logger.success(m18n.n('backup_repository_removed', repository=name, + path=repository['path']))