initial commit
This commit is contained in:
commit
e848de475e
6 changed files with 233 additions and 0 deletions
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
configurable backup-script for bash
|
168
backup.sh
Executable file
168
backup.sh
Executable file
|
@ -0,0 +1,168 @@
|
|||
#!/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
|
9
main.cfg
Normal file
9
main.cfg
Normal file
|
@ -0,0 +1,9 @@
|
|||
[general]
|
||||
confdir=/PATH/TO/THE/CONFIGUGATION/FILES
|
||||
configs="user.cfg www.cfg system.cfg"
|
||||
backupdir=/BASE/PATH/ON/THE/BACKUP/SERVER
|
||||
backupdir_local=/LOCAL/PATH/TO/MOUNT/POINT
|
||||
logfile=$confdir/logfile.log
|
||||
keyfile=/PATH/TO/KEYFILE/id_rsa
|
||||
userserver="backupuser@backup.server"
|
||||
[/general]
|
15
system.cfg
Normal file
15
system.cfg
Normal file
|
@ -0,0 +1,15 @@
|
|||
[general]
|
||||
rootdir=/
|
||||
dirssingle="root etc"
|
||||
backupdirsingle=system
|
||||
[/general]
|
||||
[root]
|
||||
rotate=10
|
||||
time=1
|
||||
monthly=yes
|
||||
[/root]
|
||||
[etc]
|
||||
rotate=30
|
||||
time=1
|
||||
monthly=yes
|
||||
[/etc]
|
23
user.cfg
Normal file
23
user.cfg
Normal file
|
@ -0,0 +1,23 @@
|
|||
[general]
|
||||
rootdir=/home
|
||||
dirssingle="user1 user2 user3"
|
||||
backupdirsingle=users
|
||||
[/general]
|
||||
[user1]
|
||||
#daily backup with 3 old versions
|
||||
rotate=3
|
||||
time=1
|
||||
monthly=no
|
||||
[/user1]
|
||||
[user2]
|
||||
#daily incremental backup
|
||||
rotate=inc
|
||||
time=1
|
||||
monthly=no
|
||||
[/user2]
|
||||
[user3]
|
||||
#weekly backup with 3 old versions
|
||||
rotate=3
|
||||
time=7
|
||||
monthly=no
|
||||
[/user3]
|
17
www.cfg
Normal file
17
www.cfg
Normal file
|
@ -0,0 +1,17 @@
|
|||
[general]
|
||||
rootdir=/var/www
|
||||
dirssingle="domain.tld example.com"
|
||||
backupdirsingle=www
|
||||
[/general]
|
||||
[domain.tld]
|
||||
#daily incremental backup with monthly snapshots
|
||||
rotate=inc
|
||||
time=1
|
||||
monthly=yes
|
||||
[/domain.tld]
|
||||
[example.com]
|
||||
#backup every third day and hold 5 old versions
|
||||
rotate=5
|
||||
time=3
|
||||
monthly=no
|
||||
[/example.com]
|
Loading…
Reference in a new issue