#!/bin/bash # This script is intended to be run from a cron job by a local account # on a build machine--either debuild on debuild.mit.edu or builder on # linux-build-10.mit.edu. The account should have: # # * A keytab installed in $HOME/keytab containing a keytab for # daemon/HOSTNAME, which should have write access to the build # directory and apt repository. # # * A GPG secret key capable of signing packages for the apt # repository. # # * A file named $HOME/autodebathenify.config specifying shell # variable assignments for: # - error_addr: An email address to send errors to # - scripts_dir: Directory containing Debathena scripts (da, etc.) # - build_dir: Build directory location, up through "third". # - packages: A list of packages to keep up to date # It should also specify an environment variable assignment for # DEBATHENA_APT. # Send all output to a logfile. mkdir -p "$HOME/logs" logfile=$HOME/logs/$(date '+%Y-%m-%d-%H').log exec >$logfile 2>&1 # Read configuration; if it's not complete, do nothing. config=$HOME/autodebathenify.config . $HOME/autodebathenify.config if [ ! -n "$error_addr" -o ! -n "$scripts_dir" -o ! -n "$build_dir" -o \ ! -n "$packages" ]; then echo "Incomplete $config; doing nothing." exit fi suppress=$HOME/autodebathenify.suppress if [ -e "$suppress" ]; then if [ $(($(date +%s) - $(stat -c %Y "$suppress"))) -ge 86400 ]; then /usr/sbin/sendmail -t << EOM From: Autodebathenify <$error_addr> To: Autodebathenify <$error_addr> Subject: WARNING: Previous autodebathenify failure has not been addressed Autodebathenify previously experienced a failure on $(stat -c %y "$suppress") Please correct this failure immediately. Autodebathenify will stop running until $suppress is removed. EOM fi echo "$suppress exists; not running." exit fi # Send an error report to $error_addr and suppress future runs until a # human has checked things out. This function does not remove the run # file and does not exit the script. error() { touch "$suppress" /usr/sbin/sendmail -t << EOM From: Autodebathenify <$error_addr> To: Autodebathenify <$error_addr> Subject: Autodebathenify failure: $1 Autodebathenify has experienced a failure. Please see $logfile on $(hostname) for more details. Autodebathenify will stop running until $suppress is removed. EOM } # Similar to error, but do not suppress future runs. error_transient() { /usr/sbin/sendmail -t << EOM From: Autodebathenify <$error_addr> To: Autodebathenify <$error_addr> Subject: Autodebathenify failure: $1 Autodebathenify has experienced a transient failure. Autodebathenify will continue running; investigation is not required unless this failure repeats itself. If that happens, see $logfile on $(hostname) for more details. EOM } # Exit handler. If a subsidiary command exited with status 3, we # treat it as a transient failure; otherwise we treat it as a failure # requiring human investigation. In either case, remove the run file. on_failure() { if [ 3 -eq "$?" ]; then error_transient "$state" else error "$state" fi rm -f "$runfile" } # Make sure runs of this script do not overlap. runfile=$HOME/autodebathenify.running if [ -e "$runfile" ]; then # A previous invocation appears to still be running. pid=$(cat "$runfile") if ! kill -0 "$pid" 2>/dev/null; then # Okay, it's not really running. Perhaps the machine has # rebooted. Wait for manual intervention before running again. error "Stale runfile" else echo "$runfile exists; not running." fi exit fi echo $$ > $runfile trap on_failure EXIT set -e # Acquire credentials. state="acquiring credentials" export KRB5CCNAME=$HOME/autodebathenify.ccache kinit -k -t "$HOME/keytab" daemon/$(hostname --fqdn) aklog export PATH=${scripts_dir}:$PATH . "$scripts_dir"/debian-versions.sh state="changing to build dir" cd "$build_dir" for pkg in $packages; do state="changing to $pkg in build dir" cd "$pkg" for code in $DEBIAN_CODES; do state="updating $pkg for $code" echo "--- Updating $pkg for $code (amd64) ---" ./debathenify-"$pkg" "$code"-amd64 -A source binary upload echo "--- Updating $pkg for $code (i386) ---" ./debathenify-"$pkg" "$code"-i386 source binary upload done cd .. done state="cleaning up" kdestroy rm -f "$runfile" trap '' EXIT