system-helpers/usr/local/bin/borgwrapper

185 lines
7 KiB
Bash
Executable file

#!/usr/bin/env bash
# called before backup
borgwrapper_pre_backup() {
return;
}
# called after backup
borgwrapper_post_backup() {
return;
}
# usage
usage() {
USAGE=$(cat <<EOF
Usage: borgwrapper [CONFIG_FILE (absolute path)]
A script which wraps commonly used functions for borg.
If no CONFIG_FILE is given, HOME/.borgwrapper.conf is used. This fallback option
has to exist or the script will exit.
Configuration can be done in any file and any pre-defined variable can be overwritten.
The following are at least required for the script to work:
- BORGWRAPPER_BACKUP_NAME // [a-z09], should be unique for multiple backups (with the same remote user)
- BORGWRAPPER_BACKUP_FILES // an array of files and directories to backup, e.g. =('/home', '/root')
- BORGWRAPPER_BACKUP_REPOSITORY // trailing slash, add "user@host:/dir/" if remote
The following are optional or have reasonable defaults:
- BORGWRAPPER_BACKUP_PASSWORD='' // the password
- BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT=$(date "+%s")
- BORGWRAPPER_BACKUP_PRUNE=true // prune the repository (cleans old backups; uses BORGWRAPPER_BACKUP_KEEP_IN_DAYS)? false|true
- BORGWRAPPER_BACKUP_KEEP_IN_DAYS=60 // in days, integer only (used for prune)
- BORGWRAPPER_BACKUP_CHECK=true // checks entire repository, this is slow! false|true
- BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS=604800 // determine when "borg check" has to run by comparing current time with latest run check (determined by last mod time of $BORGWRAPPER_BACKUP_CHECK_FILE). default is 7 days, 0 will always run the check
- BORGWRAPPER_BACKUP_CHECK_FILE="~/.borg-backup-BORGWRAPPER_BACKUP_NAME.check" // used for time comparison
- BORGWRAPPER_BACKUP_LOG=true // log? false|true
- BORGWRAPPER_BACKUP_LOG_PRUNE=true // overwrite old log for each execution? false|true
- BORGWRAPPER_BACKUP_LOG_FILE="~/.borg-backup-BORGWRAPPER_BACKUP_NAME.log" // log file to save output to to
- BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL=false // send email (BORGWRAPPER_BACKUP_LOG has to be set to true)? false|true
- BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS="" // mail.rc has to be configured
- BORGWRAPPER_BACKUP_NOTIFY_UI=false // use notify-send for UI notification? false|true
Borg specific values can also be overwritten and have reasonable defaults:
- BORGWRAPPER_BORG_BINARY=borg; // defaults to /usr/bin/borg (determined by 'which borg'), adjust to a virtualenv if needed
- BORGWRAPPER_BORG_INIT_PARAMS="--encryption=none"; // encryption=none|repokey-blake2|...
- BORGWRAPPER_BORG_CREATE_PARAMS="-v -s -p -C lz4";
- BORGWRAPPER_BORG_CHECK_PARAMS="-v";
- BORGWRAPPER_BORG_PRUNE_PARAMS="-v -s -d BORGWRAPPER_BACKUP_KEEP_IN_DAYS";
More information can be found in the docs: https://borgbackup.readthedocs.io
The following functions are executed before and after the backup and can also be overwritten in the config file by redefining them:
- borgwrapper_pre_backup
- borgwrapper_post_backup
You can copy this script to '/usr/local/bin' and use create a custom CONFIG_FILE as user. Examples can be found in '/usr/share/doc/<scriptname>'.
EOF
)
echo "$USAGE";
}
set -e;
# vars and defaults
BORGWRAPPER_BACKUP_PASSWORD=''
BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT=$(date "+%s")
BORGWRAPPER_BACKUP_PRUNE=true
BORGWRAPPER_BACKUP_KEEP_IN_DAYS=60
BORGWRAPPER_BACKUP_CHECK=true
BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS=604800
BORGWRAPPER_BACKUP_CHECK_FILE="$HOME/.borg-backup-$BORGWRAPPER_BACKUP_NAME.check"
BORGWRAPPER_BACKUP_LOG=true
BORGWRAPPER_BACKUP_LOG_PRUNE=true
BORGWRAPPER_BACKUP_LOG_FILE="$HOME/.borg-backup-$BORGWRAPPER_BACKUP_NAME.log"
BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL=false
BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS=""
BORGWRAPPER_BACKUP_NOTIFY_UI=false
BORGWRAPPER_BORG_BINARY=$(which borg);
BORGWRAPPER_BORG_INIT_PARAMS="--encryption=none";
BORGWRAPPER_BORG_CREATE_PARAMS="-v -s -p -C lz4";
BORGWRAPPER_BORG_CHECK_PARAMS="-v";
BORGWRAPPER_BORG_PRUNE_PARAMS="-v -s -d $BORGWRAPPER_BACKUP_KEEP_IN_DAYS";
# check for config file
source_config() {
local config=$1;
local configFallback=$2;
if [[ ! -f "$config" ]]; then
if [[ ! -f "$configFallback" ]]; then
echo "No config file specified and could not find default in '$configFallback'!";
echo "";
usage;
exit 1;
else
config=$configFallback;
fi
fi
set -a;
source "$config";
set +a;
}
source_config "$1" "$HOME/.borgwrapper.conf"
# start and info
echo "Using $BORGWRAPPER_BORG_BINARY as binary"
borgwrapper_pre_backup;
# export passphrase if not blank
if [ ! -z "$BORGWRAPPER_BACKUP_PASSWORD" ]; then
export BORG_PASSPHRASE=$BORGWRAPPER_BACKUP_PASSWORD
fi
# init hint
echo "Hint: If you haven't, you need to create the borg repository manually before first run if it doesn't exist:";
echo "$BORGWRAPPER_BORG_BINARY init $BORGWRAPPER_BORG_INIT_PARAMS $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME";
# notify UI
if [ "$BORGWRAPPER_BACKUP_NOTIFY_UI" = true ]; then
notify-send "Starting backup" $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME::$BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT;
fi
# create
$BORGWRAPPER_BORG_BINARY create $BORGWRAPPER_BORG_CREATE_PARAMS $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME::$BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT "${BORGWRAPPER_BACKUP_FILES[@]}";
# check
if [ "$BORGWRAPPER_BACKUP_CHECK" = true ]; then
# use for first time creation
doCheck=false
if [ ! -f "$BORGWRAPPER_BACKUP_CHECK_FILE" ]; then
touch $BORGWRAPPER_BACKUP_CHECK_FILE
doCheck=true
fi
# compare date
lastMod=$(date -r $BORGWRAPPER_BACKUP_CHECK_FILE +%s)
age=$(($BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT - $lastMod))
if [ "$age" -gt "$BORGWRAPPER_BACKUP_CHECK_MAX_AGE_IN_SECONDS" ]; then
doCheck=true
fi
if [ "$doCheck" = true ]; then
$BORGWRAPPER_BORG_BINARY check $BORGWRAPPER_BORG_CHECK_PARAMS $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME;
touch $BORGWRAPPER_BACKUP_CHECK_FILE
fi
fi
# prune
if [ "$BORGWRAPPER_BACKUP_PRUNE" = true ]; then
$BORGWRAPPER_BORG_BINARY prune $BORGWRAPPER_BORG_PRUNE_PARAMS $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME;
fi
# log
if [ "$BORGWRAPPER_BACKUP_LOG" = true ]; then
if [ "$BORGWRAPPER_BACKUP_LOG_PRUNE" = true ] && [ -f "$BORGWRAPPER_BACKUP_LOG_FILE" ]; then
rm $BORGWRAPPER_BACKUP_LOG_FILE;
fi
touch $BORGWRAPPER_BACKUP_LOG_FILE;
$BORGWRAPPER_BORG_BINARY list -v $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME >> $BORGWRAPPER_BACKUP_LOG_FILE;
echo "---" >> $BORGWRAPPER_BACKUP_LOG_FILE;
$BORGWRAPPER_BORG_BINARY info $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME::$BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT >> $BORGWRAPPER_BACKUP_LOG_FILE;
if [ "$BORGWRAPPER_BACKUP_NOTIFY_VIA_MAIL" = true ]; then
cat $BORGWRAPPER_BACKUP_LOG_FILE|mailx -Ssendwait -s "[backup $BORGWRAPPER_BACKUP_NAME]" $BORGWRAPPER_BACKUP_NOTIFY_MAIL_ADDRESS;
fi
fi
# notify UI
if [ "$BORGWRAPPER_BACKUP_NOTIFY_UI" = true ]; then
notify-send "Finished backup" $BORGWRAPPER_BACKUP_REPOSITORY$BORGWRAPPER_BACKUP_NAME::$BORGWRAPPER_BACKUP_TIMESTAMP_FORMAT;
fi
borgwrapper_post_backup;