#!/bin/bash # # Borg script for home folder backups. # Adapted from https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups # Parameters BASENAME="`basename $0`" DESTINATION="$1" OPTION="$2" BASE_CONFIG="$HOME/.config/borger" CONFIG="$BASE_CONFIG/$DESTINATION" # Print info function info { printf "[$BASENAME] [%s] %s\n" "$(date)" "$*" >&2; } # Fata error function fatal { info [fatal] $* exit 1; } function borger_usage { # Ensure we have our base config folder mkdir -p $BASE_CONFIG # List available targets if [ -z "$DESTINATION" ]; then echo "usage: $BASENAME [--check]" echo -n "available destinations from $BASE_CONFIG: " ls $BASE_CONFIG exit 1 fi } # Config function borger_config { # Ensure we have an username if [ -z "$USER" ]; then USER="`whoami`" fi # In case your home folder is a symlink if [ ! -z "`readlink $HOME`" ]; then ORIG="`readlink $HOME`" else ORIG="$HOME" fi # Default backup config keepdaily="7" keepweekly="4" keepmonth="6" encryption="keyfile" placeholder="{user}" if [ -e "$CONFIG" ] ; then source $CONFIG else fatal "No such config $CONFIG" fi # Setting this, so the repo does not need to be given on the commandline: if [ -z "$BORG_REPO" ]; then export BORG_REPO_DIR="/var/backups/users/$USER/borg" export BORG_REPO="ssh://$SSH_SERVER:$SSH_PORT/$BORG_REPO_DIR" fi } # Check function borger_check { if [ "$OPTION" == "--check" ]; then borg list exit $? fi } # Our trap function borger_trap { trap 'info Backup interrupted >&2; exit 2' INT TERM } # Initialize function borger_init { if ! ssh $SSH_SERVER -p $SSH_PORT test -f $BORG_REPO_DIR/config; then info "Initializing borg repository at $BORG_REPO..." borg init --encryption=$encryption $BORG_REPO init_exit=$? if [ "$init_exit" != "0" ]; then fatal "Error initializing repository" fi fi } # Backup the most important directories into an archive named after # the machine this script is currently running on: function borger_create { info "Starting backup..." borg create \ --verbose \ --filter AME \ --list \ --stats \ --show-rc \ --compression lz4 \ --exclude-caches \ ::"${placeholder}-{now}" \ $ORIG backup_exit=$? if [ "$backup_exit" != "0" ]; then fatal "Error creating snapshot" fi } # Use the `prune` subcommand to maintain daily, weekly and monthly archives. # The '${placeholder}-' prefix is very important to limit prune's operation to # one specific archive and not apply to archives also. function borger_prune { info "Pruning repository..." borg prune \ --list \ --prefix "${placeholder}-" \ --show-rc \ --keep-daily $keepdaily \ --keep-weekly $keepweekly \ --keep-monthly $keepmonthly \ prune_exit=$? if [ "$prune_exit" != "0" ]; then fatal "Error pruning repository" fi } # Main borger_usage borger_config borger_check borger_trap borger_init borger_create borger_prune