#!/bin/ksh ######################################################################## # buildall - automated multi-platform build tool # # 10/09/97 - marcel - created # 10/13/97 - marcel - support shared build tree # 2/11/98 - marcel - updated for 4.0 Beta builds (need -update) # 2/26/98 - marcel - added -r, -t and host specifiers # 7/01/99 - robodan - added VAR=value ability # 8/01/99 - robodan - explicitly know about building on localhost # 10/15/99 - robodan - remove older OSes from build list # 2000/4/7 - robodan - Created mstone version ######################################################################## # # This script is intended to do a set of UNIX builds for a # given CVS module. It is designed to use 'rsh' between a # set of trusting hosts and use shared NFS storage with common # mount points (e.g. /u/username/...) # # To check if you have rights to rsh to a particular host, try: # rsh hostname "echo $PATH" # You may have to edit your .rhosts or /etc/hosts.equiv # # A target directory will be created based on the current date. # # A set of global build logs plus a log per platform are kept # in a log directory under the target # # It will checkout a copy of the source, duplicate it for # each platform and perform a set of remote builds in parallel. # The script will exit when all the work has been completed. # # Example usage: # cd ~/src; buildall msg # Result: # ~/src/19980210_40.1/ # ~/src/19980210_40.1/logs/... # ~/src/19980210_40.1/src/... # ... # # Buildhosts DEFAULT_BUILDHOSTS="kimo nugget vsync shave purgatory trex0" usage() { echo "" echo "usage: buildall [ make assigns... ] < -t | target > [ -r ] [ buildhosts... ]" echo " [ -t | --test]: just test rsh and report OS versions." echo " [-r | --respin]: rebuild in place using existing source." echo " [-p | --postbuild]: Execute post build command too." echo " [make assigns]: e.g. VARIANT=release" echo " : one of: mstone42" echo " [buildhosts...]: default [$DEFAULT_BUILDHOSTS]" echo "" exit 1 } ######################################################################## # Set these defaults and options for your desired build ######################################################################## # Target base destination directory DESTBASE=`pwd` # Can we do multiple ARCH builds in same source tree SHARESRC=yes DESCRIPTION="" BUILDHOSTS="" RESPIN="no" POSTBUILD="no" JUST_TEST="no" DESTTYPE="" CO_CMD="cvs -d $CVSROOT -q checkout" CHECKOUT="" CHECKOUT2="" #MOZCVSROOT=':pserver:anonymous@cvs.mozilla.org:/cvsroot' MOZCVSROOT=':pserver:robodan%netscape.com@cvs.mozilla.org:/cvsroot' MAKE="gmake" MK_ARG="" ARGS="$@" for ARG in "$@"; do # If this is a make assignment (FOO=whatever), add it to make command # Arguments with quotes in them dont go all the way through. # Make args trick: 'FOO=nop -j 2' # The pre-post arg stuff uses hostnames as a switch, ugly calling syntax. if [[ -n "`echo z$ARG | egrep '^z[A-Z0-9_]+=[^ ]'`" ]] ; then if [[ -n "$DESCRIPTION" ]] ; then echo "Arg after target is ignored! ($ARG)" continue fi if [[ -z "$BUILDHOSTS" ]] ; then # pre args MAKE="$MAKE $ARG" else # post args MK_ARG="$MK_ARG $ARG" fi continue fi # should we just rebuild todays latest source... if [[ "$ARG" = "-r" || "$ARG" = "--respin" || "$ARG" = "respin" ]]; then RESPIN="yes" continue fi # should we just run post build command... if [[ "$ARG" = "-p" || "$ARG" = "--postbuild" || "$ARG" = "postbuild" ]]; then POSTBUILD="yes" continue fi # should we just test remote connectivity and execute permissions... if [[ "$ARG" = "-t" || "$ARG" = "--test" ]]; then JUST_TEST="yes" RESPIN="yes" continue fi # We will pull source using: "$CHECKOUT" # And build on each machine: "cd $BUILDDIR && $BUILDCMD" # expand targets (but dont confuse hosts for targets (msg7)) # These will build just mstone # expand targets (but dont confuse hosts for targets (msg7)) if [[ "$BUILDCMD" = "" && "$ARG" = mailstone* ]]; then case ${ARG#mstone} in "") "42") DESTTYPE=_MSTONE42 MS_BRANCH="" #BUILDCMD="$MAKE $MK_ARG debug release" #POSTCMD="$MAKE $MK_ARG all_DBG.OBJ all_OPT.OBJ" BUILDCMD="$MAKE $MK_ARG rpackage" POSTCMD="$MAKE $MK_ARG all_OPT" ;; *) echo "Unknown mstone version in $ARG" echo "Try mstone42" exit 1;; esac DESCRIPTION="Mstone $MS_BRANCH" BUILDDIR=./mozilla/mstone CVSROOT=$MOZCVSROOT CHECKOUT="$CO_CMD $MS_BRANCH mozilla/mstone" # BUG No way to unpack perl, gd, and gnuplot before building continue fi ######################### # Other... ######################### # These will print some tools info if [[ "$ARG" = "tools" ]]; then CHECKOUT="$CO_CMD modules" BUILDDIR=. BUILDCMD="which gcc && ls -l /tools/ns/bin/gcc && which gcc-2.7.2.1 && ls -l /tools/ns/bin/gcc-2.7.2.1" continue fi ######################### # Everything else is assumed to be a hostname ######################### BUILDHOSTS="$ARG $BUILDHOSTS" done # for ARG in $*; do if [[ "$BUILDHOSTS" = "" ]]; then BUILDHOSTS=$DEFAULT_BUILDHOSTS fi if [[ "$BUILDCMD" = "" && "$JUST_TEST" = "no" ]]; then usage fi ######################################################################## # You shouldn't have to modify stuff below here too much ######################################################################## # Who and Where are we PROG=buildall RSH=rsh SYS=`uname -s` echo SYS=$SYS if [[ "$SYS" = "HP-UX" ]]; then RSH=remsh fi ######################################################################## # Simple log output function ######################################################################## log() { # echo "[`date +\"%Y/%m/%d %H:%M:%S\"`] $PROG: $*" echo "`date +\"%H:%M:%S\"` $PROG: $*" } ######################################################################## # Error ######################################################################## quit() { log "$* (exiting)..." exit 1 } # Where should the work be done REV=1 WORKDIR=$DESTBASE/`date +"%Y%m%d"`$DESTTYPE.$REV LASTWORKDIR=$WORKDIR LASTREV=$REV while [[ -d $WORKDIR ]]; do LASTREV=$REV let "REV= REV + 1" LASTWORKDIR=$WORKDIR WORKDIR=$DESTBASE/`date +"%Y%m%d"`$DESTTYPE.$REV done if [[ "$RESPIN" = "yes" ]]; then WORKDIR=$LASTWORKDIR REV=$LASTREV fi BUILDREV=$REV if [[ ! -d $WORKDIR && "$RESPIN" = "yes" ]]; then quit "missing expected respin workdir ($WORKDIR)" fi mkdir -p $WORKDIR # Where to send logs LOGDIR=$WORKDIR/logs [[ -d $LOGDIR ]] || mkdir $LOGDIR # What tool to use for compressed tar if [[ -x /tools/ns/bin/tar ]] ; then # ROBDAN 9-15-98 for Linux TAR=/tools/ns/bin/tar else TAR=tar fi SRCDIR=$WORKDIR/src SRCTAR=$WORKDIR/src.tar.gz ######################################################################## # The function which extracts the source and prepares for copies ######################################################################## prepare_source() { log "Preparing source code..." mkdir $SRCDIR (cd $SRCDIR; log "Extracting source in $SRCDIR..."; log "$CHECKOUT > $LOGDIR/cvs-co.txt"; $CHECKOUT > $LOGDIR/cvs-co.txt; RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $CHECKOUT"; fi if [[ "$CHECKOUT2" != "" ]]; then log "$CHECKOUT2 >> $LOGDIR/cvs-co.txt"; $CHECKOUT2 >> $LOGDIR/cvs-co.txt; RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $CHECKOUT2"; fi fi log "Listing source..."; ls -Rl > $LOGDIR/src-ls-Rl.txt log "Archiving source..." $TAR czf $SRCTAR . ) RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): cannot prepare source"; else log "Source extraction complete"; fi } ######################################################################## # The function which does a build ######################################################################## do_rbuild() { OSDEST=$1 if [ "$SHARESRC" = "yes" ]; then RSRCDIR=$SRCDIR else RSRCDIR=$WORKDIR/$OSDEST fi [[ -d $RSRCDIR ]] || mkdir -p $RSRCDIR cd $RSRCDIR; # do any late variable expansions RAWCMD=$BUILDCMD BUILDCMD=$(eval echo $RAWCMD) if [[ $RHOST = localhost ]] ; then log "Build locally for $OSDEST ($BUILDCMD)..."; cd $BUILDDIR && pwd && $BUILDCMD && echo $PROG: Success RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST build"; fi log "Completed local build..." return fi if [[ "$SHARESRC" != "yes" ]]; then log "Extracting source for $OSDEST..."; $RSH $RHOST -n "cd $RSRCDIR && pwd && $TAR xzf $SRCTAR"; RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST source extraction"; fi else log "Using common source in $RSRCDIR"; fi log "Building for $OSDEST ($BUILDCMD)..."; $RSH $RHOST -n "cd $RSRCDIR/$BUILDDIR && pwd && $BUILDCMD && echo $PROG: Success" RET=$? if [[ $RET -ne 0 ]]; then quit "### Failed($RET): $OSDEST build"; fi log "Completed $OSDEST..."; } buildhost() { RHOST=$1 log "Query $RHOST configuration..."; if [[ $RHOST = localhost ]] ; then uname -s > /tmp/$$.$RHOST 2>&1 else $RSH $RHOST -n "uname -s" > /tmp/$$.$RHOST 2>&1 RET=$? if [[ $RET -ne 0 ]]; then quit "..[$RHOST] ### Failed($RET): $RSH $RHOST -n \"uname -s\""; fi fi ROSTYPE=`tail -1 /tmp/$$.$RHOST` if [[ "$ROSTYPE" = "AIX" ]]; then $RSH $RHOST -n "uname -v" > /tmp/$$.$RHOST 2>&1 ROSTYPE=${ROSTYPE}`tail -1 /tmp/$$.$RHOST` fi if [[ $RHOST = localhost ]] ; then uname -r > /tmp/$$.$RHOST 2>&1 else $RSH $RHOST -n "uname -r" > /tmp/$$.$RHOST 2>&1 fi ROSREV=`tail -1 /tmp/$$.$RHOST` rm /tmp/$$.$RHOST if [[ $RHOST = localhost ]] ; then OSDEST=`hostname | cut -f1 -d.`-${ROSTYPE}${ROSREV} else OSDEST=${RHOST}-${ROSTYPE}${ROSREV} fi log "..Building on [$OSDEST]..." REV=1 # find unique logfile name OSLOG=$LOGDIR/$OSDEST.$REV while [[ -f $OSLOG ]]; do let "REV = REV + 1" OSLOG=$LOGDIR/$OSDEST.$REV done if [[ "$JUST_TEST" = "yes" ]]; then echo "$PROG: Success" > $OSLOG else ( do_rbuild $OSDEST ) > $OSLOG 2>&1 fi grep "$PROG: Success" $OSLOG > /dev/null RET=$? if [[ $RET -eq 0 ]]; then RESULT="SUCCESS"; else RESULT="FAILURE($RET)"; fi log "..Completed [$OSDEST] <$RESULT>."; } ######################################################################## # The function which initiates all the builds ######################################################################## do_builds() { log "Launching builds..." for HOST in $BUILDHOSTS; do buildhost $HOST & done } ######################################################################## # main ######################################################################## main() { if [[ "$JUST_TEST" = "yes" ]]; then log "Automated test starting..." else log "Automated build of [$DESCRIPTION] starting..." fi log "" log " ARGS = $ARGS" log " BUILDHOSTS = $BUILDHOSTS" log " WORKDIR = $WORKDIR" log " SRCDIR = $SRCDIR" log " LOGDIR = $LOGDIR" log " CHECKOUT = $CHECKOUT" log " BUILDDIR = $BUILDDIR" log " BUILDCMD = $BUILDCMD" log " RESPIN = $RESPIN" log "" [[ "$RESPIN" = "no" ]] && prepare_source do_builds log "Waiting for all builds to complete..." wait log "All builds completed." if [[ -n "$POSTCMD" && "$POSTBUILD" = "yes" ]] ; then log "Running post build command." REV=1 # find unique logfile name POSTLOG=$LOGDIR/postbuild.$REV while [[ -f $POSTLOG ]]; do let "REV = REV + 1" POSTLOG=$LOGDIR/postbuild.$REV done echo "Dir $SRCDIR/$BUILDDIR" > $POSTLOG echo "Cmd $POSTCMD" >> $POSTLOG (cd $SRCDIR/$BUILDDIR && $POSTCMD && echo $PROG: Success) >> $POSTLOG 2>&1 log "Post build command completed." elif [[ -n "$POSTCMD" ]] ; then echo "Skipping post build command: $POSTCMD" fi } REV=1 PROGLOG=$LOGDIR/$PROG.$REV while [[ -f $PROGLOG ]]; do REV=`expr $REV + 1` PROGLOG=$LOGDIR/$PROG.$REV done main | tee $PROGLOG 2>&1 exit 0