[enh] Do not bind mounting if no backup archive is created (wip #298)

This commit is contained in:
Jérôme Lebleu 2016-04-30 17:19:12 +02:00
parent c3fd005027
commit fa89291504
2 changed files with 39 additions and 21 deletions

View file

@ -1,4 +1,4 @@
CAN_BIND=1 CAN_BIND=${CAN_BIND:-1}
# Bind a directory or copy it on error # Bind a directory or copy it on error
# #
@ -7,25 +7,36 @@ CAN_BIND=1
# | arg: destdir - mountpoint or destination directory # | arg: destdir - mountpoint or destination directory
# | arg: as_root - 1 to execute commands as root # | arg: as_root - 1 to execute commands as root
ynh_bind_or_cp() { ynh_bind_or_cp() {
SRCDIR=$1 local SRCDIR=$1
DESTDIR=$2 local DESTDIR=$2
SUDO_CMD="sudo" local SUDO_CMD=
[[ "$3" != "1" ]] && SUDO_CMD="" [[ "${3}" = "1" ]] && SUDO_CMD="sudo"
if [[ $CAN_BIND == 1 ]]; then [[ ! -f "${DESTDIR}" ]] || {
$SUDO_CMD mkdir -p $DESTDIR echo "Destination directory '${DESTDIR}' already exists" >&2
$SUDO_CMD mount --bind "$SRCDIR" "$DESTDIR" return 1
if [[ $? == 0 ]]; then }
for m in $(mount | grep " $SRCDIR" | awk '{ print $3 }'); do
$SUDO_CMD mount --bind "$m" "${DESTDIR}${m#${SRCDIR}}" # attempt to bind mounting the directory
done if [[ "${CAN_BIND}" = "1" ]]; then
return eval $SUDO_CMD mkdir -p "${DESTDIR}"
if sudo mount --rbind "${SRCDIR}" "${DESTDIR}"; then
return 0
else
CAN_BIND=0
echo "Bind mounting seems to be disabled on your system."
echo "You have maybe to check your apparmor configuration."
fi fi
echo "Error: bind mounting seems to be disabled on your system."
echo "You have maybe to check your apparmor configuration." # delete mountpoint directory safely
CAN_BIND=0 mountpoint -q "${DESTDIR}" && sudo umount -R "${DESTDIR}"
eval $SUDO_CMD rm -rf "${DESTDIR}"
fi fi
$SUDO_CMD cp -r "$SRCDIR" "$DESTDIR"
# ... or just copy the directory
eval $SUDO_CMD mkdir -p $(dirname "${DESTDIR}")
eval $SUDO_CMD cp -a "${SRCDIR}" "${DESTDIR}"
} }
# Create a directory under /tmp # Create a directory under /tmp

View file

@ -73,6 +73,7 @@ def backup_create(name=None, description=None, output_directory=None,
""" """
# TODO: Add a 'clean' argument to clean output directory # TODO: Add a 'clean' argument to clean output directory
tmp_dir = None tmp_dir = None
env_var = {}
# Validate what to backup # Validate what to backup
if ignore_hooks and ignore_apps: if ignore_hooks and ignore_apps:
@ -110,9 +111,13 @@ def backup_create(name=None, description=None, output_directory=None,
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.n('backup_output_directory_not_empty')) m18n.n('backup_output_directory_not_empty'))
# Define temporary directory # Do not compress, so set temporary directory to output one and
# disable bind mounting to prevent data loss in case of a rm
# See: https://dev.yunohost.org/issues/298
if no_compress: if no_compress:
logger.debug('bind mounting will be disabled')
tmp_dir = output_directory tmp_dir = output_directory
env_var['CAN_BIND'] = 0
else: else:
output_directory = archives_path output_directory = archives_path
@ -159,7 +164,8 @@ def backup_create(name=None, description=None, output_directory=None,
if not hooks or hooks_filtered: if not hooks or hooks_filtered:
logger.info(m18n.n('backup_running_hooks')) logger.info(m18n.n('backup_running_hooks'))
ret = hook_callback('backup', hooks_filtered, args=[tmp_dir]) ret = hook_callback('backup', hooks_filtered, args=[tmp_dir],
env=env_var)
if ret['succeed']: if ret['succeed']:
info['hooks'] = ret['succeed'] info['hooks'] = ret['succeed']
@ -216,8 +222,9 @@ def backup_create(name=None, description=None, output_directory=None,
subprocess.call(['install', '-Dm555', app_script, tmp_script]) subprocess.call(['install', '-Dm555', app_script, tmp_script])
# Prepare env. var. to pass to script # Prepare env. var. to pass to script
env_dict = {} app_id, app_instance_nb = _parse_app_instance_name(
app_id, app_instance_nb = _parse_app_instance_name(app_instance_name) app_instance_name)
env_dict = env_var.copy()
env_dict["YNH_APP_ID"] = app_id env_dict["YNH_APP_ID"] = app_id
env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb) env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)