mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[wip] List archives of custom backup method
This commit is contained in:
parent
1219583692
commit
7815093863
1 changed files with 87 additions and 53 deletions
|
@ -38,6 +38,7 @@ from collections import OrderedDict
|
||||||
from moulinette import msignals, m18n
|
from moulinette import msignals, m18n
|
||||||
from yunohost.utils.error import YunohostError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils import filesystem
|
from moulinette.utils import filesystem
|
||||||
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_file
|
from moulinette.utils.filesystem import read_file
|
||||||
|
|
||||||
|
@ -1435,6 +1436,11 @@ class BackupMethod(object):
|
||||||
"""Return the string name of a BackupMethod (eg "tar" or "copy")"""
|
"""Return the string name of a BackupMethod (eg "tar" or "copy")"""
|
||||||
raise YunohostError('backup_abstract_method')
|
raise YunohostError('backup_abstract_method')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def archive_path(self):
|
||||||
|
"""Return the archive path"""
|
||||||
|
return self.repo.location + '::' + self.name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return the backup name"""
|
"""Return the backup name"""
|
||||||
|
@ -1940,7 +1946,7 @@ class TarBackupMethod(BackupMethod):
|
||||||
path=archive_file)
|
path=archive_file)
|
||||||
|
|
||||||
def _get_info_string(self):
|
def _get_info_string(self):
|
||||||
info_file = "%s/%s.info.json" % (self.repo.path, self.name)
|
info_file = os.path.join(self.repo.path, self.name + '.info.json')
|
||||||
|
|
||||||
if not os.path.exists(info_file):
|
if not os.path.exists(info_file):
|
||||||
tar = tarfile.open(self.archive_path, "r:gz")
|
tar = tarfile.open(self.archive_path, "r:gz")
|
||||||
|
@ -1976,20 +1982,12 @@ class BorgBackupMethod(BackupMethod):
|
||||||
|
|
||||||
if self.repo.quota:
|
if self.repo.quota:
|
||||||
cmd += ['--storage-quota', self.repo.quota]
|
cmd += ['--storage-quota', self.repo.quota]
|
||||||
borg = self._run_borg_command(cmd)
|
self._call('init', 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'
|
||||||
|
|
||||||
@property
|
|
||||||
def archive_path(self):
|
|
||||||
"""Return the archive path"""
|
|
||||||
return self.repo.location + '::' + self.name
|
|
||||||
|
|
||||||
def need_mount(self):
|
def need_mount(self):
|
||||||
return True
|
return True
|
||||||
|
@ -1998,10 +1996,7 @@ class BorgBackupMethod(BackupMethod):
|
||||||
""" Backup prepared files with borg """
|
""" Backup prepared files with borg """
|
||||||
|
|
||||||
cmd = ['borg', 'create', self.archive_path, './']
|
cmd = ['borg', 'create', self.archive_path, './']
|
||||||
borg = self._run_borg_command(cmd)
|
self._call('backup', cmd)
|
||||||
return_code = borg.wait()
|
|
||||||
if return_code:
|
|
||||||
raise YunohostError('backup_borg_mount_error')
|
|
||||||
|
|
||||||
def mount(self, restore_manager):
|
def mount(self, restore_manager):
|
||||||
""" Extract and mount needed files with borg """
|
""" Extract and mount needed files with borg """
|
||||||
|
@ -2016,42 +2011,41 @@ class BorgBackupMethod(BackupMethod):
|
||||||
borg_return_code = borg.wait()
|
borg_return_code = borg.wait()
|
||||||
untar_return_code = untar.wait()
|
untar_return_code = untar.wait()
|
||||||
if borg_return_code + untar_return_code != 0:
|
if borg_return_code + untar_return_code != 0:
|
||||||
err = untar.communicate()[1]
|
# err = untar.communicate()[1]
|
||||||
raise YunohostError('backup_borg_backup_error')
|
raise YunohostError('backup_borg_mount_error')
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
|
""" Return a list of archives names
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_borg_list_error -- Raised if the borg script failed
|
||||||
|
"""
|
||||||
cmd = ['borg', 'list', self.repo.location, '--short']
|
cmd = ['borg', 'list', self.repo.location, '--short']
|
||||||
borg = self._run_borg_command(cmd)
|
out = self._call('list', cmd)
|
||||||
return_code = borg.wait()
|
|
||||||
if return_code:
|
|
||||||
raise YunohostError('backup_borg_list_error')
|
|
||||||
|
|
||||||
out, _ = borg.communicate()
|
|
||||||
|
|
||||||
result = out.strip().splitlines()
|
result = out.strip().splitlines()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _assert_archive_exists(self):
|
def _assert_archive_exists(self):
|
||||||
|
""" Trigger an error if archive is missing
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_borg_exist_error -- Raised if the borg script failed
|
||||||
|
"""
|
||||||
cmd = ['borg', 'list', self.archive_path]
|
cmd = ['borg', 'list', self.archive_path]
|
||||||
borg = self._run_borg_command(cmd)
|
self._call('exist', cmd)
|
||||||
return_code = borg.wait()
|
|
||||||
if return_code:
|
|
||||||
raise YunohostError('backup_borg_archive_name_unknown')
|
|
||||||
|
|
||||||
def _get_info_string(self):
|
def _get_info_string(self):
|
||||||
# Export as tar info file through a pipe
|
""" Return json string of the info.json file
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_borg_info_error -- Raised if the custom script failed
|
||||||
|
"""
|
||||||
cmd = ['borg', 'extract', '--stdout', self.archive_path, 'info.json']
|
cmd = ['borg', 'extract', '--stdout', self.archive_path, 'info.json']
|
||||||
borg = self._run_borg_command(cmd)
|
return self._call('info', cmd)
|
||||||
return_code = borg.wait()
|
|
||||||
if return_code:
|
|
||||||
raise YunohostError('backup_borg_info_error')
|
|
||||||
|
|
||||||
out, _ = borg.communicate()
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
def _run_borg_command(self, cmd, stdout=None):
|
def _run_borg_command(self, cmd, stdout=None):
|
||||||
|
""" Call a submethod of borg with the good context
|
||||||
|
"""
|
||||||
env = dict(os.environ)
|
env = dict(os.environ)
|
||||||
|
|
||||||
if self.repo.domain:
|
if self.repo.domain:
|
||||||
|
@ -2071,6 +2065,16 @@ class BorgBackupMethod(BackupMethod):
|
||||||
|
|
||||||
return subprocess.Popen(cmd, env=env, stdout=stdout)
|
return subprocess.Popen(cmd, env=env, stdout=stdout)
|
||||||
|
|
||||||
|
def _call(self, action, cmd):
|
||||||
|
borg = self._run_borg_command(cmd)
|
||||||
|
return_code = borg.wait()
|
||||||
|
if return_code:
|
||||||
|
raise YunohostError('backup_borg_' + action + '_error')
|
||||||
|
|
||||||
|
out, _ = borg.communicate()
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CustomBackupMethod(BackupMethod):
|
class CustomBackupMethod(BackupMethod):
|
||||||
|
@ -2101,9 +2105,9 @@ class CustomBackupMethod(BackupMethod):
|
||||||
return self._need_mount
|
return self._need_mount
|
||||||
|
|
||||||
ret = hook_callback('backup_method', [self.method],
|
ret = hook_callback('backup_method', [self.method],
|
||||||
args=self._get_args('need_mount'))
|
args=['need_mount'])
|
||||||
|
|
||||||
self._need_mount = True if ret['succeed'] else False
|
self._need_mount = bool(ret['succeed'])
|
||||||
return self._need_mount
|
return self._need_mount
|
||||||
|
|
||||||
def backup(self):
|
def backup(self):
|
||||||
|
@ -2114,10 +2118,8 @@ class CustomBackupMethod(BackupMethod):
|
||||||
backup_custom_backup_error -- Raised if the custom script failed
|
backup_custom_backup_error -- Raised if the custom script failed
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ret = hook_callback('backup_method', [self.method],
|
self._call('backup', self.work_dir, self.name, self.repo.location, self.manager.size,
|
||||||
args=self._get_args('backup'))
|
self.manager.description)
|
||||||
if ret['failed']:
|
|
||||||
raise YunohostError('backup_custom_backup_error')
|
|
||||||
|
|
||||||
def mount(self, restore_manager):
|
def mount(self, restore_manager):
|
||||||
"""
|
"""
|
||||||
|
@ -2127,15 +2129,47 @@ class CustomBackupMethod(BackupMethod):
|
||||||
backup_custom_mount_error -- Raised if the custom script failed
|
backup_custom_mount_error -- Raised if the custom script failed
|
||||||
"""
|
"""
|
||||||
super(CustomBackupMethod, self).mount(restore_manager)
|
super(CustomBackupMethod, self).mount(restore_manager)
|
||||||
ret = hook_callback('backup_method', [self.method],
|
self._call('mount', self.work_dir, self.name, self.repo.location, self.manager.size,
|
||||||
args=self._get_args('mount'))
|
self.manager.description)
|
||||||
if ret['failed']:
|
|
||||||
raise YunohostError('backup_custom_mount_error')
|
|
||||||
|
|
||||||
def _get_args(self, action):
|
def list(self):
|
||||||
"""Return the arguments to give to the custom script"""
|
""" Return a list of archives names
|
||||||
return [action, self.work_dir, self.name, self.repo, self.manager.size,
|
|
||||||
self.manager.description]
|
Exceptions:
|
||||||
|
backup_custom_list_error -- Raised if the custom script failed
|
||||||
|
"""
|
||||||
|
out = self._call('list', self.repo.location)
|
||||||
|
result = out.strip().splitlines()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _assert_archive_exists(self):
|
||||||
|
""" Trigger an error if archive is missing
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_custom_exist_error -- Raised if the custom script failed
|
||||||
|
"""
|
||||||
|
self._call('exist', self.name, self.repo.location)
|
||||||
|
|
||||||
|
def _get_info_string(self):
|
||||||
|
""" Return json string of the info.json file
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_custom_info_error -- Raised if the custom script failed
|
||||||
|
"""
|
||||||
|
return self._call('info', self.name, self.repo.location)
|
||||||
|
|
||||||
|
def _call(self, *args):
|
||||||
|
""" Call a submethod of backup method hook
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
backup_custom_ACTION_error -- Raised if the custom script failed
|
||||||
|
"""
|
||||||
|
ret = hook_callback('backup_method', [self.method],
|
||||||
|
args=args)
|
||||||
|
if ret['failed']:
|
||||||
|
raise YunohostError('backup_custom_' + args[0] + '_error')
|
||||||
|
|
||||||
|
return ret['succeed'][self.method]['stdreturn']
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2333,7 +2367,7 @@ def backup_info(name, repo=None, with_details=False, human_readable=False):
|
||||||
|
|
||||||
repo = BackupRepository.get(repo)
|
repo = BackupRepository.get(repo)
|
||||||
|
|
||||||
info = repo.info(name)
|
info = repo.method.info(name)
|
||||||
|
|
||||||
# Historically backup size was not here, in that case we know it's a tar archive
|
# Historically backup size was not here, in that case we know it's a tar archive
|
||||||
size = info.get('size', 0)
|
size = info.get('size', 0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue