Added bitcron(1) and a cron to update and HUP the ircd
git-svn-id: svn+ssh://svn.ipng.nl/usr/share/subversion/repositories/irc.efnet.nl@7 0a436592-62d7-4152-98a5-b7e29e440240
This commit is contained in:
329
cron/bitcron
Executable file
329
cron/bitcron
Executable file
@ -0,0 +1,329 @@
|
||||
#!/usr/local/bin/bash
|
||||
|
||||
# Original author: Pim van Pelt <pim@bit.nl>
|
||||
# Taken from OSS publication upstream:
|
||||
# debit.bit.nl:/debian/dists/stable/main/binary-i386/bit-cron-1.9-20060627.02.deb
|
||||
# and modified for use at Google.
|
||||
#
|
||||
# Author: Pim van Pelt <pim@google.com>
|
||||
|
||||
# This is the master cron file format. It is designed to be quiet
|
||||
# and not shout anything at all to stdout/stderr in normal use.
|
||||
#
|
||||
# Usage: bitcron [-n] /path/to/crondefinition.cron [arg [arg ..]]
|
||||
#
|
||||
# This program eats either one or two arguments from the commandline.
|
||||
# If -n is given as the first argument, output is sent to stdout rather
|
||||
# than MAILTO or ESCALATE_MAILTO (this is a `dryrun'). The next argument
|
||||
# is a filename consisting of the cron definition. The file is sourced
|
||||
# and executed, but within a framework that makes crons much easier to
|
||||
# live with. You SHOULD have the filename of your crondefinition end
|
||||
# in ".cron", so it is apparent to other people that this is indeed
|
||||
# a cron definition. All other arguments are passed to the crontab's
|
||||
# main function, called bitcron_main; see below.
|
||||
#
|
||||
# The cron definition file consists of the following shell variables:
|
||||
#
|
||||
# PATH: Optional. You can set a standard path for your cron to search
|
||||
# programs in. Note that cron sets a minimal path, so you probably need
|
||||
# this if you are going to call programs from weird places.
|
||||
# Example: PATH=$PATH
|
||||
#
|
||||
# AUTHOR: Mandatory. Your full name, so we can track the author in case
|
||||
# something goes horribly wrong.
|
||||
# Example: AUTHOR="Pim van Pelt"
|
||||
#
|
||||
# NAME: Mandatory. The name of your script. This MUST be a terse
|
||||
# descriptive name consisting of [A-Za-z0-9\-\_], and in particular
|
||||
# no whitespace. It's used in logs and mails.
|
||||
# Example: NAME="example"
|
||||
#
|
||||
# MASTERLOG: Optional. If this is set, the transcript of the log is copied
|
||||
# to this file upon completion. If it is not set, the transcript is silently
|
||||
# deleted. Please make sure that this filename is writable for the calling
|
||||
# user, and that its name reveals who wrote it (including $NAME is a good
|
||||
# idea.
|
||||
# Example: MASTERLOG="/var/log/cron-${NAME}.log"
|
||||
#
|
||||
# MAILTO: Optional. If this is set, the transcript of the log is mailed to
|
||||
# this user using /usr/sbin/sendmail -t, in the event of no warnings,
|
||||
# errors, or fatal errors, aka 'if all went well'. If it is not set, the
|
||||
# mail is not sent on succesful completion of this cronjob. Please use
|
||||
# with care if your cron runs often.
|
||||
# Example: MAILTO="pim+noise@google.com"
|
||||
#
|
||||
# ESCALATE_MAILTO: Mandatory. If this is set, the transcript of the log
|
||||
# is mailed to this user using /usr/sbin/sendmail -t, in the event of
|
||||
# any warning, error or fatal error, aka 'if anything borked'. Please
|
||||
# make sure that this address is not a single person, but rather a role
|
||||
# account. This ensures better closure and continuity.
|
||||
# Example: ESCALATE_MAILTO="maps-alerts@google.com"
|
||||
#
|
||||
# Variables your script MUST NOT change are:
|
||||
# ERR, WRN, HOSTNAME, FATAL, FQDN
|
||||
#
|
||||
# Your cron-definition does not shebang. It begins with these variables.
|
||||
# It then has at least one function called bitcron_main(), in which you write
|
||||
# your cron just like you normally would, but each step is prepended by a
|
||||
# short oneliner describing what you are doing and appended with a line
|
||||
# stating you are done doing it, followed by an empty line.
|
||||
#
|
||||
# In your bitcron_main() script, you have three functions at your disposal:
|
||||
# warning $TEXT
|
||||
# error $TEXT
|
||||
# fatal $TEXT
|
||||
#
|
||||
# where warning() prints the TEXT and increments the warning counter, error()
|
||||
# increments the error counter and fatal() increments the error counter and
|
||||
# immediately halts execution of the cron.
|
||||
#
|
||||
# For example:
|
||||
# bitcron_main()
|
||||
# {
|
||||
# echo "Running rsync"
|
||||
# rsync blabla || warning "Could not rsync"
|
||||
# echo "Done (rsync)"
|
||||
# echo ""
|
||||
#
|
||||
# echo "Doing something crucial"
|
||||
# /usr/local/bin/crucial.sh blabla || \
|
||||
# fatal "Could not do the crucial stuff, aborting!"
|
||||
# echo "Done (crucial)"
|
||||
# echo ""
|
||||
#
|
||||
# echo "Succesfully executed the cron"
|
||||
# }
|
||||
#
|
||||
# In the event of a fatal error (retval of crucial.sh != 0), the line
|
||||
# 'echo "Done (crucial)"' will not be executed, rather the cronscript
|
||||
# stops and mails to the escalation mail address that there was a serious
|
||||
# error which needs human intervention.
|
||||
#
|
||||
# Return values of bitcron depend on the presence of errors or warnings.
|
||||
# If there are no errors nor warnings, 0 is returned to the calling shell.
|
||||
# If there are errors, 127 is returned. If there are no errors, but there
|
||||
# are warnings, 126 is returned. If you somewhere set the RETVAL variable
|
||||
# (which is optional), that value is returned instead.
|
||||
#
|
||||
# Please note that your bitcron_main() function MUST NOT use exit. This messes up
|
||||
# the clean execution of this script, prohibiting it from mailing or
|
||||
# returning a decent exitcode to the calling shell.
|
||||
#
|
||||
|
||||
# BITCRON_SEARCHPATH="/usr/local/cronscripts/ /etc/cronscripts/ ./"
|
||||
BITCRON_SEARCHPATH="~/cronscripts/ ./"
|
||||
BITCRON_REPORTTOOL="/usr/sbin/sendmail -t"
|
||||
|
||||
function fatal()
|
||||
{
|
||||
echo ""
|
||||
echo "===== FATAL ====="
|
||||
echo $1
|
||||
echo "===== FATAL ====="
|
||||
ERR=$(($ERR + 1))
|
||||
FATAL=1;
|
||||
bitcron_end
|
||||
}
|
||||
|
||||
function error()
|
||||
{
|
||||
echo ""
|
||||
echo "===== ERROR ====="
|
||||
echo $1
|
||||
echo "===== ERROR ====="
|
||||
ERR=$(($ERR + 1))
|
||||
}
|
||||
|
||||
function warning()
|
||||
{
|
||||
echo ""
|
||||
echo "===== WARNING ====="
|
||||
echo $1
|
||||
echo "===== WARNING ====="
|
||||
WRN=$(($WRN + 1))
|
||||
}
|
||||
|
||||
function bitcron_report()
|
||||
{
|
||||
if [ $WRN -eq 0 -a $ERR -eq 0 ]; then
|
||||
if [ ! -z "$MAILTO" ]; then
|
||||
(
|
||||
echo "From: $HOSTNAME $NAME <`whoami`@$FQDN>"
|
||||
echo "To: $MAILTO"
|
||||
echo "Subject: bitcron $NAME - succesful"
|
||||
echo "Date: `date '+%a, %d %b %Y %T %z'`"
|
||||
echo "Errors-To: $MAILTO"
|
||||
echo "Reply-To: $MAILTO"
|
||||
echo "X-bitcron: $NAME"
|
||||
echo "X-Precedence: automatic"
|
||||
echo ""
|
||||
echo "Dear reader,"
|
||||
echo ""
|
||||
echo "This is the $0 program on $HOSTNAME informing"
|
||||
echo "you I have succesfully executed the bitcron $NAME."
|
||||
echo ""
|
||||
echo "The log that I have for this cronjob follows:"
|
||||
cat $LOG
|
||||
echo ""
|
||||
echo "This mail is purely FYI, user intervention is not required."
|
||||
echo ""
|
||||
echo "-- "
|
||||
echo "Cheers,"
|
||||
echo " $HOSTNAME"
|
||||
) | ${BITCRON_REPORTTOOL}
|
||||
fi
|
||||
else
|
||||
(
|
||||
echo "From: $HOSTNAME $NAME <`whoami`@$FQDN>"
|
||||
echo "To: $ESCALATE_MAILTO"
|
||||
if [ ! -z "$MAILTO" ]; then
|
||||
echo "CC: $MAILTO"
|
||||
fi
|
||||
if [ $FATAL -eq 0 ]; then
|
||||
echo "Subject: bitcron $NAME - $ERR error(s), $WRN warning(s)"
|
||||
else
|
||||
echo "Subject: bitcron $NAME - FATAL - $ERR error(s), $WRN warning(s)"
|
||||
fi
|
||||
echo "Date: `date '+%a, %d %b %Y %T %z'`"
|
||||
echo "Errors-To: $ESCALATE_MAILTO"
|
||||
echo "Reply-To: $ESCALATE_MAILTO"
|
||||
echo "X-Precedence: automatic"
|
||||
echo "X-bitcron: $NAME"
|
||||
echo "X-Errors: $ERR"
|
||||
echo "X-Warnings: $WRN"
|
||||
echo ""
|
||||
echo "Dear reader,"
|
||||
echo ""
|
||||
echo "This is the $0 program on $HOSTNAME informing"
|
||||
echo "you that there was a problem running the bitcron $NAME."
|
||||
echo ""
|
||||
echo "The logfile that lead up to this:"
|
||||
cat $LOG
|
||||
echo ""
|
||||
echo "I hope you can deal with this situation ASAP."
|
||||
echo ""
|
||||
echo "-- "
|
||||
echo "Cheers,"
|
||||
echo " $HOSTNAME"
|
||||
) | ${BITCRON_REPORTTOOL}
|
||||
fi
|
||||
}
|
||||
|
||||
function bitcron_begin()
|
||||
{
|
||||
if [ -z "$MASTERLOG" ]; then
|
||||
LOG="/tmp/bitcron-$NAME.$$"
|
||||
else
|
||||
LOG="${MASTERLOG}.$$"
|
||||
fi
|
||||
rm -f -- $LOG
|
||||
exec 3>&1 4>&2 1>$LOG 2>&1
|
||||
WRN=0
|
||||
ERR=0
|
||||
FATAL=0
|
||||
FQDN=$(hostname)
|
||||
HOSTNAME=$(hostname -s)
|
||||
if [ "A`echo $FQDN | grep '\.'`" = "A" ]; then
|
||||
FQDN="${FQDN}.corp.google.com"
|
||||
fi
|
||||
|
||||
echo "Beginning $NAME cronjob at `date`"
|
||||
echo ""
|
||||
}
|
||||
|
||||
function bitcron_end()
|
||||
{
|
||||
echo ""
|
||||
echo "Done with $NAME cronjob at `date`"
|
||||
echo ""
|
||||
echo "There were $ERR error(s) and $WRN warning(s)"
|
||||
if [ $FATAL -ne 0 ]; then
|
||||
echo "This script had a fatal error!"
|
||||
fi
|
||||
|
||||
exec 1>&3 2>&4
|
||||
|
||||
bitcron_report
|
||||
|
||||
if [ ! -z "$MASTERLOG" ]; then
|
||||
cp -f -- "$LOG" "$MASTERLOG"
|
||||
fi
|
||||
rm -f -- $LOG >/dev/null 2>&1
|
||||
if [ ! -z $RETVAL ]; then
|
||||
exit $RETVAL
|
||||
elif [ $ERR -ne 0 ]; then
|
||||
exit 127
|
||||
elif [ $WRN -ne 0 ]; then
|
||||
exit 126
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
function bitcron_usage()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: bitcron [-n] /path/to/crondefinition.cron [arg [arg ..]]"
|
||||
echo ""
|
||||
echo "Please read the bitcron script. It has documentation at the"
|
||||
echo "top of the file. Look in $0 for more details."
|
||||
echo "-- Author: Pim van Pelt <pim@google.com>"
|
||||
}
|
||||
|
||||
# Here goes!
|
||||
if [ $# -lt 1 ]; then
|
||||
bitcron_usage
|
||||
exit 128
|
||||
fi
|
||||
|
||||
# See if we are in dryrun mode.
|
||||
if [ $1 = "-n" ]; then
|
||||
BITCRON_REPORTTOOL="/bin/cat"
|
||||
shift
|
||||
fi
|
||||
|
||||
BITCRON_DEFINITION=$1
|
||||
shift;
|
||||
#
|
||||
# Search through paths if the cron definition was not an absolute path.
|
||||
#
|
||||
if [ ${BITCRON_DEFINITION%%/*} ]; then
|
||||
for BITCRON_DIR in ${BITCRON_SEARCHPATH}; do
|
||||
if [ -r ${BITCRON_DIR}${BITCRON_DEFINITION} ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
else
|
||||
BITCRON_DIR=""
|
||||
fi
|
||||
|
||||
if [ ! -r ${BITCRON_DIR}${BITCRON_DEFINITION} ]; then
|
||||
echo "bitcron: Unreadable cron definition: ${BITCRON_DIR}${BITCRON_DEFINITION}"
|
||||
if [ ${BITCRON_DEFINITION%%/*} ]; then
|
||||
echo "I tried in: ${BITCRON_SEARCHPATH}"
|
||||
fi
|
||||
bitcron_usage
|
||||
exit 128
|
||||
fi
|
||||
|
||||
|
||||
. ${BITCRON_DIR}${BITCRON_DEFINITION}
|
||||
|
||||
if [ -z "$NAME" ]; then
|
||||
echo "bitcron: Missing mandatory variable NAME in ${BITCRON_DIR}${BITCRON_DEFINITION}"
|
||||
bitcron_usage
|
||||
exit 128
|
||||
fi
|
||||
if [ -z "$AUTHOR" ]; then
|
||||
echo "bitcron: Missing mandatory variable AUTHOR in ${BITCRON_DIR}${BITCRON_DEFINITION}"
|
||||
bitcron_usage
|
||||
exit 128
|
||||
fi
|
||||
if [ -z "$ESCALATE_MAILTO" ]; then
|
||||
echo "bitcron: Missing mandatory variable ESCALATE_MAILTO in ${BITCRON_DIR}${BITCRON_DEFINITION}"
|
||||
bitcron_usage
|
||||
exit 128
|
||||
fi
|
||||
|
||||
bitcron_begin
|
||||
bitcron_main $*
|
||||
bitcron_end
|
28
cron/update.cron
Normal file
28
cron/update.cron
Normal file
@ -0,0 +1,28 @@
|
||||
NAME="ircd_update"
|
||||
AUTHOR="Pim van Pelt"
|
||||
MAILTO="pim@ipng.nl"
|
||||
ESCALATE_MAILTO="pim@ipng.nl"
|
||||
MASTERLOG="/home/ircd/cronscripts/logs/${NAME}.log"
|
||||
|
||||
PATH=/usr/local/bin:/usr/bin:/bin:/home/ircd/bin
|
||||
|
||||
function bitcron_main()
|
||||
{
|
||||
DIFF="/tmp/${NAME}.diff.$$"
|
||||
|
||||
cd ~/ircd/etc || fatal "No config directory"
|
||||
|
||||
svn diff -r HEAD > $DIFF || fatal "Could not read the SVN repository"
|
||||
|
||||
[ ! -r $DIFF ] && fatal "Cannot read diff file"
|
||||
|
||||
[ -s $DIFF ] && {
|
||||
echo "Incorporating these diffs from the repository"
|
||||
cat $DIFF
|
||||
svn update || error "Could not update local copy"
|
||||
echo "Sending -HUP to the ircd"
|
||||
pkill -HUP ircd || error "Could not send HUP to ircd"
|
||||
}
|
||||
|
||||
rm -f -- $DIFF
|
||||
}
|
Reference in New Issue
Block a user