X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fupstream%2Fbackupninja.git;a=blobdiff_plain;f=src%2Fbackupninja.in;h=34c0bd618e265fff7211d497609512985729b8e1;hp=387743fe1934719454b64f61a0095a251120ae06;hb=846213cfa48e026bdd7cacaebd46973207a809ba;hpb=85a7eb350aa10565a9c1c72fd3a3a98d8d2a7504 diff --git a/src/backupninja.in b/src/backupninja.in index 387743f..34c0bd6 100755 --- a/src/backupninja.in +++ b/src/backupninja.in @@ -1,4 +1,6 @@ #!@BASH@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# # |\_ # B A C K U P N I N J A /()/ # `\| @@ -19,7 +21,7 @@ ##################################################### ## FUNCTIONS -function setupcolors() { +function setupcolors () { BLUE="\033[34;01m" GREEN="\033[32;01m" YELLOW="\033[33;01m" @@ -30,9 +32,9 @@ function setupcolors() { COLORS=($BLUE $GREEN $YELLOW $RED $PURPLE) } -function colorize() { +function colorize () { if [ "$usecolors" == "yes" ]; then - local typestr=`echo "$@" | sed 's/\(^[^:]*\).*$/\1/'` + local typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'` [ "$typestr" == "Debug" ] && type=0 [ "$typestr" == "Info" ] && type=1 [ "$typestr" == "Warning" ] && type=2 @@ -66,7 +68,7 @@ function printmsg() { type=$1 shift if [ $type == 100 ]; then - typestr=`echo "$@" | sed 's/\(^[^:]*\).*$/\1/'` + typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'` [ "$typestr" == "Debug" ] && type=0 [ "$typestr" == "Info" ] && type=1 [ "$typestr" == "Warning" ] && type=2 @@ -123,70 +125,50 @@ function msg { let "msgcount += 1" } -function setfile() { - CURRENT_CONF_FILE=$1 -} - -function setsection() { - CURRENT_SECTION=$1 -} - - -# -# create a temporary file in a secure way. -# -function maketemp() { - if [ -x /bin/mktemp ] - then - local tempfile=`mktemp /tmp/$1.XXXXXXXX` - else - DATE=`date` - sectmp=`echo $DATE | /usr/bin/md5sum | cut -d- -f1` - local tempfile=/tmp/$1.$sectmp - fi - echo $tempfile -} - - -# -# sets a global var with name equal to $1 -# to the value of the configuration parameter $1 -# $2 is the default. -# - -function getconf() { - CURRENT_PARAM=$1 - ret=`awk -f $scriptdir/parseini S=$CURRENT_SECTION P=$CURRENT_PARAM $CURRENT_CONF_FILE` - # if nothing is returned, set the default - if [ "$ret" == "" -a "$2" != "" ]; then - ret="$2" - fi - - # replace * with %, so that it is not globbed. - ret="${ret//\\*/__star__}" - - # this is weird, but single quotes are needed to - # allow for returned values with spaces. $ret is still expanded - # because it is in an 'eval' statement. - eval $1='$ret' -} - # # enforces very strict permissions on configuration file $file. # function check_perms() { - local file=$1 - local perms=`ls -ld $file` - perms=${perms:4:6} - if [ "$perms" != "------" ]; then - echo "Configuration files must not be group or world writable/readable! Dying on file $file" - fatal "Configuration files must not be group or world writable/readable! Dying on file $file" - fi - if [ `ls -ld $file | awk '{print $3}'` != "root" ]; then - echo "Configuration files must be owned by root! Dying on file $file" - fatal "Configuration files must be owned by root! Dying on file $file" - fi + local file=$1 + debug "check_perms $file" + local perms + local owners + + perms=($(stat -L --format='%A' $file)) + debug "perms: $perms" + local gperm=${perms:4:3} + debug "gperm: $gperm" + local wperm=${perms:7:3} + debug "wperm: $wperm" + + owners=($(stat -L --format='%g %G %u %U' $file)) + local gid=${owners[0]} + local group=${owners[1]} + local owner=${owners[2]} + + if [ "$owner" != 0 ]; then + echo "Configuration files must be owned by root! Dying on file $file" + fatal "Configuration files must be owned by root! Dying on file $file" + fi + + if [ "$wperm" != '---' ]; then + echo "Configuration files must not be world writable/readable! Dying on file $file" + fatal "Configuration files must not be world writable/readable! Dying on file $file" + fi + + if [ "$gperm" != '---' ]; then + case "$admingroup" in + $gid|$group) :;; + + *) + if [ "$gid" != 0 ]; then + echo "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file" + fatal "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file" + fi + ;; + esac + fi } # simple lowercase function @@ -196,7 +178,7 @@ function tolower() { # simple to integer function function toint() { - echo "$1" | tr [:alpha:] -d + echo "$1" | tr -d '[:alpha:]' } # @@ -222,7 +204,7 @@ function isnow() { whendayofweek=$1; at=$2; whentime=$3; whenday=`toint "$whendayofweek"` whendayofweek=`tolower "$whendayofweek"` - whentime=`echo "$whentime" | sed 's/:[0-9][0-9]$//' | sed -r 's/^([0-9])$/0\1/'` + whentime=`echo "$whentime" | @SED@ 's/:[0-9][0-9]$//' | @SED@ -r 's/^([0-9])$/0\1/'` if [ "$whendayofweek" == "everyday" -o "$whendayofweek" == "daily" ]; then whendayofweek=$nowdayofweek @@ -326,7 +308,7 @@ function process_action() { echo "" > $bufferfile echo_debug_msg=1 ( - . $scriptdir/$suffix $file + . $scriptdirectory/$suffix $file ) 2>&1 | ( while read a; do echo $a >> $bufferfile @@ -426,23 +408,37 @@ if [ ! -r "$conffile" ]; then fatal "Configuration file $conffile not found." fi -scriptdir=`grep scriptdirectory $conffile | awk '{print $3}'` -if [ ! -n "$scriptdir" ]; then - echo "Cound not find entry 'scriptdirectory' in $conffile" - fatal "Cound not find entry 'scriptdirectory' in $conffile" +# find $libdirectory +libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'` +if [ -z "$libdirectory" ]; then + if [ -d "@libdir@" ]; then + libdirectory="@libdir@" + else + echo "Could not find entry 'libdirectory' in $conffile." + fatal "Could not find entry 'libdirectory' in $conffile." + fi +else + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." + fatal "Lib directory $libdirectory not found." + fi fi -if [ ! -d "$scriptdir" ]; then - echo "Script directory $scriptdir not found." - fatal "Script directory $scriptdir not found." -fi +# include shared functions +. $libdirectory/tools +. $libdirectory/vserver setfile $conffile # get global config options (second param is the default) getconf configdirectory @CFGDIR@/backup.d +getconf scriptdirectory @datadir@ +getconf reportdirectory getconf reportemail +getconf reporthost +getconf reportspace getconf reportsuccess yes +getconf reportuser getconf reportwarning yes getconf loglevel 3 getconf when "Everyday at 01:00" @@ -452,17 +448,21 @@ getconf usecolors "yes" getconf SLAPCAT /usr/sbin/slapcat getconf LDAPSEARCH /usr/bin/ldapsearch getconf RDIFFBACKUP /usr/bin/rdiff-backup +getconf CSTREAM=/usr/bin/cstream +getconf MYSQLADMIN /usr/bin/mysqladmin getconf MYSQL /usr/bin/mysql getconf MYSQLHOTCOPY /usr/bin/mysqlhotcopy getconf MYSQLDUMP /usr/bin/mysqldump getconf PGSQLDUMP /usr/bin/pg_dump getconf PGSQLDUMPALL /usr/bin/pg_dumpall +getconf PGSQLUSER postgres getconf GZIP /bin/gzip getconf RSYNC /usr/bin/rsync -getconf vservers no -getconf VSERVERINFO /usr/sbin/vserver-info -getconf VSERVER /usr/sbin/vserver -getconf VROOTDIR `if [ -f "$VSERVERINFO" ]; then $VSERVERINFO info SYSINFO |grep vserver-Rootdir | awk '{print $2}'; fi` +getconf admingroup root + +# initialize vservers support +# (get config variables and check real vservers availability) +init_vservers nodialog if [ ! -d "$configdirectory" ]; then echo "Configuration directory '$configdirectory' not found." @@ -472,15 +472,10 @@ fi [ -f "$logfile" ] || touch $logfile if [ "$UID" != "0" ]; then - echo "$0 can only be run as root" + echo "`basename $0` can only be run as root" exit 1 fi -if [ "$vservers" == "yes" -a ! -d "$VROOTDIR" ]; then - echo "vservers option set in config, but $VROOTDIR is not a directory!" - fatal "vservers option set in config, but $VROOTDIR is not a directory!" -fi - ## Process each configuration file # by default, don't make files which are world or group readable. @@ -496,12 +491,17 @@ errormsg="" if [ "$singlerun" ]; then files=$singlerun else - files=`find $configdirectory -mindepth 1 ! -name '.*.swp' | sort -n` + files=`find $configdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n` + + if [ -z "$files" ]; then + fatal "No backup actions configured in '$configdirectory', run ninjahelper!" + fi fi for file in $files; do [ -f "$file" ] || continue + check_perms ${file%/*} # check containing dir check_perms $file suffix="${file##*.}" base=`basename $file` @@ -510,7 +510,7 @@ for file in $files; do continue fi - if [ -e "$scriptdir/$suffix" ]; then + if [ -e "$scriptdirectory/$suffix" ]; then process_action $file $suffix else error "Can't process file '$file': no handler script for suffix '$suffix'" @@ -541,9 +541,24 @@ if [ $doit == 1 ]; then echo ${messages[$i]} done echo -e "$errormsg" - } | mail $reportemail -s "backupninja: $hostname $subject" + if [ "$reportspace" == "yes" ]; then + previous="" + for i in $(ls "$configdirectory"); do + backuploc=$(grep ^directory "$configdirectory"/"$i" | @AWK@ '{print $3}') + if [ "$backuploc" != "$previous" ]; then + df -h "$backuploc" + previous="$backuploc" + fi + done + fi + } | mail -s "backupninja: $hostname $subject" $reportemail fi if [ $actions_run != 0 ]; then info "FINISHED: $actions_run actions run. $fatals fatal. $errors error. $warnings warning." fi + +if [ -n "$reporthost" ]; then + debug "send $logfile to $reportuser@$reporthost:$reportdirectory" + rsync -qt $logfile $reportuser@$reporthost:$reportdirectory +fi