#!/bin/bash
#
# nightly_backup: Script to pause any virtual machines that are running,
# do an rsync backup, then unpause the virtual machines. Set the SRCE
# and DEST variables below, as well as the USER variable. Script assumes
# that $DEST is a separate partition. If this is not the case for you,
# comment out the line _mount_check below.
#
# Sample cron entry runs script at 4:30 AM:
# 30 04 * * * /usr/local/bin/nightly_backup >>/var/log/nightly_backup.log 2>&1
# 
# Sample /etc/logrotate.d/nightly_backup file 
# /var/log/nightly_backup.log {
#     monthly
#     missingok
#     rotate 4
#     compress
# }
#
# --exclude-from file syntax:
# Copy directory but not its contents:
# + Cache/
# - **/Cache/**
#
# Do not copy (file or directory)
# - .gvfs 
#
# $Id: nightly_backup,v 1.1 2011/12/03 19:23:15 kevin Exp kevin $

SCRIPT=${0##*/}
PATH=/bin:/usr/bin
USER=kevin
SRCE=/home
DEST=/Archive
ARGS="-Ha --delete --stats --exclude-from=/usr/local/bin/rsync_exclude"
RUNLOG=/tmp/${SCRIPT}-??.log
VARLOG=/var/log/${SCRIPT}.log
RECIPIENT=kevin.lastname@gmail.com

# Set the date format
_date() { 
    date "+%a %b %d %T %Y"; 
}

# Log file
_log() { 
    _log "$(_date): ${*}\n" | tee -a ${VARLOG} | >>${RUNLOG} 2>&1
}    

# Make sure log file is removed
_exit() {
    ERRORLEVEL=${1}
    [ -f ${RUNLOG} ] && rm -f ${RUNLOG}
    exit ${ERRORLEVEL}
}

# Mail results to ${RECIPIENT}
_sendmail() {
    mutt -s "${SUBJECT}" ${RECIPIENT} < ${RUNLOG}
}

# Function to pause or resume running virtual machines
_pause-resume() {
    ARG=${1}
    VMS=$(su - ${USER} -c "vboxmanage --nologo list runningvms")
    if [ -n "${VMS}" ]; then
        printf "${VMS}\n" | while read VM; do
            VM=${VM%% \{*}
            _log "Running ${ARG} on ${VM}...\n"
            su - ${USER} -c "vboxmanage --nologo controlvm ${VM} ${ARG}"
        done
    else
        _log "No VMs are running.\n"
    fi
}

# Abort backup if ${DEST} partition is not mounted
_mount_check() {
    if mount | grep -w "${DEST}" &>/dev/null; then
        _log "${DEST} is mounted. Proceeding with backup.\n"
    else
        SUBJECT="${SCRIPT}: ${DEST} is not mounted. Aborting backup.\n"
        _log "${SUBJECT}"
        _sendmail
        _exit 1
    fi
}

# Start banner
_log "*** $(_date): Starting nightly backup ***\n"

# Make sure $DEST is mounted
# Comment out _mount_check if $DEST is not a partition
_mount_check

# Pause virtual machines 
_pause-resume pause

# Flush pending writes
sync
echo "3" >/proc/sys/vm/drop_caches
sleep 3

# Do the backup
rsync ${ARGS} ${SRCE} ${DEST} >>${RUNLOG} 2>&1

# Resume virtual machines
_pause-resume resume 

# Exit banner
_log "*** $(_date): Finished nightly backup ***\n\n"

# Send mail results to ${RECIPIENT}
SUBJECT="${SCRIPT}: Backup results"
_sendmail

# Exit
_exit 0
