backup-scripts/backup.sh
2014-09-11 10:38:13 +02:00

168 lines
6.8 KiB
Bash
Executable file

#!/bin/bash
#set -x
# main configuration
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
config_file="$script_dir/main.cfg"
# timestamps yyyy-mm-dd and unixtime for calculating
backup_stamp=$(date +%F)
backup_time=$(date -d$backup_stamp +%s)
# check if it is the first of the month to do monthly backups
backup_month="no"
if [ "$(echo $backup_stamp | cut -d- -f3)" = "01" ]
then
backup_month="yes"
fi
# source a specified section from a specified config
function source_section {
config_name="$1"
section_name="$2"
section_start="^\[$section_name\]$"
section_end="^\[/$section_name\]$"
line_start=$(grep -n "$section_start" "$config_name" | cut -d: -f1)
line_end=$(expr $(grep -n "$section_end" "$config_name" | cut -d: -f1) - 1)
line_diff=$(expr $line_end - $line_start)
head -n $line_end "$config_name" | tail -n $line_diff > /tmp/backup.tmp
source /tmp/backup.tmp
rm -f /tmp/backup.tmp
}
# copy file with rsync to server and save last timestamp to logfile
function rsync_server {
filefrom="$1"
dirto="$2"
logfileentry="$3"
#nice -n 19 rsync -rle "ssh -i $keyfile" "$1" "$userserver:$dirto"
# limit the bandwith
nice -n 19 rsync --bwlimit=100000 -rle "ssh -i $keyfile" "$1" "$userserver:$dirto"
ret=$?
if [ $ret -ne 0 ]
then
echo "problem in rsync: $filefrom"
fi
echo "$filefrom" | grep ".month." > /dev/null 2>&1
ret2=$?
# on monthly backups and connection errors there should be no update of logfile
if [ $ret2 -ne 0 -a $ret -ne 0 ]
then
sed -e "s/^$logfileentry .*$/${logfileentry} $backup_time/" "$logfile" > "$logfile.tmp"
mv -f "$logfile.tmp" "$logfile"
fi
}
# general section from main config
source_section "$config_file" "general"
# handle all specified configs
for config_single in $configs
do
# does the configuration file exists?
config_act="$confdir/$config_single"
if [ -e "$config_act" ]
then
# general section from specific config
source_section "$config_act" "general"
# change folder for backup
pushd "$rootdir" > /dev/null
# handle all specified folders
for dir_single in $dirssingle
do
# check if folder exists
if [ -e "$dir_single" ]
then
# section for specified folder
source_section "$config_act" "$dir_single"
# rotate is done through days, so we have to know the interval in sections
rotate_stamp=$(expr $time \* 24 \* 60 \* 60)
# for new configurations that does not have a last timestamp we create a zero one
grep "^${config_single}_$dir_single " $logfile > /dev/null 2>&1
if [ $? -ne 0 ]
then
echo "${config_single}_$dir_single 0" >> $logfile
fi
# get the stamp for the last backup
last_stamp=$(grep "^${config_single}_$dir_single " $logfile | cut -d" " -f2)
# get the stamp for the next backup
now_stamp=$(expr $last_stamp + $rotate_stamp)
do_backup="no"
do_monthly="no"
do_normal="no"
# check wether it is time to do a backup by time and also month
if [ $now_stamp -le $backup_time ]
then
do_backup="yes"
if [ "$rotate" != "inc" ]
then
do_normal="yes"
fi
fi
if [ "$backup_month" = "yes" -a "$monthly" = "yes" ]
then
do_backup="yes"
do_monthly="yes"
fi
# now we are sure to do a backup
if [ "$do_backup" = "yes" ]
then
# we want an incremental backup since last one
if [ "$rotate" = "inc" ]
then
# tar is not able to handle unix-timestamps, so we calculate the required one
tar_stamp=$(date -d "1970-01-01 $last_stamp sec" +%F)
# only changed files since last modification in backup
nice -n 19 tar czf "$dir_single.$backup_stamp.tar.gz" --warning=none -N "$tar_stamp" "$dir_single"
rsync_server "$dir_single.$backup_stamp.tar.gz" "$backupdir/$backupdirsingle/" "${config_single}_$dir_single"
# delete backups from local
rm -f "$dir_single.$backup_stamp.tar.gz"
fi # if [ "$rotate" = "inc" ]
# we want a full backup
if [ "$do_monthly" = "yes" -o "$do_normal" = "yes" ]
then
# backup everything
nice -n 19 tar czf "$dir_single.tar.gz" --warning=none "$dir_single"
# check wether we should rotate
if [ "$rotate" != "inc" -a "$do_normal" = "yes" ]
then
# mount for renaming
sshfs $userserver:$backupdir $backupdir_local -o IdentityFile=$keyfile -o IdentitiesOnly=yes
# rotate old backups
for count in `seq $rotate -1 2`
do
count_last=$(expr $count - 1)
rm -f "$backupdir_local/$backupdirsingle/$dir_single.tar.gz.$count"
mv -f "$backupdir_local/$backupdirsingle/$dir_single.tar.gz.$count_last" "$backupdir_local/$backupdirsingle/$dir_single.tar.gz.$count" > /dev/null 2>&1
done
rm -f "$backupdir_local/$backupdirsingle/$dir_single.tar.gz.1"
mv -f "$backupdir_local/$backupdirsingle/$dir_single.tar.gz" "$backupdir_local/$backupdirsingle/$dir_single.tar.gz.1" > /dev/null 2>&1
# unmount
umount $backupdir_local
fi # if [ "$rotate" != "inc" -a "$do_normal" = "yes" ]
# copy new backups
if [ "$do_normal" = "yes" ]
then
rsync_server "$dir_single.tar.gz" "$backupdir/$backupdirsingle/" "${config_single}_$dir_single"
fi
if [ "$do_monthly" = "yes" ]
then
#TODO: check why move sometimes causes problems
nice -n 19 cp "$dir_single.tar.gz" "$dir_single.$backup_stamp.month.tar.gz"
rsync_server "$dir_single.$backup_stamp.month.tar.gz" "$backupdir/$backupdirsingle/" "${config_single}_$dir_single"
fi
# delete backups from local
rm -f "$dir_single.$backup_stamp.month.tar.gz"
rm -f "$dir_single.tar.gz"
fi # if [ "$do_monthly" = "yes" -o "$do_normal" = "yes" ]
fi # if [ "$do_backup" = "yes" ]
fi # if [ -e "$dir_single" ]
done # for dir_single in $dirssingle
# go back
popd > /dev/null
fi # if [ -e "$config_act" ]
done # for config_single in $configs