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