Improve docs.
[wizbackup.git] / wizbackup
index 975fc6a9e42e819b25a0d49d7983edf3320cb4d0..746cfba7022435e3c1924188fa2c09ed329c0ce0 100755 (executable)
--- a/wizbackup
+++ b/wizbackup
@@ -1,10 +1,10 @@
 #!/bin/bash
 #
-# WizBackup 2.0 - Simple rsync backup with snapshots
+# WizBackup 3.0 - Simple rsync backup with snapshots
 # Based on incremental-backup 0.1 by Matteo Mattei
 #
 # Copyright 2006 Matteo Mattei <matteo.mattei@gmail.com>
-# Copyright 2007, 2008, 2009, 2010, 2011 Bernie Innocenti <bernie@codewiz.org>
+# Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2015 Bernie Innocenti <bernie@codewiz.org>
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -38,37 +38,45 @@ SRC=$1; shift
 # Destination directory (will be created if it doesn't exist)
 DEST=$1; shift
 
+CONFIG_FILE="/etc/wizbackup/wizbackup.conf"
+
 # NOTE: --timeout needs to be large enough: if a large dir tree don't change a lot of time can pass without I/O
 # NOTE: --inplace will clobber linked files in older snapshots. DON'T USE IT!
 RSYNC_OPTS="-HAXa --stats --timeout 1800 --numeric-ids --delete --delete-excluded --ignore-errors $@"
 
-# Number of saved snapshots
-SNAPSHOTS=45
+# Number of months to keep
+MONTHS=3
 
 # Abort backup if the destination volume has less than these GBs free
 MIN_FREE_GB=10
 
 RESULT=500
-DATE=`date +"%Y%m%d"`
+DATE="$(date +"%Y%m%d")"
+if [ $(date +"%d") -eq 1 ]; then
+       DATE="${DATE}-monthly"
+elif [ $(date +"%w") -eq 0 ]; then
+       DATE="${DATE}-weekly"
+fi
 DEST="`echo $DEST | sed -e 's/\/$//'`"
 
+if [ -f "$CONFIG_FILE" ]; then
+       source "$CONFIG_FILE"
+fi
 
 # Use "backup" ssh key with ssh protocol, or password file for rsync protocol
 if [ "${SRC%:*}" == "rsync" ]; then
        RSYNC_OPTS="$RSYNC_OPTS --password-file=/etc/wizbackup/rsync_password --contimeout 10"
 else
-       export RSYNC_RSH="ssh -i /etc/wizbackup/ssh_id -c arcfour -x -o VerifyHostKeyDNS=yes -o StrictHostKeyChecking=no"
+       export RSYNC_RSH="ssh -i /etc/wizbackup/ssh_id -x -o VerifyHostKeyDNS=yes -o StrictHostKeyChecking=no"
 fi
 
 # Error tolerant grep
-tgrep()
-{
+tgrep() {
        grep "$@"
        return 0
 }
 
-do_backup()
-{
+do_backup() {
        set -o pipefail
        echo "$(date): rsync $RSYNC_OPTS $SRC $DEST/tmp/"
        rsync $RSYNC_OPTS "$SRC" "$DEST/tmp/" 2>&1 | tgrep -v -E 'vanished|some files'
@@ -91,9 +99,7 @@ do_backup()
        set +o pipefail
 }
 
-
-do_init()
-{
+do_init() {
        # Safety net (4 slashes just in case)
        case "$DEST" in
                /|//|///|////) exit 666 ;;
@@ -107,18 +113,18 @@ do_init()
        cd "$DEST" || exit 668
 }
 
-do_prune()
-{
-       local old="`ls | grep -v tmp | head -n -$SNAPSHOTS`"
-       if [ ! -z "$old" ]; then
+do_prune() {
+       local num_snapshots="$1"
+       local suffix="$2"
+       local oldest="$(ls 2>/dev/null -d [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$suffix | head -n -$num_snapshots)"
+       for old in $oldest; do
                echo "$(date): Removing oldest snapshot(s): $old..."
                rm -rf "$old" || exit 669
-       fi
+       done
 }
 
-do_link()
-{
-       local newest=`ls | grep  -v tmp | tail -n 1`
+do_link() {
+       local newest=`ls -d [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]* | tail -n 1`
        if [ -d "$DEST/tmp" ]; then
                echo "$(date): Continuing with pre-existing snapshot $DEST/tmp"
        elif [ -z "$newest" ]; then
@@ -137,8 +143,7 @@ do_link()
        fi
 }
 
-do_test()
-{
+do_test() {
        # TODO: test for free space and free inodes in the $DEST filesystem
        block_size=`stat --file-system --format "%S" "$DEST"`
        free_blocks=`stat --file-system --format "%f" "$DEST"`
@@ -168,10 +173,11 @@ do_test()
 # make sure to be root
 if (( `id -u` != 0 )); then { echo "Sorry, must be root.  Exiting..."; exit; } fi
 
-echo "$(date): BEGIN backup: $SRC -> $DEST"
-echo "$(date): $0 $SRC $DEST $@"
+echo "$(date): BEGIN backup: $0 $SRC $DEST $@"
 do_init
-do_prune
+do_prune 6 ""
+do_prune 4 "-weekly"
+do_prune $MONTHS "-monthly"
 do_test
 do_link
 do_backup