Skip to content

Instantly share code, notes, and snippets.

@benyanke
Last active May 9, 2017 16:14
Show Gist options
  • Save benyanke/4c0eefd45c3482dd126f69c742cb5ef3 to your computer and use it in GitHub Desktop.
Save benyanke/4c0eefd45c3482dd126f69c742cb5ef3 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Network Share Incremental Backup Script
# By Ben Yanke <ben@benyanke.com>
# Last modified May, 2017
#
# This script allows you to make backups of a network share, and to keep incremental backups, using
# rsync's incremental backup feature. Old copies are retained without extra storage, because unchanged files are
# hard linked to old snapshots instead of newly copied. By this method, only one copy of any given file is
# stored, but you also have multiple, complete, nonincremental backups on your backup server.
#
# The only negative consequence of this is that you should not manually edit the files on your backup server,
# because editing one file will modify all copies, since they're hard linked. Allow rsync to handle the snapshots
# and it will be flawless.
#
# This script assumes the mounts have been set up in fstab.
#
# To run regular backups, an example cron schedule is found below:
#
##################################################
#
# # Nightly : 3am, except 1st, 9th, 16th, 23rd, and 30th
# 0 3 2-8,10-15,17-22,24-29,31 * * /opt/backups/run-backup.sh --night > /opt/backups/log 2> /opt/backups/errorlog
#
# # Weekly : 3am on 9th, 16th, 23rd, and 30th
# 0 3 9,16,23,30 * * /opt/backups/run-backup.sh --week > /opt/backups/log 2> /opt/backups/errorlog
#
# # Monthly : 1st of the month at 3am (except jan, apr, jul, oct)
# 0 3 1 2,3,5,6,8,9,11,12 * /opt/backups/run-backup.sh --month > /opt/backups/log 2> /opt/backups/errorlog
#
# # Quarterly : 1st of the month (apr, jul, oct) at 3am
# 0 3 1 4,7,10 * /opt/backups/run-backup.sh --quarter > /opt/backups/log 2> /opt/backups/errorlog
#
# # Yearly : Jan 1 at 3am
# 0 3 1 1 * /opt/backups/run-backup.sh --year > /opt/backups/log 2> /opt/backups/errorlog
#
# Root check
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
# Based on:
# https://www.marksanborn.net/howto/use-rsync-for-daily-weekly-and-full-monthly-backups/
# TODO: Alert admin upon backup job complete
# TODO: Error handling
trap cleanup EXIT
# Directory containing mountpoints (only need readonly)
source="/mnt/fileserver-mounts"
# Directory for backups
backup="/mnt/backup-pool/fileserver-backups/snapshots"
# Things to exclude
exclude=".fuse_hidden*"
function mountremote() {
# Mount remote directories
# for f in $source; do
for f in $(ls $source); do
if [[ -d $source/$f ]]; then
sudo mount $source/$f & >/dev/null 2>&1
fi
done
# Mounts run in parallel - wait until they're done here
wait;
# mount -a || return 1;
}
function unmountremote() {
sudo umount $source/* >/dev/null 2>&1
}
function nightbk() {
echo "STARTING NIGHTLY BACKUP";
rsync -a -v --exclude '$exclude' --delete --recursive $source $backup/00-nightly
}
function weekbk() {
echo "STARTING WEEKLY BACKUP";
rsync -a -v --exclude '$exclude' --link-dest $backup/00-nightly --delete --recursive $backup/00-nightly/* $backup/01-weekly
}
function monthbk() {
echo "STARTING MONTHLY BACKUP";
rsync -a -v --exclude '$exclude' --link-dest $backup/00-nightly --delete --recursive $backup/00-nightly/* $backup/02-monthly
}
function quarterbk() {
echo "STARTING MONTHLY BACKUP";
rsync -a -v --exclude '$exclude' --link-dest $backup/00-nightly --delete --recursive $backup/00-nightly/* $backup/03-quarterly
}
function yearbk() {
echo "STARTING YEARLY BACKUP";
rsync -a -v --exclude '$exclude' --link-dest $backup/00-nightly --delete --recursive $backup/00-nightly/* $backup/04-yearly
}
# Finish function
function cleanup() {
unmountremote
}
# Add more error handling here later
# Ensure network shares are mounted
mountremote >/dev/null 2>&1
if [[ $* == *-a* ]] | [[ $* == *--all* ]] ; then
nightbk
weekbk
monthbk
quarterbk
yearbk
elif [[ $* == *--night* ]] || [[ $* == *-n* ]] ; then
nightbk
unmountremote
exit 0
elif [[ $* == *--week* ]] || [[ $* == *-w* ]] ; then
nightbk
weekbk
unmountremote
exit 0
elif [[ $* == *--month* ]] || [[ $* == *-m* ]] ; then
nightbk
monthbk
unmountremote
exit 0
elif [[ $* == *--quarter* ]] || [[ $* == *-q* ]] ; then
nightbk
quarterbk
unmountremote
exit 0
elif [[ $* == *--year* ]] || [[ $* == *-y* ]] ; then
nightbk
yearbk
unmountremote
exit 0
elif [[ $* == *--auto* ]]; then
echo "";
echo "ERROR: AUTO not yet implemented";
exit 1;
else
echo "";
echo "ERROR: Option not specified. Run again, specifying --night, --week, --month, --quarter, --year, --all, or --auto (auto not yet implemented)";
exit 1;
fi
unmountremote
cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment