diff --git a/README.md b/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..8fb59af --- /dev/null +++ b/backup.sh @@ -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 diff --git a/run-backup.sh b/run-backup.sh deleted file mode 100755 index 980bde3..0000000 --- a/run-backup.sh +++ /dev/null @@ -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 diff --git a/server-wrap.sh b/server-wrap.sh index 2399af9..f1272b0 100755 --- a/server-wrap.sh +++ b/server-wrap.sh @@ -5,18 +5,31 @@ if [ -z ${BORG_REPO_PATH} ]; then exit 1 fi +# Temporarilly disallow glob +set -o noglob + SOCK_SRV="$2" SOCK_CLI="$3" CLIENT_SOCAT="'bash -c \"exec socat STDIO UNIX-CONNECT:$SOCK_CLI\"'" -CLIENT="$4" -BORG_CMD="${@:5}" +MODE="$4" +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" #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 "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 " echo "usage: sudo -u $user_name [env vars] $0 [-t|--tcp] local-listening-port remote-connecting-port path-to/socat-wrapper user@sourcehost " @@ -35,5 +48,8 @@ else exec socat UNIX-LISTEN:"$SOCK_SRV" \ "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 + +# Re-allow glob +set +o noglob