X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fupstream%2Fbackupninja.git;a=blobdiff_plain;f=src%2Fbackupninja.in;h=2a1b76ebae4c1d512a6a3f800a92a7e9573cc326;hp=16ac7a7dc5e5417ffeae1f64b23b427ea4a562f8;hb=a1c625fcc3c1bdcc81bb23aee3bea95051d6cc20;hpb=f07f4b873b5d4b0dbe18df8cd6078826b2a0afd1 diff --git a/src/backupninja.in b/src/backupninja.in index 16ac7a7..2a1b76e 100755 --- a/src/backupninja.in +++ b/src/backupninja.in @@ -29,17 +29,18 @@ function setupcolors () { RED="\033[31;01m" OFF="\033[0m" CYAN="\033[36;01m" - COLORS=($BLUE $GREEN $YELLOW $RED $PURPLE) + COLORS=($BLUE $GREEN $YELLOW $RED $PURPLE $CYAN) } 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 [ "$typestr" == "Error" ] && type=3 [ "$typestr" == "Fatal" ] && type=4 + [ "$typestr" == "Halt" ] && type=5 color=${COLORS[$type]} endcolor=$OFF echo -e "$color$@$endcolor" @@ -54,6 +55,7 @@ function colorize () { # 2 - warnings - yellow # 3 - errors - red # 4 - fatal - purple +# 5 - halt - cyan # First variable passed is the error level, all others are printed # if 1, echo out all warnings, errors, or fatal @@ -68,15 +70,16 @@ 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 [ "$typestr" == "Error" ] && type=3 [ "$typestr" == "Fatal" ] && type=4 + [ "$typestr" == "Halt" ] && type=5 typestr="" else - types=(Debug Info Warning Error Fatal) + types=(Debug Info Warning Error Fatal Halt) typestr="${types[$type]}: " fi @@ -95,7 +98,7 @@ function printmsg() { function logmsg() { if [ -w "$logfile" ]; then - echo -e `date "+%h %d %H:%M:%S"` "$@" >> $logfile + echo -e `LC_ALL=C date "+%h %d %H:%M:%S"` "$@" >> $logfile fi } @@ -118,6 +121,10 @@ function fatal() { printmsg 4 "$@" exit 2 } +function halt() { + printmsg 5 "$@" + exit 2 +} msgcount=0 function msg { @@ -131,32 +138,40 @@ function msg { function check_perms() { local file=$1 + debug "check_perms $file" local perms - perms=($(stat -L --printf='%a %g %G %u %U' $file)) - local gperm=${perms[0]:1:1} - local wperm=${perms[0]:2:1} - local gid=${perms[1]} - local group=${perms[2]} - local owner=${perms[3]} + 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 -gt 0 ]; then + 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 -gt 0 ]; then + if [ "$gperm" != '---' ]; then case "$admingroup" in $gid|$group) :;; *) if [ "$gid" != 0 ]; then - echo "Configuration files must writable/readable by group ${perms[2]}! Dying on file $file" - fatal "Configuration files must writable/readable by group ${perms[2]}! Dying on file $file" + 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 @@ -165,12 +180,12 @@ function check_perms() { # simple lowercase function function tolower() { - echo "$1" | tr [:upper:] [:lower:] + echo "$1" | tr '[:upper:]' '[:lower:]' } # simple to integer function function toint() { - echo "$1" | tr -d [:alpha:] + echo "$1" | tr -d '[:alpha:]' } # @@ -185,18 +200,21 @@ function toint() { # we grab the current time once, since processing # all the configs might take more than an hour. -nowtime=`date +%H` -nowday=`date +%d` -nowdayofweek=`date +%A` +nowtime=`LC_ALL=C date +%H` +nowday=`LC_ALL=C date +%d` +nowdayofweek=`LC_ALL=C date +%A` nowdayofweek=`tolower "$nowdayofweek"` function isnow() { local when="$1" set -- $when + + [ "$when" == "manual" ] && return 0 + 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 @@ -244,19 +262,20 @@ The following options are available: When in debug mode, output to the console will be colored: EOF - debug=1 - debug "Debugging info (when run with -d)" - info "Informational messages (verbosity level 4)" - warning "Warnings (verbosity level 3 and up)" - error "Errors (verbosity level 2 and up)" - fatal "Fatal, halting errors (always shown)" + usecolors=yes + colorize "Debug: Debugging info (when run with -d)" + colorize "Info: Informational messages (verbosity level 4)" + colorize "Warning: Warnings (verbosity level 3 and up)" + colorize "Error: Errors (verbosity level 2 and up)" + colorize "Fatal: Errors which halt a given backup action (always shown)" + colorize "Halt: Errors which halt the whole backupninja run (always shown)" } ## ## this function handles the running of a backup action ## ## these globals are modified: -## fatals, errors, warnings, actions_run, errormsg +## halts, fatals, errors, warnings, actions_run, errormsg ## function process_action() { @@ -282,9 +301,9 @@ function process_action() { ret=$? IFS=$'\t\n' if [ $ret == 0 ]; then - debug "skipping $file because it is not $w" + debug "skipping $file because current time does not match $w" else - info ">>>> starting action $file (because it is $w)" + info ">>>> starting action $file (because current time matches $w)" run="yes" fi done @@ -314,10 +333,15 @@ function process_action() { _warnings=`cat $bufferfile | grep "^Warning: " | wc -l` _errors=`cat $bufferfile | grep "^Error: " | wc -l` _fatals=`cat $bufferfile | grep "^Fatal: " | wc -l` + _halts=`cat $bufferfile | grep "^Halt: " | wc -l` - ret=`grep "\(^Warning: \|^Error: \|^Fatal: \)" $bufferfile` + ret=`grep "\(^Warning: \|^Error: \|^Fatal: \|Halt: \)" $bufferfile` rm $bufferfile - if [ $_fatals != 0 ]; then + if [ $_halts != 0 ]; then + msg "*halt* -- $file" + errormsg="$errormsg\n== halt request from $file==\n\n$ret\n" + passthru "Halt: <<<< finished action $file: FAILED" + elif [ $_fatals != 0 ]; then msg "*failed* -- $file" errormsg="$errormsg\n== fatal errors from $file ==\n\n$ret\n" passthru "Fatal: <<<< finished action $file: FAILED" @@ -334,6 +358,7 @@ function process_action() { info "<<<< finished action $file: SUCCESS" fi + let "halts += _halts" let "fatals += _fatals" let "errors += _errors" let "warnings += _warnings" @@ -371,8 +396,8 @@ while [ $# -ge 1 ]; do singlerun=$2 processnow=1 else - echo "--run option must be fallowed by a backupninja action file" - fatal "--run option must be fallowed by a backupninja action file" + echo "--run option must be followed by a backupninja action file" + fatal "--run option must be followed by a backupninja action file" usage fi shift @@ -401,7 +426,7 @@ if [ ! -r "$conffile" ]; then fi # find $libdirectory -libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'` +libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'` if [ -z "$libdirectory" ]; then if [ -d "@libdir@" ]; then libdirectory="@libdir@" @@ -425,8 +450,12 @@ 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" @@ -436,11 +465,14 @@ 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 admingroup root @@ -467,6 +499,7 @@ fi umask 077 # these globals are set by process_action() +halts=0 fatals=0 errors=0 warnings=0 @@ -476,7 +509,7 @@ errormsg="" if [ "$singlerun" ]; then files=$singlerun else - files=`find -L $configdirectory -mindepth 1 -maxdepth 1 -type f ! -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!" @@ -485,6 +518,7 @@ fi for file in $files; do [ -f "$file" ] || continue + [ "$halts" = "0" ] || continue check_perms ${file%/*} # check containing dir check_perms $file @@ -526,9 +560,27 @@ 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" -a -n "$backuploc" ]; 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." + if [ "$halts" != "0" ]; then + info "Backup was halted prematurely. Some actions may not have run." + fi +fi + +if [ -n "$reporthost" ]; then + debug "send $logfile to $reportuser@$reporthost:$reportdirectory" + rsync -qt $logfile $reportuser@$reporthost:$reportdirectory fi