185 lines
7 KiB
Bash
Executable file
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;
|
|
|