borg-reverse/backup.sh

128 lines
3.6 KiB
Bash
Executable File

#!/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