mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] Manage local backup archive and extend backup_restore
This commit is contained in:
parent
d1cb0b0d80
commit
c594ce03a6
4 changed files with 101 additions and 45 deletions
|
@ -559,7 +559,7 @@ backup:
|
||||||
|
|
||||||
### backup_create()
|
### backup_create()
|
||||||
create:
|
create:
|
||||||
action_help: Backup and create a local archive
|
action_help: Create a backup local archive
|
||||||
api: POST /backup
|
api: POST /backup
|
||||||
configuration:
|
configuration:
|
||||||
lock: false
|
lock: false
|
||||||
|
@ -570,14 +570,19 @@ backup:
|
||||||
|
|
||||||
### backup_restore()
|
### backup_restore()
|
||||||
restore:
|
restore:
|
||||||
action_help: Restore from an encrypted backup tarball
|
action_help: Restore from a local backup archive
|
||||||
api: POST /restore
|
api: POST /restore
|
||||||
configuration:
|
configuration:
|
||||||
authenticate: false
|
authenticate: false
|
||||||
lock: false
|
|
||||||
arguments:
|
arguments:
|
||||||
path:
|
name:
|
||||||
help: Path of the restauration package
|
help: Name of the local backup archive
|
||||||
|
--ignore-apps:
|
||||||
|
help: Do not restore apps
|
||||||
|
action: store_true
|
||||||
|
--force:
|
||||||
|
help: Force restauration on an already installed system
|
||||||
|
action: store_true
|
||||||
|
|
||||||
### backup_list()
|
### backup_list()
|
||||||
list:
|
list:
|
||||||
|
|
108
backup.py
108
backup.py
|
@ -42,7 +42,7 @@ logger = getActionLogger('yunohost.backup')
|
||||||
|
|
||||||
def backup_create(ignore_apps=False):
|
def backup_create(ignore_apps=False):
|
||||||
"""
|
"""
|
||||||
Backup and create a local archive
|
Create a backup local archive
|
||||||
|
|
||||||
Keyword arguments:
|
Keyword arguments:
|
||||||
ignore_apps -- Do not backup apps
|
ignore_apps -- Do not backup apps
|
||||||
|
@ -67,7 +67,7 @@ def backup_create(ignore_apps=False):
|
||||||
else:
|
else:
|
||||||
os.system('chown -hR admin: %s' % tmp_dir)
|
os.system('chown -hR admin: %s' % tmp_dir)
|
||||||
|
|
||||||
# Add app's backup hooks
|
# Add apps backup hook
|
||||||
if not ignore_apps:
|
if not ignore_apps:
|
||||||
try:
|
try:
|
||||||
for app_id in os.listdir('/etc/yunohost/apps'):
|
for app_id in os.listdir('/etc/yunohost/apps'):
|
||||||
|
@ -79,16 +79,16 @@ def backup_create(ignore_apps=False):
|
||||||
msignals.display(m18n.n('unbackup_app', app_id),
|
msignals.display(m18n.n('unbackup_app', app_id),
|
||||||
'warning')
|
'warning')
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
logger.info("unable to add app's backup hooks: %s", str(e))
|
logger.info("unable to add apps backup hook: %s", str(e))
|
||||||
|
|
||||||
# Run hooks
|
# Run hooks
|
||||||
m18n.display(m18n.n('backup_running_hooks'))
|
msignals.display(m18n.n('backup_running_hooks'))
|
||||||
hook_callback('backup', [tmp_dir])
|
hook_callback('backup', [tmp_dir])
|
||||||
|
|
||||||
# TODO: Add a backup info file
|
# TODO: Add a backup info file
|
||||||
|
|
||||||
# Create the archive
|
# Create the archive
|
||||||
m18n.display(m18n.n('backup_creating_archive'))
|
msignals.display(m18n.n('backup_creating_archive'))
|
||||||
archive_file = "%s/%s.tar.gz" % (archives_path, timestamp)
|
archive_file = "%s/%s.tar.gz" % (archives_path, timestamp)
|
||||||
try:
|
try:
|
||||||
tar = tarfile.open(archive_file, "w:gz")
|
tar = tarfile.open(archive_file, "w:gz")
|
||||||
|
@ -119,51 +119,89 @@ def backup_create(ignore_apps=False):
|
||||||
msignals.display(m18n.n('backup_complete'), 'success')
|
msignals.display(m18n.n('backup_complete'), 'success')
|
||||||
|
|
||||||
|
|
||||||
def backup_restore(path):
|
def backup_restore(name, ignore_apps=False, force=False):
|
||||||
"""
|
"""
|
||||||
Restore from an encrypted backup tarball
|
Restore from a local backup archive
|
||||||
|
|
||||||
Keyword argument:
|
Keyword argument:
|
||||||
path -- Path to the restore directory
|
name -- Name of the local backup archive
|
||||||
|
ignore_apps -- Do not restore apps
|
||||||
|
force -- Force restauration on an already installed system
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.tools import tools_postinstall
|
|
||||||
from yunohost.hook import hook_add
|
from yunohost.hook import hook_add
|
||||||
from yunohost.hook import hook_callback
|
from yunohost.hook import hook_callback
|
||||||
|
|
||||||
path = os.path.abspath(path)
|
# Retrieve and open the archive
|
||||||
|
archive_file = backup_info(name)['path']
|
||||||
try:
|
try:
|
||||||
with open("%s/yunohost/current_host" % path, 'r') as f:
|
tar = tarfile.open(archive_file, "r:gz")
|
||||||
|
except:
|
||||||
|
logger.exception("unable to open the archive '%s' for reading",
|
||||||
|
archive_file)
|
||||||
|
raise MoulinetteError(errno.EIO, m18n.n('backup_archive_open_failed'))
|
||||||
|
|
||||||
|
# Check temporary directory
|
||||||
|
tmp_dir = "%s/tmp/%s" % (backup_path, name)
|
||||||
|
if os.path.isdir(tmp_dir):
|
||||||
|
logger.warning("temporary directory for restoration '%s' already exists",
|
||||||
|
tmp_dir)
|
||||||
|
os.system('rm -rf %s' % tmp_dir)
|
||||||
|
|
||||||
|
# Extract the tarball
|
||||||
|
msignals.display(m18n.n('backup_extracting_archive'))
|
||||||
|
tar.extractall(tmp_dir)
|
||||||
|
tar.close()
|
||||||
|
|
||||||
|
# Retrieve domain from the backup
|
||||||
|
try:
|
||||||
|
with open("%s/yunohost/current_host" % tmp_dir, 'r') as f:
|
||||||
domain = f.readline().rstrip()
|
domain = f.readline().rstrip()
|
||||||
except IOError:
|
except IOError:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('invalid_restore_package'))
|
logger.error("unable to retrieve domain from '%s/yunohost/current_host'",
|
||||||
|
tmp_dir)
|
||||||
|
raise MoulinetteError(errno.EIO, m18n.n('backup_invalid_archive'))
|
||||||
|
|
||||||
#TODO Decrypt & extract tarball
|
# Check if YunoHost is installed
|
||||||
|
if os.path.isfile('/etc/yunohost/installed'):
|
||||||
try:
|
msignals.display(m18n.n('yunohost_already_installed'), 'warning')
|
||||||
with open('/etc/yunohost/installed') as f:
|
if not force:
|
||||||
#raise MoulinetteError(errno.EINVAL, m18n.n('yunohost_already_installed'))
|
try:
|
||||||
msignals.display(m18n.n('restoring_installed_system'), 'warning')
|
# Ask confirmation for restoring
|
||||||
time.sleep(5)
|
i = msignals.prompt(m18n.n('restore_confirm_yunohost_installed',
|
||||||
pass
|
answers='y/N'))
|
||||||
except IOError:
|
except NotImplemented:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if i == 'y' or i == 'Y':
|
||||||
|
force = True
|
||||||
|
if not force:
|
||||||
|
raise MoulinetteError(errno.EEXIST, m18n.n('restore_failed'))
|
||||||
|
else:
|
||||||
|
from yunohost.tools import tools_postinstall
|
||||||
|
logger.info("executing the post-install...")
|
||||||
tools_postinstall(domain, 'yunohost', True)
|
tools_postinstall(domain, 'yunohost', True)
|
||||||
|
|
||||||
# Add app's restore hooks
|
# Add apps restore hook
|
||||||
try:
|
if not ignore_apps:
|
||||||
for app_id in os.listdir('/etc/yunohost/apps'):
|
try:
|
||||||
hook = '/etc/yunohost/apps/'+ app_id +'/scripts/restore'
|
# TODO: Check if the app_id is part of the backup archive
|
||||||
if os.path.isfile(hook):
|
for app_id in os.listdir('/etc/yunohost/apps'):
|
||||||
hook_add(app_id, hook)
|
hook = '/etc/yunohost/apps/'+ app_id +'/scripts/restore'
|
||||||
else:
|
if os.path.isfile(hook):
|
||||||
msignals.display(m18n.n('unrestore_app', app_id),
|
hook_add(app_id, hook)
|
||||||
'warning')
|
else:
|
||||||
except IOError:
|
msignals.display(m18n.n('unrestore_app', app_id),
|
||||||
pass
|
'warning')
|
||||||
|
except IOError as e:
|
||||||
|
logger.info("unable to add apps restore hook: %s", str(e))
|
||||||
|
|
||||||
# Run hook
|
# Run hooks
|
||||||
hook_callback('restore', [path])
|
msignals.display(m18n.n('restore_running_hooks'))
|
||||||
|
hook_callback('restore', [tmp_dir])
|
||||||
|
|
||||||
|
# Remove temporary directory
|
||||||
|
os.system('rm -rf %s' % tmp_dir)
|
||||||
|
|
||||||
msignals.display(m18n.n('restore_complete'), 'success')
|
msignals.display(m18n.n('restore_complete'), 'success')
|
||||||
|
|
||||||
|
|
|
@ -130,14 +130,17 @@
|
||||||
|
|
||||||
"backup_running_hooks" : "Running backup hooks...",
|
"backup_running_hooks" : "Running backup hooks...",
|
||||||
"backup_creating_archive" : "Creating the backup archive...",
|
"backup_creating_archive" : "Creating the backup archive...",
|
||||||
|
"backup_extracting_archive" : "Extracting the backup archive...",
|
||||||
"backup_archive_open_failed" : "Unable to open the backup archive",
|
"backup_archive_open_failed" : "Unable to open the backup archive",
|
||||||
"backup_archive_name_unknown" : "Unknown local backup archive name",
|
"backup_archive_name_unknown" : "Unknown local backup archive name",
|
||||||
"backup_complete" : "Backup complete",
|
"backup_complete" : "Backup complete",
|
||||||
"invalid_restore_package" : "Invalid restore package",
|
"backup_invalid_archive" : "Invalid backup archive",
|
||||||
|
"restore_confirm_yunohost_installed" : "Do you really want to restore an already installed system? [{answers:s}]",
|
||||||
|
"restore_running_hooks" : "Running restoration hooks...",
|
||||||
|
"restore_failed" : "Unable to restore the system",
|
||||||
"restore_complete" : "Restore complete",
|
"restore_complete" : "Restore complete",
|
||||||
"restoring_installed_system" : "You are trying to restore a backup on an already installed system, abort unless you know what you are doing!",
|
"unbackup_app" : "App '{:s}' will not be saved",
|
||||||
"unbackup_app" : "'{:s}' will NOT be saved",
|
"unrestore_app" : "App '{:s}' will not be restored",
|
||||||
"unrestore_app" : "'{:s}' will NOT be restored",
|
|
||||||
|
|
||||||
"field_invalid" : "Invalid field '{:s}'",
|
"field_invalid" : "Invalid field '{:s}'",
|
||||||
"mail_domain_unknown" : "Unknown mail address domain '{:s}'",
|
"mail_domain_unknown" : "Unknown mail address domain '{:s}'",
|
||||||
|
|
|
@ -128,9 +128,19 @@
|
||||||
"packages_upgrade_failed" : "Impossible de mettre à jour tous les paquets",
|
"packages_upgrade_failed" : "Impossible de mettre à jour tous les paquets",
|
||||||
"system_upgraded" : "Système mis à jour avec succès",
|
"system_upgraded" : "Système mis à jour avec succès",
|
||||||
|
|
||||||
|
"backup_running_hooks" : "Exécution des scripts de sauvegarde...",
|
||||||
|
"backup_creating_archive" : "Création de l'archive de sauvegarde...",
|
||||||
|
"backup_extracting_archive" : "Extraction de l'archive de sauvegarde...",
|
||||||
|
"backup_archive_open_failed" : "Impossible d'ouvrir l'archive de sauvegarde",
|
||||||
|
"backup_archive_name_unknown" : "Nom d'archive de sauvegarde locale inconnu",
|
||||||
"backup_complete" : "Sauvegarde terminée",
|
"backup_complete" : "Sauvegarde terminée",
|
||||||
"invalid_restore_package" : "Dossier de restauration invalide",
|
"backup_invalid_archive" : "Archive de sauvegarde incorrecte",
|
||||||
|
"restore_confirm_yunohost_installed" : "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",
|
||||||
|
"restore_running_hooks" : "Exécution des scripts de restauration...",
|
||||||
|
"restore_failed" : "Impossible de restaurer le système",
|
||||||
"restore_complete" : "Restauration terminée",
|
"restore_complete" : "Restauration terminée",
|
||||||
|
"unbackup_app" : "L'application '{:s}' ne sera pas sauvegardée",
|
||||||
|
"unrestore_app" : "L'application '{:s}' ne sera pas restaurée",
|
||||||
|
|
||||||
"field_invalid" : "Champ incorrect : {:s}",
|
"field_invalid" : "Champ incorrect : {:s}",
|
||||||
"mail_domain_unknown" : "Domaine '{:s}' de l'adresse mail inconnu",
|
"mail_domain_unknown" : "Domaine '{:s}' de l'adresse mail inconnu",
|
||||||
|
|
Loading…
Add table
Reference in a new issue