217 lines
5.1 KiB
Bash
Executable File
217 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# shellcheck disable=SC2001 # See if you can use ${variable//search/replace} instead.
|
|
# It is more easy with sed to remove multiple trailing /
|
|
|
|
sq_toolBin=rsync
|
|
sq_aptOpt=
|
|
sq_config=0
|
|
|
|
seq_config() {
|
|
if initSeqConfig -t "${seq_configName:?}" "${seq_configTemplate:?}" ; then
|
|
sq_config=1
|
|
else
|
|
error -e "Check output for errors"
|
|
# End if no configuration file exists
|
|
dry || return 1
|
|
fi
|
|
|
|
interactive || sq_aptOpt="-y"
|
|
return 0
|
|
}
|
|
|
|
step_1_info() {
|
|
echo "Backup root"
|
|
echoinfo "Essential excludes are provided in the configuration template."
|
|
echoinfo "(${seq_configTemplate})"
|
|
}
|
|
step_1_options() { echo "[ADDITIONAL_EXCLUDES...]"; }
|
|
step_1_alias() { echo "buroot"; }
|
|
step_1() {
|
|
local buTarget="/backup"
|
|
if (( ! sq_config )) ; then
|
|
error -e "Cannot backup root without properly configured excludes"
|
|
error -e " (expected config: ${seq_configFile:?})"
|
|
else
|
|
buTarget="$BACKUP_TARGET"
|
|
fi
|
|
|
|
# don't use step number
|
|
shift
|
|
|
|
step budir / "$buTarget" "${BACKUP_EXCLUDES[@]}" "$@"
|
|
}
|
|
|
|
step_3_info() {
|
|
# Backup single directory recursively
|
|
local opt=()
|
|
local dir='<SOURCE>'
|
|
local tar='[TARGET]'
|
|
local tarOpt=0
|
|
local exc=()
|
|
shift
|
|
while [[ "${1:-}" =~ ^- ]] ; do
|
|
case "${1}" in
|
|
--)
|
|
shift && break;;
|
|
-f)
|
|
opt+=("${1:-}" "'${2:-}'")
|
|
shift 2;;
|
|
-t)
|
|
tarOpt=1
|
|
shift;;
|
|
-*)
|
|
opt+=("${1}")
|
|
shift ;;
|
|
esac
|
|
done
|
|
if [ -n "${1:-}" ] ; then
|
|
dir="$1"
|
|
shift
|
|
if (( tarOpt )) ; then
|
|
tar="$BACKUP_TARGET"
|
|
else
|
|
tar="${1:-}"
|
|
shift
|
|
fi
|
|
for arg in "$@" ; do
|
|
exc+=("'$arg'")
|
|
done
|
|
(( ${#exc[@]} )) || exc=("[NO EXCLUDES]")
|
|
fi
|
|
echo "Backup ${opt[*]} '$dir' '$tar' ${exc[*]}"
|
|
echoinfo " -f : Replace default flags (can be used multiple times)"
|
|
echoinfo " (default: ${sq_rsyncFlags[*]})"
|
|
echoinfo " -n : No remount to rw"
|
|
echoinfo " -t : Using configuration value as TARGET"
|
|
echoinfo " <DIRECTORY> [EXCLUDES...]"
|
|
echoinfo "EXCLUDES path notation starts within $dir"
|
|
echoinfo " e.g. to exclude $dir/a:"
|
|
echoinfo " $0 budir $dir $tar /a"
|
|
}
|
|
sq_rsyncFlags=("-avxHAX" "--delete")
|
|
step_3_options() { echo "[OPTION] <DIRECTORY> [TARGET] [EXCLUDES...]"; }
|
|
step_3_alias() { echo "budir"; }
|
|
step_3() {
|
|
local configTarget=0
|
|
local remount=1
|
|
local buSource=
|
|
local buTarget=
|
|
local buExcludes=
|
|
local buLog=
|
|
local customFlags=()
|
|
# don't use step number
|
|
shift
|
|
|
|
for _ in "$@"; do
|
|
case "$1" in
|
|
--)
|
|
shift && break;;
|
|
-t)
|
|
configTarget=1
|
|
shift;;
|
|
-n)
|
|
remount=0
|
|
shift;;
|
|
-f)
|
|
shift
|
|
customFlags+=("${1:-}")
|
|
shift;;
|
|
esac
|
|
done
|
|
|
|
(( "${#customFlags[@]}" )) || customFlags=("${sq_rsyncFlags[@]}")
|
|
if [ -z "${1:-}" ] ; then
|
|
error -e "Nothing found to backup $1"
|
|
exit 1
|
|
fi
|
|
|
|
buLog="$(basename -- "$1")"
|
|
if [ "$buLog" == "/" ] ; then
|
|
buLog="root"
|
|
buSource="$1"
|
|
else
|
|
# remove trailing slashes
|
|
buSource="$(echo "$1" | sed 's:/*$::')"
|
|
fi
|
|
buLog="backup_${buLog}"
|
|
shift
|
|
|
|
if (( configTarget )) && (( sq_config )) ; then
|
|
# Taking target from config
|
|
buTarget="$(echo "$BACKUP_TARGET" | sed 's:/*$::')"
|
|
else
|
|
if [ -z "$1" ] ; then
|
|
error -e "No valid target found"
|
|
exit 1
|
|
fi
|
|
buTarget="$(echo "$1" | sed 's:/*$::')"
|
|
shift
|
|
fi
|
|
if [ ! -d "${buTarget}" ] && [ ! -L "${buTarget}" ]
|
|
then
|
|
error -e "Backup target (${buTarget}) doesn't exist"
|
|
exit 1
|
|
fi
|
|
|
|
for exclu in "$@"; do
|
|
buExcludes+=("--exclude='$exclu'")
|
|
done
|
|
|
|
info "Source : $buSource"
|
|
info "Target : $buTarget"
|
|
info "Excludes: $*"
|
|
|
|
#fix doubling trailing slash on verbose output when backing up root
|
|
local tmpSource="$buSource/"
|
|
local tmpTarget=
|
|
|
|
tmpTarget="${buTarget}/$(basename -- "${buSource}")"
|
|
if [ "$buSource" == "/" ] ; then
|
|
tmpSource="/"
|
|
tmpTarget="${buTarget}/"
|
|
fi
|
|
|
|
if (( remount )) ; then
|
|
# remount target to be writable
|
|
exep "mount -o rw,remount '${buTarget}' >>/dev/null 2>&1"
|
|
endReturn "Remount (${buTarget}) to be writable failed"
|
|
fi
|
|
|
|
if [ ! -w "${buTarget}" ] ; then
|
|
error -e "Backup target (${buTarget}) is not writable"
|
|
exit 1
|
|
fi
|
|
|
|
checkInstalled
|
|
exep "mv -f '${buTarget}/${buLog}0.log' '/tmp/${buLog}1.log' 2>/dev/null"
|
|
exep "'${sq_toolBin}' ${customFlags[*]} --info=stats2 ${buExcludes[*]} '${tmpSource}' '${tmpTarget}' > '/tmp/${buLog}0.log'"
|
|
|
|
# mv is not the right tool moving files to a different file system
|
|
exe cp /tmp/"${buLog}"*.log "${buTarget}"
|
|
exe rm -rf /tmp/"${buLog}"*.log
|
|
exe sync
|
|
if (( remount )) ; then
|
|
exep "mount -o ro,remount '${buTarget}' >>/dev/null 2>&1"
|
|
fi
|
|
}
|
|
|
|
step_100_info() { echo "Install ${sq_toolBin}"; }
|
|
step_100_alias() { echo "install"; }
|
|
step_100() {
|
|
exe apt update
|
|
exe apt install ${sq_toolBin} ${sq_aptOpt}
|
|
}
|
|
|
|
checkInstalled() {
|
|
if ! command -v ${sq_toolBin} >>/dev/null ; then
|
|
step install
|
|
fi
|
|
sq_toolBin="$(command -v ${sq_toolBin})"
|
|
}
|
|
|
|
# shellcheck disable=SC2034 # Appears unused
|
|
readonly sqr_minVersion=16
|
|
# shellcheck disable=SC1091 # Don't follow this source
|
|
. /usr/local/bin/sequencer.sh
|