Skip to content

Instantly share code, notes, and snippets.

@davidscholberg
Last active December 29, 2017 23:31
Show Gist options
  • Save davidscholberg/a8cf4d44951e59ffde6d60e14cae62ab to your computer and use it in GitHub Desktop.
Save davidscholberg/a8cf4d44951e59ffde6d60e14cae62ab to your computer and use it in GitHub Desktop.
#!/bin/sh
# Pull incremental backups from remote host
TIMESTAMP=$(date +%F--%H-%M-%S)
SRC_LOC="$1"
SRC_HOST="$(echo "$SRC_LOC" | cut -f 2 -d @)"
SRC_DIR="/*"
DEST_BASE="/srv/mnt/backups/incremental/$SRC_HOST"
DEST_DIR_TMP_BASE="$DEST_BASE/tmp"
DEST_DIR_TMP="$DEST_DIR_TMP_BASE/$TIMESTAMP"
DEST_DIR="$DEST_BASE/$TIMESTAMP"
RSYNC_OPTS="\
-aHAX \
--stats
--numeric-ids \
--exclude=/dev/* \
--exclude=/lost+found \
--exclude=/mnt/* \
--exclude=/proc/* \
--exclude=/run/* \
--exclude=/srv/mnt/* \
--exclude=/sys/* \
--exclude=/tmp/* \
--exclude=/var/lib/docker/overlay2/* \
--exclude=/var/lib/machines/* \
--exclude=/var/lib/nfs/rpc_pipefs/* \
--exclude=/home/*/media/* \
--exclude=/home/*/.cache/mozilla/* \
--exclude=/home/*/.cache/chromium/*\
"
# Prompt user for confirmation and read input
confirm() {
echo -n "Proceed? [Y/n] "
local RESPONSE=
read -r RESPONSE
case $RESPONSE in
[Nn][Oo]|[Nn])
false
;;
*)
true
;;
esac
}
# Kill the script
# usage: die "$message" $status
die() {
echo "$1" 1>&2
exit $2
}
do_backup() {
if [ -t 0 ]; then
set -f
echo running: rsync $RSYNC_OPTS $SRC_LOC:$SRC_DIR $DEST_DIR_TMP
set +f
confirm || die "backup aborted by user" 2
fi
set -f
RSYNC_OUTPUT="$(rsync $RSYNC_OPTS $SRC_LOC:$SRC_DIR $DEST_DIR_TMP 2>&1)"
RET="$?"
set +f
if [ "$RET" -ne "0" ]; then
die "$RSYNC_OUTPUT" $RET
fi
mv "$DEST_DIR_TMP" "$DEST_DIR"
if [ "$?" -ne "0" ]; then
die "couldn't move backup $DEST_DIR_TMP to $DEST_DIR" 3
fi
if [ -t 0 ]; then
echo moved backup "$DEST_DIR_TMP" to "$DEST_DIR"
echo finished backup
fi
}
# Find previous backup if any
find_prev_dir() {
PREV_DIRS="$(find "$DEST_BASE" -mindepth 1 -maxdepth 1 -type d)"
if [ "$?" -ne "0" ]; then
die "error: failed to determine previous backup dir" 1
fi
if [ -n "$PREV_DIRS" ]; then
local PREV_DIR=$(\
echo "$PREV_DIRS" \
| grep -E '[0-9]{4}(-[0-9]{2}){2}-(-[0-9]{2}){3}' \
| sort -r \
| sed -n '1 p'\
)
if [ -n "$PREV_DIR" ]; then
RSYNC_OPTS="$RSYNC_OPTS --link-dest=$PREV_DIR"
fi
fi
}
# Make sure necessary directories are created
prep_dirs() {
mkdir -p "$DEST_DIR_TMP_BASE"
}
prep_dirs
find_prev_dir
do_backup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment