Files
BorgBackupWrapper/borg.backup.file.sh
Clemens Schwaighofer bba8be6a42 Exclude File check is if file is >0 and fix wrong check for tmp file
Exclude file was only checked if it exists, even if it was empty it
would start processing.
In the exclude check there was also a wrong check for the tmp exclude
file, it actually checked if the main exclude file was >0 instead of the
tmp file.
2022-08-30 09:56:20 +09:00

209 lines
8.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Plain file backup
# set last edit date + time
MODULE="file";
MODULE_VERSION="1.2.2";
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "${DIR}/borg.backup.functions.init.sh";
# include and exclude file
INCLUDE_FILE="borg.backup.${MODULE}.include";
EXCLUDE_FILE="borg.backup.${MODULE}.exclude";
# init verify, compact and check file
BACKUP_INIT_FILE="borg.backup.${MODULE}.init";
BACKUP_COMPACT_FILE="borg.backup.${MODULE}.compact";
BACKUP_CHECK_FILE="borg.backup.${MODULE}.check";
# lock file
BACKUP_LOCK_FILE="borg.backup.${MODULE}.lock";
# verify valid data
. "${DIR}/borg.backup.functions.verify.sh";
# exit if include file is missing
if [ ! -f "${BASE_FOLDER}${INCLUDE_FILE}" ]; then
echo "[! $(date +'%F %T')] The include folder file ${INCLUDE_FILE} is missing";
. "${DIR}/borg.backup.functions.close.sh" 1;
exit 1;
fi;
printf "${PRINTF_SUB_BLOCK}" "INCLUDE" "$(date +'%F %T')" "${MODULE}";
# folders to backup
FOLDERS=();
# this if for debug output with quoted folders
FOLDERS_Q=();
# include list
while read include_folder; do
# strip any leading spaces from that folder
include_folder=$(echo "${include_folder}" | sed -e 's/^[ \t]*//');
# check that those folders exist, warn on error,
# but do not exit unless there are no valid folders at all
# skip folders that are with # in front (comment)
if [[ "${include_folder}" =~ ${REGEX_COMMENT} ]]; then
echo "# [C] Comment: '${include_folder}'";
else
# skip if it is empty
if [ ! -z "${include_folder}" ]; then
# if this is a glob, do a double check that the base folder actually exists (?)
if [[ "${include_folder}" =~ $REGEX_GLOB ]]; then
# if this is */ then allow it
# remove last element beyond the last /
# if there is no path, just allow it (general rule)
_include_folder=${include_folder%/*};
# if still a * inside -> add as is, else check for folder
if [[ "${include_folder}" =~ $REGEX_GLOB ]]; then
FOLDER_OK=1;
echo "+ [I] Backup folder with folder path glob '${include_folder}'";
# glob (*) would be escape so we replace it with a temp part and then reinsert it
FOLDERS_Q+=($(printf "%q" "$(echo "${include_folder}" | sed 's/\*/_STARGLOB_/g')" | sed 's/_STARGLOB_/\*/g'));
FOLDERS+=("${include_folder}");
elif [ ! -d "${_include_folder}" ]; then
echo "- [I] Backup folder with glob '${include_folder}' does not exist or is not accessable";
else
FOLDER_OK=1;
echo "+ [I] Backup folder with glob '${include_folder}'";
# we need glob fix
FOLDERS_Q+=($(printf "%q" "$(echo "${include_folder}" | sed 's/\*/_STARGLOB_/g')" | sed 's/_STARGLOB_/\*/g'));
FOLDERS+=("${include_folder}");
fi;
# normal folder
elif [ ! -d "${include_folder}" ] && [ ! -e "${include_folder}" ]; then
echo "- [I] Backup folder or file '${include_folder}' does not exist or is not accessable";
else
FOLDER_OK=1;
# if it is a folder, remove the last / or the symlink check will not work
if [ -d "${include_folder}" ]; then
_include_folder=${include_folder%/*};
else
_include_folder=${include_folder};
fi;
# Warn if symlink & folder -> only smylink will be backed up
if [ -h "${_include_folder}" ]; then
echo "~ [I] Target '${include_folder}' is a symbolic link. No real data will be backed up";
else
echo "+ [I] Backup folder or file '${include_folder}'";
fi;
FOLDERS_Q+=($(printf "%q" "${include_folder}"));
FOLDERS+=("${include_folder}");
fi;
fi;
fi;
done<"${BASE_FOLDER}${INCLUDE_FILE}";
# exclude list, only if file exists and is larger than zero
if [ -s "${BASE_FOLDER}${EXCLUDE_FILE}" ]; then
printf "${PRINTF_SUB_BLOCK}" "EXCLUDE" "$(date +'%F %T')" "${MODULE}";
# check that the folders in that exclude file are actually valid,
# remove non valid ones and warn
#TMP_EXCLUDE_FILE=$(mktemp --tmpdir ${EXCLUDE_FILE}.XXXXXXXX); # non mac
TMP_EXCLUDE_FILE=$(mktemp "${TEMPDIR}${EXCLUDE_FILE}".XXXXXXXX);
while read exclude_folder; do
# strip any leading spaces from that folder
exclude_folder=$(echo "${exclude_folder}" | sed -e 's/^[ \t]*//');
# folder or any type of file is ok
# because of glob files etc, exclude only comments (# start)
if [[ "${exclude_folder}" =~ ${REGEX_COMMENT} ]]; then
echo "# [C] Comment: '${exclude_folder}'";
else
# skip if it is empty
if [ ! -z "${exclude_folder}" ]; then
# if it DOES NOT start with a / we assume free folder and add as is
if [[ "${exclude_folder}" != /* ]]; then
echo "${exclude_folder}" >> ${TMP_EXCLUDE_FILE};
echo "+ [E] General exclude: '${exclude_folder}'";
# if this is a glob, do a double check that the base folder actually exists (?)
elif [[ "${exclude_folder}" =~ $REGEX_GLOB ]]; then
# remove last element beyond the last /
# if there is no path, just allow it (general rule)
_exclude_folder=${exclude_folder%/*};
if [ ! -d "${_exclude_folder}" ]; then
echo "- [E] Exclude folder with glob '${exclude_folder}' does not exist or is not accessable";
else
echo "${exclude_folder}" >> ${TMP_EXCLUDE_FILE};
echo "+ [E] Exclude folder with glob '${exclude_folder}'";
fi;
# do a warning for a possible invalid folder
# but we do not a exclude if the data does not exist
elif [ ! -d "${exclude_folder}" ] && [ ! -e "${exclude_folder}" ]; then
echo "- [E] Exclude folder or file '${exclude_folder}' does not exist or is not accessable";
else
echo "${exclude_folder}" >> ${TMP_EXCLUDE_FILE};
# if it is a folder, remove the last / or the symlink check will not work
if [ -d "${exclude_folder}" ]; then
_exclude_folder=${exclude_folder%/*};
else
_exclude_folder=${exclude_folder};
fi;
# warn if target is symlink folder
if [ -h "${_exclude_folder}" ]; then
echo "~ [I] Target '${exclude_folder}' is a symbolic link. No real data will be excluded from backup";
else
echo "+ [E] Exclude folder or file '${exclude_folder}'";
fi;
fi;
fi;
fi;
done<"${BASE_FOLDER}${EXCLUDE_FILE}";
# avoid blank file add by checking if the tmp file has a size >0
if [ -s "${TMP_EXCLUDE_FILE}" ]; then
OPT_EXCLUDE="--exclude-from=${TMP_EXCLUDE_FILE}";
fi;
fi;
# set a special file prefix
BACKUP_SET_PREFIX="${MODULE},";
# add the repository set before we add the folders
# base command
COMMAND="${BORG_COMMAND} create -v ${OPT_LIST} ${OPT_PROGRESS} ${OPT_COMPRESSION} -s ${OPT_REMOTE} ${OPT_EXCLUDE} ";
# add repoistory, after that the folders will be added on call
COMMAND=${COMMAND}${REPOSITORY}::${ONE_TIME_TAG}${BACKUP_SET_PREFIX}${BACKUP_SET};
# if info print info and then abort run
. "${DIR}/borg.backup.functions.info.sh";
if [ $FOLDER_OK -eq 1 ]; then
printf "${PRINTF_SUB_BLOCK}" "BACKUP" "$(date +'%F %T')" "${MODULE}";
# show command
if [ ${DEBUG} -eq 1 ]; then
echo $(echo ${COMMAND} | sed -e 's/[ ][ ]*/ /g') ${FOLDERS_Q[*]};
fi;
# execute backup command
if [ ${DRYRUN} -eq 0 ]; then
# need to redirect std error to std out so all data is printed to the correct pipe
# for the IFS="#" to work we need to replace options spaces with exactly ONE #
$(echo "${COMMAND}" | sed -e 's/[ ][ ]*/#/g') ${FOLDERS[*]} 2>&1 || echo "[!] Borg backup aborted.";
fi;
# remove the temporary exclude file if it exists
if [ -f "${TMP_EXCLUDE_FILE}" ]; then
rm -f "${TMP_EXCLUDE_FILE}";
fi;
else
echo "[! $(date +'%F %T')] No folders where set for the backup";
. "${DIR}/borg.backup.functions.close.sh" 1;
exit 1;
fi;
# clean up, always verbose, but only if we do not run one time tag
if [ -z "${ONE_TIME_TAG}" ]; then
printf "${PRINTF_SUB_BLOCK}" "PRUNE" "$(date +'%F %T')" "${MODULE}";
# build command
COMMAND="${BORG_COMMAND} prune ${OPT_REMOTE} -v --list ${OPT_PROGRESS} ${DRY_RUN_STATS} -P ${BACKUP_SET_PREFIX} ${KEEP_OPTIONS[*]} ${REPOSITORY}";
echo "Prune repository with keep${KEEP_INFO:1}";
if [ ${DEBUG} -eq 1 ]; then
echo "${COMMAND//#/ }" | sed -e 's/[ ][ ]*/ /g';
fi;
# for the IFS="#" to work we need to replace options spaces with exactly ONE #
$(echo "${COMMAND}" | sed -e 's/[ ][ ]*/#/g') 2>&1 || echo "[!] Borg prune aborted";
# if this is borg version >1.2 we need to run compact after prune
. "${DIR}/borg.backup.functions.compact.sh" "auto";
# check in auto mode
. "${DIR}/borg.backup.functions.check.sh" "auto";
else
echo "[#] No prune with tagged backup";
fi;
. "${DIR}/borg.backup.functions.close.sh";
# __END__