mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] Bind folders in data backup hooks instead of copying them
This commit is contained in:
parent
8c3e27b769
commit
7280a56e16
7 changed files with 74 additions and 14 deletions
29
data/apps/helpers.d/filesystem
Normal file
29
data/apps/helpers.d/filesystem
Normal file
|
@ -0,0 +1,29 @@
|
|||
CAN_BIND=1
|
||||
|
||||
# Bind a directory or copy it on error
|
||||
#
|
||||
# usage: ynh_bind_or_cp srcdir destdir as_root
|
||||
# | arg: srcdir - directory to bind or copy
|
||||
# | arg: destdir - mountpoint or destination directory
|
||||
# | arg: as_root - 1 to execute commands as root
|
||||
ynh_bind_or_cp() {
|
||||
SRCDIR=$1
|
||||
DESTDIR=$2
|
||||
SUDO_CMD="sudo"
|
||||
[[ "$3" != "1" ]] && SUDO_CMD=""
|
||||
|
||||
if [[ $CAN_BIND == 1 ]]; then
|
||||
$SUDO_CMD mkdir -p $DESTDIR
|
||||
$SUDO_CMD mount --bind "$SRCDIR" "$DESTDIR"
|
||||
if [[ $? == 0 ]]; then
|
||||
for m in $(mount | grep " $SRCDIR" | awk '{ print $3 }'); do
|
||||
$SUDO_CMD mount --bind "$m" "${DESTDIR}${m#${SRCDIR}}"
|
||||
done
|
||||
return
|
||||
fi
|
||||
echo "Error: bind mounting seems to be disabled on your system."
|
||||
echo "You have maybe to check your apparmor configuration."
|
||||
CAN_BIND=0
|
||||
fi
|
||||
$SUDO_CMD cp -r "$SRCDIR" "$DESTDIR"
|
||||
}
|
|
@ -1,4 +1,10 @@
|
|||
backup_dir="$1/data/home"
|
||||
mkdir -p $backup_dir
|
||||
|
||||
sudo rsync -a --exclude='/yunohost*' /home/ $backup_dir/
|
||||
. /usr/share/yunohost/apps/helpers
|
||||
|
||||
for f in $(find /home/* -type d -prune | awk -F/ '{print $NF}'); do
|
||||
if [[ ! "$f" =~ ^yunohost|lost\+found ]]; then
|
||||
ynh_bind_or_cp "/home/$f" "${backup_dir}/$f" 1
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
backup_dir="$1/data/mail"
|
||||
|
||||
sudo cp -a /var/mail/. $backup_dir
|
||||
. /usr/share/yunohost/apps/helpers
|
||||
|
||||
ynh_bind_or_cp /var/mail $backup_dir 1
|
||||
|
|
13
data/hooks/post_backup_create/99-umount
Normal file
13
data/hooks/post_backup_create/99-umount
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
tmp_dir=$1
|
||||
retcode=$2
|
||||
|
||||
FAILURE=0
|
||||
|
||||
# Iterate over inverted ordered mountpoints to prevent issues
|
||||
for m in $(mount | grep " ${tmp_dir}" | awk '{ print $3 }' | tac); do
|
||||
sudo umount $m
|
||||
[[ $? != 0 ]] && FAILURE=1
|
||||
done
|
||||
|
||||
exit $FAILURE
|
|
@ -119,8 +119,12 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
filesystem.rm(tmp_dir, recursive=True)
|
||||
filesystem.mkdir(tmp_dir, 0750, parents=True, uid='admin')
|
||||
|
||||
def _clean_tmp_dir():
|
||||
filesystem.rm(tmp_dir, True, True)
|
||||
def _clean_tmp_dir(retcode=0):
|
||||
ret = hook_callback('post_backup_create', args=[tmp_dir, retcode])
|
||||
if not ret['failed']:
|
||||
filesystem.rm(tmp_dir, True, True)
|
||||
else:
|
||||
msignals.display(m18n.n('backup_cleaning_failed'), 'warning')
|
||||
|
||||
# Initialize backup info
|
||||
info = {
|
||||
|
@ -194,7 +198,7 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
|
||||
# Check if something has been saved
|
||||
if ignore_hooks and not info['apps']:
|
||||
_clean_tmp_dir()
|
||||
_clean_tmp_dir(1)
|
||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
||||
|
||||
# Create backup info file
|
||||
|
@ -224,7 +228,7 @@ def backup_create(name=None, description=None, output_directory=None,
|
|||
logger.exception("unable to open the archive '%s' for writing",
|
||||
archive_file)
|
||||
if tar is None:
|
||||
_clean_tmp_dir()
|
||||
_clean_tmp_dir(2)
|
||||
raise MoulinetteError(errno.EIO,
|
||||
m18n.n('backup_archive_open_failed'))
|
||||
tar.add(tmp_dir, arcname='')
|
||||
|
@ -435,8 +439,8 @@ def backup_info(name, with_details=False, human_readable=False):
|
|||
for d in ['apps', 'hooks']:
|
||||
result[d] = info[d]
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
def backup_delete(name):
|
||||
"""
|
||||
Delete a backup
|
||||
|
@ -444,12 +448,12 @@ def backup_delete(name):
|
|||
Keyword arguments:
|
||||
name -- Name of the local backup archive
|
||||
|
||||
"""
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
hook_callback('pre_backup_delete', args=[name])
|
||||
|
||||
|
||||
archive_file = '%s/%s.tar.gz' % (archives_path, name)
|
||||
|
||||
|
||||
info_file = "%s/%s.info.json" % (archives_path, name)
|
||||
for backup_file in [archive_file,info_file]:
|
||||
if not os.path.isfile(backup_file):
|
||||
|
@ -459,8 +463,9 @@ def backup_delete(name):
|
|||
os.remove(backup_file)
|
||||
except:
|
||||
logger.exception("unable to delete '%s'", backup_file)
|
||||
raise MoulinetteError(errno.EIO, m18n.n('backup_delete_error',backup_file))
|
||||
|
||||
raise MoulinetteError(errno.EIO,
|
||||
m18n.n('backup_delete_error',backup_file))
|
||||
|
||||
hook_callback('post_backup_delete', args=[name])
|
||||
|
||||
msignals.display(m18n.n('backup_deleted'), 'success')
|
||||
|
|
|
@ -212,11 +212,15 @@ def hook_callback(action, hooks=[], args=None):
|
|||
state = 'succeed'
|
||||
filename = '%s-%s' % (priority, name)
|
||||
try:
|
||||
hook_exec(info['path'], args=args)
|
||||
ret = hook_exec(info['path'], args=args)
|
||||
except:
|
||||
logger.exception("error while executing hook '%s'",
|
||||
info['path'])
|
||||
state = 'failed'
|
||||
if ret != 0:
|
||||
logger.error("error while executing hook '%s', retcode: %d",
|
||||
info['path'], ret)
|
||||
state = 'failed'
|
||||
try:
|
||||
result[state][name].append(info['path'])
|
||||
except KeyError:
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
"backup_archive_name_exists" : "Backup archive name already exists",
|
||||
"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_complete" : "Backup complete",
|
||||
"backup_invalid_archive" : "Invalid backup archive",
|
||||
"restore_confirm_yunohost_installed" : "Do you really want to restore an already installed system? [{answers:s}]",
|
||||
|
|
Loading…
Add table
Reference in a new issue