#!/bin/bash
function outputToEmailAndLog {
echo "[`date +"%Y-%m-%d_%H:%M:%S %z(%Z)"`] ${1}" >> ${logFile}
echo "${1}" >> ${emailFile}
echo "${1}"
}
function outputToLog {
echo "[`date +"%Y-%m-%d_%H:%M:%S %z(%Z)"`] ${1}" >> ${logFile}
echo "${1}"
}
# createMissingDirectories(destinationPath)
function createMissingDirectories {
[ -d ${1} ] || mkdir ${1}
[ -d ${1}/current ] || mkdir ${1}/current
[ -d ${1}/daily ] || mkdir ${1}/daily
[ -d ${1}/weekly ] || mkdir ${1}/weekly
[ -d ${1}/monthly ] || mkdir ${1}/monthly
}
# rsyncCopy(sourcePath, destinationPath)
function rsyncCopy {
# Copy current data
outputToEmailAndLog "Copy from ${1} to ${2}"
rsync -avzO --delete ${1}/ ${2}/current >> ${logFile} 2>&1
if ! [ $? = 24 -o $? = 0 ] ; then {
outputToEmailAndLog "Error: Rsync finished ${1} with errors!"
errorOccurred=true
} fi
}
# hardlinkRotate(rotatePath, intervalSign)
function hardlinkRotate {
outputToEmailAndLog "Rotate ${1} ${2}"
if [ "${2}" = "daily" -o "${2}" = "weekly" -o "${2}" = "monthly" ]; then {
# Rotate hardlinks
dailyBackupDirectory=${1}/daily/${startDateTime}
cp -al ${1}/current ${dailyBackupDirectory}
if ! [ $? = 0 ] ; then {
outputToEmailAndLog "Error: Rotate finished ${1} with errors!"
errorOccurred=true
} fi
touch ${dailyBackupDirectory}
} fi
if [ "${2}" = "weekly" -o "${2}" = "monthly" ]; then {
# Delete old hardlink directories and moving other directories
find ${1}/daily -maxdepth 1 -type d -mtime +7 -exec rm -r {} ';'
oldestDailyBackupDirectory=$(ls -d ${1}/daily/* -r | tail -n1)
outputToEmailAndLog "Using weekly ${oldestDailyBackupDirectory}"
if [ "${oldestDailyBackupDirectory}" != "" ]; then {
mv ${oldestDailyBackupDirectory} ${1}/weekly/
if ! [ $? = 0 ] ; then {
outputToEmailAndLog "Error: Rotate finished ${1} with errors!"
errorOccurred=true
} fi
} fi
} fi
if [ "${2}" = "monthly" ]; then {
find ${1}/weekly -maxdepth 1 -type d -mtime +30 -exec rm -r {} ';'
oldestWeeklyBackupDirectory=$(ls -d ${1}/weekly/* -r | tail -n1)
outputToEmailAndLog "Using monthly ${oldestWeeklyBackupDirectory}"
if [ "${oldestWeeklyBackupDirectory}" != "" ]; then {
mv ${oldestWeeklyBackupDirectory} ${1}/monthly/
if ! [ $? = 0 ] ; then {
outputToEmailAndLog "Error: Rotate finished ${1} with errors!"
errorOccurred=true
} fi
} fi
} fi
# Flush filesystem inode cache
sync
}
weekday=`date -u +"%u"`
dayOfMonth=`date -u +"%d"`
startDateTime=`date +"%Y%m%d_%H%M%S"`
startDateTimeHumanReadable=`date +"%d.%m.%Y %H:%M:%S"`
errorOccurred=false
if [ "${dayOfMonth}" = "01" ]; then {
intervalSign=monthly
} elif [ "${weekday}" = "7" ]; then {
intervalSign=weekly
} else {
intervalSign=daily
} fi
# Delete old log files older than 14 days
find /media/backup/log/backup_* -mtime +14 -exec rm {} ';'
logFile=/media/backup/log/backup_${startDateTime}_${intervalSign}.log
emailFile=/media/backup/log/backup_${startDateTime}_${intervalSign}.email
# Log start
outputToEmailAndLog "Starting ${intervalSign} backup from /media/data to /media/backup at ${startDateTimeHumanReadable}"
createMissingDirectories /media/backup/samba
rsyncCopy /media/data/samba /media/backup/samba
hardlinkRotate /media/backup/samba ${intervalSign}
createMissingDirectories /media/backup/gitRepository
rsyncCopy /media/data/gitRepository /media/backup/gitRepository
hardlinkRotate /media/backup/gitRepository ${intervalSign}
createMissingDirectories /media/backup/scripts
rsyncCopy /media/data/scripts /media/backup/scripts
hardlinkRotate /media/backup/scripts ${intervalSign}
# Flush filesystem inode cache
sync
# Log end
outputToEmailAndLog "Finished backup at `date +"%d.%m.%Y %H:%M:%S"`"
outputToEmailAndLog ""
# Check disk usage
outputToEmailAndLog "Usage of data disk: $(df /dev/sdc1 -h --output=used | tail -1) of $(df /dev/sdc1 -h --output=size | tail -1) ($(df /dev/sdc1 -h --output=pcent | tail -1))"
outputToEmailAndLog "Usage of backup disk: $(df /dev/sdd1 -h --output=used | tail -1) of $(df /dev/sdd1 -h --output=size | tail -1) ($(df /dev/sdd1 -h --output=pcent | tail -1))"
outputToEmailAndLog ""
if [ -f /var/run/reboot-required ]; then
outputToEmailAndLog "Ein Neustart des Servers `${HOSTNAME}` ist erforderlich!"
outputToEmailAndLog ""
fi
# Send email
errorSign=
if [ "${errorOccurred}" = "true" ]; then {
errorSign=Error:
} fi
mail -s "${errorSign}${HOSTNAME} ${intervalSign} backup" "test@example.com" < ${emailFile}
if [ $? = 0 ]; then {
outputToLog "Email was sent"
outputToLog ""
} else {
outputToLog "Error while sending email"
outputToLog ""
exit 1
} fi |
54053(+78) Besucher