put killbysubdir in right directory
[amitay/build-farm.git] / build_test.fns
1 #!/bin/sh -*- mode: shell-script; sh-indentation: 8; indent-tabs-mode: t; -*-
2
3 # build_farm -- distributed build/test architecture for samba, rsync, etc
4
5 # Copyright (C) 2001 by Andrew Tridgell <tridge@samba.org>
6 # Copyright (C) 2001 by Andrew Bartlett <abartlet@samba.org>
7 # Copyright (C) 2001, 2003 by Martin Pool <mbp@samba.org>
8
9 # default maximum runtime for any command
10 MAXTIME=12000
11 # default maximum memory size (100M) for any command
12 MAXMEM=100000
13 RUN_FROM_BUILD_FARM=yes
14 export RUN_FROM_BUILD_FARM
15
16 deptrees="";
17
18 build_test_fns_id='$Id$'
19
20 #############################
21 # build a signature of a tree, used to see if we
22 # need to rebuild 
23 sum_tree() {
24         sum_tree_test_root=$1
25         sum_tree_tree=$2
26         sum_tree_sum=$3
27         sum_tree_scm=$4
28         find $sum_tree_test_root/$sum_tree_tree -type f -print | grep -v version.h | sort | xargs sum > $sum_tree_sum
29         sum build_test build_test.fns >> $sum_tree_sum
30
31         if [ -f "$host.fns" ]; then
32             sum $host.fns >> $sum_tree_sum
33         else
34             sum generic.fns >> $sum_tree_sum
35         fi
36
37         if [ -f "$test_root/$tree.$scm" ]; then
38             sum "$test_root/$tree.$scm" >> $sum_tree_sum
39         fi
40
41         for d in $deptrees; do
42             dscm=`choose_scm "$d"`
43             if [ -f "$test_root/$d.$dscm" ]; then
44                 sum "$test_root/$d.$dscm" >> $sum_tree_sum
45             fi
46         done
47 }
48
49 #############################
50 # send the logs to the master site
51 send_logs() {
52         if [ "$nologreturn" = "yes" ]; then
53                 echo "skipping log transfer"
54         else
55                 log="$1"
56                 err="$2"
57                 shift
58                 shift
59                 chmod 0644 "$log" "$err"
60
61                 # xargs -i is implemented differently or not at all.
62                 # GNU xargs did not implement "-I" until 4.2.9:
63                 xargs --version 2>&1 | grep "^GNU xargs" > /dev/null
64                 status=$?
65                 if [ x"$status" = x"0" ]; then
66                         XARGS_IS_GNU=yes
67                 fi
68
69                 if [ x"$XARGS_IS_GNU" = x"yes" ]; then
70                         XARGS_I="xargs -i"
71                 else
72                         XARGS_I="xargs -I '{}'"
73                 fi
74
75                 find $log -size +40000 | $XARGS_I sh -c 'dd if={} bs=1024 count=20000 of={}.tmp && mv {}.tmp {} &&  echo "\n***LOG TRUNCATED***" >> {}'
76                 find $err -size +40000 | $XARGS_I sh -c 'dd if={} bs=1024 count=20000 of={}.tmp && mv {}.tmp {} &&  echo "\n***LOG TRUNCATED***" >> {}'
77
78                 rsync $* -c -q --password-file=.password -z --timeout=200 \
79                     "$log" "$err" $host@build.samba.org::build_farm_data/
80         fi
81 }
82
83 #############################
84 # send the logs when they haven't changed
85 # the aim is to just update the servers timestamp.
86 # sending with a very large rsync block size does this
87 # with minimal network traffic
88 send_logs_skip() {
89     touch "$1" "$2"
90     send_logs "$1" "$2" -B 10000000
91 }
92
93 ############################
94 # fetch the latest copy of the tree
95 fetch_tree() {
96         if [ "$norsync" = "yes" ]; then
97                 echo "skipping tree transfer"
98         else
99                 fetchtree=$1
100                 if rsync --exclude=autom4te.cache/ --exclude=.svn/ --exclude=.git/ \
101                         --delete-excluded -q --partial --timeout=200 -ctrlpz --delete --ignore-errors \
102                         samba.org::ftp/unpacked/$fetchtree/ $test_root/$fetchtree; then
103                         echo "transferred $fetchtree OK"
104                 else
105                         echo "transfer of $fetchtree failed code $?"
106                         return 1
107                 fi
108         fi
109         return 0
110 }
111
112 ############################
113 # fetch the latest copy of the rev meta info
114 fetch_revinfo() {
115     tree=$1
116     scm=$2
117
118     test -z "$scm" && return 1
119     test x"$scm" = x"unknown" && return 1
120     test x"$scm" = x"cvs" && return 1
121
122     if [ "$norsync" = "yes" ]; then
123         echo "skipping .revinfo.$scm transfer"
124     else
125         if [ -r $test_root/$tree.$scm ]; then
126                 rm -f $test_root/$tree.$scm.old
127             mv $test_root/$tree.$scm $test_root/$tree.$scm.old
128         fi
129         rsync -q --timeout=200 -clz --ignore-errors \
130             samba.org::ftp/unpacked/$tree/.revinfo.$scm $test_root/$tree.$scm
131     fi
132     if [ -r $test_root/$tree.$scm ]; then
133         return 0;
134     fi
135     return 1
136 }
137
138 ############################
139 # choose the scm that is used for the given project
140 choose_scm() {
141         tree=$1
142
143         case "$tree" in
144                 samba* | rsync | libreplace | talloc | tdb | ldb | pidl | ccache*)
145                         echo "git"
146                         return 0
147                 ;;
148         esac
149
150         echo "svn"
151         return 0
152 }
153
154 locknesting=0
155
156 ############################
157 # grab a lock file. Not atomic, but close :)
158 # tries to cope with NFS
159 lock_file() {
160         if [ -z "$lock_root" ]; then
161           lock_root=`pwd`;
162         fi
163         lckf="$lock_root/$1"
164         machine=`cat "$lckf" 2> /dev/null | cut -d: -f1`
165         pid=`cat "$lckf" 2> /dev/null | cut -d: -f2`
166
167         if [ "$pid" = "$$" ]; then
168             locknesting=`expr $locknesting + 1`
169             echo "lock nesting now $locknesting"
170             return 0
171         fi
172
173         if test -f "$lckf"; then
174             test $machine = $host || {
175                 echo "lock file $lckf is valid for other machine $machine"
176                 return 1                 
177             }
178             kill -0 $pid && {
179                 echo "lock file $lckf is valid for process $pid"
180                 return 1
181             }
182             echo "stale lock file $lckf for $machine:$pid"
183             cat "$lckf"
184             /bin/rm -f "$lckf"
185         fi
186         echo "$host:$$" > "$lckf"
187         return 0
188 }
189
190 ############################
191 # unlock a lock file
192 unlock_file() {
193         if [ -z "$lock_root" ]; then
194           lock_root=`pwd`;
195         fi
196         if [ "$locknesting" != "0" ]; then
197             locknesting=`expr $locknesting - 1`
198             echo "lock nesting now $locknesting"
199         else 
200             lckf="$lock_root/$1"
201             /bin/rm -f "$lckf"
202         fi
203 }
204
205 ############################
206 # run make, and print trace
207 do_make() {
208
209   if [ x"$MAKE" = x ] 
210   then
211     MAKE=make
212   fi 
213
214   MMTIME=$MAXTIME
215   # some trees don't need as much time
216   case "$tree" in
217         rsync | tdb | talloc | libreplace | ccache*)
218           if [ "$compiler" != "checker" ]; then
219               MMTIME=`expr $MMTIME / 5`
220           fi
221           ;;
222   esac
223   
224     
225   for t in $*; do
226     if [ x"$BUILD_FARM_NUM_JOBS" = x ]; then
227       echo "$MAKE $t"
228       ./timelimit $MMTIME "$MAKE" "$t"
229       status=$?
230     else
231       # we can parallelize everything and all targets
232       if [ x"$t" = xeverything ] || [ x"$t" = xall]; then
233         echo "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
234         ./timelimit $MMTIME "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
235         status=$?
236       else
237         echo "$MAKE $t"
238         ./timelimit $MMTIME "$MAKE" "$t"
239         status=$?
240       fi
241     fi
242
243     if [ $status != 0 ]; then
244       return $status;
245     fi
246
247   done
248
249   return 0
250 }      
251
252 ############################
253 # configure the tree
254 action_configure() {
255         if [ ! -x $srcdir/configure -a -r $srcdir/Makefile.PL ]; then
256                 perl $srcdir/Makefile.PL PREFIX="$prefix"
257                 cstatus=$?
258                 echo "CONFIGURE STATUS: $cstatus"
259                 return $cstatus;
260         fi
261         if [ ! -x $srcdir/configure ]; then
262             ls -l $srcdir/configure
263             echo "$srcdir/configure is missing"
264             cstatus=255
265             echo "CONFIGURE STATUS: $cstatus"
266             return $cstatus;
267         fi
268         echo "CFLAGS=$CFLAGS"
269         echo configure options: $config_and_prefix
270         echo CC="$CCACHE $compiler" $srcdir/configure $config_and_prefix
271         CC="$CCACHE $compiler"
272         export CC
273         ./timelimit $MAXTIME $srcdir/configure $config_and_prefix
274         cstatus=$?
275         if [ x"$cstatus" != x"0" ]; then
276                 if [ -f config.log ]; then
277                         echo "contents of config.log:"
278                         cat config.log
279                 fi
280                 if [ -f bin/config.log ]; then
281                         echo "contents of config.log:"
282                         cat bin/config.log
283                 fi
284         fi
285         echo "CONFIGURE STATUS: $cstatus"
286         return $cstatus;
287 }
288
289 ############################
290 # show the configure log
291 action_config_log() {
292     log_files="config.log bin/config.log"
293     for f in $log_files; do
294         if [ -f $f ]; then
295             echo "contents of config.log:"
296             cat $f
297             return 0;
298         fi
299     done
300     return 0
301 }
302
303 ############################
304 # show the config.h
305 action_config_header() {
306     hdr_files="config.h include/config.h bin/default/config.h bin/default/source4/include/config.h bin/default/source3/include/config.h"
307     for h in $hdr_files; do
308         if [ -f $h ]; then
309             echo "contents of $h:"
310             cat $h
311             return 0;
312         fi
313     done
314     return 0;
315 }
316
317 copy_dir() {
318         Tsrc=$1
319         Tdst=$2
320         pwd
321         echo rsync -a --delete $Tsrc/ $Tdst
322         rsync -a --delete $Tsrc/ $Tdst || return 1
323         return 0
324 }
325
326 s4selftest_create() {
327         lock_file "s4selftest.lck" || {
328             echo "s4selftest_create: already locked"
329             return 1;
330         }
331
332         # we currently only need smbtorture
333         mkdir -p $s4selftest/source/bin
334         echo "s4selftest_create: rsync -aL $builddir/bin/smbtorture.static $s4selftest/source/bin/smbtorture"
335         rsync -aL $builddir/bin/smbtorture.static $s4selftest/source/bin/smbtorture || {
336             echo "s4selftest_create: failed rsync"
337             unlock_file "s4selftest.lck";
338             return 1;
339         }
340
341         unlock_file "s4selftest.lck"
342         echo "s4selftest_create: OK"
343         return 0;
344
345         copy_dir $builddir/bin $s4selftest/source/bin || {
346                 rm -rf $s4selftest/;
347                 unlock_file "s4selftest.lck";
348                 return 1;
349         }
350
351         copy_dir $srcdir/setup $s4selftest/source/setup || {
352                 rm -rf $s4selftest/;
353                 unlock_file "s4selftest.lck";
354                 return 1;
355         }
356
357         copy_dir $srcdir/../testprogs $s4selftest/testprogs || {
358                 rm -rf $s4selftest/;
359                 unlock_file "s4selftest.lck";
360                 return 1;
361         }
362
363         copy_dir $srcdir/selftest $s4selftest/source/selftest || {
364                 rm -rf $s4selftest/;
365                 unlock_file "s4selftest.lck";
366                 return 1;
367         }
368
369         copy_dir $srcdir/script $s4selftest/source/script || {
370                 rm -rf $s4selftest/;
371                 unlock_file "s4selftest.lck";
372                 return 1;
373         }
374
375         mkdir -p $s4selftest/source/scripting || {
376                 rm -rf $s4selftest/;
377                 unlock_file "s4selftest.lck";
378                 return 1;
379         }
380
381         unlock_file "s4selftest.lck"
382 }
383
384 s4selftest_update() {
385         lock_file "s4selftest.lck" || {
386             echo "s4selftest_update LOCKED"
387             return 1;
388         }
389
390         echo tmp.$tree.$compiler.$$ >tmp.dirname
391         tempdir=`cut -b1-32 tmp.dirname`
392         rm -f tmp.dirname
393
394         echo "COPYING $s4selftest => $tempdir"
395         copy_dir $s4selftest $tempdir || {
396                 rm -rf $tempdir;
397                 unlock_file "s4selftest.lck";
398                 echo "s4selftest_update COPY FAILED"
399                 return 1;
400         }
401
402         echo "RENAMING $tempdir $s4selftest.$tree.$compiler"
403         rm -rf $s4selftest.$tree.$compiler
404         mv $tempdir $s4selftest.$tree.$compiler
405
406         unlock_file "s4selftest.lck"
407         echo "s4selftest_update OK"
408         return 0
409 }
410
411 ############################
412 # build the tree
413 action_build() {
414         case "$tree" in
415         samba_4*)
416                 do_make everything
417                 bstatus=$?
418                 if test x"$bstatus" != x"0"; then
419                         # the 2nd 'make everything' is to work around a bug
420                         # in netbsd make. 
421                         do_make everything
422                         bstatus=$?
423                 fi
424
425                 if test x"$bstatus" != x"0"; then
426                         do_make testsuite
427                         bstatus=$?
428                 fi
429
430                 if test x"$bstatus" = x"0"; then
431                         s4selftest_create
432                 fi
433
434                 ;;
435         samba_3*)
436                 do_make everything torture
437                 bstatus=$?
438                 ;;
439         *)
440                 do_make all
441                 bstatus=$?
442                 ;;
443         esac
444
445         echo "BUILD STATUS: $bstatus"
446
447         return $bstatus
448 }
449
450 ############################
451 # show static analysis results
452 action_cc_checker() {
453
454         # default to passing the cc_checker
455         cccstatus=0
456
457         if [ -f ibm_checker.out ]; then
458                 cat ibm_checker.out
459                 cccstatus=`cat ibm_checker.out | grep '^\-\- ' | wc -l`
460         fi
461
462         echo "CC_CHECKER STATUS: $cccstatus"
463         return $cccstatus;      
464 }
465
466 ############################
467 # install the tree
468 action_install() {
469         if [ -d $prefix ]; then
470                 if [ "$noclean" != "yes" ]; then
471                     rm -rf $prefix
472                 fi
473         fi
474
475         do_make install
476         istatus=$?
477         echo "INSTALL STATUS: $istatus"
478         return $istatus;
479 }
480
481 ############################
482 # test the tree
483 action_test_samba() {
484         do_make test
485         totalstatus=$?
486         # if we produced a test summary then show it
487         [ -f st/summary ] && {
488             echo "TEST SUMMARY"
489             cat st/summary
490         }
491         return "$totalstatus"
492 }
493
494 action_test_generic() {
495         CC="$compiler"
496         export CC
497         do_make installcheck
498         totalstatus=$?
499         echo "TEST STATUS: $totalstatus"
500         return "$totalstatus"
501 }
502
503 action_test_lorikeet_heimdal() {
504         CC="$compiler"
505         export CC
506         SOCKET_WRAPPER_DIR=`pwd`/sw
507         mkdir $SOCKET_WRAPPER_DIR
508         export SOCKET_WRAPPER_DIR
509         do_make check
510         totalstatus=$?
511         SOCKET_WRAPPER_DIR=
512         export SOCKET_WRAPPER_DIR
513         echo "TEST STATUS: $totalstatus"
514         return "$totalstatus"
515 }
516
517
518 #############################
519 # attempt some basic tests of functionaility
520 # starting as basic as possible, and getting incresingly complex
521
522 action_test() {
523         # Samba needs crufty code of its own for backward
524         # compatiblity.  I think a better way to do this in the future
525         # is to just call 'make installcheck'.
526         case "$tree" in
527         samba*|smb-build|pidl)
528             action_test_samba
529             ;;
530         lorikeet-heimdal*)
531             action_test_lorikeet_heimdal
532             ;;
533         *)
534             action_test_generic
535             ;;
536         esac
537 }
538
539 ###########################
540 # do a test build of a particular tree
541 test_tree() {
542         tree=$1
543         source=$2
544         compiler="$3"
545         shift
546         shift
547         shift
548         if [ "$compiler" = "gcc" ] && [ "$tree" != "ccache" ] && [ "$tree" != "ccache-maint" ] && ccache -V > /dev/null; then
549             CCACHE="ccache"
550             export CCACHE
551         else
552             CCACHE=""
553         fi
554
555         # limit our resource usage
556         ulimit -t $MAXTIME 2> /dev/null
557
558         # max mem size 100M
559         ulimit -m $MAXMEM 2> /dev/null
560
561         # max file size 100M
562         # darn, this affects sparse files too! disable it
563         # ulimit -f 100000 2> /dev/null
564
565         # try and limit the number of open files to 250. That means we'll discover
566         # fd leaks faster
567         ulimit -n 250 2> /dev/null
568
569         # Keep stuff private
570         umask 077
571
572         if [ -z "$test_root" ]; then
573                 test_root=`pwd`
574         fi
575
576         log="build.$tree.$host.$compiler.log"
577         err="build.$tree.$host.$compiler.err"
578         sum="build.$tree.$host.$compiler.sum"
579         lck="build.$tree.lck"
580         srcdir="$test_root/$tree/$source"
581
582         lock_file "$lck" || {
583                 return
584         }
585
586         # work out what other trees this package depends on
587         deptrees=""
588         case "$tree" in
589             samba-gtk)
590                 deptrees="samba_4_0_test"
591                 ;;
592         esac
593
594         scm=`choose_scm "$tree"`
595
596         # pull the entries, if any
597         if fetch_revinfo "$tree" "$scm"; then
598             for d in $deptrees; do
599                 dscm=`choose_scm "$d"`
600                 if [ -f "$test_root/$d.$dscm" ]; then
601                     if [ "$d" != "$tree" ]; then
602                         cat "$test_root/$d.$dscm" >> $test_root/$tree.$scm
603                     fi
604                 fi
605             done
606             rm -f $test_root/$tree.$compiler.$scm.old
607             mv $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old
608             cp $test_root/$tree.$scm $test_root/$tree.$compiler.$scm
609             if cmp $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old > /dev/null; then
610                 echo "skip: $tree.$compiler nothing changed in $scm"
611                 cd $test_root
612                 send_logs_skip "$log" "$err"
613                 unlock_file "$lck"
614                 return
615             fi
616         fi
617
618         # pull the tree
619         fetch_tree "$tree" || {
620             cd $test_root
621             unlock_file "$lck"
622             return
623         }
624
625         if [ ! -x $srcdir/configure ] && [ "$tree" != "pidl" ]; then
626                 echo "skip: $tree.$compiler configure not present, try again next time!"
627                 cd $test_root
628                 unlock_file "$lck"
629                 return
630         fi
631
632         echo "Starting build of $tree.$compiler in process $$ at `date`"
633
634         case "$tree" in
635             libreplace)
636                 builddir="$test_root/tmp.$tree.$compiler"
637                 usingtmpbuild=1
638                 if [ -d $builddir ]; then
639                     rm -rf $builddir
640                 fi
641                 mkdir -p $builddir
642                 export builddir
643             ;;
644             *)
645                 builddir=$srcdir
646                 usingtmpbuild=0
647                 export builddir
648             ;;
649         esac
650         
651         if [ ! x$USER = x"" ]; then
652             whoami=$USER
653         else 
654             if [ ! x$LOGNAME = x"" ]; then
655                 whoami=$LOGNAME
656             else
657                 whoami=build
658             fi
659         fi
660
661         prefix="$test_root/prefix/$tree.$compiler"
662         mkdir -p "$prefix"
663
664         s4selftest=$test_root/s4selftest
665         export s4selftest
666
667         sw_config=$config
668
669         case "$tree" in
670         lorikeet-heimdal)
671                 sw_config="$config --enable-socket-wrapper"
672                 ;;
673         samba_4*)
674                 sw_config="$config --enable-socket-wrapper"
675                 sw_config="$sw_config --enable-nss-wrapper"
676                 sw_config="$sw_config --enable-uid-wrapper"
677                 ;;
678         samba_3*)
679                 sw_config="$config --enable-socket-wrapper"
680                 sw_config="$sw_config --enable-nss-wrapper"
681                 s4selftest_update "$tree" "$compiler" && {
682                         t="$s4selftest.$tree.$compiler/source"
683                         #sw_config="$sw_config --with-samba4srcdir=$t"
684                         t="$t/bin/smbtorture"
685                         sw_config="$sw_config --with-smbtorture4-path=$t"
686                 }
687                 ;;
688         samba-gtk)
689                 PKG_CONFIG_PATH="$test_root/prefix/samba_4_0_test.$compiler/lib/pkgconfig"
690                 export PKG_CONFIG_PATH
691                 ;;
692         *)
693                 testsuite=testsuite
694                 ;;
695         esac
696
697         if [ "$LCOV_REPORT" = "yes" ]; then
698             GCOV_FLAGS="--coverage"
699             CFLAGS="$CFLAGS $GCOV_FLAGS" 
700             LDFLAGS="$LDFLAGS $GCOV_FLAGS" 
701             export CFLAGS LDFLAGS
702         fi
703
704         config_and_prefix="$sw_config --prefix=$prefix"
705
706         # see if we need to rebuild
707         sum_tree $test_root $tree $sum $scm
708         echo "CFLAGS=$CFLAGS $config_and_prefix" >> $sum
709
710         if cmp "$sum" "$sum.old" > /dev/null; then
711                 echo "skip: $tree.$compiler nothing changed"
712                 cd $test_root
713                 send_logs_skip "$log" "$err"
714                 unlock_file "$lck"
715                 echo "Ending build of $tree.$compiler in process $$ at `date`"
716                 return
717         fi
718
719         # we do need to rebuild - save the old sum
720         /bin/rm -f $sum.old
721         mv $sum $sum.old
722
723         actions="$*"
724         
725         if [ "$actions" = "" ]; then
726             actions="configure config_log config_header build install test"
727         fi
728
729         # start the build
730         (
731         {
732                 # we all want to be able to read the output...
733                 LANG=C
734                 export LANG
735
736                 uname -a
737
738                 echo ""
739                 echo "build_test          : $build_test_id"
740                 echo "build_test.fns      : $build_test_fns_id"
741                 echo "local settings file : $build_test_settings_local_file"
742                 echo "local functions file: $build_test_fns_local_file"
743                 echo "used .fns file      : $build_test_used_fns_file"
744                 echo ""
745
746                 # we need to be able to see if a build farm machine is accumulating
747                 # stuck processes. We do this in two ways, as we don't know what style
748                 # of ps it will have
749                 ps xfuw 2> /dev/null
750                 ps -fu $USER 2> /dev/null
751
752                 echo "building $tree with CC=$compiler on $host at "`date`
753                 echo "builddir=$builddir"
754                 echo "prefix=$prefix"
755
756                 echo "Showing limits"
757                 ulimit -a 2> /dev/null
758
759                 # the following is for non-samba builds only
760                 if [ "$scm" = "svn" -a -r $test_root/$tree.svn ]; then
761                   h_rev=`grep 'Revision: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
762                   if [ -n "$h_rev" ]; then
763                         echo "HIGHEST SVN REVISION: $h_rev"
764                   fi
765                   rev=`grep 'Last Changed Rev: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
766                   if [ -n "$rev" ]; then
767                         echo "BUILD REVISION: $rev"
768                   fi
769                 elif [ "$scm" = "git" -a -r $test_root/$tree.git ]; then
770                   csha1=`cat $test_root/$tree.git |head -3 | tail -1`
771                   if [ -n "$csha1" ]; then
772                     echo "BUILD COMMIT REVISION: $csha1"
773                   fi
774                   cdate=`cat $test_root/$tree.git |head -4 | tail -1`
775                   if [ -n "$cdate" ]; then
776                     echo "BUILD COMMIT DATE: $cdate"
777                   fi
778                   ctime=`cat $test_root/$tree.git |head -2 | tail -1`
779                   if [ -n "$ctime" ]; then
780                     echo "BUILD COMMIT TIME: $ctime"
781                   fi
782                 fi
783
784                 if [ -x $test_root/killbysubdir ]; then
785                     $test_root/killbysubdir $builddir
786                 fi
787
788                 for action in $actions; do
789
790                     echo Running action $action
791
792                     date
793
794                     cd $builddir || exit 1
795                     export srcdir
796                     df .
797                     mount
798                     vmstat
799
800                     ( action_$action )
801                     action_status=$?
802
803                     df .
804
805                     if [ $action_status != 0 ]; then
806                         echo "ACTION FAILED: $action";
807                     else
808                         echo "ACTION PASSED: $action";
809                     fi
810                     
811                     if [ $action_status != 0 ]; then 
812                         break;
813                     fi
814
815                 done
816
817                 if [ "$LCOV_REPORT" = "yes" ]; then
818                     case "$tree" in
819                         lorikeet-heimdal*)
820                             lcov --directory $builddir --capture --output-file $builddir/$tree.lcov.info
821                             ;;
822                         samba_3_master*)
823                             lcov --base-directory $builddir --directory $builddir/.. --capture --output-file $builddir/$tree.lcov.info
824                             ;;
825                         samba_4*)
826                             # ugly hack for s4, as lcov is otherwise not able to find 
827                             # these files
828                             rm -f heimdal/lib/*/{lex,parse,sel-lex}.{gcda,gcno}
829                             lcov --base-directory $builddir --directory $builddir/.. --capture --output-file $builddir/$tree.lcov.info
830                             ;;
831                         *)
832                             lcov --base-directory $builddir --directory $builddir --capture --output-file $builddir/$tree.lcov.info
833                             ;;
834                     esac
835                     genhtml -o $builddir/coverage $builddir/$tree.lcov.info
836                 fi
837
838                 if [ "$noclean" = "yes" ]; then
839                     echo cleanup skipped!
840                 else
841                     echo cleaning up
842                     do_make clean
843                 fi
844                 date
845         } 3>&2 2>&1 1>&3 | tee "$err"
846         ) > "$log" 2>&1
847         # be aware the above channel swap may sometimes result in unordered
848         # stdout/stderr merge
849
850         if [ "$LCOV_REPORT" = "yes" ]; then
851             chmod u=rwX,g=rX,o=rX -R $builddir/coverage
852             rsync -rct -q --password-file=.password -z --timeout=200 \
853                 $builddir/coverage/ $host@build.samba.org::lcov_data/$host/$tree/
854         fi
855
856         cd $test_root
857
858         /bin/rm -rf $prefix
859         if [ "$usingtmpbuild" = "1" ]; then
860             if [ "$noclean" = "yes" ]; then
861                 echo builddir cleanup skipped!
862             else
863                 /bin/rm -rf $builddir
864             fi
865         fi
866         # send the logs to the master site
867         send_logs "$log" "$err"
868
869         # cleanup
870         echo "Ending build of $tree.$compiler in process $$ at `date`"
871         unlock_file "$lck"
872 }
873
874 #########################################################
875 # if you want to build only one project at a time
876 # add 'global_lock' after 'per_run_hook' and
877 # 'global_unlock' to the end of the file
878 global_lock() {
879     lock_file "global.lck" || {
880         exit 0
881     }
882 }
883 global_unlock() {
884     unlock_file "global.lck"
885 }
886
887 delete_old_tree() {
888         otree=$1
889
890         test -z "$otree" && return 0;
891
892         rm -rf $otree
893         rm -rf $otree.svn
894         rm -rf $otree.*.svn
895         rm -rf $otree.git
896         rm -rf $otree.*.git
897         rm -rf s4selftest.$otree.*
898         rm -rf build.$otree.*
899 }
900
901 # this is a special fn that allows us to add a "special" hook to the build
902 # farm that we want to do to the build farm. never leave it empty. instead,
903 # use ":" as the fn body.
904 per_run_hook() {
905     # build the timelimit utility
906     echo "Building timelimit"
907     mkdir -p $builddir
908     $compiler $TIMELIMIT_FLAGS -o $builddir/timelimit $test_root/timelimit.c || exit 1
909
910     # build the killbysubdir utility
911     echo "Building killbysubdir"
912     $compiler -o $test_root/killbysubdir $test_root/killbysubdir.c
913
914     # kill old processes on systems with a known problem
915     case $host in
916         nohost)
917             echo "just a placeholder";
918             ;;
919         deckchair)
920             rm -f deckchair.fns
921             ;;
922     esac
923     # trim the log if too large
924     if [ "`wc -c < build.log`" -gt 2000000 ]; then
925         rm -f build.log
926     fi
927
928     delete_old_tree "samba_3_2"
929     delete_old_tree "samba_3_2_test"
930     delete_old_tree "samba4"
931     delete_old_tree "samba_4_0_test"
932     delete_old_tree "samba_3_X_test"
933     delete_old_tree "samba_3_X_devel"
934 }
935
936
937 ######################################################
938 # main code that is run on each call to the build code
939 rsync --timeout=200 -q -az build.samba.org::build_farm/*.c .
940
941
942 # build.log can grow to an excessive size, trim it beyond 50M
943 if [ -f build.log ]; then
944   find build.log -size +100000 -exec /bin/rm '{}' \;
945 fi
946