Move to a more general approach

We need to be able to easily run backups for multiple different
machines.
This is a very hacky approach built on top of a hacky origin, but at the
moment we just need something.

For the longest time, this code has only been run manually to backup a
few key remote machines to a local disk. This is less than ideal.
master
mj-saunders 2022-11-04 11:43:05 +04:00
parent 2c13f747b8
commit f648dc627f
4 changed files with 148 additions and 52 deletions

View File

127
backup.sh 100755
View File

@ -0,0 +1,127 @@
#!/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

View File

@ -1,47 +0,0 @@
#!/bin/bash
#user_name=borg
#if [ "$(id --user --name)" != "$bbbs_user_name" ]; then
# echo "$0 must be run as $bbbs_user_name"
# exit
#fi
REPO=omn-rss
log_prefix="/home/wuwei/.borg/logs/"$(date --utc "+%Y-%m")
mkdir --parent "${log_prefix}"
log_file="${log_prefix}/"$(date --utc "+%Y-%m-%d_%H.%M.%SZ")"_$client.log"
BORG_OPTIONS="--show-version --show-rc --list --stats --one-file-system --exclude-nodump --exclude-caches --keep-exclude-tags"
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_EXCLUDE="--exclude /var/lib/lxd/*/rootfs/lost+found --exclude /var/lib/lxd/*/rootfs/media/* --exclude /var/lib/lxd/*/rootfs/mnt/* \
--exclude /var/lib/lxd/*/rootfs/proc/* --exclude /var/lib/lxd/*/rootfs/run/* --exclude /var/lib/lxd/*/rootfs/sys/* \
--exclude /var/lib/lxd/*/rootfs/tmp/*"
# Especially when not using --one-file-system
# --exclude /var/run # -> /run
SOCK_SRV="/tmp/borg-server.sock"
SOCK_CLI="/tmp/borg-client.sock"
. ./server-wrap.sh -s $SOCK_SRV $SOCK_CLI $REPO \
borg create \
"$BORG_OPTIONS" \
"$COMMON_EXCLUDE" "$VOLATILE_EXCLUDE" \
"$LXD_EXCLUDE" \
ssh://backup-server/$BORG_REPO_PATH/$REPO::{utcnow:%Y-%m-%d} \
"$COMMON_TARGET" \
#> $log_file 2>&1
2>&1 | tee $log_file
# Tidy up Remote - HOW???
#rm $SOCK_CLI
# --exclude /var/lib/lxd/ \
# --exclude /var/lib/vz/images/ \
# Tidy up
rm $SOCK_SRV

View File

@ -5,18 +5,31 @@ if [ -z ${BORG_REPO_PATH} ]; then
exit 1 exit 1
fi fi
# Temporarilly disallow glob
set -o noglob
SOCK_SRV="$2" SOCK_SRV="$2"
SOCK_CLI="$3" SOCK_CLI="$3"
CLIENT_SOCAT="'bash -c \"exec socat STDIO UNIX-CONNECT:$SOCK_CLI\"'" CLIENT_SOCAT="'bash -c \"exec socat STDIO UNIX-CONNECT:$SOCK_CLI\"'"
CLIENT="$4" MODE="$4"
BORG_CMD="${@:5}" REPO="$5"
BORG_CMD="${@:6}"
# Add some cleanup to the command
BORG_CMD+=" && rm $SOCK_CLI"
echo $REMOTE_CMD # Make command more robust from premature expansion
BORG_CMD=`echo $BORG_CMD | sed "s/--exclude\s\(\S\+\)/--exclude \'\1\'/g"`
echo $BORG_CMD
if [ $MODE == "extract" ]; then
SH_CMD="cd /mnt"
fi
#user_name="borg" #user_name="borg"
#if [ "$(id --user --name)" != "$user_name" -o $# -lt 6 ]; then #if [ "$(id --user --name)" != "$user_name" -o $# -lt 6 ]; then
if [ $# -lt 5 ]; then if [ $# -lt 6 ]; then
echo "$0 must be run as $user_name" echo "$0 must be run as $user_name"
echo "usage: sudo -u $user_name [env vars] $0 [-s|--socket] path-to/local-listening.sock path-to/remote-connecting.sock path-to/socat-wrapper user@sourcehost <client borg command>" echo "usage: sudo -u $user_name [env vars] $0 [-s|--socket] path-to/local-listening.sock path-to/remote-connecting.sock path-to/socat-wrapper user@sourcehost <client borg command>"
echo "usage: sudo -u $user_name [env vars] $0 [-t|--tcp] local-listening-port remote-connecting-port path-to/socat-wrapper user@sourcehost <client borg command>" echo "usage: sudo -u $user_name [env vars] $0 [-t|--tcp] local-listening-port remote-connecting-port path-to/socat-wrapper user@sourcehost <client borg command>"
@ -35,5 +48,8 @@ else
exec socat UNIX-LISTEN:"$SOCK_SRV" \ exec socat UNIX-LISTEN:"$SOCK_SRV" \
"EXEC:borg serve --append-only --restrict-to-path $BORG_REPO_PATH --umask 077" & "EXEC:borg serve --append-only --restrict-to-path $BORG_REPO_PATH --umask 077" &
ssh -t -R "$SOCK_CLI":"$SOCK_SRV" $CLIENT sudo BORG_RSH="$CLIENT_SOCAT" "$BORG_CMD" ssh -t -R "$SOCK_CLI":"$SOCK_SRV" $REPO sudo BORG_RSH="$CLIENT_SOCAT" "$BORG_CMD"
fi fi
# Re-allow glob
set +o noglob