mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[fix] Validate backup/restore hooks and show restoration result
This commit is contained in:
parent
76c7b3b3db
commit
a51e395bca
2 changed files with 90 additions and 25 deletions
|
@ -62,7 +62,7 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
|
||||
"""
|
||||
# TODO: Add a 'clean' argument to clean output directory
|
||||
from yunohost.hook import hook_callback, hook_exec
|
||||
from yunohost.hook import hook_list, hook_callback, hook_exec
|
||||
|
||||
tmp_dir = None
|
||||
|
||||
|
@ -136,9 +136,24 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
|
||||
# Run system hooks
|
||||
if not ignore_hooks:
|
||||
msignals.display(m18n.n('backup_running_hooks'))
|
||||
hooks_ret = hook_callback('backup', hooks, args=[tmp_dir])
|
||||
info['hooks'] = hooks_ret['succeed']
|
||||
# Check hooks availibility
|
||||
hooks_available = hook_list('backup')['hooks']
|
||||
hooks_filtered = set()
|
||||
if hooks:
|
||||
for hook in hooks:
|
||||
if hook not in hooks_available:
|
||||
logger.exception("backup hook '%s' not found", hook)
|
||||
msignals.display(m18n.n('backup_hook_unknown', hook=hook),
|
||||
'error')
|
||||
else:
|
||||
hooks_filtered.add(hook)
|
||||
else:
|
||||
hooks_filtered = hooks_available
|
||||
|
||||
if hooks_filtered:
|
||||
msignals.display(m18n.n('backup_running_hooks'))
|
||||
ret = hook_callback('backup', hooks_filtered, args=[tmp_dir])
|
||||
info['hooks'] = ret['succeed']
|
||||
|
||||
# Backup apps
|
||||
if not ignore_apps:
|
||||
|
@ -205,10 +220,10 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
finally:
|
||||
filesystem.rm(tmp_script, force=True)
|
||||
|
||||
# Check if something has been saved
|
||||
if ignore_hooks and not info['apps']:
|
||||
_clean_tmp_dir(1)
|
||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
||||
# Check if something has been saved
|
||||
if not info['hooks'] and not info['apps']:
|
||||
_clean_tmp_dir(1)
|
||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
||||
|
||||
# Create backup info file
|
||||
with open("%s/info.json" % tmp_dir, 'w') as f:
|
||||
|
@ -270,9 +285,12 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=Fals
|
|||
force -- Force restauration on an already installed system
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_add
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.hook import hook_exec
|
||||
from yunohost.hook import hook_add, hook_list, hook_callback, hook_exec
|
||||
|
||||
# Validate what to restore
|
||||
if ignore_hooks and ignore_apps:
|
||||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('restore_action_required'))
|
||||
|
||||
# Retrieve and open the archive
|
||||
info = backup_info(name)
|
||||
|
@ -291,6 +309,13 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=Fals
|
|||
tmp_dir)
|
||||
os.system('rm -rf %s' % tmp_dir)
|
||||
|
||||
def _clean_tmp_dir(retcode=0):
|
||||
ret = hook_callback('post_backup_restore', args=[tmp_dir, retcode])
|
||||
if not ret['failed']:
|
||||
filesystem.rm(tmp_dir, True, True)
|
||||
else:
|
||||
msignals.display(m18n.n('restore_cleaning_failed'), 'warning')
|
||||
|
||||
# Extract the tarball
|
||||
msignals.display(m18n.n('backup_extracting_archive'))
|
||||
tar.extractall(tmp_dir)
|
||||
|
@ -308,6 +333,12 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=Fals
|
|||
logger.info("restoring from backup '%s' created on %s", name,
|
||||
time.ctime(info['created_at']))
|
||||
|
||||
# Initialize restauration summary result
|
||||
result = {
|
||||
'apps': [],
|
||||
'hooks': {},
|
||||
}
|
||||
|
||||
# Check if YunoHost is installed
|
||||
if os.path.isfile('/etc/yunohost/installed'):
|
||||
msignals.display(m18n.n('yunohost_already_installed'), 'warning')
|
||||
|
@ -338,18 +369,40 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=Fals
|
|||
logger.info("executing the post-install...")
|
||||
tools_postinstall(domain, 'yunohost', True)
|
||||
|
||||
# Run hooks
|
||||
# Run system hooks
|
||||
if not ignore_hooks:
|
||||
if hooks is None or len(hooks)==0:
|
||||
hooks=info['hooks'].keys()
|
||||
# Filter hooks to execute
|
||||
hooks_list = set(info['hooks'].keys())
|
||||
_is_hook_in_backup = lambda h: True
|
||||
if hooks:
|
||||
def _is_hook_in_backup(h):
|
||||
if h in hooks_list:
|
||||
return True
|
||||
logger.warning("hook '%s' not executed in the backup '%s'",
|
||||
h, archive_file)
|
||||
msignals.display(m18n.n('backup_archive_hook_not_exec', hook=h),
|
||||
'error')
|
||||
return False
|
||||
else:
|
||||
hooks = hooks_list
|
||||
|
||||
hooks_filtered=list(set(hooks) & set(info['hooks'].keys()))
|
||||
hooks_unexecuted=set(hooks) - set(info['hooks'].keys())
|
||||
for hook in hooks_unexecuted:
|
||||
logger.warning("hook '%s' not in this backup", hook)
|
||||
msignals.display(m18n.n('backup_hook_unavailable', hook), 'warning')
|
||||
msignals.display(m18n.n('restore_running_hooks'))
|
||||
hook_callback('restore', hooks_filtered, args=[tmp_dir])
|
||||
# Check hooks availibility
|
||||
hooks_available = hook_list('restore')['hooks']
|
||||
hooks_filtered = set()
|
||||
for hook in hooks:
|
||||
if not _is_hook_in_backup(hook):
|
||||
continue
|
||||
if hook not in hooks_available:
|
||||
logger.exception("restoration hook '%s' not found", hook)
|
||||
msignals.display(m18n.n('restore_hook_unavailable', hook=hook),
|
||||
'error')
|
||||
continue
|
||||
hooks_filtered.add(hook)
|
||||
|
||||
if hooks_filtered:
|
||||
msignals.display(m18n.n('restore_running_hooks'))
|
||||
ret = hook_callback('restore', hooks_filtered, args=[tmp_dir])
|
||||
result['hooks'] = ret['succeed']
|
||||
|
||||
# Add apps restore hook
|
||||
if not ignore_apps:
|
||||
|
@ -409,14 +462,21 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=Fals
|
|||
'error')
|
||||
# Cleaning app directory
|
||||
shutil.rmtree(app_setting_path, ignore_errors=True)
|
||||
else:
|
||||
result['apps'].append(app_id)
|
||||
finally:
|
||||
filesystem.rm(tmp_script, force=True)
|
||||
|
||||
# Remove temporary directory
|
||||
os.system('rm -rf %s' % tmp_dir)
|
||||
# Check if something has been restored
|
||||
if not result['hooks'] and not result['apps']:
|
||||
_clean_tmp_dir(1)
|
||||
raise MoulinetteError(errno.EINVAL, m18n.n('restore_nothings_done'))
|
||||
|
||||
_clean_tmp_dir()
|
||||
msignals.display(m18n.n('restore_complete'), 'success')
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def backup_list(with_info=False, human_readable=False):
|
||||
"""
|
||||
|
|
|
@ -144,6 +144,7 @@
|
|||
"backup_output_directory_required" : "You must provide an output directory for the backup",
|
||||
"backup_output_directory_forbidden" : "Forbidden output directory",
|
||||
"backup_output_directory_not_empty" : "Output directory is not empty",
|
||||
"backup_hook_unknown" : "Backup hook '{hook:s}' unknown",
|
||||
"backup_running_hooks" : "Running backup hooks...",
|
||||
"backup_running_app_script" : "Running backup script of app '{:s}'...",
|
||||
"backup_creating_archive" : "Creating the backup archive...",
|
||||
|
@ -151,18 +152,22 @@
|
|||
"backup_archive_open_failed" : "Unable to open the backup archive",
|
||||
"backup_archive_name_unknown" : "Unknown local backup archive named '{:s}'",
|
||||
"backup_archive_name_exists" : "Backup archive name already exists",
|
||||
"backup_archive_hook_not_exec" : "Hook '{hook:s}' not executed in this backup",
|
||||
"backup_archive_app_not_found" : "App '{app:s}' not found in the backup archive",
|
||||
"backup_app_failed" : "Unable to back up the app '{app:s}'",
|
||||
"backup_nothings_done" : "There is nothing to save",
|
||||
"backup_cleaning_failed" : "Unable to clean backup directory",
|
||||
"backup_cleaning_failed" : "Unable to clean backup temporary directory",
|
||||
"backup_complete" : "Backup complete",
|
||||
"backup_invalid_archive" : "Invalid backup archive",
|
||||
"backup_hook_unavailable" : "The hook '{:s}' is not in this backup",
|
||||
"restore_action_required" : "You must specify something to restore",
|
||||
"restore_confirm_yunohost_installed" : "Do you really want to restore an already installed system? [{answers:s}]",
|
||||
"restore_hook_unavailable" : "Restauration hook '{hook:s}' not available on your system",
|
||||
"restore_app_failed" : "Unable to restore the app '{app:s}'",
|
||||
"restore_running_hooks" : "Running restoration hooks...",
|
||||
"restore_running_app_script" : "Running restore script of app '{app:s}'...",
|
||||
"restore_failed" : "Unable to restore the system",
|
||||
"restore_nothings_done" : "Nothing has been restored",
|
||||
"restore_cleaning_failed" : "Unable to clean restoration temporary directory",
|
||||
"restore_complete" : "Restore complete",
|
||||
"restore_already_installed_app": "An app is already installed with the id '{app:s}'",
|
||||
"unbackup_app" : "App '{app:s}' will not be saved",
|
||||
|
|
Loading…
Add table
Reference in a new issue