From c0126ff1ef90513ce5df48fc41326704a2cef555 Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Sun, 4 Mar 2007 10:29:26 +0000 Subject: [PATCH] added ninjareport added ale to AUTHORS for ldap fixes adjusted sys handler to allow for turning off of sfdisk (#404071) --- AUTHORS | 3 +- ChangeLog | 38 +++++--- etc/backupninja.conf.in | 13 +++ examples/example.sys | 2 + handlers/sys | 59 +++++++----- handlers/sys.helper | 4 + src/Makefile.am | 6 +- src/backupninja.in | 8 ++ src/ninjareport.in | 205 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 301 insertions(+), 37 deletions(-) create mode 100755 src/ninjareport.in diff --git a/AUTHORS b/AUTHORS index 03a9de4..fad2bbb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,4 +20,5 @@ Brad Fritz -- trac patch garcondumonde@riseup.net Martin Krafft madduck@debian.org -- admingroup patch Anarcat -- lotsa patches -Jamie McClelland - cstream patches +Jamie McClelland -- cstream patches +ale -- ldap cleanup \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 98482ac..0bae02e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,32 +1,44 @@ version 0.9.5 -- unreleased + ninjareport + . Added first draft of method to aggregate reports from many servers into + one email. Requires logtail, rsync, configuration of reporthost, + reportdirectory and reportuser in backupninja.conf. Configure cron to + run once a day, and individual backupninjas not to report by email their + status, then enjoy one email report from all hosts, rather than multiple backupninja changes . Fixed checks on configuration files permissions, since the patch applied to fix #370396 broke this, especially for configuration files created with permissions 000 by an older ninjahelper version. . Enhanced portability for other platforms handler changes + ldap: + . Fixed shell command quoting issues, missing 'then' clauses, cleaned up + compress=yes to be less redundant and not create empty uncompressed file + mysql: + . Fixed case where odd combination of configuration options caused sqldump + backups to get overwritten with an empty file (Closes: #402679) + pgsql: + . Support configuring PGSQLUSER for real, and document it a bit; this + broken support actually prevented pgsql handler to work for VServers + (Closes: #396578) + rdiff: + . Added cstream support to allow for bandwidth limiting + rub + . Fixed typo in rub handler that caused it to not work + . Changed to use lib/vserver code + . Fixed fsck error sys: . Fixed typo breaking things for VServers. . Fix bug when vrootdir is on its own partition (Closes: #395928) . Better sfdisk error and output handling: should now properly warn when it does not manage to backup a partition table, and shut up when it succeeds (Closes: #396632) - rub - . Fixed typo in rub handler that caused it to not work - . Changed to use lib/vserver code - . Fixed fsck error - pgsql: - . Support configuring PGSQLUSER for real, and document it a bit; this - broken support actually prevented pgsql handler to work for VServers - (Closes: #396578) - mysql: - . Fixed case where odd combination of configuration options caused sqldump - backups to get overwritten with an empty file (Closes: #402679) - rdiff: - . Added cstream support to allow for bandwidth limiting + . Added option to not use sfdisk at all, useful for vserver/xen instances + that produce warnings about no harddisks found (Closes: #404071) fixed 'make install' bug that failed if /etc/backup.d already existed changed spaces to tabs in Makefile.am updated examples/Makefile.am and handlers/Makefile.am to include rsnap/rub files + version 0.9.4 -- October 6th, 2006 backupninja changes diff --git a/etc/backupninja.conf.in b/etc/backupninja.conf.in index 090561f..f7668a5 100644 --- a/etc/backupninja.conf.in +++ b/etc/backupninja.conf.in @@ -29,6 +29,19 @@ reportwarning = yes # the backup email report reportspace = no +# where to rsync the backupninja.log to be aggregated in +# a ninjareport +reporthost = + +# what user to connect to reporthost to sync the +# backupninja.log +reportuser = ninja + +# where on the reporthost should the report go +# NOTE: the name of the log will be used in the report, +# use a globally unique name, preferably the hostname +reportdirectory = /var/lib/backupninja/reports + # set to the administration group that is allowed to # read/write configuration files in /etc/backup.d admingroup = root diff --git a/examples/example.sys b/examples/example.sys index a05726b..a5b349b 100644 --- a/examples/example.sys +++ b/examples/example.sys @@ -26,7 +26,9 @@ # partitions = yes # partitionsfile = /var/backups/partitions.*.txt +# dosfdisk = yes # hardware = yes # hardwarefile = /var/backups/hardware.txt +# dohwinfo = yes diff --git a/handlers/sys b/handlers/sys index ce9c5b0..3e7f03e 100755 --- a/handlers/sys +++ b/handlers/sys @@ -33,6 +33,8 @@ else fi getconf packages yes +getconf dosfdisk yes +getconf dohwinfo yes if [ $os = "debian" ] then getconf packagesfile /var/backups/dpkg-selections.txt @@ -419,14 +421,18 @@ if [ $usevserver = yes ]; then fi if [ "$partitions" == "yes" ]; then + if [ "$dosfdisk" == "yes" ]; then if [ ! -x "$SFDISK" ]; then warning "can't find sfdisk, skipping sfdisk report." partitions="no" fi + fi + if [ "$dohwinfo" == "yes" ]; then if [ ! -x "$HWINFO" ]; then warning "can't find hwinfo, skipping partition report." partitions="no" fi + fi fi if [ "$hardware" == "yes" ]; then @@ -436,6 +442,29 @@ if [ "$hardware" == "yes" ]; then fi fi +## HARDWARE ############################# + +# +# here we use hwinfo to dump a table listing all the +# information we can find on the hardware of this machine +# + +if [ "$hardware" == "yes" ]; then + if [ "dohwinfo" == "yes" ]; then + if [ -f $hardwarefile ]; then + rm $hardwarefile + fi + touch $hardwarefile + echo -e "\n\n====================== summary ======================\n" >> $hardwarefile + debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile" + $HWINFO --short --cpu --network --disk --pci >> $hardwarefile + for flag in cpu network bios pci; do + echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile + $HWINFO --$flag >> $hardwarefile + done + fi +fi + ## PARTITIONS ############################# @@ -443,7 +472,8 @@ fi # these files can be used to directly partition a disk of the same size. if [ "$partitions" == "yes" ]; then - devices=`$SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` + if [ "$dosfdisk" == "yes" ]; then + devices=`$SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` if [ "$devices" == "" ]; then warning "No harddisks found" fi @@ -459,25 +489,10 @@ if [ "$partitions" == "yes" ]; then warning "The partition table for $dev could not be saved." fi done -fi - -## HARDWARE ############################# - -# -# here we use hwinfo to dump a table listing all the -# information we can find on the hardware of this machine -# - -if [ "$hardware" == "yes" ]; then - if [ -f $hardwarefile ]; then - rm $hardwarefile - fi - touch $hardwarefile - echo -e "\n\n====================== summary ======================\n" >> $hardwarefile - debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile" - $HWINFO --short --cpu --network --disk --pci >> $hardwarefile - for flag in cpu network disk bios pci; do - echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile - $HWINFO --$flag >> $hardwarefile - done + fi + if [ "$dohwinfo" == "yes" ]; then + debug "Using $HWINFO to get all available disk information" + echo -e "\n\n====================== $disk ======================\n" >> $hardwarefile + $HWINFO --disk >> $hardwarefile + fi fi diff --git a/handlers/sys.helper b/handlers/sys.helper index b6e3b8c..6451ae2 100644 --- a/handlers/sys.helper +++ b/handlers/sys.helper @@ -7,16 +7,19 @@ sys_wizard() { checkBox "new sys action" "check options" \ "packages" "list of all installed packages." on \ "partitions" "the partition table of all disks." on \ + "sfdisk" "use sfdisk to get partition information." on \ "hardware" "detailed hardware information" on [ $? = 1 ] && return; result="$REPLY" packages="packages = no" partitions="partitions = no" + sfdisk="dosfdisk = no" hardware="hardware = no" for opt in $result; do case $opt in '"packages"') packages="packages = yes";; '"partitions"') partitions="partitions = yes";; + '"sfdisk"') sfdisk="dosfdisk = yes";; '"hardware"') hardware="hardware = yes";; esac done @@ -24,6 +27,7 @@ sys_wizard() { cat > $next_filename < ninjahelper chmod ugo+x ninjahelper +ninjareport: $(srcdir)/ninjareport.in + rm -f ninjareport + $(edit) $(srcdir)/ninjareport.in > ninjareport + chmod ugo+x ninjareport diff --git a/src/backupninja.in b/src/backupninja.in index 02ffa25..ef959f2 100755 --- a/src/backupninja.in +++ b/src/backupninja.in @@ -433,9 +433,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" @@ -555,3 +558,8 @@ 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 diff --git a/src/ninjareport.in b/src/ninjareport.in new file mode 100755 index 0000000..b68efb8 --- /dev/null +++ b/src/ninjareport.in @@ -0,0 +1,205 @@ +#!@BASH@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# +# Ninjareport - generate a single simple report for a lot of hosts +# +# requires logtail +# +# Copyright (C) 2007 - riseup.net -- property is theft. + +# TODO: +# +# . check for logs that are never updating and warn +# . change constantly updating logs (maildir) to be more friendly +# . documentation +# . maybe make config option that lists all hosts that should report-in, and if +# one doesn't then warn +# . restrict rsync somehow? +# . abstract path for logtail +# . on the report master, the reportdirectory should be set where the reports will be going, note this + +mail=1 +display=0 + +process() { + +# look in the logfile for any lines like the following: +# Jan 20 01:02:46 Info: FINISHED: 2 actions run. 0 fatal. 0 error. 0 warning. +# +# note: some backups never finish, such as the maildir one, need to handle these +# perhaps by looking for FAILED messages? +# note2: what about logs that aren't being updated? this is a failure case and +# should be looked for +# note3: there are also these entries: +# Jan 20 14:00:01 Fatal: No backup actions configured in '/etc/backup.d', run ninjahelper! + +# The following has to be done without invoking a subshell (see BashFAQ #24) +logupdates=`maketemp ninjadata` + +/usr/sbin/logtail -f $host > $logupdates +grep FINISHED $logupdates | +( + fatal=0 + warning=0 + error=0 + + while read line + do + line_array=($line) + fatal=$(($fatal + ${line_array[8]})) + error=$(($error + ${line_array[10]})) + warning=$(($warning + ${line_array[12]})) + done + if (( $fatal || $warning || $error )); then + echo "`basename $host .log`: $fatal fatals found, $error errors found, $warning warnings found" >> $statusfile + echo "" >> $reportappend + echo "`basename $host .log` log entries since last ninjareport" >> $reportappend + echo "---------" >> $reportappend + cat $logupdates >> $reportappend + rm $logupdates + fi +) + +} + +generatereport() { + +reportfile=`maketemp ninjareport` + +# Generate a report, only if there are failures +if [ -s $statusfile ]; then + echo " backupninja mission failures - `date`" >> $reportfile + echo " --------------------------------------------------------------" >> $reportfile + echo "" >> $reportfile + cat $statusfile | column -t >> $reportfile + echo "" >> $reportfile + echo " log entries from failed reports" >> $reportfile + echo " -----------------------------------" >> $reportfile + cat $reportappend >> $reportfile +fi + +} + +usage() { + cat << EOF +This script generates a backupninja status report for all configured +systems. It requires that each status report is placed in a spot where +ninjareport can read it, reports are mailed to the reportemail +configured in @CFGDIR@/backupninja.conf. + +The following options are available: +-h, --help This usage message +-f, --conffile FILE Use FILE for the configuration instead + of @CFGDIR@/backupninja.conf +-m, --mail Mail the report to this address +-o, --out Don't mail the report, just display it + +EOF +} + +##################################################### +## MAIN + +conffile="@CFGDIR@/backupninja.conf" + +## process command line options + +while [ $# -ge 1 ]; do + case $1 in + -h|--help) + usage + exit 0 + ;; + -f|--conffile) + if [ -f $2 ]; then + conffile=$2 + else + echo "-f|--conffile option must be followed by an existing filename" + fatal "-f|--conffile option must be followed by an existing filename" + usage + fi + # we shift here to avoid processing the file path + shift + ;; + -m|--mail) + reportemail=$2 + shift + ;; + -o|--out) + mail=0 + display=1 + ;; + *) + echo "Unknown option $1" + usage + exit + ;; + esac + shift +done + +## Load and confirm basic configuration values + +# bootstrap +if [ ! -r "$conffile" ]; then + echo "Configuration file $conffile not found." + fatal "Configuration file $conffile not found." +fi + +# 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." + exit 1 + fi +else + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." + exit 1 + fi +fi + +# include shared functions +. $libdirectory/tools + +setfile $conffile + +getconf reportdirectory +getconf reportemail + +## Process each configuration file + +hosts=`find $reportdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '*.offset' | sort -n` + +if [ -z "$hosts" ]; then + echo "Fatal: No backupninja reports found in '$reportdirectory'!" + mail=0 +fi + +statusfile=`maketemp ninjastatus` +reportappend=`maketemp ninjaappend` + +for host in $hosts; do + [ -f "$host" ] || continue + # Check somehow that the file is a valid report file + process $host +done + +generatereport + +## mail the report to the report address or display it + +if [ -s $reportfile ]; then + if [ $mail == 1 ]; then + mail -s "backupninja mission failure report" $reportemail < $reportfile + fi +fi + +if [ $display == 1 ]; then + cat $reportfile +fi +