Skip to content

Instantly share code, notes, and snippets.

@ilyaevseev
Last active November 28, 2021 23:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilyaevseev/636657101393482bc14a to your computer and use it in GitHub Desktop.
Save ilyaevseev/636657101393482bc14a to your computer and use it in GitHub Desktop.
Rsnap - do periodic incremental snapshots using Rsync and ls4sweep.
#!/bin/sh
Fail() {
logger -p "user.err" -t "rsnap" -s "$@";
#echo "$@" | mail -s "rsnap failed on $(hostname -f)" admins
exit 1
}
#====== Parse command line =================================
test $# -ge 2 || Fail "usage: $0 src destdir [custom-rsync-args..]"
src="$1"; shift
destbase="$1"; shift
test -e "$destbase/" || Fail "missing directory $destbase"
#====== Prepare logdir =====================================
now="$(date +%Y-%m-%d_%H%M)"
logdir="$destbase/logs"
mkdir -p "$logdir"
test -d "$logdir" || Fail "cannot create logdir $logdir"
#====== Check previous snapshot ============================
prevsnap="$destbase/last"
prevopt=""
if test -e "$prevsnap"; then
test -L "$prevsnap" || Fail "$prevsnap exists, but is not symlink"
prevopt="--link-dest=$prevsnap"
fi
#====== Prepare for new snapshot ===========================
newsnap="$destbase/$now"
mkdir "$newsnap" || Fail "mkdir $newsnap"
cd "$newsnap/" || Fail "chdir $newsnap"
#====== Do rsync ===========================================
L="$logdir/$now-rsync.log"
E="$logdir/$now-rsync.err"
if ! rsync -auxXSH --stats --delete --numeric-ids "$@" $prevopt "$src/" . > "$L" 2>"$E"; then
mv "$newsnap" "$newsnap.failed"
Fail "rsync failed, see $E"
fi
# Rebind symlink..
cd "$destbase"
rm -f "last"
ln -s "$now" "last"
#====== Delete old snapshots ===============================
sweep_policy="5:1,5:3,5:10,15:30,15:90,15:360,99:1000"
sweep_mask='????-??-??_????' # ..see $now assignment above!!
L1="$logdir/$now-sweep.log"
E1="$logdir/$now-sweep.err"
E2="$logdir/$now-rm.err"
test "$DONT_SWEEP" = "1" ||
ls4sweep --ctime "$sweep_policy" $sweep_mask 2>"$E1" |
grep -v "^$now$" | tee "$L1" | xargs rm -rf >"$E2" 2>&1 || Fail "rm"
#====== Delete old logs ====================================
find "$logdir/" -type f -mtime "+90" -delete || Fail "rm-old-logs"
find "$logdir/" -type f -empty -delete || Fail "rm-empty-logs"
## END ##
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment