#!/bin/sh

THIS=$(basename $0)
PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin
MYHOST=nerdville
HOME_SNAPSHOT=/home_snapshot
SCRIPT_DIR=/root/scripts/backup
MOUNT_SNAPSHOT=$SCRIPT_DIR/mount-snapshot
BACKUP_TREE=$SCRIPT_DIR/backup-tree
LOGFILE=/tmp/$THIS.$(whoami).$MYHOST.log
MIRROR_VERIFY=$SCRIPT_DIR/mirror-verify
CHECK_FRESHNESS=$SCRIPT_DIR/backup-check-freshness
REMOTE_SERVER=somewhere.com
REMOTE_ACCOUNT=user@$REMOTE_SERVER
REMOTE_BASEDIR=backups
RDIFF_BACKUP=rdiff-backup
DUMPDIR=/home/backups/database
DUMPDIR_SNAPSHOT=$HOME_SNAPSHOT/backups/database/
SUBVERSION_MIRROR=/home/backups/mirrors/subversion
SUBVERSION_MIRROR_SNAPSHOT=$HOME_SNAPSHOT/backups/mirrors/subversion/
verify=false
[ "$1" = verify ] && verify=true
if [ "$1" = check_freshness ]; then
    # ----------------------------------------------
    # Check on other people's backups who use my backup server
    # ----------------------------------------------
    $CHECK_FRESHNESS $REMOTE_ACCOUNT \
        $REMOTE_BASEDIR/mirrors/spak-home-sarah/.backup_tree_timestamp 3
    #$CHECK_FRESHNESS $REMOTE_ACCOUNT \
    #    $REMOTE_BASEDIR/mirrors/gray-home-susan/.backup_tree_timestamp 3
    #$CHECK_FRESHNESS $REMOTE_ACCOUNT \
    #    $REMOTE_BASEDIR/mirrors/lisa-home-lisa/.backup_tree_timestamp 3
    exit 0
fi


function die() {
  echo "$0: $*"
  exit 1
}

echo "---------------------------------------------------------------------" >>$LOGFILE
echo "Starting $THIS run with options: $*" >>$LOGFILE
date >>$LOGFILE
echo "---------------------------------------------------------------------" >>$LOGFILE

# exit if this isn't running on the correct host
[ "$HOSTNAME" = $MYHOST ] || die "\$HOSTNAME not set or this is not $MYHOST"

# make sure home is mounted.  I do this by putting an empty file called
# .is_mounted at the root of all my filesystems.
[ -f /home/.is_mounted ] || die "/home/.is_mounted not found)"

# make sure backups root on remote is mounted
ssh $REMOTE_ACCOUNT "[ -f $REMOTE_BASEDIR/.is_mounted ]" 2>/dev/null \
    || die "$REMOTE_BASEDIR on $REMOTE_ACCOUNT is not mounted " \
           "($REMOTE_BASEDIR/.is_mounted not found)"

# -------------
# Update subversion mirror
# -------------
cd $SUBVERSION_MIRROR || die "couldn't cd $SUBVERSION_MIRROR"
for f in *; do
    svn update $f >>$LOGFILE || echo "error during svn update $f"
done

# -----------------------------------------------
# Dump Subversion Repositories and Databases
# -----------------------------------------------
# Keep a dump of subversion repositories locally, and
# a rdiff-backup of the dumps on remote

