On error just print error, but do not reset env vars, if this is done on verify error the init afterwards will store all settings in the wrong path
475 lines
18 KiB
Bash
475 lines
18 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# allow variables in printf format string
|
|
# shellcheck disable=SC2059
|
|
|
|
if [ -z "${MODULE}" ]; then
|
|
echo "Script cannot be run on its own";
|
|
exit 1;
|
|
fi;
|
|
|
|
# start time in seconds
|
|
START=$(date +'%s');
|
|
# set init date, or today if not file is set
|
|
BACKUP_INIT_DATE='';
|
|
if [ -f "${BASE_FOLDER}${BACKUP_INIT_FILE}" ]; then
|
|
BACKUP_INIT_DATE=$(printf '%(%c)T' "$(cat "${BASE_FOLDER}${BACKUP_INIT_FILE}" 2>/dev/null)");
|
|
fi;
|
|
# start logging from here
|
|
exec &> >(tee -a "${LOG}");
|
|
printf "${PRINTF_MASTER_BLOCK}" "START" "$(date +'%F %T')" "${MODULE}";
|
|
# show info for version always
|
|
printf "${PRINTF_INFO_STRING}" "Script version" "${VERSION}";
|
|
# show type
|
|
printf "${PRINTF_INFO_STRING}" "Backup module" "${MODULE}";
|
|
printf "${PRINTF_INFO_STRING}" "Module version" "${MODULE_VERSION}";
|
|
# borg version
|
|
printf "${PRINTF_INFO_STRING}" "Borg version" "${BORG_VERSION}";
|
|
# host name
|
|
printf "${PRINTF_INFO_STRING}" "Hostname" "${HOSTNAME}";
|
|
# show base folder always
|
|
printf "${PRINTF_INFO_STRING}" "Base folder" "${BASE_FOLDER}";
|
|
# Module init date (when init file was writen)
|
|
printf "${PRINTF_INFO_STRING}" "Module init date" "${BACKUP_INIT_DATE}";
|
|
# print last compact date if positive integer
|
|
# only if borg > 1.2
|
|
if [ "$(version "$BORG_VERSION")" -ge "$(version "1.2.0")" ]; then
|
|
if [ "${COMPACT_INTERVAL##*[!0-9]*}" ]; then
|
|
printf "${PRINTF_INFO_STRING}" "Module compact interval" "${COMPACT_INTERVAL}";
|
|
if [ -f "${BASE_FOLDER}${BACKUP_COMPACT_FILE}" ]; then
|
|
LAST_COMPACT_DATE=$(cat "${BASE_FOLDER}${BACKUP_COMPACT_FILE}" 2>/dev/null);
|
|
printf "${PRINTF_INFO_STRING}" "Module last compact" \
|
|
"$(printf '%(%c)T' "${LAST_COMPACT_DATE}") ($(convert_time $(($(date +%s) - LAST_COMPACT_DATE))) ago)";
|
|
else
|
|
printf "${PRINTF_INFO_STRING}" "Module last compact" "No compact run yet"
|
|
fi;
|
|
fi;
|
|
fi;
|
|
# print last check date if positive integer
|
|
if [ "${CHECK_INTERVAL##*[!0-9]*}" ]; then
|
|
printf "${PRINTF_INFO_STRING}" "Module check interval" "${CHECK_INTERVAL}";
|
|
# get last check date
|
|
if [ -f "${BASE_FOLDER}${BACKUP_CHECK_FILE}" ]; then
|
|
LAST_CHECK_DATE=$(cat "${BASE_FOLDER}${BACKUP_CHECK_FILE}" 2>/dev/null);
|
|
printf "${PRINTF_INFO_STRING}" "Module last check" \
|
|
"$(printf '%(%c)T' "${LAST_CHECK_DATE}") ($(convert_time $(($(date +%s) - LAST_CHECK_DATE))) ago)";
|
|
else
|
|
printf "${PRINTF_INFO_STRING}" "Module last check" "No check run yet";
|
|
fi;
|
|
fi;
|
|
|
|
# if force verify is true set VERIFY to 1 unless INFO is 1
|
|
# Needs bash 4.0 at lesat for this
|
|
if [ "${FORCE_VERIFY,,}" = "true" ] && [ "${INFO}" -eq 0 ]; then
|
|
VERIFY=1;
|
|
if [ "${DEBUG}" -eq 1 ]; then
|
|
echo "Force repository verify";
|
|
fi;
|
|
fi;
|
|
|
|
# remote borg path
|
|
if [ -n "${TARGET_BORG_PATH}" ]; then
|
|
if [[ "${TARGET_BORG_PATH}" =~ \ |\' ]]; then
|
|
echo "Space found in ${TARGET_BORG_PATH}. Aborting";
|
|
echo "There are issues with passing on paths with spaces"
|
|
echo "as parameters"
|
|
exit;
|
|
fi;
|
|
OPT_REMOTE="--remote-path="$(printf "%q" "${TARGET_BORG_PATH}");
|
|
fi;
|
|
|
|
if [ -z "${TARGET_FOLDER}" ]; then
|
|
echo "[! $(date +'%F %T')] No target folder has been set yet";
|
|
exit 1;
|
|
else
|
|
# There are big issues with TARGET FOLDERS with spaces
|
|
# we should abort anything with this
|
|
if [[ "${TARGET_FOLDER}" =~ \ |\' ]]; then
|
|
echo "Space found in ${TARGET_FOLDER}. Aborting";
|
|
echo "There is some problem with passing paths with spaces as";
|
|
echo "repository base folder"
|
|
exit;
|
|
fi;
|
|
|
|
# This does not care for multiple trailing or leading slashes
|
|
# it just makes sure we have at least one set
|
|
# for if we have a single slash, remove it
|
|
TARGET_FOLDER=${TARGET_FOLDER%/}
|
|
TARGET_FOLDER=${TARGET_FOLDER#/}
|
|
# and add slash front and back and escape the path
|
|
TARGET_FOLDER=$(printf "%q" "/${TARGET_FOLDER}/");
|
|
fi;
|
|
|
|
# if we have user/host then we build the ssh command
|
|
TARGET_SERVER='';
|
|
# allow host only (if full setup in .ssh/config)
|
|
# user@host OR ssh://user@host:port/ IF TARGET_PORT is set
|
|
# user/host/port
|
|
if [ -n "${TARGET_USER}" ] && [ -n "${TARGET_HOST}" ] && [ -n "${TARGET_PORT}" ]; then
|
|
TARGET_SERVER="ssh://${TARGET_USER}@${TARGET_HOST}:${TARGET_PORT}/";
|
|
# host/port
|
|
elif [ -n "${TARGET_HOST}" ] && [ -n "${TARGET_PORT}" ]; then
|
|
TARGET_SERVER="ssh://${TARGET_HOST}:${TARGET_PORT}/";
|
|
# user/host
|
|
elif [ -n "${TARGET_USER}" ] && [ -n "${TARGET_HOST}" ]; then
|
|
TARGET_SERVER="${TARGET_USER}@${TARGET_HOST}:";
|
|
# host
|
|
elif [ -n "${TARGET_HOST}" ]; then
|
|
TARGET_SERVER="${TARGET_HOST}:";
|
|
fi;
|
|
# we dont allow special characters, so we don't need to special escape it
|
|
REPOSITORY="${TARGET_SERVER}${TARGET_FOLDER}${BACKUP_FILE}";
|
|
printf "${PRINTF_INFO_STRING}" "Repository" "${REPOSITORY}";
|
|
|
|
# check if given compression name and level are valid
|
|
OPT_COMPRESSION='';
|
|
if [ -n "${COMPRESSION}" ]; then
|
|
# valid compression
|
|
if [ "${COMPRESSION}" = "lz4" ] || [ "${COMPRESSION}" = "zlib" ] || [ "${COMPRESSION}" = "lzma" ] || [ "${COMPRESSION}" = "zstd" ]; then
|
|
OPT_COMPRESSION="-C=${COMPRESSION}";
|
|
# if COMPRESSION_LEVEL, check it is a valid regex
|
|
# for zlib, zstd, lzma
|
|
if [ -n "${COMPRESSION_LEVEL}" ] && { [ "${COMPRESSION}" = "zlib" ] || [ "${COMPRESSION}" = "lzma" ] || [ "${COMPRESSION}" = "zstd" ]; }; then
|
|
MIN_COMPRESSION=0;
|
|
MAX_COMPRESSION=0;
|
|
case "${COMPRESSION}" in
|
|
zlib|lzma)
|
|
MIN_COMPRESSION=0;
|
|
MAX_COMPRESSION=9;
|
|
;;
|
|
zstd)
|
|
MIN_COMPRESSION=1;
|
|
MAX_COMPRESSION=22;
|
|
;;
|
|
*)
|
|
MIN_COMPRESSION=0;
|
|
MAX_COMPRESSION=0;
|
|
;;
|
|
esac;
|
|
# if [ "${COMPRESSION}" = "zlib" ] || [ "${COMPRESSION}" = "lzma" ]
|
|
# MIN_COMPRESSION=0;
|
|
# MAX_COMPRESSION=9;
|
|
# elif [ "${COMPRESSION}" = "zstd" ]; then
|
|
# MIN_COMPRESSION=1;
|
|
# MAX_COMPRESSION=22;
|
|
# fi;
|
|
error_message="[! $(date +'%F %T')] Compression level for ${COMPRESSION} needs to be a numeric value between ${MIN_COMPRESSION} and ${MAX_COMPRESSION}: ${COMPRESSION_LEVEL}";
|
|
if ! [[ "${COMPRESSION_LEVEL}" =~ ${REGEX_NUMERIC} ]]; then
|
|
echo "${error_message}";
|
|
exit 1;
|
|
elif [ "${COMPRESSION_LEVEL}" -lt "${MIN_COMPRESSION}" ] || [ "${COMPRESSION_LEVEL}" -gt "${MAX_COMPRESSION}" ]; then
|
|
echo "${error_message}";
|
|
exit 1;
|
|
else
|
|
OPT_COMPRESSION=${OPT_COMPRESSION}","${COMPRESSION_LEVEL};
|
|
fi;
|
|
fi;
|
|
else
|
|
echo "[! $(date +'%F %T')] Compress setting need to be lz4, zstd, zlib or lzma. Or empty for no compression: ${COMPRESSION}";
|
|
exit 1;
|
|
fi;
|
|
fi;
|
|
|
|
# home folder, needs to be set if there is eg a HOME=/ in the crontab
|
|
if [ ! -w "${HOME}" ] || [ "${HOME}" = '/' ]; then
|
|
HOME=$(eval echo "$(whoami)");
|
|
fi;
|
|
|
|
# keep optionfs (for files)
|
|
KEEP_OPTIONS=();
|
|
# keep info string (for files)
|
|
KEEP_INFO="";
|
|
# override standard keep for tagged backups
|
|
if [ -n "${ONE_TIME_TAG}" ]; then
|
|
BACKUP_SET="{now:%Y-%m-%dT%H:%M:%S}";
|
|
# set empty to avoid problems
|
|
KEEP_OPTIONS=("");
|
|
else
|
|
# build options and info string,
|
|
# also flag BACKUP_SET check if hourly is set
|
|
BACKUP_SET_VERIFY=0;
|
|
if [ "${KEEP_LAST}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-last=${KEEP_LAST}");
|
|
KEEP_INFO="${KEEP_INFO}, last: ${KEEP_LAST}";
|
|
fi;
|
|
if [ "${KEEP_HOURS}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-hourly=${KEEP_HOURS}");
|
|
KEEP_INFO="${KEEP_INFO}, hourly: ${KEEP_HOURS}";
|
|
BACKUP_SET_VERIFY=1;
|
|
fi;
|
|
if [ "${KEEP_DAYS}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-daily=${KEEP_DAYS}");
|
|
KEEP_INFO="${KEEP_INFO}, daily: ${KEEP_DAYS}";
|
|
fi;
|
|
if [ "${KEEP_WEEKS}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-weekly=${KEEP_WEEKS}");
|
|
KEEP_INFO="${KEEP_INFO}, weekly: ${KEEP_WEEKS}";
|
|
fi;
|
|
if [ "${KEEP_MONTHS}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-monthly=${KEEP_MONTHS}");
|
|
KEEP_INFO="${KEEP_INFO}, monthly: ${KEEP_MONTHS}";
|
|
fi;
|
|
if [ "${KEEP_YEARS}" -gt 0 ]; then
|
|
KEEP_OPTIONS+=("--keep-yearly=${KEEP_YEARS}");
|
|
KEEP_INFO="${KEEP_INFO}, yearly: ${KEEP_YEARS}";
|
|
fi;
|
|
if [ -n "${KEEP_WITHIN}" ]; then
|
|
# check for invalid string. can only be number + H|d|w|m|y
|
|
if [[ "${KEEP_WITHIN}" =~ ^[0-9]+[Hdwmy]{1}$ ]]; then
|
|
KEEP_OPTIONS+=("--keep-within=${KEEP_WITHIN}");
|
|
KEEP_INFO="${KEEP_INFO}, within: ${KEEP_WITHIN}";
|
|
if [[ "${KEEP_WITHIN}" == *"H"* ]]; then
|
|
BACKUP_SET_VERIFY=1;
|
|
fi;
|
|
else
|
|
echo "[! $(date +'%F %T')] KEEP_WITHIN has invalid string.";
|
|
exit 1;
|
|
fi;
|
|
fi;
|
|
# abort if KEEP_OPTIONS is empty
|
|
if [ "${#KEEP_OPTIONS[@]}" -eq "0" ]; then
|
|
echo "[! $(date +'%F %T')] It seems no KEEP_* entries where set in a valid format.";
|
|
exit 1;
|
|
fi;
|
|
# set BACKUP_SET if empty, set to Year-month-day
|
|
if [ -z "${BACKUP_SET}" ]; then
|
|
BACKUP_SET="{now:%Y-%m-%d}";
|
|
fi;
|
|
# backup set check, and there is no hour entry (%H) in the archive string
|
|
# we add T%H:%M:%S in this case, before the last }
|
|
if [ ${BACKUP_SET_VERIFY} -eq 1 ] && [[ "${BACKUP_SET}" != *"%H"* ]]; then
|
|
BACKUP_SET=$(echo "${BACKUP_SET}" | sed -e "s/}/T%H:%M:%S}/");
|
|
fi;
|
|
fi;
|
|
|
|
# check if we have lock file, check pid in lock file, if no matching pid found
|
|
# running remove lock file
|
|
if [ -f "${BASE_FOLDER}${BACKUP_LOCK_FILE}" ]; then
|
|
LOCK_PID=$(cat "${BASE_FOLDER}${BACKUP_LOCK_FILE}" 2>/dev/null);
|
|
# check if lock file pid has an active program attached to it
|
|
if [ -f "/proc/${LOCK_PID}/cmdline" ]; then
|
|
echo "Script is already running on PID: ${$}";
|
|
. "${DIR}/borg.backup.functions.close.sh" 1;
|
|
exit 1;
|
|
else
|
|
echo "[#] Clean up stale lock file for PID: ${LOCK_PID}";
|
|
rm "${BASE_FOLDER}${BACKUP_LOCK_FILE}";
|
|
fi;
|
|
fi;
|
|
echo "${$}" > "${BASE_FOLDER}${BACKUP_LOCK_FILE}";
|
|
|
|
# for folders list split set to "#" and keep the old setting as is
|
|
_IFS=${IFS};
|
|
IFS="#";
|
|
# turn off for non file
|
|
if [ "${MODULE}" != "file" ]; then
|
|
IFS=${_IFS};
|
|
fi;
|
|
|
|
# borg call, replace ##...## parts during run
|
|
# used in all modules, except 'file'
|
|
_BORG_CALL="${BORG_COMMAND} create ${OPT_REMOTE} -v ${OPT_LIST} ${OPT_PROGRESS} ${OPT_COMPRESSION} -s --stdin-name ##FILENAME## ${REPOSITORY}::##BACKUP_SET## -";
|
|
_BORG_PRUNE="${BORG_COMMAND} prune ${OPT_REMOTE} -v --list ${OPT_PROGRESS} ${DRY_RUN_STATS} -P ##BACKUP_SET_PREFIX## ${KEEP_OPTIONS[*]} ${REPOSITORY}";
|
|
|
|
# general borg settings
|
|
# set base path to config directory to keep cache/config separated
|
|
export BORG_BASE_DIR="${BASE_FOLDER}";
|
|
# ignore non encrypted access
|
|
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK="${_BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK}";
|
|
# ignore moved repo access
|
|
export BORG_RELOCATED_REPO_ACCESS_IS_OK="${_BORG_RELOCATED_REPO_ACCESS_IS_OK}";
|
|
# and for debug print that tout
|
|
if [ "${DEBUG}" -eq 1 ]; then
|
|
echo "export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=${_BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK};";
|
|
echo "export BORG_RELOCATED_REPO_ACCESS_IS_OK=${_BORG_RELOCATED_REPO_ACCESS_IS_OK};";
|
|
echo "export BORG_BASE_DIR=\"${BASE_FOLDER}\";";
|
|
fi;
|
|
# prepare debug commands only
|
|
COMMAND_EXPORT="export BORG_BASE_DIR=\"${BASE_FOLDER}\";"
|
|
COMMAND_INFO="${COMMAND_EXPORT}${BORG_COMMAND} info ${OPT_REMOTE} ${REPOSITORY}";
|
|
# if the is not there, call init to create it
|
|
# if this is user@host, we need to use ssh command to verify if the file is there
|
|
# else a normal verify is ok
|
|
# unless explicit given, verify is skipped
|
|
# MARK: VERIFY / INFO
|
|
if [ "${VERIFY}" -eq 1 ] || [ "${INIT}" -eq 1 ]; then
|
|
printf "${PRINTF_SUB_BLOCK}" "VERIFY" "$(date +'%F %T')" "${MODULE}";
|
|
if [ -n "${TARGET_SERVER}" ]; then
|
|
if [ "${DEBUG}" -eq 1 ]; then
|
|
echo "${BORG_COMMAND} info ${OPT_REMOTE} ${REPOSITORY} 2>&1|grep \"Repository ID:\"";
|
|
fi;
|
|
# use borg info and verify if it returns "Repository ID:" in the first line
|
|
REPO_VERIFY=$(${BORG_COMMAND} info ${OPT_REMOTE} "${REPOSITORY}" 2>&1);
|
|
if ! $?; then
|
|
echo "[!] Repository verify error: ${REPO_VERIFY}";
|
|
REPO_VERIFY="";
|
|
else
|
|
REPO_VERIFY=$(echo "${REPO_VERIFY}" | grep "Repository ID:");
|
|
fi;
|
|
# | grep "Repository ID:"
|
|
# this is currently a hack to work round the error code in borg info
|
|
# this checks if REPO_VERIFY holds this error message and then starts init
|
|
if [[ -z "${REPO_VERIFY}" ]] || [[ "${REPO_VERIFY}" =~ ${REGEX_ERROR} ]]; then
|
|
INIT_REPOSITORY=1;
|
|
fi;
|
|
elif [ ! -d "${REPOSITORY}" ]; then
|
|
INIT_REPOSITORY=1;
|
|
fi;
|
|
# if verrify but no init and repo is there but init file is missing set it
|
|
if [ "${VERIFY}" -eq 1 ] && [ "${INIT}" -eq 0 ] && [ "${INIT_REPOSITORY}" -eq 0 ] &&
|
|
[ ! -f "${BASE_FOLDER}${BACKUP_INIT_FILE}" ]; then
|
|
# write init file
|
|
echo "[!] Add missing init verify file";
|
|
date +%s > "${BASE_FOLDER}${BACKUP_INIT_FILE}";
|
|
fi;
|
|
# end if verified but repository is not here
|
|
if [ "${VERIFY}" -eq 1 ] && [ "${INIT}" -eq 0 ] && [ "${INIT_REPOSITORY}" -eq 1 ]; then
|
|
echo "[! $(date +'%F %T')] No repository. Please run with -I flag to initialze repository";
|
|
. "${DIR}/borg.backup.functions.close.sh" 1;
|
|
exit 1;
|
|
fi;
|
|
if [ "${EXIT}" -eq 1 ] && [ "${VERIFY}" -eq 1 ] && [ "${INIT}" -eq 0 ]; then
|
|
echo "Repository exists";
|
|
echo "For more information run:"
|
|
echo "${COMMAND_INFO}";
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
exit;
|
|
fi;
|
|
fi;
|
|
# MARK: INIT
|
|
if [ "${INIT}" -eq 1 ] && [ "${INIT_REPOSITORY}" -eq 1 ]; then
|
|
|
|
printf "${PRINTF_SUB_BLOCK}" "INIT" "$(date +'%F %T')" "${MODULE}";
|
|
if [ "${DEBUG}" -eq 1 ] || [ "${DRYRUN}" -eq 1 ]; then
|
|
echo "${BORG_COMMAND} init ${OPT_REMOTE} -e ${ENCRYPTION} ${OPT_VERBOSE} ${REPOSITORY}";
|
|
echo "${BORG_COMMAND} key export ${REPOSITORY}";
|
|
echo "${BORG_COMMAND} key export --paper ${REPOSITORY}";
|
|
fi
|
|
if [ "${DRYRUN}" -eq 0 ]; then
|
|
# should trap and exit properly here
|
|
${BORG_COMMAND} init ${OPT_REMOTE} -e "${ENCRYPTION}" ${OPT_VERBOSE} "${REPOSITORY}";
|
|
# show the key file
|
|
if [ "${ENCRYPTION}" = "keyfile" ]; then
|
|
echo "--- [ENCRYPTION KEY] --[START]-------------------------------------------------->";
|
|
echo "Store the key and password in a safe place";
|
|
echo "export BORG_BASE_DIR=\"${BASE_FOLDER}\";borg key export [--paper] ${REPOSITORY}";
|
|
echo "----[BORG KEY] -------------------------------->";
|
|
${BORG_COMMAND} key export "${REPOSITORY}";
|
|
echo "----[BORG KEY:paper] -------------------------->";
|
|
${BORG_COMMAND} key export --paper "${REPOSITORY}";
|
|
echo "--- [ENCRYPTION KEY] --[END ]-------------------------------------------------->";
|
|
fi;
|
|
# write init file
|
|
date +%s > "${BASE_FOLDER}${BACKUP_INIT_FILE}";
|
|
echo "Repository initialized";
|
|
echo "For more information run:"
|
|
echo "${COMMAND_INFO}";
|
|
fi
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
# exit after init
|
|
exit;
|
|
elif [ "${INIT}" -eq 1 ] && [ "${INIT_REPOSITORY}" -eq 0 ]; then
|
|
echo "[! $(date +'%F %T')] Repository already initialized";
|
|
echo "For more information run:"
|
|
echo "${COMMAND_INFO}";
|
|
. "${DIR}/borg.backup.functions.close.sh" 1;
|
|
exit 1;
|
|
fi;
|
|
|
|
# verify for init file
|
|
if [ ! -f "${BASE_FOLDER}${BACKUP_INIT_FILE}" ]; then
|
|
echo "[! $(date +'%F %T')] It seems the repository has never been initialized."
|
|
echo "Please run -I to initialize or if already initialzed run with -C for init update."
|
|
. "${DIR}/borg.backup.functions.close.sh" 1;
|
|
exit 1;
|
|
fi;
|
|
|
|
# MARK: LIST / PRINT
|
|
# PRINT OUT current data, only do this if REPO exists
|
|
if [ "${PRINT}" -eq 1 ]; then
|
|
printf "${PRINTF_SUB_BLOCK}" "PRINT" "$(date +'%F %T')" "${MODULE}";
|
|
FORMAT="{archive:<45} {comment:6} {start} - {end} [{id}] ({username}@{hostname}){NL}"
|
|
# show command on debug or dry run
|
|
if [ "${DEBUG}" -eq 1 ] || [ "${DRYRUN}" -eq 1 ]; then
|
|
echo "export BORG_BASE_DIR=\"${BASE_FOLDER}\";${BORG_COMMAND} list ${OPT_REMOTE} --format ${FORMAT} ${REPOSITORY}";
|
|
fi;
|
|
# run info command if not a dry drun
|
|
if [ "${DRYRUN}" -eq 0 ]; then
|
|
${BORG_COMMAND} list ${OPT_REMOTE} --format "${FORMAT}" "${REPOSITORY}" ;
|
|
fi;
|
|
if [ "${VERBOSE}" -eq 1 ]; then
|
|
echo "";
|
|
echo "Base command info:"
|
|
echo "export BORG_BASE_DIR=\"${BASE_FOLDER}\";${BORG_COMMAND} [COMMAND] ${OPT_REMOTE} ${REPOSITORY}::[BACKUP] [PATH]";
|
|
echo "Replace [COMMAND] with list for listing or extract for restoring backup data."
|
|
echo "Replace [BACKUP] with archive name."
|
|
echo "If no [PATH] is given then all files will be restored."
|
|
echo "Before extracting -n (dry run) is recommended to use."
|
|
echo "If archive size is needed the info command with archive name has to be used."
|
|
echo "When listing files in an archive set (::SET) the --format command can be used."
|
|
echo "Example: \"{mode} {user:6} {group:6} {size:8d} {csize:8d} {dsize:8d} {dcsize:8d} {mtime} {path}{extra} [{health}]{NL}\""
|
|
else
|
|
echo "export BORG_BASE_DIR=\"${BASE_FOLDER}\";${BORG_COMMAND} [COMMAND] ${OPT_REMOTE} [FORMAT] ${REPOSITORY}::[BACKUP] [PATH]";
|
|
fi;
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
exit;
|
|
fi;
|
|
|
|
# run borg compact command and exit
|
|
if [ "${COMPACT}" -eq 1 ]; then
|
|
. "${DIR}/borg.backup.functions.compact.sh";
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
exit;
|
|
fi;
|
|
|
|
# run borg check command and exit
|
|
if [ "${CHECK}" -eq 1 ]; then
|
|
. "${DIR}/borg.backup.functions.check.sh";
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
exit;
|
|
fi;
|
|
|
|
# DELETE ONE TIME TAG
|
|
if [ -n "${DELETE_ONE_TIME_TAG}" ]; then
|
|
printf "${PRINTF_SUB_BLOCK}" "DELETE" "$(date +'%F %T')" "${MODULE}";
|
|
# if a "*" is inside we don't do ONE archive, but globbing via -a option
|
|
DELETE_ARCHIVE=""
|
|
OPT_GLOB="";
|
|
# this is more or less for debug only
|
|
if [[ "${DELETE_ONE_TIME_TAG}" =~ $REGEX_GLOB ]]; then
|
|
OPT_GLOB="-a '${DELETE_ONE_TIME_TAG}'"
|
|
else
|
|
DELETE_ARCHIVE="::"${DELETE_ONE_TIME_TAG};
|
|
fi
|
|
# if this is borg <1.2 OPT_LIST does not work
|
|
if [ "$(version "$BORG_VERSION")" -lt "$(version "1.2.0")" ]; then
|
|
OPT_LIST="";
|
|
fi;
|
|
# if exists, delete and exit
|
|
# show command on debug or dry run
|
|
if [ "${DEBUG}" -eq 1 ]; then
|
|
echo "${BORG_COMMAND} delete ${OPT_REMOTE} ${OPT_LIST} -s ${OPT_GLOB} ${REPOSITORY}${DELETE_ARCHIVE}";
|
|
fi;
|
|
# run delete command if not a dry drun
|
|
# NOTE seems to be glob is not working if wrapped into another variable
|
|
if [[ "${DELETE_ONE_TIME_TAG}" =~ $REGEX_GLOB ]]; then
|
|
${BORG_COMMAND} delete ${OPT_REMOTE} ${OPT_LIST} ${DRY_RUN_STATS} -a "${DELETE_ONE_TIME_TAG}" ${REPOSITORY};
|
|
else
|
|
${BORG_COMMAND} delete ${OPT_REMOTE} ${OPT_LIST} ${DRY_RUN_STATS} ${REPOSITORY}${DELETE_ARCHIVE};
|
|
fi;
|
|
# if not a dry run, compact repository after delete
|
|
# not that compact only works on borg 1.2
|
|
if [ "$(version "$BORG_VERSION")" -ge "$(version "1.2.0")" ]; then
|
|
if [ "${DRYRUN}" -eq 0 ]; then
|
|
${BORG_COMMAND} compact ${OPT_REMOTE} "${REPOSITORY}";
|
|
fi;
|
|
if [ "${DEBUG}" -eq 1 ]; then
|
|
echo "${BORG_COMMAND} compact ${OPT_REMOTE} ${REPOSITORY}";
|
|
fi;
|
|
fi;
|
|
. "${DIR}/borg.backup.functions.close.sh";
|
|
exit;
|
|
fi;
|
|
|
|
# __END__
|