#!/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 = # $2 = # $3 = # $4 = | 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