2021-12-13 10:36:44 +09:00
#!/usr/bin/env bash
2025-12-01 16:53:50 +09:00
# allow variables in printf format string
# shellcheck disable=SC2059
2022-04-25 06:49:57 +09:00
if [ -z " ${ MODULE } " ] ; then
echo "Script cannot be run on its own" ;
exit 1;
fi ;
2021-12-13 10:36:44 +09:00
# start time in seconds
START = $( date +'%s' ) ;
2022-04-01 11:16:38 +09:00
# set init date, or today if not file is set
2022-04-25 06:49:57 +09:00
BACKUP_INIT_DATE = '' ;
if [ -f " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " ] ; then
2025-12-01 16:53:50 +09:00
BACKUP_INIT_DATE = $( printf '%(%c)T' " $( cat " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " 2>/dev/null) " ) ;
2022-04-25 06:49:57 +09:00
fi ;
2021-12-13 10:36:44 +09:00
# start logging from here
exec & > >( tee -a " ${ LOG } " ) ;
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_MASTER_BLOCK } " "START" " $( date +'%F %T' ) " " ${ MODULE } " ;
2021-12-13 10:36:44 +09:00
# show info for version always
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Script version" " ${ VERSION } " ;
2021-12-13 10:36:44 +09:00
# show type
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Backup module" " ${ MODULE } " ;
printf " ${ PRINTF_INFO_STRING } " "Module version" " ${ MODULE_VERSION } " ;
2022-03-28 11:27:35 +09:00
# borg version
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Borg version" " ${ BORG_VERSION } " ;
2022-04-01 11:16:38 +09:00
# host name
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Hostname" " ${ HOSTNAME } " ;
2021-12-13 10:36:44 +09:00
# show base folder always
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Base folder" " ${ BASE_FOLDER } " ;
2022-04-01 11:16:38 +09:00
# Module init date (when init file was writen)
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Module init date" " ${ BACKUP_INIT_DATE } " ;
2022-06-06 14:58:36 +09:00
# print last compact date if positive integer
# only if borg > 1.2
2025-12-01 16:53:50 +09:00
if [ " $( version " $BORG_VERSION " ) " -ge " $( version "1.2.0" ) " ] ; then
2022-06-06 14:58:36 +09:00
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" \
2025-12-01 16:53:50 +09:00
" $( printf '%(%c)T' " ${ LAST_COMPACT_DATE } " ) ( $( convert_time $(( $( date +%s) - LAST_COMPACT_DATE)) ) ago) " ;
2022-06-06 14:58:36 +09:00
else
printf " ${ PRINTF_INFO_STRING } " "Module last compact" "No compact run yet"
fi ;
fi ;
fi ;
2022-04-25 06:49:57 +09:00
# print last check date if positive integer
if [ " ${ CHECK_INTERVAL ##*[!0-9]* } " ] ; then
printf " ${ PRINTF_INFO_STRING } " "Module check interval" " ${ CHECK_INTERVAL } " ;
2022-06-06 14:58:36 +09:00
# 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" \
2025-12-01 16:53:50 +09:00
" $( printf '%(%c)T' " ${ LAST_CHECK_DATE } " ) ( $( convert_time $(( $( date +%s) - LAST_CHECK_DATE)) ) ago) " ;
2022-06-06 14:58:36 +09:00
else
printf " ${ PRINTF_INFO_STRING } " "Module last check" "No check run yet" ;
fi ;
2022-04-25 06:49:57 +09:00
fi ;
2021-12-13 10:36:44 +09:00
2022-04-18 15:30:03 +09:00
# if force verify is true set VERIFY to 1 unless INFO is 1
2021-12-13 10:36:44 +09:00
# Needs bash 4.0 at lesat for this
2025-12-01 16:53:50 +09:00
if [ " ${ FORCE_VERIFY ,, } " = "true" ] && [ " ${ INFO } " -eq 0 ] ; then
2022-04-18 15:30:03 +09:00
VERIFY = 1;
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] ; then
2022-04-18 15:30:03 +09:00
echo "Force repository verify" ;
2021-12-13 10:36:44 +09:00
fi ;
fi ;
# remote borg path
2025-12-01 16:53:50 +09:00
if [ -n " ${ TARGET_BORG_PATH } " ] ; then
2021-12-13 10:36:44 +09:00
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
2025-12-01 16:53:50 +09:00
if [ -n " ${ TARGET_USER } " ] && [ -n " ${ TARGET_HOST } " ] && [ -n " ${ TARGET_PORT } " ] ; then
2021-12-13 10:36:44 +09:00
TARGET_SERVER = " ssh:// ${ TARGET_USER } @ ${ TARGET_HOST } : ${ TARGET_PORT } / " ;
# host/port
2025-12-01 16:53:50 +09:00
elif [ -n " ${ TARGET_HOST } " ] && [ -n " ${ TARGET_PORT } " ] ; then
2021-12-13 10:36:44 +09:00
TARGET_SERVER = " ssh:// ${ TARGET_HOST } : ${ TARGET_PORT } / " ;
# user/host
2025-12-01 16:53:50 +09:00
elif [ -n " ${ TARGET_USER } " ] && [ -n " ${ TARGET_HOST } " ] ; then
2021-12-13 10:36:44 +09:00
TARGET_SERVER = " ${ TARGET_USER } @ ${ TARGET_HOST } : " ;
# host
2025-12-01 16:53:50 +09:00
elif [ -n " ${ TARGET_HOST } " ] ; then
2021-12-13 10:36:44 +09:00
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 } " ;
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_INFO_STRING } " "Repository" " ${ REPOSITORY } " ;
2021-12-13 10:36:44 +09:00
2022-04-18 15:30:03 +09:00
# check if given compression name and level are valid
2022-03-03 10:23:39 +09:00
OPT_COMPRESSION = '' ;
2025-12-01 16:53:50 +09:00
if [ -n " ${ COMPRESSION } " ] ; then
2021-12-13 10:36:44 +09:00
# 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
2025-12-01 16:53:50 +09:00
if [ -n " ${ COMPRESSION_LEVEL } " ] && { [ " ${ COMPRESSION } " = "zlib" ] || [ " ${ COMPRESSION } " = "lzma" ] || [ " ${ COMPRESSION } " = "zstd" ] ; } ; then
2021-12-13 10:36:44 +09:00
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
2025-12-01 16:53:50 +09:00
echo " ${ error_message } " ;
2021-12-13 10:36:44 +09:00
exit 1;
2025-12-01 16:53:50 +09:00
elif [ " ${ COMPRESSION_LEVEL } " -lt " ${ MIN_COMPRESSION } " ] || [ " ${ COMPRESSION_LEVEL } " -gt " ${ MAX_COMPRESSION } " ] ; then
echo " ${ error_message } " ;
2021-12-13 10:36:44 +09:00
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 ;
2022-03-28 11:27:35 +09:00
# keep optionfs (for files)
2022-03-31 11:01:02 +09:00
KEEP_OPTIONS = ( ) ;
2022-03-28 11:27:35 +09:00
# keep info string (for files)
2021-12-13 10:36:44 +09:00
KEEP_INFO = "" ;
2022-03-28 11:27:35 +09:00
# override standard keep for tagged backups
2025-12-01 16:53:50 +09:00
if [ -n " ${ ONE_TIME_TAG } " ] ; then
2022-03-28 11:27:35 +09:00
BACKUP_SET = "{now:%Y-%m-%dT%H:%M:%S}" ;
2022-03-31 11:01:02 +09:00
# set empty to avoid problems
KEEP_OPTIONS = ( "" ) ;
2022-03-28 11:27:35 +09:00
else
# build options and info string,
# also flag BACKUP_SET check if hourly is set
2022-04-18 15:30:03 +09:00
BACKUP_SET_VERIFY = 0;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_LAST } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-last= ${ KEEP_LAST } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , last: ${ KEEP_LAST } " ;
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_HOURS } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-hourly= ${ KEEP_HOURS } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , hourly: ${ KEEP_HOURS } " ;
2022-04-18 15:30:03 +09:00
BACKUP_SET_VERIFY = 1;
2022-03-28 11:27:35 +09:00
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_DAYS } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-daily= ${ KEEP_DAYS } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , daily: ${ KEEP_DAYS } " ;
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_WEEKS } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-weekly= ${ KEEP_WEEKS } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , weekly: ${ KEEP_WEEKS } " ;
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_MONTHS } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-monthly= ${ KEEP_MONTHS } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , monthly: ${ KEEP_MONTHS } " ;
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ KEEP_YEARS } " -gt 0 ] ; then
2022-03-28 11:27:35 +09:00
KEEP_OPTIONS += ( " --keep-yearly= ${ KEEP_YEARS } " ) ;
KEEP_INFO = " ${ KEEP_INFO } , yearly: ${ KEEP_YEARS } " ;
fi ;
2025-12-01 16:53:50 +09:00
if [ -n " ${ KEEP_WITHIN } " ] ; then
2022-03-28 11:27:35 +09:00
# 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
2022-04-18 15:30:03 +09:00
BACKUP_SET_VERIFY = 1;
2022-03-28 11:27:35 +09:00
fi ;
else
echo " [! $( date +'%F %T' ) ] KEEP_WITHIN has invalid string. " ;
exit 1;
2021-12-13 10:36:44 +09:00
fi ;
2022-03-28 11:27:35 +09:00
fi ;
# abort if KEEP_OPTIONS is empty
2022-03-31 11:01:02 +09:00
if [ " ${# KEEP_OPTIONS [@] } " -eq "0" ] ; then
2022-03-28 11:27:35 +09:00
echo " [! $( date +'%F %T' ) ] It seems no KEEP_* entries where set in a valid format. " ;
2021-12-13 10:36:44 +09:00
exit 1;
fi ;
2022-03-28 11:27:35 +09:00
# 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 }
2022-04-18 15:30:03 +09:00
if [ ${ BACKUP_SET_VERIFY } -eq 1 ] && [ [ " ${ BACKUP_SET } " != *"%H" * ] ] ; then
2022-03-28 11:27:35 +09:00
BACKUP_SET = $( echo " ${ BACKUP_SET } " | sed -e "s/}/T%H:%M:%S}/" ) ;
fi ;
2021-12-13 10:36:44 +09:00
fi ;
2022-04-25 06:49:57 +09:00
# 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
2025-12-01 16:53:50 +09:00
if [ -f " /proc/ ${ LOCK_PID } /cmdline " ] ; then
2022-04-25 06:49:57 +09:00
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 } " ;
2021-12-13 10:36:44 +09:00
# 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 ;
2021-12-14 10:24:42 +09:00
# borg call, replace ##...## parts during run
# used in all modules, except 'file'
2022-03-28 11:27:35 +09:00
_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 } " ;
2021-12-14 10:24:42 +09:00
2021-12-13 10:36:44 +09:00
# general borg settings
# set base path to config directory to keep cache/config separated
export BORG_BASE_DIR = " ${ BASE_FOLDER } " ;
# ignore non encrypted access
2025-12-01 16:53:50 +09:00
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = " ${ _BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK } " ;
2021-12-13 10:36:44 +09:00
# ignore moved repo access
2025-12-01 16:53:50 +09:00
export BORG_RELOCATED_REPO_ACCESS_IS_OK = " ${ _BORG_RELOCATED_REPO_ACCESS_IS_OK } " ;
2021-12-13 10:36:44 +09:00
# and for debug print that tout
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] ; then
2021-12-13 10:36:44 +09:00
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 } \"; "
2022-03-28 11:27:35 +09:00
COMMAND_INFO = " ${ COMMAND_EXPORT } ${ BORG_COMMAND } info ${ OPT_REMOTE } ${ REPOSITORY } " ;
2021-12-13 10:36:44 +09:00
# if the is not there, call init to create it
2022-04-18 15:30:03 +09:00
# 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
2025-12-01 17:04:03 +09:00
# MARK: VERIFY / INFO
2025-12-01 16:53:50 +09:00
if [ " ${ VERIFY } " -eq 1 ] || [ " ${ INIT } " -eq 1 ] ; then
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_SUB_BLOCK } " "VERIFY" " $( date +'%F %T' ) " " ${ MODULE } " ;
2025-12-01 16:53:50 +09:00
if [ -n " ${ TARGET_SERVER } " ] ; then
if [ " ${ DEBUG } " -eq 1 ] ; then
2025-12-03 13:03:46 +09:00
echo " ${ BORG_COMMAND } info ${ OPT_REMOTE } ${ REPOSITORY } 2>&1 " ;
2021-12-13 10:36:44 +09:00
fi ;
2022-04-18 15:30:03 +09:00
# use borg info and verify if it returns "Repository ID:" in the first line
2025-12-03 13:03:46 +09:00
REPO_VERIFY = $( ${ BORG_COMMAND } info ${ OPT_REMOTE } " ${ REPOSITORY } " 2>& 1) ;
2025-12-03 12:45:56 +09:00
__LAST_ERROR = $?
if [ $__LAST_ERROR -ne 0 ] ; then
2025-12-03 12:38:01 +09:00
echo " [!] Repository verify error: ${ REPO_VERIFY } " ;
REPO_VERIFY = "" ;
else
REPO_VERIFY = $( echo " ${ REPO_VERIFY } " | grep "Repository ID:" ) ;
fi ;
# | grep "Repository ID:"
2021-12-13 10:36:44 +09:00
# this is currently a hack to work round the error code in borg info
2022-04-18 15:30:03 +09:00
# this checks if REPO_VERIFY holds this error message and then starts init
if [ [ -z " ${ REPO_VERIFY } " ] ] || [ [ " ${ REPO_VERIFY } " = ~ ${ REGEX_ERROR } ] ] ; then
2021-12-13 10:36:44 +09:00
INIT_REPOSITORY = 1;
fi ;
elif [ ! -d " ${ REPOSITORY } " ] ; then
INIT_REPOSITORY = 1;
fi ;
2022-04-18 15:30:03 +09:00
# if verrify but no init and repo is there but init file is missing set it
2025-12-01 16:53:50 +09:00
if [ " ${ VERIFY } " -eq 1 ] && [ " ${ INIT } " -eq 0 ] && [ " ${ INIT_REPOSITORY } " -eq 0 ] &&
2022-04-25 06:49:57 +09:00
[ ! -f " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " ] ; then
2021-12-13 10:36:44 +09:00
# write init file
2022-04-18 15:30:03 +09:00
echo "[!] Add missing init verify file" ;
2025-12-01 16:53:50 +09:00
date +%s > " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " ;
2021-12-13 10:36:44 +09:00
fi ;
2022-04-18 15:30:03 +09:00
# end if verified but repository is not here
2025-12-01 16:53:50 +09:00
if [ " ${ VERIFY } " -eq 1 ] && [ " ${ INIT } " -eq 0 ] && [ " ${ INIT_REPOSITORY } " -eq 1 ] ; then
2021-12-13 10:36:44 +09:00
echo " [! $( date +'%F %T' ) ] No repository. Please run with -I flag to initialze repository " ;
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " 1;
2021-12-13 10:36:44 +09:00
exit 1;
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ EXIT } " -eq 1 ] && [ " ${ VERIFY } " -eq 1 ] && [ " ${ INIT } " -eq 0 ] ; then
2021-12-13 10:36:44 +09:00
echo "Repository exists" ;
echo "For more information run:"
echo " ${ COMMAND_INFO } " ;
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " ;
2021-12-13 10:36:44 +09:00
exit;
fi ;
fi ;
2025-12-01 16:53:50 +09:00
# MARK: INIT
if [ " ${ INIT } " -eq 1 ] && [ " ${ INIT_REPOSITORY } " -eq 1 ] ; then
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_SUB_BLOCK } " "INIT" " $( date +'%F %T' ) " " ${ MODULE } " ;
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] || [ " ${ DRYRUN } " -eq 1 ] ; then
2022-03-28 11:27:35 +09:00
echo " ${ BORG_COMMAND } init ${ OPT_REMOTE } -e ${ ENCRYPTION } ${ OPT_VERBOSE } ${ REPOSITORY } " ;
2025-12-01 16:53:50 +09:00
echo " ${ BORG_COMMAND } key export ${ REPOSITORY } " ;
echo " ${ BORG_COMMAND } key export --paper ${ REPOSITORY } " ;
2021-12-13 10:36:44 +09:00
fi
2025-12-01 16:53:50 +09:00
if [ " ${ DRYRUN } " -eq 0 ] ; then
2021-12-13 10:36:44 +09:00
# should trap and exit properly here
2025-12-01 17:04:03 +09:00
${ BORG_COMMAND } init ${ OPT_REMOTE } -e " ${ ENCRYPTION } " ${ OPT_VERBOSE } " ${ REPOSITORY } " ;
2025-12-01 16:53:50 +09:00
# show the key file
if [ " ${ ENCRYPTION } " = "keyfile" ] ; then
echo "--- [ENCRYPTION KEY] --[START]-------------------------------------------------->" ;
echo "Store the key and password in a safe place" ;
2025-12-01 17:04:03 +09:00
echo " export BORG_BASE_DIR=\" ${ BASE_FOLDER } \";borg key export [--paper] ${ REPOSITORY } " ;
2025-12-01 16:53:50 +09:00
echo "----[BORG KEY] -------------------------------->" ;
${ BORG_COMMAND } key export " ${ REPOSITORY } " ;
echo "----[BORG KEY:paper] -------------------------->" ;
${ BORG_COMMAND } key export --paper " ${ REPOSITORY } " ;
echo "--- [ENCRYPTION KEY] --[END ]-------------------------------------------------->" ;
fi ;
2021-12-13 10:36:44 +09:00
# write init file
2025-12-01 16:53:50 +09:00
date +%s > " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " ;
2021-12-13 10:36:44 +09:00
echo "Repository initialized" ;
echo "For more information run:"
echo " ${ COMMAND_INFO } " ;
fi
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " ;
2021-12-13 10:36:44 +09:00
# exit after init
exit;
2025-12-01 16:53:50 +09:00
elif [ " ${ INIT } " -eq 1 ] && [ " ${ INIT_REPOSITORY } " -eq 0 ] ; then
2021-12-13 10:36:44 +09:00
echo " [! $( date +'%F %T' ) ] Repository already initialized " ;
echo "For more information run:"
echo " ${ COMMAND_INFO } " ;
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " 1;
2021-12-13 10:36:44 +09:00
exit 1;
fi ;
2022-04-18 15:30:03 +09:00
# verify for init file
2022-04-25 06:49:57 +09:00
if [ ! -f " ${ BASE_FOLDER } ${ BACKUP_INIT_FILE } " ] ; then
2021-12-13 10:36:44 +09:00
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."
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " 1;
2021-12-13 10:36:44 +09:00
exit 1;
fi ;
2025-12-01 17:04:03 +09:00
# MARK: LIST / PRINT
2021-12-13 10:36:44 +09:00
# PRINT OUT current data, only do this if REPO exists
2025-12-01 16:53:50 +09:00
if [ " ${ PRINT } " -eq 1 ] ; then
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_SUB_BLOCK } " "PRINT" " $( date +'%F %T' ) " " ${ MODULE } " ;
2022-03-29 07:01:31 +09:00
FORMAT = "{archive:<45} {comment:6} {start} - {end} [{id}] ({username}@{hostname}){NL}"
2021-12-13 10:36:44 +09:00
# show command on debug or dry run
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] || [ " ${ DRYRUN } " -eq 1 ] ; then
2022-03-28 11:27:35 +09:00
echo " export BORG_BASE_DIR=\" ${ BASE_FOLDER } \"; ${ BORG_COMMAND } list ${ OPT_REMOTE } --format ${ FORMAT } ${ REPOSITORY } " ;
2021-12-13 10:36:44 +09:00
fi ;
# run info command if not a dry drun
2025-12-01 16:53:50 +09:00
if [ " ${ DRYRUN } " -eq 0 ] ; then
${ BORG_COMMAND } list ${ OPT_REMOTE } --format " ${ FORMAT } " " ${ REPOSITORY } " ;
2021-12-13 10:36:44 +09:00
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ VERBOSE } " -eq 1 ] ; then
2021-12-13 10:36:44 +09:00
echo "" ;
echo "Base command info:"
2022-03-28 11:27:35 +09:00
echo " export BORG_BASE_DIR=\" ${ BASE_FOLDER } \"; ${ BORG_COMMAND } [COMMAND] ${ OPT_REMOTE } ${ REPOSITORY } ::[BACKUP] [PATH] " ;
2021-12-13 10:36:44 +09:00
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."
2022-03-28 11:27:35 +09:00
echo "When listing files in an archive set (::SET) the --format command can be used."
2021-12-13 10:36:44 +09:00
echo "Example: \"{mode} {user:6} {group:6} {size:8d} {csize:8d} {dsize:8d} {dcsize:8d} {mtime} {path}{extra} [{health}]{NL}\""
else
2022-03-28 11:27:35 +09:00
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 ;
2022-06-06 14:58:36 +09:00
# run borg compact command and exit
2025-12-01 16:53:50 +09:00
if [ " ${ COMPACT } " -eq 1 ] ; then
2022-06-06 14:58:36 +09:00
. " ${ DIR } /borg.backup.functions.compact.sh " ;
. " ${ DIR } /borg.backup.functions.close.sh " ;
exit;
fi ;
2022-04-25 06:49:57 +09:00
# run borg check command and exit
2025-12-01 16:53:50 +09:00
if [ " ${ CHECK } " -eq 1 ] ; then
2022-04-25 06:49:57 +09:00
. " ${ DIR } /borg.backup.functions.check.sh " ;
2022-04-18 15:30:03 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " ;
exit;
fi ;
2022-03-28 11:27:35 +09:00
# DELETE ONE TIME TAG
2025-12-01 16:53:50 +09:00
if [ -n " ${ DELETE_ONE_TIME_TAG } " ] ; then
2022-04-25 06:49:57 +09:00
printf " ${ PRINTF_SUB_BLOCK } " "DELETE" " $( date +'%F %T' ) " " ${ MODULE } " ;
2022-03-28 11:27:35 +09:00
# 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
2025-12-01 16:53:50 +09:00
if [ " $( version " $BORG_VERSION " ) " -lt " $( version "1.2.0" ) " ] ; then
2022-03-28 11:27:35 +09:00
OPT_LIST = "" ;
fi ;
# if exists, delete and exit
# show command on debug or dry run
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] ; then
2022-03-28 11:27:35 +09:00
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
2025-12-01 16:53:50 +09:00
if [ " $( version " $BORG_VERSION " ) " -ge " $( version "1.2.0" ) " ] ; then
if [ " ${ DRYRUN } " -eq 0 ] ; then
${ BORG_COMMAND } compact ${ OPT_REMOTE } " ${ REPOSITORY } " ;
2022-03-28 11:27:35 +09:00
fi ;
2025-12-01 16:53:50 +09:00
if [ " ${ DEBUG } " -eq 1 ] ; then
2023-05-10 16:30:23 +09:00
echo " ${ BORG_COMMAND } compact ${ OPT_REMOTE } ${ REPOSITORY } " ;
2022-03-28 11:27:35 +09:00
fi ;
2021-12-13 10:36:44 +09:00
fi ;
2022-03-28 11:27:35 +09:00
. " ${ DIR } /borg.backup.functions.close.sh " ;
2021-12-13 10:36:44 +09:00
exit;
fi ;
# __END__