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"
# 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
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
printmsg 4 "$@"
exit 2
}
+function halt() {
+ printmsg 5 "$@"
+ exit 2
+}
msgcount=0
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
# 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:]'
}
#
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
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() {
_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"
info "<<<< finished action $file: SUCCESS"
fi
+ let "halts += _halts"
let "fatals += _fatals"
let "errors += _errors"
let "warnings += _warnings"
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
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@"
# 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"
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
umask 077
# these globals are set by process_action()
+halts=0
fatals=0
errors=0
warnings=0
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!"
for file in $files; do
[ -f "$file" ] || continue
+ [ "$halts" = "0" ] || continue
check_perms ${file%/*} # check containing dir
check_perms $file
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