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"
|
backup_dir="$1/data/home"
|
||||||
mkdir -p $backup_dir
|
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"
|
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.rm(tmp_dir, recursive=True)
|
||||||
filesystem.mkdir(tmp_dir, 0750, parents=True, uid='admin')
|
filesystem.mkdir(tmp_dir, 0750, parents=True, uid='admin')
|
||||||
|
|
||||||
def _clean_tmp_dir():
|
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)
|
filesystem.rm(tmp_dir, True, True)
|
||||||
|
else:
|
||||||
|
msignals.display(m18n.n('backup_cleaning_failed'), 'warning')
|
||||||
|
|
||||||
# Initialize backup info
|
# Initialize backup info
|
||||||
info = {
|
info = {
|
||||||
|
@ -194,7 +198,7 @@ def backup_create(name=None, description=None, output_directory=None,
|
||||||
|
|
||||||
# Check if something has been saved
|
# Check if something has been saved
|
||||||
if ignore_hooks and not info['apps']:
|
if ignore_hooks and not info['apps']:
|
||||||
_clean_tmp_dir()
|
_clean_tmp_dir(1)
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
||||||
|
|
||||||
# Create backup info file
|
# 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",
|
logger.exception("unable to open the archive '%s' for writing",
|
||||||
archive_file)
|
archive_file)
|
||||||
if tar is None:
|
if tar is None:
|
||||||
_clean_tmp_dir()
|
_clean_tmp_dir(2)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise MoulinetteError(errno.EIO,
|
||||||
m18n.n('backup_archive_open_failed'))
|
m18n.n('backup_archive_open_failed'))
|
||||||
tar.add(tmp_dir, arcname='')
|
tar.add(tmp_dir, arcname='')
|
||||||
|
@ -459,7 +463,8 @@ def backup_delete(name):
|
||||||
os.remove(backup_file)
|
os.remove(backup_file)
|
||||||
except:
|
except:
|
||||||
logger.exception("unable to delete '%s'", backup_file)
|
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])
|
hook_callback('post_backup_delete', args=[name])
|
||||||
|
|
||||||
|
|
|
@ -212,11 +212,15 @@ def hook_callback(action, hooks=[], args=None):
|
||||||
state = 'succeed'
|
state = 'succeed'
|
||||||
filename = '%s-%s' % (priority, name)
|
filename = '%s-%s' % (priority, name)
|
||||||
try:
|
try:
|
||||||
hook_exec(info['path'], args=args)
|
ret = hook_exec(info['path'], args=args)
|
||||||
except:
|
except:
|
||||||
logger.exception("error while executing hook '%s'",
|
logger.exception("error while executing hook '%s'",
|
||||||
info['path'])
|
info['path'])
|
||||||
state = 'failed'
|
state = 'failed'
|
||||||
|
if ret != 0:
|
||||||
|
logger.error("error while executing hook '%s', retcode: %d",
|
||||||
|
info['path'], ret)
|
||||||
|
state = 'failed'
|
||||||
try:
|
try:
|
||||||
result[state][name].append(info['path'])
|
result[state][name].append(info['path'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -152,6 +152,7 @@
|
||||||
"backup_archive_name_exists" : "Backup archive name already exists",
|
"backup_archive_name_exists" : "Backup archive name already exists",
|
||||||
"backup_app_failed" : "Unable to back up the app '{app:s}'",
|
"backup_app_failed" : "Unable to back up the app '{app:s}'",
|
||||||
"backup_nothings_done" : "There is nothing to save",
|
"backup_nothings_done" : "There is nothing to save",
|
||||||
|
"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",
|
||||||
"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}]",
|
||||||
|
|
Loading…
Add table
Reference in a new issue