#!/bin/bash
# Script to backup Redmine files to a mounted storage device
# with daily, weekly, monthly backup rotation

# Sysadmin email address
sysadmin_email="admin@domain.com"

# What to backup
db_dump_file="/usr/share/redmine/db/redmine-database-dump.sql"

backup_files="$db_dump_file /usr/share/redmine/files /var/hg /var/svn /etc/apache2/conf.d/hg.conf" 
backup_files="$backup_files /etc/apache2/sites-available/redmine /etc/init/s3.conf /etc/cron.d/redmine"
backup_files="$backup_files /usr/local/bin/backup-redmine.sh"

# Where to backup to
backup_dir="/mnt/s3"

# Set database access
redmine_db_name="redmine"
redmine_db_user="redmine"
redmine_db_password="password"

# Encryption
encrypt="true"
secret_passphrase="secret"

# Set rotation in units of days
daily_remove_older_than=6
weekly_remove_older_than=31
monthly_remove_older_than=62

# Redirect stderr to a log file
error_log="/tmp/backup-redmine.log"
exec 6>&2
exec 2>$error_log

on_exit() {
    # Restore IO output
    exec 2>&6  6>$-

    # Check for errors
    if [ -s "$error_log" ]; then
        logger -t "$0" -s "#### Backup Failed ####"
        logger -t "$0" -s -f "$error_log"
        cat "$error_log" | mail -s "Backup failed!"  $sysadmin_email
     else
        logger -t "$0" -s "Backup Complete"
    fi

    # Clean up
    rm -f $error_log
}

trap on_exit EXIT SIGHUP SIGINT SIGQUIT SIGTERM

# Setup variables for the archive filename.
hostname=$(hostname -s)
date_time_stamp=`date +%Y-%m-%d_%Hh%Mm`        # Datestamp e.g 2011-12-31_23h59m
date_stamp=`date +%Y-%m-%d`                    # Date p e.g 2011-12-31
date_day_of_week=`date +%A`                    # Day of the week e.g. Monday
date_day_of_month=`date +%e`                   # Date of the Month e.g. 27

# Is the  backup directory mounted?
mount | grep -sq "$backup_dir"
if  [ $? != 0 ]; then
   echo "backup destination ${backup_dir} is not mounted" >&2
  exit 1
fi

# Make required directories
[ -d "$backup_dir/monthly" ] || mkdir "$backup_dir/monthly"
[ -d "$backup_dir/weekly" ] || mkdir "$backup_dir/weekly"
[ -d "$backup_dir/daily" ] || mkdir "$backup_dir/daily"

# Delete old archives
find "${backup_dir}/monthly" -mtime +"$monthly_remove_older_than" -type f -name "${hostname}_*" -exec rm {} \;
find "${backup_dir}/weekly" -mtime +"$weekly_remove_older_than" -type f -name "${hostname}_*" -exec rm {} \;
find "${backup_dir}/daily" -mtime +"$daily_remove_older_than" -type f -name "${hostname}_*" -exec rm {} \;

archive_file="${backup_dir}/daily/${hostname}_${date_time_stamp}.tgz"

[ $encrypt == "true" ] && archive_file="${archive_file}.gpg"

# Dump the redmine database
rm -f "${db_dump_file}"
mysqldump --user="${redmine_db_name}" --password="${redmine_db_password}" "${redmine_db_name}" > $db_dump_file

# Write the archive file to the backup directory
if [ $encrypt == "true" ]; then
    tar czP $backup_files | gpg -c -z 0 --yes --no-use-agent --passphrase="${secret_passphrase}" -o "${archive_file}" 
else
    tar czfP "${archive_file}" $backup_files
fi

# Make a weekly backup on Saturday
if [ $date_day_of_week == "Saturday" ]; then
    weekly_count=$(find "${backup_dir}/weekly" -type f -name "${hostname}_${date_stamp}*" | wc -l)
    [ $weekly_count == "0" ] && cp "${archive_file}" "${backup_dir}/weekly/" 
fi

# Make a monthly backup on the first day of every  month
if [ $date_day_of_month == "1" ]; then
    monthly_count=$(find "${backup_dir}/monthly" -type f -name "${hostname}_${date_stamp}*" | wc -l)
    [ $monthly_count == "0" ] && cp "${archive_file}" "${backup_dir}/monthly/" 
fi

if [ -s "$error_log" ]; then
    exit 1
else
    exit 0
fi

