#!/bin/bash # Stop on any error and provide some info if DEBUG set set -e [ -n "$DEBUG" ] && set -x display_usage() { echo -e "Usage: $0 create|extract repo-name\n" } exit_abnormal () { display_usage exit 1 } if [ $# -ne 2 ]; then exit_abnormal fi if [ `id -u` -eq 0 ]; then echo "This script must not be run as root!" exit_abnormal fi #user_name=borg #if [ "$(id --user --name)" != "$bbbs_user_name" ]; then # echo "$0 must be run as $bbbs_user_name" # exit #fi while getopts "h?" option; do case "$option" in h|\?) display_usage exit 0 ;; esac done MODE=$1 REPO=$2 if [ $MODE != "create" ] && [ $MODE != "extract" ]; then echo "Mode must be either 'create' or 'extract'" exit_abnormal fi log_base_dir="${HOME}/.borg/logs" month_dir=$(date --utc "+%Y-%m") log_dir=${log_base_dir}/${month_dir} log_file=${log_dir}/$(date --utc "+%Y-%m-%d_%H.%M.%SZ")_${REPO}.log mkdir --parent "${log_dir}" echo "To monitor progress, run this in another terminal:" echo "$ tail -f ${log_file}" # Temporarilly disallow glob set -o noglob BORG_OPTIONS="--show-rc --list --stats --one-file-system --exclude-caches" if [ -z $BORG_OLD ]; then BORG_OPTIONS+=" --show-version --exclude-nodump --keep-exclude-tags" fi [ -n $DEBUG ] && BORG_OPTIONS+=" --verbose" COMMON_TARGET="/ /boot /etc /root /home /opt /srv /var /var/log /usr" COMMON_EXCLUDE="--exclude /sys/ --exclude /proc/ --exclude /dev/ --exclude /run/ --exclude /var/run/ --exclude /var/lock --exclude /mnt/" VOLATILE_EXCLUDE="--exclude /tmp/ --exclude /var/tmp/ --exclude /lost+found --exclude /var/cache/ --exclude /root/.cache --exclude /home/*/.cache" LXD_BASE="/var/lib/lxd/*/rootfs" LXD_EXCLUDE="--exclude $LXD_BASE/lost+found --exclude $LXD_BASE/media/* --exclude $LXD_BASE/mnt/* \ --exclude $LXD_BASE/proc/* --exclude $LXD_BASE/run/* --exclude $LXD_BASE/sys/* \ --exclude $LXD_BASE/tmp/*" LXC_BASE="/home/*/.local/share/lxc/*/rootfs" LXC_EXCLUDE="--exclude $LXC_BASE/lost+found --exclude $LXC_BASE/media/* --exclude $LXC_BASE/mnt/* \ --exclude $LXC_BASE/proc/* --exclude $LXC_BASE/run/* --exclude $LXC_BASE/sys/* \ --exclude $LXC_BASE/tmp/*" # Especially when not using --one-file-system # --exclude /var/run # -> /run SOCK_LOCAL="/tmp/borg-local.sock" SOCK_REMOTE="/tmp/borg-remote.sock" if [ $MODE == 'create' ]; then echo "=== CREATING" . ./server-wrap.sh -s $SOCK_LOCAL $SOCK_REMOTE $MODE $REPO \ borg create \ "$BORG_OPTIONS" \ "$COMMON_EXCLUDE" "$VOLATILE_EXCLUDE" \ "$LXD_EXCLUDE" "$LXC_EXCLUDE" \ ssh://backup-server/$BORG_REPO_PATH/$REPO::{utcnow:%Y-%m-%d} \ "$COMMON_TARGET" \ 2>&1 | tee ${log_file} # Tidy up Client .sock - dealt with in 'server-wrap.sh' # . Chance are, on error, the .sock file will not be cleaned up properly # Current setup requires no specific files on remote machine # Could perhaps require one small script that just handles any necessary cleanup # --exclude /var/lib/lxd/ \ # --exclude /var/lib/vz/images/ \ # TODO: Test and fix up extract procedure else echo "=== EXTRACTING" ARCHIVE=$(borg info $BORG_REPO_PATH/$REPO --last 1 | grep 'Archive name' | awk '{print $3}') . ./server-wrap.sh -s $SOCK_LOCAL $SOCK_REMOTE $MODE $REPO \ borg extract \ --dry-run \ ssh://backup-server/$BORG_REPO_PATH/$REPO::$ARCHIVE \ 2>&1 | tee $log_file fi # Re-allow glob set +o noglob # Tidy up - if necessary if [ -f $SOCK_LOCAL ]; then rm $SOCK_LOCAL fi