# Dump subversion repositories
echo "Dumping subversion repositories" >> $LOGFILE
dump_error=false
[ -d $DUMPDIR ] || die "directory $DUMPDIR not found"
for f in /var/lib/subversion/*; do
    if [ -d $f ]; then
        FILE=$(basename $f)
        echo "Dumping $f to $DUMPDIR/$FILE.subversion-dump" >> $LOGFILE
        svnadmin dump $f > $DUMPDIR/$FILE.subversion-dump 2>>$LOGFILE
        if [ $? -ne 0 ]; then
            echo "Error during svnadmin dump $f"
            dump_error=true
        fi
    else
        echo "Directory $f not found"
    fi
done

# Dump MySQL databases
echo "Dumping MySQL databases to $DUMPDIR" >> $LOGFILE
# if MySQL is not running, fire it up
/etc/init.d/mysql start >/dev/null 2>/dev/null
mysqldump -ubackup -p$(cat /root/mysql-backup-passwd) tiki \
    >$DUMPDIR/tiki.mysql-dump 2>>$LOGFILE
if [ $? -ne 0 ]; then
    echo "error during mysqldump of tiki"
    dump_error=true
fi
mysqldump -ubackup -p$(cat /root/mysql-backup-passwd) nothermarker \
    >$DUMPDIR/nothermarker.mysql-dump 2>>$LOGFILE
if [ $? -ne 0 ]; then
    echo "error during mysqldump of nothermarker"
    dump_error=true
fi

# == Create new timestamps before snapshot is frozen ==
touch $DUMPDIR/.backup_tree_timestamp \
    || die "touch $DUMPDIR/.backup_tree_timestamp failed (permissions problem?)" 
touch $SUBVERSION_MIRROR/.backup_tree_timestamp \
    || die "touch $SUBVERSION_MIRROR/.backup_tree_timestamp failed (permissions problem?)" 
touch /home/janet/.backup_tree_timestamp \
    || die "touch /home/janet/.backup_tree_timestamp failed (permissions problem?)" 
touch /home/user/Maildir/.backup_tree_timestamp \
    || die "touch /home/user/Maildir/.backup_tree_timestamp failed (permissions problem?)" 
touch /home/ha-dirs/.backup_tree_timestamp \
    || die "touch /home/ha-dirs/.backup_tree_timestamp failed (permissions problem?)" 

# ===============
# Mount snapshot
# ===============
$MOUNT_SNAPSHOT mount /dev/home_vg/backup_lv 1000M /dev/home_vg/home_lv $HOME_SNAPSHOT \
    >>$LOGFILE 2>&1 || die "error with $MOUNT_SNAPSHOT during mount"
echo "Snapshot created at $(date)" >>$LOGFILE

# ===========================================================
# $1 = <directory>
# $2 = <remote account>
# $3 = <remote basedir>
# $4 = <generator program> | all
function backup_tree_wrapper () {
    echo "Backing up $1 to $2::$3" >>$LOGFILE
    generator=""
    [ $4 != all ] && generator="--filelist-generator $4"
    $BACKUP_TREE "$1" "$2" "$3" --no-touch-timestamp $generator 2>&1 >>$LOGFILE

    if [ $verify = true ]; then
        echo "Verifying subversion mirror" >>$LOGFILE
        $BACKUP_TREE "$1" "$2" "$3" --no-touch-timestamp $generator verify \
            2>&1 >>$LOGFILE
    fi
}

# -------------
# Transfer or Verify subversion mirror to $REMOTE_ACCOUNT
# -------------
backup_tree_wrapper $SUBVERSION_MIRROR_SNAPSHOT $REMOTE_ACCOUNT \
    $REMOTE_BASEDIR/mirrors/subversion all

# -------------
# Transfer or Verify database dumps to $REMOTE_ACCOUNT
# -------------
backup_tree_wrapper $DUMPDIR_SNAPSHOT $REMOTE_ACCOUNT \
    $REMOTE_BASEDIR/database all

# -------------
# Home directories rdiff-backup
# -------------
backup_tree_wrapper $HOME_SNAPSHOT/janet/ $REMOTE_ACCOUNT \
    $REMOTE_BASEDIR/mirrors/nerdville-home-janet $HOME_SNAPSHOT/janet/.backup_filelist

# -------------
# Mail
# -------------
backup_tree_wrapper $HOME_SNAPSHOT/user/Maildir/ $REMOTE_ACCOUNT \
    $REMOTE_BASEDIR/mail $HOME_SNAPSHOT/user/Maildir/.backup_filelist

# ----------------------------------------------
# Server base (ha-dirs)
# ----------------------------------------------
backup_tree_wrapper $HOME_SNAPSHOT/ha-dirs/ $REMOTE_ACCOUNT \
    $REMOTE_BASEDIR/ha-dirs $HOME_SNAPSHOT/ha-dirs/.backup_filelist

# ===============
# Remove snapshot
# ===============
cd / # move out of $HOME_SNAPSHOT so we don't get an "in use" error from umount
$MOUNT_SNAPSHOT unmount /dev/home_vg/backup_lv $HOME_SNAPSHOT >>$LOGFILE 2>&1 \
    || die "error with $MOUNT_SNAPSHOT during unmount"
echo "Snapshot removed at $(date)" >>$LOGFILE

# ----------------------------------------------
# Verify Data store (this is synchronized manually with unison)
# ----------------------------------------------
if [ $verify = true ]; then
    for f in art,books,old,photo,reference,software; do
        # FIXME: video is skipped for now
        S=/home/$f
        D=$REMOTE_ACCOUNT:backups
        echo "Verifying that $S matches $D" >>$LOGFILE
        $MIRROR_VERIFY $S $D | tee --append $LOGFILE
    done
    echo "Remember to 'unison data'"
    # ----------------------------------------------
    echo "Verifying music archive" >>$LOGFILE
    $MIRROR_VERIFY /home/music $REMOTE_ACCOUNT:/stor2
    echo "Remember to 'unison music'"
fi

# ----------------------------------------------
# Misc
# ----------------------------------------------
# Do an apt-get update while we're at it...
apt-get update >/dev/null 2>/dev/null

