A Simple Server Sync Script

Raw

#!/bin/bash
# A Simple Server Sync Script

### Required packages

#	rsync -- runs the data sync process
#	cifs-utils -- for windows/smb shares
#	sshfs -- for ssh mounts
#	msmtp -- for email notifications

### User-defined variables

# Name the backup job
BackupName="Client Name Backup"

# The path where logs should be stored
LogFolder="$HOME/Logs/client"

# The path to the source/root folder to be backed up
SourcePath="/media/clientmounts/client-name"
# The path to the backup target/repository
TargetPath="/media/repo-name/client-name/sync"

# The command used to mount the backup source
SourceMountCommand="sshfs hostname.domain:../../media/local $SourcePath"
# The command used to mount the backup target
TargetMountCommand="sudo mount -a"

# Email notification settings
SMTP_From="sender@domain.com"
SMTP_To="recipient@domain.com"

### End of user-defined variables

LogFile="$LogFolder/backup.log"
ReportFile=$(mktemp)
Output=$(mktemp)

### Functions

Say() {
	echo "$1"
	echo "$(date +%b%d) | $(date +%H:%M) | $1" >> $LogFile
	echo "$(date +%b%d) | $(date +%H:%M) | $1" >> $ReportFile ;}

Fail() { Say "$1" ; SendNotify ; exit ;}

SayHead() {
	Say "============================"
	Say "Starting $BackupName"
	Say "============================" ;}

SayFoot() {
	Say "============================"
	Say "Finished $BackupName"
	Say "============================"
	Say "Running time: $Time"
	Say "============================" ;}

MountPath() {
	case $1 in
		Source)	$SourceMountCommand &&
			if [ ! -d $SourcePath ]
			then Fail "There was a problem mounting backup source."
			fi ;;
		Target) $TargetMountCommand &&
			if [ ! -d $TargetPath ]
			then Fail "There was a problem mounting backup target."
			fi ;;
	esac ;}

Check() {
	if [ ! -d $2 ]
	then MountPath $1 || Fail "Failed to mount backup $1."
	fi ;}

ProcessArgs() {
	cd $TargetPath
	rm -rf $1.backup.7
	mv $1.backup.6 $1.backup.7
	mv $1.backup.5 $1.backup.6
	mv $1.backup.4 $1.backup.5
	mv $1.backup.3 $1.backup.4
	mv $1.backup.2 $1.backup.3
	mv $1.backup.1 $1.backup.2
	mv $1.backup.0 $1.backup.1
	Say "Syncing '$1'."
	rsync -a --delete --link-dest=../$1.backup.1 $SourcePath/$1/ $1.backup.0/ &>$LogFolder/rsync-$1.log &&
	Say "Completed syncing '$1'." ;}

Backup() {
	for arg in $* ; do
		Check Source $SourcePath/$arg || Fail "Failed to mount source share(s)."
		Check Target $TargetPath || Fail "Failed to mount target folder(s)."
		ProcessArgs $arg || Say "There were errors syncing '$arg'."
	done ;}

SendNotify() {
	echo "To: $SMTP_To" >> $Output
	echo "From: $SMTP_From" >> $Output
	echo "Subject: $BackupName" >> $Output
	echo "" >> $Output
	cat $ReportFile >> $Output
	cat $Output | msmtp $SMTP_To || Say "SMTP notification failed."
	shred $Output
	shred $ReportFile ;}

# The SendNotify function requires msmtp package
# and a properly-configured ~/.msmtprc

# For example, your ~/.msmtprc file should
# look something like this:

#	defaults
#	auth on
#	tls on
#	tls_trust_file /etc/ssl/certs/ca-certificates.crt
#	logfile ~/.msmtp.log
#
#	account default
#	host smtp.office365.com
#	port 587
#	from sender@domainname.com
#	user sender@domainname.com
#	password password

# If you put your password in this file
# you will need to 'chmod 600 ~/.msmtprc'
# to protect the file. Alternatively, you can use
# 'passwordeval' with an encrypted key file.
# That line would look something like:

#	passwordeval "gpg -d --quiet --for-your-eyes-only ~/keyfile.gpg | sed -e '$a\'"

### Commands

# If your source and target mounts are in /etc/fstab
# This line should take care of mounting needs
#sudo mount -a

mkdir -p $LogFolder

SayHead

Backup share1 share2 share3

# Running time of the script is recorded at the end
Duration=$SECONDS
Time="$(($Duration / 60)) minutes and $((Duration % 60)) seconds"

SayFoot

SendNotify