#!/bin/bash
#
# Version: 2.0
# Changelog:
# initial 24.02.2008
# last modify 16.02.2009 - add iwatch observation
#
# to do:
# better handling with logfiles
# set paths by parameter
# handling for old backupfiles
BACKUPPATH="/data/backup/configs/" # backuppath for files
CONFIGFILE="$(dirname $0)/configfiles.conf" # scriptconfig
DATAPATH="/data" # datapath to backup
BACKUPDISK="/backup/backup" # backupdisk
IWATCHPATH="/data/doku/ipa" # observation dir for iwatch
IBACKUPPATH="/data/backup/iwatch" # backuppath for iwatchfiles
LOGIWATCH="/var/log/backup/iwatch.log" # logfile vor iwatch (if running in verbose mode)
LOGFILE="/var/log/backup/backup.log" # logfile
DATE=`date +%d%m%Y%H%M` # date like 240220081430 (day month year hour minute)
TIMESTAMP="date +%X" # timestamps for logfile
ROOT_UID=0 # root user-id
# usage: how to use this script
F_USAGE () {
cat << EOF
Backup Script
Usage:
-b backup the files from ${CONFIGFILE}
-s sync ${DATAPATH} to ${BACKUPPATH}
-B first backup the files from ${CONFIGFILE}, then sync ${DATAPATH} to ${BACKUPPATH}
-r restore all files from ${CONFIGFILE} (untestet)
-nt also backup notext files with iwatch
-V Verboselevel for iwatch function
-i observate ${IWATCHPATH} and make backup by changing
warning: you can run out of disk space or inodes with this function!
EOF
exit 1
}
# backup: backup the defined configfiles
F_BACKUP () {
echo "# `${TIMESTAMP}`: backup the files from ${CONFIGFILE}" >> ${LOGFILE}
while read input
do
rsync -avR --progress $input ${BACKUPPATH} | tee -a ${LOGFILE}
done < ${CONFIGFILE}
}
# restore: copy back all data - untested, becauce this is a backup script, nobody needs restore
F_RESTORE () {
while read input
do
if [ ! -e $(dirname $input) ];
then
mkdir -p $(dirname $input)
fi
cp -r ${BACKUPPATH}$input $(dirname $input)
done < ${CONFIGFILE}
}
# resync: sync the datapath with the backupdisk
F_RSYNC ()
{
echo "# `${TIMESTAMP}`: sync ${DATAPATH} to ${BACKUPPATH}" >> ${LOGFILE}
rsync -av --progress ${DATAPATH} ${BACKUPDISK} | tee -a ${LOGFILE}
}
# iwatch function, copy data to IBACKUPPATH
iF_COPY ()
{
echo "copy $1 to ${IBACKUPPATH}" >> ${LOGFILE}
cp $1 ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g`
}
# iwatch function, make a differential backup
iF_DIFFBACK ()
{
if [ ! -e ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g` ];
then
iF_COPY "$1"
elif [ `file -b $1 | grep " text" > /dev/null; echo $?` -eq 0 -o "${IWATCH_NOTXT}" == 0 ];
then
diff -U 0 -a $1 ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g` >> ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g`.${DATE}.diff
# restore with `patch ${IBACKUPPATH}/file ${IBACKUPPATH}/file.diff`
#cp $1 ${IBACKUPPATH}/`basename $1`.${DATE}.oldfile
else
echo "$1 seems not do be a textfile" >> ${LOGIWATCH}
fi
}
# iwatch function, make a list with deletet files
iF_LIST ()
{
# echo "$1" >> ${IBACKUPPATH}/delfiles.txt
mv ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g` ${IBACKUPPATH}/`echo $1 | sed s@${IWATCHPATH}@@g`.${DATE}.deleted
}
F_IWATCH ()
{
####
#################################################################
# observate a path and make a backup by changing files
# needs the tool iwatch installed on the system
# use the above definded iF_* functions
#################################################################
#loglevel (more definitions are expectet) # debug
case ${IWATCH_V} in
"0")
iwatch -e all_events ${IWATCHPATH} >> ${LOGIWATCH} &
;;
"1")
iwatch -e default ${IWATCHPATH} >> ${LOGIWATCH} &
;;
esac
#create logfile
if [ ! -e ${LOGIWATCH} ] ;
then
if [ ! -d $(dirname ${LOGIWATCH}) ];
then
mkdir -p $(dirname ${LOGIWATCH})
fi
else
mv ${LOGIWATCH} ${LOGIWATCH}_${DATE}
fi
touch ${LOGIWATCH}
#sync data with existing backup
#rsync -av ${IWATCHPATH}/ ${IBACKUPPATH}/
for file in $( find ${IWATCHPATH} -type f )
do
diff -q $file ${IBACKUPPATH}/`echo $file | sed s@${IWATCHPATH}@@g` > /dev/null 2>&1
local ANSWER="$?"
if [ $ANSWER -eq 1 ];
then
iF_DIFFBACK "$file" &
elif [ $ANSWER -eq 2 ];
then
iF_COPY "$file" &
fi
done
#begin observation
iwatch -r -e create -c "$0 'iF_COPY' '%f'" ${IWATCHPATH} &
iwatch -r -e modify,close_write -c "$0 'iF_DIFFBACK' '%f'" ${IWATCHPATH} &
iwatch -r -e move,delete,delete_self -c "$0 'iF_LIST' '%f'" ${IWATCHPATH} &
}
##########################################################################################
##########################################################################################
# RUN
##########################################################################################
##########################################################################################
# some tests:
if [ "$#" -eq "0" ] ;
then
F_USAGE
fi
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "You must be root to run this script."
exit 1
fi
if [ ! -e ${LOGFILE} ] ;
then
if [ ! -d $(dirname ${LOGFILE}) ];
then
mkdir -p $(dirname ${LOGFILE})
fi
else
mv ${LOGFILE} ${LOGFILE}_${DATE}
fi
touch ${LOGFILE}
echo "# backup from ${DATE} start" >> ${LOGFILE}
# read the parameters:
while [ "$#" -gt "0" ] ;
do
case $1 in
-B) # backup and sync: F_BACKUP + F_RSYNC
F_BACKUP
F_RSYNC
shift
;;
-b) # backup configs: F_BACKUP
F_BACKUP
shift
;;
-s) # syncinc data: F_RSYNC
F_RSYNC
shift
;;
-r) # restore configs: F_RESTORE
F_RESTORE
shift
;;
-V) # verboselevel
IWATCH_V=$2
shift
shift
;;
-nt) # also backup notext files with iwatch
IWATCH_NOTXT=$2
shift
shift
;;
-i) # iwatch observation
F_IWATCH &
shift
;;
iF_COPY) # iwatch function
iF_COPY $2 &
exit 0
;;
iF_DIFFBACK) # iwatch function
iF_DIFFBACK $2 &
exit 0
;;
iF_LIST) # iwatch function
iF_LIST $2 &
exit 0
;;
*) # default
F_USAGE
break
;;
esac
done
echo "# `${TIMESTAMP}` end" >> ${LOGFILE}
exit 0
##########################################################################################
# EOF