mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #106 from zamentur/unstable
[fix] Allow to restore app correctly
This commit is contained in:
commit
05c71a871e
18 changed files with 109 additions and 41 deletions
|
@ -636,6 +636,9 @@ backup:
|
||||||
--ignore-apps:
|
--ignore-apps:
|
||||||
help: Do not restore apps
|
help: Do not restore apps
|
||||||
action: store_true
|
action: store_true
|
||||||
|
--ignore-hooks:
|
||||||
|
help: Do not restore hooks
|
||||||
|
action: store_true
|
||||||
--force:
|
--force:
|
||||||
help: Force restauration on an already installed system
|
help: Force restauration on an already installed system
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
backup_dir="$1/conf/ldap"
|
backup_dir="$1/conf/ldap"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
# Fix for first jessie yunohost where slapd.conf is called slapd-yuno.conf
|
# Fix for first jessie yunohost where slapd.conf is called slapd-yuno.conf
|
||||||
# without slapcat doesn't work
|
# without slapcat doesn't work
|
||||||
|
@ -11,5 +11,5 @@ fi
|
||||||
sudo cp -a /etc/ldap/slapd.conf $backup_dir/
|
sudo cp -a /etc/ldap/slapd.conf $backup_dir/
|
||||||
|
|
||||||
sudo slapcat -l $backup_dir/slapcat.ldif.raw
|
sudo slapcat -l $backup_dir/slapcat.ldif.raw
|
||||||
egrep -v "^entryCSN:" < $backup_dir/slapcat.ldif.raw > $backup_dir/slapcat.ldif
|
sudo bash -c "egrep -v '^entryCSN:' < $backup_dir/slapcat.ldif.raw > $backup_dir/slapcat.ldif"
|
||||||
rm -f $backup_dir/slapcat.ldif.raw
|
sudo rm -f $backup_dir/slapcat.ldif.raw
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
backup_dir="$1/conf/ssh"
|
backup_dir="$1/conf/ssh"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/ssh/. $backup_dir
|
if [ -d /etc/ssh/ ]; then
|
||||||
|
sudo cp -a /etc/ssh/. $backup_dir
|
||||||
|
else
|
||||||
|
echo "SSH is not installed"
|
||||||
|
fi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/ynh/mysql"
|
backup_dir="$1/conf/ynh/mysql"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/yunohost/mysql $backup_dir/
|
sudo cp -a /etc/yunohost/mysql $backup_dir/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/ssowat"
|
backup_dir="$1/conf/ssowat"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/ssowat/. $backup_dir
|
sudo cp -a /etc/ssowat/. $backup_dir
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
backup_dir="$1/data/home"
|
backup_dir="$1/data/home"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
. /usr/share/yunohost/apps/helpers
|
. /usr/share/yunohost/apps/helpers
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/ynh/firewall"
|
backup_dir="$1/conf/ynh/firewall"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/yunohost/firewall* $backup_dir
|
sudo cp -a /etc/yunohost/firewall* $backup_dir
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/ynh/certs"
|
backup_dir="$1/conf/ynh/certs"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/yunohost/certs/. $backup_dir
|
sudo cp -a /etc/yunohost/certs/. $backup_dir
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
backup_dir="$1/conf/xmpp"
|
backup_dir="$1/conf/xmpp"
|
||||||
mkdir -p $backup_dir/{etc,var}
|
sudo mkdir -p $backup_dir/{etc,var}
|
||||||
|
|
||||||
sudo cp -a /etc/metronome/. $backup_dir/etc
|
sudo cp -a /etc/metronome/. $backup_dir/etc
|
||||||
sudo cp -a /var/lib/metronome/. $backup_dir/var
|
sudo cp -a /var/lib/metronome/. $backup_dir/var
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/nginx"
|
backup_dir="$1/conf/nginx"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/nginx/conf.d/. $backup_dir
|
sudo cp -a /etc/nginx/conf.d/. $backup_dir
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/cron"
|
backup_dir="$1/conf/cron"
|
||||||
mkdir -p $backup_dir
|
sudo mkdir -p $backup_dir
|
||||||
|
|
||||||
sudo cp -a /etc/cron.d/yunohost* $backup_dir/
|
sudo cp -a /etc/cron.d/yunohost* $backup_dir/
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
backup_dir="$1/conf/ssh"
|
backup_dir="$1/conf/ssh"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/ssh
|
if [ -d /etc/ssh/ ]; then
|
||||||
sudo service ssh restart
|
sudo cp -a $backup_dir/. /etc/ssh
|
||||||
|
sudo service ssh restart
|
||||||
|
else
|
||||||
|
echo "SSH is not installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
backup_dir="$1/conf/ynh/mysql"
|
backup_dir="$1/conf/ynh/mysql"
|
||||||
|
|
||||||
service mysql restart
|
sudo service mysql restart
|
||||||
sudo cp -a $backup_dir/mysql /etc/yunohost/mysql
|
sudo cp -a $backup_dir/mysql /etc/yunohost/mysql
|
||||||
mysqlpwd=$(sudo cat /etc/yunohost/mysql)
|
mysqlpwd=$(sudo cat /etc/yunohost/mysql)
|
||||||
sudo mysqladmin flush-privileges -p"$mysqlpwd"
|
sudo mysqladmin flush-privileges -p"$mysqlpwd"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
backup_dir="$1/conf/ynh/certs"
|
backup_dir="$1/conf/ynh/certs"
|
||||||
|
|
||||||
mkdir -p /etc/yunohost/certs/
|
sudo mkdir -p /etc/yunohost/certs/
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/yunohost/certs/
|
sudo cp -a $backup_dir/. /etc/yunohost/certs/
|
||||||
sudo yunohost app ssowatconf
|
sudo yunohost app ssowatconf
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
backup_dir="$1/data/mail"
|
backup_dir="$1/data/mail"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /var/mail
|
sudo cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
|
||||||
|
|
||||||
# Restart services to use migrated certs
|
# Restart services to use migrated certs
|
||||||
sudo service postfix restart
|
sudo service postfix restart
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
backup_dir="$1/conf/nginx"
|
backup_dir="$1/conf/nginx"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/nginx/conf.d
|
# Copy all conf except apps specific conf located in DOMAIN.d
|
||||||
|
sudo find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec sudo cp -a {} /etc/nginx/conf.d/ \;
|
||||||
|
|
||||||
# Restart to use new conf and certs
|
# Restart to use new conf and certs
|
||||||
sudo service nginx restart
|
sudo service nginx restart
|
||||||
|
|
|
@ -162,6 +162,8 @@ def backup_create(name=None, description=None, output_directory=None,
|
||||||
for app_id in apps_filtered:
|
for app_id in apps_filtered:
|
||||||
app_setting_path = '/etc/yunohost/apps/' + app_id
|
app_setting_path = '/etc/yunohost/apps/' + app_id
|
||||||
|
|
||||||
|
tmp_app_dir = '{:s}/apps/{:s}'.format(tmp_dir, app_id)
|
||||||
|
|
||||||
# Check if the app has a backup script
|
# Check if the app has a backup script
|
||||||
app_script = app_setting_path + '/scripts/backup'
|
app_script = app_setting_path + '/scripts/backup'
|
||||||
if not os.path.isfile(app_script):
|
if not os.path.isfile(app_script):
|
||||||
|
@ -169,8 +171,22 @@ def backup_create(name=None, description=None, output_directory=None,
|
||||||
msignals.display(m18n.n('unbackup_app', app_id),
|
msignals.display(m18n.n('unbackup_app', app_id),
|
||||||
'warning')
|
'warning')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Copy the app restore script
|
||||||
|
app_restore_script = app_setting_path + '/scripts/restore'
|
||||||
|
if os.path.isfile(app_script):
|
||||||
|
try:
|
||||||
|
filesystem.mkdir(tmp_app_dir, 0750, True, uid='admin')
|
||||||
|
shutil.copy(app_restore_script, tmp_app_dir)
|
||||||
|
except:
|
||||||
|
logger.exception("error while copying restore script of '%s'", app_id)
|
||||||
|
msignals.display(m18n.n('restore_app_copy_failed', app=app_id),
|
||||||
|
'warning')
|
||||||
|
else:
|
||||||
|
logger.warning("restore script '%s' not found", app_script)
|
||||||
|
msignals.display(m18n.n('unrestorable_app', app_id),
|
||||||
|
'warning')
|
||||||
|
|
||||||
tmp_app_dir = '{:s}/apps/{:s}'.format(tmp_dir, app_id)
|
|
||||||
tmp_app_bkp_dir = tmp_app_dir + '/backup'
|
tmp_app_bkp_dir = tmp_app_dir + '/backup'
|
||||||
msignals.display(m18n.n('backup_running_app_script', app_id))
|
msignals.display(m18n.n('backup_running_app_script', app_id))
|
||||||
try:
|
try:
|
||||||
|
@ -192,6 +208,8 @@ def backup_create(name=None, description=None, output_directory=None,
|
||||||
i = app_info(app_id)
|
i = app_info(app_id)
|
||||||
info['apps'][app_id] = {
|
info['apps'][app_id] = {
|
||||||
'version': i['version'],
|
'version': i['version'],
|
||||||
|
'name': i['name'],
|
||||||
|
'description': i['description'],
|
||||||
}
|
}
|
||||||
finally:
|
finally:
|
||||||
filesystem.rm(tmp_script, force=True)
|
filesystem.rm(tmp_script, force=True)
|
||||||
|
@ -249,7 +267,7 @@ def backup_create(name=None, description=None, output_directory=None,
|
||||||
return { 'archive': info }
|
return { 'archive': info }
|
||||||
|
|
||||||
|
|
||||||
def backup_restore(name, hooks=[], apps=[], ignore_apps=False, force=False):
|
def backup_restore(name, hooks=[], apps=[], ignore_apps=False, ignore_hooks=False, force=False):
|
||||||
"""
|
"""
|
||||||
Restore from a local backup archive
|
Restore from a local backup archive
|
||||||
|
|
||||||
|
@ -263,9 +281,11 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, force=False):
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_add
|
from yunohost.hook import hook_add
|
||||||
from yunohost.hook import hook_callback
|
from yunohost.hook import hook_callback
|
||||||
|
from yunohost.hook import hook_exec
|
||||||
|
|
||||||
# Retrieve and open the archive
|
# Retrieve and open the archive
|
||||||
archive_file = backup_info(name)['path']
|
info = backup_info(name)
|
||||||
|
archive_file = info['path']
|
||||||
try:
|
try:
|
||||||
tar = tarfile.open(archive_file, "r:gz")
|
tar = tarfile.open(archive_file, "r:gz")
|
||||||
except:
|
except:
|
||||||
|
@ -327,32 +347,61 @@ def backup_restore(name, hooks=[], apps=[], ignore_apps=False, force=False):
|
||||||
logger.info("executing the post-install...")
|
logger.info("executing the post-install...")
|
||||||
tools_postinstall(domain, 'yunohost', True)
|
tools_postinstall(domain, 'yunohost', True)
|
||||||
|
|
||||||
|
# Run hooks
|
||||||
|
if not ignore_hooks:
|
||||||
|
if hooks is None or len(hooks)==0:
|
||||||
|
hooks=info['hooks'].keys()
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
# Add apps restore hook
|
# Add apps restore hook
|
||||||
if not ignore_apps:
|
if not ignore_apps:
|
||||||
# Filter applications to restore
|
# Filter applications to restore
|
||||||
apps_list = set(info['apps'].keys())
|
apps_list = set(info['apps'].keys())
|
||||||
apps_filtered = set()
|
apps_filtered = set()
|
||||||
if apps:
|
if not apps:
|
||||||
for a in apps:
|
apps=apps_list
|
||||||
if a not in apps_list:
|
|
||||||
logger.warning("app '%s' not found", a)
|
from yunohost.app import _is_installed
|
||||||
msignals.display(m18n.n('unrestore_app', a), 'warning')
|
for app_id in apps:
|
||||||
else:
|
if app_id not in apps_list:
|
||||||
apps_filtered.add(a)
|
logger.warning("app '%s' not found", app_id)
|
||||||
else:
|
|
||||||
apps_filtered = apps_list
|
|
||||||
|
|
||||||
for app_id in apps_filtered:
|
|
||||||
hook = "/etc/yunohost/apps/%s/scripts/restore" % app_id
|
|
||||||
if os.path.isfile(hook):
|
|
||||||
hook_add(app_id, hook)
|
|
||||||
logger.info("app '%s' will be restored", app_id)
|
|
||||||
else:
|
|
||||||
msignals.display(m18n.n('unrestore_app', app_id), 'warning')
|
msignals.display(m18n.n('unrestore_app', app_id), 'warning')
|
||||||
|
elif _is_installed(app_id):
|
||||||
|
logger.warning("app '%s' already installed", app_id)
|
||||||
|
msignals.display(m18n.n('restore_already_installed_app', app=app_id), 'warning')
|
||||||
|
elif not os.path.isfile('{:s}/apps/{:s}/restore'.format(tmp_dir, app_id)):
|
||||||
|
logger.warning("backup for '%s' doesn't contain a restore script", app_id)
|
||||||
|
msignals.display(m18n.n('no_restore_script', app=app_id), 'warning')
|
||||||
|
else:
|
||||||
|
apps_filtered.add(app_id)
|
||||||
|
|
||||||
|
for app_id in apps_filtered:
|
||||||
|
app_bkp_dir='{:s}/apps/{:s}'.format(tmp_dir, app_id)
|
||||||
|
try:
|
||||||
|
# Copy app settings
|
||||||
|
app_setting_path = '/etc/yunohost/apps/' + app_id
|
||||||
|
shutil.copytree(app_bkp_dir + '/settings', app_setting_path )
|
||||||
|
|
||||||
|
# Execute app restore script
|
||||||
|
app_restore_script=app_bkp_dir+'/restore'
|
||||||
|
tmp_script = '/tmp/restore_%s_%s' % (name,app_id)
|
||||||
|
subprocess.call(['install', '-Dm555', app_restore_script, tmp_script])
|
||||||
|
hook_exec(tmp_script, args=[app_bkp_dir+'/backup', app_id])
|
||||||
|
|
||||||
|
except:
|
||||||
|
logger.exception("error while restoring backup of '%s'", app_id)
|
||||||
|
msignals.display(m18n.n('restore_app_failed', app=app_id),
|
||||||
|
'error')
|
||||||
|
# Cleaning settings directory
|
||||||
|
shutil.rmtree(app_setting_path + '/settings', ignore_errors=True)
|
||||||
|
|
||||||
# Run hooks
|
|
||||||
msignals.display(m18n.n('restore_running_hooks'))
|
|
||||||
hook_callback('restore', hooks, args=[tmp_dir])
|
|
||||||
|
|
||||||
# Remove temporary directory
|
# Remove temporary directory
|
||||||
os.system('rm -rf %s' % tmp_dir)
|
os.system('rm -rf %s' % tmp_dir)
|
||||||
|
|
|
@ -155,11 +155,17 @@
|
||||||
"backup_cleaning_failed" : "Unable to clean backup directory",
|
"backup_cleaning_failed" : "Unable to clean backup directory",
|
||||||
"backup_complete" : "Backup complete",
|
"backup_complete" : "Backup complete",
|
||||||
"backup_invalid_archive" : "Invalid backup archive",
|
"backup_invalid_archive" : "Invalid backup archive",
|
||||||
|
"backup_hook_unavailable" : "The hook '{:s}' is not in this backup",
|
||||||
"restore_confirm_yunohost_installed" : "Do you really want to restore an already installed system? [{answers:s}]",
|
"restore_confirm_yunohost_installed" : "Do you really want to restore an already installed system? [{answers:s}]",
|
||||||
|
"restore_app_failed" : "Unable to restore the app '{app:s}'",
|
||||||
"restore_running_hooks" : "Running restoration hooks...",
|
"restore_running_hooks" : "Running restoration hooks...",
|
||||||
"restore_failed" : "Unable to restore the system",
|
"restore_failed" : "Unable to restore the system",
|
||||||
"restore_complete" : "Restore complete",
|
"restore_complete" : "Restore complete",
|
||||||
|
"restore_already_installed_app": "An app is already installed with the id '{app:s}'",
|
||||||
"unbackup_app" : "App '{:s}' will not be saved",
|
"unbackup_app" : "App '{:s}' will not be saved",
|
||||||
|
"unrestorable_app" : "App '{:s}' will not be restored",
|
||||||
|
"restore_app_copy_failed" : "Unable to copy the restore script of app '{app:s}'",
|
||||||
|
"no_restore_script": "No restore script found for the app '{app:s}'",
|
||||||
"unrestore_app" : "App '{:s}' will not be restored",
|
"unrestore_app" : "App '{:s}' will not be restored",
|
||||||
"backup_delete_error" : "Unable to delete '{:s}'",
|
"backup_delete_error" : "Unable to delete '{:s}'",
|
||||||
"backup_deleted" : "Backup successfully deleted",
|
"backup_deleted" : "Backup successfully deleted",
|
||||||
|
|
Loading…
Add table
Reference in a new issue