[wip] Remote borg repository

This commit is contained in:
ljf 2019-01-02 19:27:58 +01:00
parent 9f5b826078
commit d43a86b136
2 changed files with 60 additions and 23 deletions

View file

@ -891,6 +891,10 @@ backup:
action_help: List available local backup archives action_help: List available local backup archives
api: GET /backup/archives api: GET /backup/archives
arguments: arguments:
-r:
full: --repos
help: List archives in these repositories
nargs: "*"
-i: -i:
full: --with-info full: --with-info
help: Show backup information for each archive help: Show backup information for each archive

View file

@ -1889,42 +1889,75 @@ class TarBackupMethod(BackupMethod):
class BorgBackupMethod(BackupMethod): class BorgBackupMethod(BackupMethod):
def __init__(self, repo=None): def __init__(self, repo=None):
super(TarBackupMethod, self).__init__(repo) super(BorgBackupMethod, self).__init__(repo)
if not self.repo.domain: if not self.repo.domain:
filesystem.mkdir(self.repo.path, parent=True) filesystem.mkdir(self.repo.path, parent=True)
else:
#Todo Initialize remote repo cmd = ['borg', 'init', self.repo.location]
pass
if self.repo.quota:
cmd += ['--storage-quota', self.repo.quota]
borg = self._run_borg_command(cmd)
return_code = borg.wait()
if return_code:
raise YunohostError('backup_borg_init_error')
@property @property
def method_name(self): def method_name(self):
return 'borg' return 'borg'
def need_mount(self):
return True
def backup(self): def backup(self):
""" Backup prepared files with borg """ """ Backup prepared files with borg """
super(BorgBackupMethod, self).backup()
for path in self.manager.paths_to_backup: archive = self.repo.location + '::' + self.name
source = path['source'] cmd = ['borg', 'create', archive, './']
dest = os.path.join(self.repo.path, path['dest']) borg = self._run_borg_command(cmd)
if source == dest: return_code = borg.wait()
logger.debug("Files already copyed") if return_code:
return raise YunohostError('backup_borg_mount_error')
dest_parent = os.path.dirname(dest) def mount(self, restore_manager):
if not os.path.exists(dest_parent): """ Extract and mount needed files with borg """
filesystem.mkdir(dest_parent, 0o750, True, uid='admin') super(BorgBackupMethod, self).mount(restore_manager)
if os.path.isdir(source): # Export as tar needed files through a pipe
shutil.copytree(source, dest) archive = self.repo.location + '::' + self.name
else: cmd = ['borg', 'export-tar', archive, '-']
shutil.copy(source, dest) borg = self._run_borg_command(cmd, stdout=subprocess.PIPE)
# TODO run borg create command # And uncompress it into the working directory
raise YunohostError('backup_borg_not_implemented') untar = subprocess.Popen(['tar', 'x'], cwd=self.work_dir, stdin=borg.stdout)
borg_return_code = borg.wait()
untar_return_code = untar.wait()
if borg_return_code + untar_return_code != 0:
err = untar.communicate()[1]
raise YunohostError('backup_borg_backup_error')
def _run_borg_command(self, cmd, stdout=None):
env = dict(os.environ)
if self.repo.domain:
# TODO Use the best/good key
private_key = "/root/.ssh/ssh_host_ed25519_key"
# Don't check ssh fingerprint strictly the first time
# TODO improve this by publishing and checking this with DNS
strict = 'yes' if self.repo.domain in open('/root/.ssh/known_hosts').read() else 'no'
env['BORG_RSH'] = "ssh -i %s -oStrictHostKeyChecking=%s"
env['BORG_RSH'] = env['BORG_RSH'] % (private_key, strict)
# In case, borg need a passphrase to get access to the repo
if self.repo.passphrase:
cmd += ['-e', 'repokey']
env['BORG_PASSPHRASE'] = self.repo.passphrase
return subprocess.Popen(cmd, env=env, stdout=stdout)
def mount(self, mnt_path):
raise YunohostError('backup_borg_not_implemented')
class CustomBackupMethod(BackupMethod): class CustomBackupMethod(BackupMethod):
@ -1943,7 +1976,7 @@ class CustomBackupMethod(BackupMethod):
@property @property
def method_name(self): def method_name(self):
return 'borg' return 'custom'
def need_mount(self): def need_mount(self):
"""Call the backup_method hook to know if we need to organize files """Call the backup_method hook to know if we need to organize files