[fix] Errors in backup custom methods (#326)

This commit is contained in:
ljf (zamentur) 2017-07-13 19:36:31 +02:00 committed by Alexandre Aubin
parent 7be85b2e62
commit 20f4a39bf0
2 changed files with 27 additions and 19 deletions

View file

@ -748,6 +748,9 @@ backup:
full: --no-compress full: --no-compress
help: Do not create an archive file help: Do not create an archive file
action: store_true action: store_true
--methods:
help: List of backup methods to apply (copy or tar by default)
nargs: "*"
--system: --system:
help: List of system parts to backup (all by default) help: List of system parts to backup (all by default)
nargs: "*" nargs: "*"

View file

@ -1468,7 +1468,7 @@ class BackupMethod(object):
if self.manager.is_tmp_work_dir: if self.manager.is_tmp_work_dir:
filesystem.rm(self.work_dir, True, True) filesystem.rm(self.work_dir, True, True)
def _recursive_umount(directory): def _recursive_umount(self, directory):
""" """
Recursively umount sub directories of a directory Recursively umount sub directories of a directory
@ -1525,7 +1525,7 @@ class BackupMethod(object):
""" """
paths_needed_to_be_copied = [] paths_needed_to_be_copied = []
for path in self.manager.paths_to_backup: for path in self.manager.paths_to_backup:
src = path['src'] src = path['source']
if self.manager is RestoreManager: if self.manager is RestoreManager:
# TODO Support to run this before a restore (and not only before # TODO Support to run this before a restore (and not only before
@ -1534,14 +1534,17 @@ class BackupMethod(object):
src = os.path.join(self.unorganized_work_dir, src) src = os.path.join(self.unorganized_work_dir, src)
dest = os.path.join(self.work_dir, path['dest']) dest = os.path.join(self.work_dir, path['dest'])
if dest == src:
continue
dest_dir = os.path.dirname(dest) dest_dir = os.path.dirname(dest)
# Be sure the parent dir of destination exists # Be sure the parent dir of destination exists
filesystem.mkdir(dest_dir, parent=True) if not os.path.isdir(dest_dir):
filesystem.mkdir(dest_dir, parents=True)
# Try to bind files # Try to bind files
if os.path.isdir(src): if os.path.isdir(src):
filesystem.mkdir(dest, parent=True) filesystem.mkdir(dest, parents=True, force=True)
ret = subprocess.call(["mount", "-r", "--rbind", src, dest]) ret = subprocess.call(["mount", "-r", "--rbind", src, dest])
if ret == 0: if ret == 0:
continue continue
@ -1560,13 +1563,12 @@ class BackupMethod(object):
if len(paths_needed_to_be_copied) == 0: if len(paths_needed_to_be_copied) == 0:
return return
# Manage the case where we are not able to use mount bind abilities # Manage the case where we are not able to use mount bind abilities
# It could be just for some small files on different filesystems or due # It could be just for some small files on different filesystems or due
# to mounting error # to mounting error
# Compute size to copy # Compute size to copy
size = sum(disk_usage(path['src']) for path in paths_needed_to_be_copied) size = sum(disk_usage(path['source']) for path in paths_needed_to_be_copied)
size /= (1024 * 1024) # Convert bytes to megabytes size /= (1024 * 1024) # Convert bytes to megabytes
# Ask confirmation for copying # Ask confirmation for copying
@ -1583,10 +1585,11 @@ class BackupMethod(object):
# Copy unbinded path # Copy unbinded path
logger.info(m18n.n('backup_copying_to_organize_the_archive', size=size)) logger.info(m18n.n('backup_copying_to_organize_the_archive', size=size))
for path in paths_needed_to_be_copied: for path in paths_needed_to_be_copied:
if os.path.isdir(src): dest = os.path.join(self.work_dir, path['dest'])
shutil.copytree(src, dest, symlinks=True) if os.path.isdir(path['source']):
shutil.copytree(path['source'], dest, symlinks=True)
else: else:
shutil.copy(src, dest) shutil.copy(path['source'], dest)
@classmethod @classmethod
def create(cls, method, *args): def create(cls, method, *args):
@ -1616,7 +1619,7 @@ class BackupMethod(object):
if method in ["copy", "tar", "borg"]: if method in ["copy", "tar", "borg"]:
return bm_class[method](*args) return bm_class[method](*args)
else: else:
return CustomBackupMethod(*args) return CustomBackupMethod(method=method, *args)
class CopyBackupMethod(BackupMethod): class CopyBackupMethod(BackupMethod):
@ -1861,9 +1864,10 @@ class CustomBackupMethod(BackupMethod):
backup/restore operations. A user can add his own hook inside backup/restore operations. A user can add his own hook inside
/etc/yunohost/hooks.d/backup_method/ /etc/yunohost/hooks.d/backup_method/
""" """
def __init__(self, repo = None, **kwargs): def __init__(self, repo = None, method = None,**kwargs):
super(CustomBackupMethod, self).__init__(repo) super(CustomBackupMethod, self).__init__(repo)
self.args = kwargs self.args = kwargs
self.method = method
self._need_mount = None self._need_mount = None
@ -1878,13 +1882,14 @@ class CustomBackupMethod(BackupMethod):
Exceptions: Exceptions:
backup_custom_need_mount_error -- Raised if the hook failed backup_custom_need_mount_error -- Raised if the hook failed
""" """
ret = hook_callback('backup_method', method, if self._need_mount is not None:
return self._need_mount
ret = hook_callback('backup_method', [self.method],
args=self._get_args('need_mount')) args=self._get_args('need_mount'))
if ret['succeed']:
return True self._need_mount = True if ret['succeed'] else False
else: return self._need_mount
raise MoulinetteError(errno.EIO,
m18n.n('backup_custom_need_mount_error'))
def backup(self): def backup(self):
@ -1895,7 +1900,7 @@ 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', method, ret = hook_callback('backup_method', [self.method],
args=self._get_args('backup')) args=self._get_args('backup'))
if ret['failed']: if ret['failed']:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
@ -1909,7 +1914,7 @@ 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', method, ret = hook_callback('backup_method', [self.method],
args=self._get_args('mount')) args=self._get_args('mount'))
if ret['failed']: if ret['failed']:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,