mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
* New helpers ynh_store_checksum_config and ynh_compare_checksum_config Helpers for avoid destruction of personalised config files. If the config file was manually modified, make a backup of it. The name of this backup is returned, so the packager can choose which of this both file will used by default. * Implement @JimboJoe's comments. * Setting local variables as local * Adding warning about $app that should be defined * Remove "globally" in comment to limit confusion * Remove "globally" in comment to limit confusion * Remove compress and use /home/yunohost.conf/backup * Changing timestamp format to match regen-conf's * Tested and fixed ;)
148 lines
5 KiB
Text
148 lines
5 KiB
Text
CAN_BIND=${CAN_BIND:-1}
|
|
|
|
# Mark a file or a directory for backup
|
|
# Note: currently, SRCPATH will be copied or binded to DESTPATH
|
|
#
|
|
# usage: ynh_backup srcdir destdir to_bind no_root
|
|
# | arg: srcdir - directory to bind or copy
|
|
# | arg: destdir - mountpoint or destination directory
|
|
# | arg: to_bind - 1 to bind mounting the directory if possible
|
|
# | arg: no_root - 1 to execute commands as current user
|
|
ynh_backup() {
|
|
local SRCPATH=$1
|
|
local DESTPATH=$2
|
|
local TO_BIND=${3:-0}
|
|
local SUDO_CMD="sudo"
|
|
[[ "${4:-}" = "1" ]] && SUDO_CMD=
|
|
|
|
# validate arguments
|
|
[[ -e "${SRCPATH}" ]] || {
|
|
echo "Source path '${SRCPATH}' does not exist" >&2
|
|
return 1
|
|
}
|
|
|
|
# prepend the backup directory
|
|
[[ -n "${YNH_APP_BACKUP_DIR:-}" && "${DESTPATH:0:1}" != "/" ]] \
|
|
&& DESTPATH="${YNH_APP_BACKUP_DIR}/${DESTPATH}"
|
|
[[ ! -e "${DESTPATH}" ]] || {
|
|
echo "Destination path '${DESTPATH}' already exist" >&2
|
|
return 1
|
|
}
|
|
|
|
# attempt to bind mounting the directory
|
|
if [[ "${CAN_BIND}" = "1" && "${TO_BIND}" = "1" ]]; then
|
|
eval $SUDO_CMD mkdir -p "${DESTPATH}"
|
|
|
|
if sudo mount --rbind "${SRCPATH}" "${DESTPATH}"; then
|
|
# try to remount destination directory as read-only
|
|
sudo mount -o remount,ro,bind "${SRCPATH}" "${DESTPATH}" \
|
|
|| true
|
|
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
|
|
|
|
# delete mountpoint directory safely
|
|
mountpoint -q "${DESTPATH}" && sudo umount -R "${DESTPATH}"
|
|
eval $SUDO_CMD rm -rf "${DESTPATH}"
|
|
fi
|
|
|
|
# ... or just copy the directory
|
|
eval $SUDO_CMD mkdir -p $(dirname "${DESTPATH}")
|
|
eval $SUDO_CMD cp -a "${SRCPATH}" "${DESTPATH}"
|
|
}
|
|
|
|
# Deprecated helper since it's a dangerous one!
|
|
ynh_bind_or_cp() {
|
|
local AS_ROOT=${3:-0}
|
|
local NO_ROOT=0
|
|
[[ "${AS_ROOT}" = "1" ]] || NO_ROOT=1
|
|
echo "This helper is deprecated, you should use ynh_backup instead" >&2
|
|
ynh_backup "$1" "$2" 1 "$NO_ROOT"
|
|
}
|
|
|
|
# Create a directory under /tmp
|
|
#
|
|
# Deprecated helper
|
|
#
|
|
# usage: ynh_mkdir_tmp
|
|
# | ret: the created directory path
|
|
ynh_mkdir_tmp() {
|
|
echo "The helper ynh_mkdir_tmp is deprecated." >&2
|
|
echo "You should use 'mktemp -d' instead and manage permissions \
|
|
properly with chmod/chown." >&2
|
|
local TMP_DIR=$(mktemp -d)
|
|
|
|
# Give rights to other users could be a security risk.
|
|
# But for retrocompatibility we need it. (This helpers is deprecated)
|
|
chmod 755 $TMP_DIR
|
|
echo $TMP_DIR
|
|
}
|
|
|
|
# Calculate and store a file checksum into the app settings
|
|
#
|
|
# $app should be defined when calling this helper
|
|
#
|
|
# usage: ynh_store_file_checksum file
|
|
# | arg: file - The file on which the checksum will performed, then stored.
|
|
ynh_store_file_checksum () {
|
|
local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
|
ynh_app_setting_set $app $checksum_setting_name $(sudo md5sum "$1" | cut -d' ' -f1)
|
|
}
|
|
|
|
# Verify the checksum and backup the file if it's different
|
|
# This helper is primarily meant to allow to easily backup personalised/manually
|
|
# modified config files.
|
|
#
|
|
# $app should be defined when calling this helper
|
|
#
|
|
# usage: ynh_backup_if_checksum_is_different file
|
|
# | arg: file - The file on which the checksum test will be perfomed.
|
|
#
|
|
# | ret: Return the name a the backup file, or nothing
|
|
ynh_backup_if_checksum_is_different () {
|
|
local file=$1
|
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
|
local checksum_value=$(ynh_app_setting_get $app $checksum_setting_name)
|
|
if [ -n "$checksum_value" ]
|
|
then # Proceed only if a value was stored into the app settings
|
|
if ! echo "$checksum_value $file" | sudo md5sum -c --status
|
|
then # If the checksum is now different
|
|
backup_file="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
|
sudo mkdir -p "$(dirname "$backup_file")"
|
|
sudo cp -a "$file" "$backup_file" # Backup the current file
|
|
echo "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file" >&2
|
|
echo "$backup_file" # Return the name of the backup file
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Remove a file or a directory securely
|
|
#
|
|
# usage: ynh_secure_remove path_to_remove
|
|
# | arg: path_to_remove - File or directory to remove
|
|
ynh_secure_remove () {
|
|
path_to_remove=$1
|
|
forbidden_path=" \
|
|
/var/www \
|
|
/home/yunohost.app"
|
|
|
|
if [[ "$forbidden_path" =~ "$path_to_remove" \
|
|
# Match all paths or subpaths in $forbidden_path
|
|
|| "$path_to_remove" =~ ^/[[:alnum:]]+$ \
|
|
# Match all first level paths from / (Like /var, /root, etc...)
|
|
|| "${path_to_remove:${#path_to_remove}-1}" = "/" ]]
|
|
# Match if the path finishes by /. Because it seems there is an empty variable
|
|
then
|
|
echo "Avoid deleting $path_to_remove." >&2
|
|
else
|
|
if [ -e "$path_to_remove" ]
|
|
then
|
|
sudo rm -R "$path_to_remove"
|
|
else
|
|
echo "$path_to_remove wasn't deleted because it doesn't exist." >&2
|
|
fi
|
|
fi
|
|
}
|