while xargs -I is the only ever existing replacement option defined by
[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=7200
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 [ $status == 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 $* -ct -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 -crlpz --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                 ccache | distcc)
145                         echo "cvs"
146                         return 0
147                 ;;
148                 samba_3* | rsync)
149                         echo "git"
150                         return 0
151                 ;;
152         esac
153
154         echo "svn"
155         return 0
156 }
157
158 locknesting=0
159
160 ############################
161 # grab a lock file. Not atomic, but close :)
162 # tries to cope with NFS
163 lock_file() {
164         if [ -z "$lock_root" ]; then
165           lock_root=`pwd`;
166         fi
167         lckf="$lock_root/$1"
168         machine=`cat "$lckf" 2> /dev/null | cut -d: -f1`
169         pid=`cat "$lckf" 2> /dev/null | cut -d: -f2`
170
171         if [ "$pid" = "$$" ]; then
172             locknesting=`expr $locknesting + 1`
173             echo "lock nesting now $locknesting"
174             return 0
175         fi
176
177         if test -f "$lckf"; then
178             test $machine = $host || {
179                 echo "lock file $lckf is valid for other machine $machine"
180                 return 1                 
181             }
182             kill -0 $pid && {
183                 echo "lock file $lckf is valid for process $pid"
184                 return 1
185             }
186             echo "stale lock file $lckf for $machine:$pid"
187             cat "$lckf"
188             /bin/rm -f "$lckf"
189         fi
190         echo "$host:$$" > "$lckf"
191         return 0
192 }
193
194 ############################
195 # unlock a lock file
196 unlock_file() {
197         if [ -z "$lock_root" ]; then
198           lock_root=`pwd`;
199         fi
200         if [ "$locknesting" != "0" ]; then
201             locknesting=`expr $locknesting - 1`
202             echo "lock nesting now $locknesting"
203         else 
204             lckf="$lock_root/$1"
205             /bin/rm -f "$lckf"
206         fi
207 }
208
209 ############################
210 # run make, and print trace
211 do_make() {
212
213   if [ x"$MAKE" = x ] 
214   then
215     MAKE=make
216   fi 
217
218   MMTIME=$MAXTIME
219   # some trees don't need as much time
220   case "$tree" in
221         rsync | tdb | talloc | libreplace | ccache | distcc)
222           if [ "$compiler" != "checker" ]; then
223               MMTIME=`expr $MMTIME / 5`
224           fi
225           ;;
226   esac
227   
228     
229   for t in $*; do
230     if [ x"$BUILD_FARM_NUM_JOBS" = x ]; then
231       echo "$MAKE $t"
232       ./timelimit $MMTIME "$MAKE" "$t"
233       status=$?
234     else
235       # we can parallelize everything and all targets
236       if [ x"$t" = xeverything ] || [ x"$t" = xall]; then
237         echo "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
238         ./timelimit $MMTIME "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
239         status=$?
240       else
241         echo "$MAKE $t"
242         ./timelimit $MMTIME "$MAKE" "$t"
243         status=$?
244       fi
245     fi
246
247     if [ $status != 0 ]; then
248       return $status;
249     fi
250
251   done
252
253   return 0
254 }      
255
256 ############################
257 # configure the tree
258 action_configure() {
259         if [ ! -x $srcdir/configure ]; then
260             ls -l $srcdir/configure
261             echo "$srcdir/configure is missing"
262             cstatus=255
263             echo "CONFIGURE STATUS: $cstatus"
264             return $cstatus;
265         fi
266         echo "CFLAGS=$CFLAGS"
267         echo configure options: $config_and_prefix
268         echo CC="$CCACHE $compiler" $srcdir/configure $config_and_prefix
269         CC="$CCACHE $compiler"
270         export CC
271         ./timelimit $MAXTIME $srcdir/configure $config_and_prefix
272         cstatus=$?
273         echo "CONFIGURE STATUS: $cstatus"
274         if [ -f config.h ]; then
275             echo "contents of config.h:"
276             cat config.h
277         fi
278         if [ -f include/config.h ]; then
279             echo "contents of include/config.h:"
280             cat include/config.h
281         fi
282         return $cstatus;
283 }
284
285 ############################
286 # show the configure log
287 action_config_log() {
288         if [ ! -f config.log ]; then
289             return 0;
290         fi
291         echo "contents of config.log:"
292         cat config.log
293         return 0;
294 }
295
296 copy_dir() {
297         Tsrc=$1
298         Tdst=$2
299         rsync -a --delete $Tsrc/ $Tdst
300 }
301
302 s4selftest_create() {
303         lock_file "s4selftest.lck" || {
304                 return 1;
305         }
306
307         rm -rf $s4selftest/
308         mkdir -p $s4selftest/source
309
310         copy_dir $builddir/bin $s4selftest/source/bin || {
311                 rm -rf $s4selftest/;
312                 unlock_file "s4selftest.lck";
313                 return 1;
314         }
315
316         copy_dir $srcdir/setup $s4selftest/source/setup || {
317                 rm -rf $s4selftest/;
318                 unlock_file "s4selftest.lck";
319                 return 1;
320         }
321
322         copy_dir $srcdir/../testprogs $s4selftest/testprogs || {
323                 rm -rf $s4selftest/;
324                 unlock_file "s4selftest.lck";
325                 return 1;
326         }
327
328         copy_dir $srcdir/selftest $s4selftest/source/selftest || {
329                 rm -rf $s4selftest/;
330                 unlock_file "s4selftest.lck";
331                 return 1;
332         }
333
334         copy_dir $srcdir/script $s4selftest/source/script || {
335                 rm -rf $s4selftest/;
336                 unlock_file "s4selftest.lck";
337                 return 1;
338         }
339
340         mkdir -p $s4selftest/source/scripting || {
341                 rm -rf $s4selftest/;
342                 unlock_file "s4selftest.lck";
343                 return 1;
344         }
345
346         copy_dir $srcdir/scripting/libjs $s4selftest/source/scripting/libjs || {
347                 rm -rf $s4selftest/;
348                 unlock_file "s4selftest.lck";
349                 return 1;
350         }
351         
352         unlock_file "s4selftest.lck"
353 }
354
355 s4selftest_update() {
356         lock_file "s4selftest.lck" || {
357                 return 1;
358         }
359
360         copy_dir $s4selftest $s4selftest.$tree.$compiler.$$ || {
361                 rm -rf $s4selftest.$tree.$compiler.$$;
362                 unlock_file "s4selftest.lck";
363                 return 1;
364         }
365
366         rm -rf $s4selftest.$tree.$compiler
367         mv $s4selftest.$tree.$compiler.$$ $s4selftest.$tree.$compiler
368
369         unlock_file "s4selftest.lck"
370 }
371
372 ############################
373 # build the tree
374 action_build() {
375         case "$tree" in
376         samba4)
377                 do_make everything
378                 bstatus=$?
379                 if test x"$bstatus" != x"0"; then
380                         # the 2nd 'make everything' is to work around a bug
381                         # in netbsd make. 
382                         do_make everything
383                         bstatus=$?
384                 fi
385
386                 if test x"$bstatus" != x"0"; then
387                         do_make testsuite
388                         bstatus=$?
389                 fi
390
391                 if test x"$bstatus" = x"0"; then
392                         s4selftest_create
393                 fi
394
395                 ;;
396         samba_3*)
397                 do_make proto everything torture
398                 bstatus=$?
399                 ;;
400         *)
401                 do_make all
402                 bstatus=$?
403                 ;;
404         esac
405
406         echo "BUILD STATUS: $bstatus"
407
408         return $bstatus
409 }
410
411 ############################
412 # show static analysis results
413 action_cc_checker() {
414
415         # default to passing the cc_checker
416         cccstatus=0
417
418         if [ -f ibm_checker.out ]; then
419                 cat ibm_checker.out
420                 cccstatus=`cat ibm_checker.out | grep '^\-\- ' | wc -l`
421         fi
422
423         echo "CC_CHECKER STATUS: $cccstatus"
424         return $cccstatus;      
425 }
426
427 ############################
428 # install the tree
429 action_install() {
430         if [ -d $prefix ]; then
431                 if [ "$noclean" != "yes" ]; then
432                     rm -rf $prefix
433                 fi
434         fi
435
436         do_make install
437         istatus=$?
438         echo "INSTALL STATUS: $istatus"
439         return $istatus;
440 }
441
442 ############################
443 # test the tree
444 action_test_samba() {
445         do_make test
446         totalstatus=$?
447         return "$totalstatus"
448 }
449
450 action_test_generic() {
451         CC="$compiler"
452         export CC
453         do_make installcheck
454         totalstatus=$?
455         echo "TEST STATUS: $totalstatus"
456         return "$totalstatus"
457 }
458
459 action_test_lorikeet_heimdal() {
460         CC="$compiler"
461         export CC
462         SOCKET_WRAPPER_DIR=`pwd`/sw
463         mkdir $SOCKET_WRAPPER_DIR
464         export SOCKET_WRAPPER_DIR
465         do_make check
466         totalstatus=$?
467         SOCKET_WRAPPER_DIR=
468         export SOCKET_WRAPPER_DIR
469         echo "TEST STATUS: $totalstatus"
470         return "$totalstatus"
471 }
472
473
474 #############################
475 # attempt some basic tests of functionaility
476 # starting as basic as possible, and getting incresingly complex
477
478 action_test() {
479         # Samba needs crufty code of its own for backward
480         # compatiblity.  I think a better way to do this in the future
481         # is to just call 'make installcheck'.
482         case "$tree" in
483         samba*|smb-build|pidl)
484             action_test_samba
485             ;;
486         lorikeet-heimdal*)
487             action_test_lorikeet_heimdal
488             ;;
489         *)
490             action_test_generic
491             ;;
492         esac
493 }
494
495 ###########################
496 # do a test build of a particular tree
497 test_tree() {
498         tree=$1
499         source=$2
500         compiler="$3"
501         shift
502         shift
503         shift
504         if [ "$compiler" = "gcc" ] && [ "$tree" != "ccache" ] && ccache -V > /dev/null; then
505             CCACHE="ccache"
506             export CCACHE
507         else
508             CCACHE=""
509         fi
510
511         # limit our resource usage
512         ulimit -t $MAXTIME 2> /dev/null
513
514         # max mem size 100M
515         ulimit -m $MAXMEM 2> /dev/null
516
517         # max file size 100M
518         # darn, this affects sparse files too! disable it
519         # ulimit -f 100000 2> /dev/null
520
521         # try and limit the number of open files to 150. That means we'll discover
522         # fd leaks faster
523         ulimit -n 150 2> /dev/null
524
525         # Keep stuff private
526         umask 077
527
528         if [ -z "$test_root" ]; then
529                 test_root=`pwd`
530         fi
531
532         log="build.$tree.$host.$compiler.log"
533         err="build.$tree.$host.$compiler.err"
534         sum="build.$tree.$host.$compiler.sum"
535         lck="build.$tree.lck"
536         srcdir="$test_root/$tree/$source"
537
538         lock_file "$lck" || {
539                 return
540         }
541
542         # work out what other trees this package depends on
543         deptrees=""
544         case "$tree" in
545             talloc | tdb)
546                 deptrees="libreplace";
547             ;;
548             ldb)
549                 deptrees="libreplace talloc tdb";
550             ;;
551                 samba-gtk)
552                 deptrees="samba4"
553                 ;;
554         esac
555
556         scm=`choose_scm "$tree"`
557
558         # pull the entries, if any
559         if fetch_revinfo "$tree" "$scm"; then
560             for d in $deptrees; do
561                 dscm=`choose_scm "$d"`
562                 if [ -f "$test_root/$d.$dscm" ]; then
563                     if [ "$d" != "$tree" ]; then
564                         cat "$test_root/$d.$dscm" >> $test_root/$tree.$scm
565                     fi
566                 fi
567             done
568             rm -f $test_root/$tree.$compiler.$scm.old
569             mv $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old
570             cp $test_root/$tree.$scm $test_root/$tree.$compiler.$scm
571             if cmp $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old > /dev/null; then
572                 echo "skip: $tree.$compiler nothing changed in $scm"
573                 cd $test_root
574                 send_logs_skip "$log" "$err"
575                 unlock_file "$lck"
576                 return
577             fi
578         fi
579
580         # pull the tree
581         fetch_tree "$tree" || {
582             cd $test_root
583             unlock_file "$lck"
584             return
585         }
586
587         if [ ! -x $srcdir/configure ] && [ "$tree" != "pidl" ]; then
588                 echo "skip: $tree.$compiler configure not present, try again next time!"
589                 cd $test_root
590                 unlock_file "$lck"
591                 return
592         fi
593
594         echo "Starting build of $tree.$compiler in process $$ at `date`"
595
596         case "$tree" in
597             tdb | talloc | ldb | libreplace)
598                 builddir="$test_root/tmp.$tree.$compiler"
599                 usingtmpbuild=1
600                 if [ -d $builddir ]; then
601                     rm -rf $builddir
602                 fi
603                 mkdir -p $builddir
604                 export builddir
605             ;;
606             *)
607                 builddir=$srcdir
608                 usingtmpbuild=0
609                 export builddir
610             ;;
611         esac
612         
613         if [ ! x$USER = x"" ]; then
614             whoami=$USER
615         else 
616             if [ ! x$LOGNAME = x"" ]; then
617                 whoami=$LOGNAME
618             else
619                 whoami=build
620             fi
621         fi
622
623         prefix="$test_root/prefix/$tree.$compiler"
624         mkdir -p "$prefix"
625
626         s4selftest=$test_root/s4selftest
627         export s4selftest
628
629         sw_config=$config
630
631         case "$tree" in
632         lorikeet-heimdal)
633                 sw_config="$config --enable-socket-wrapper"
634                 ;;
635         samba4)
636                 sw_config="$config --enable-socket-wrapper"
637                 sw_config="$sw_config --enable-nss-wrapper"
638                 ;;
639         samba_3*)
640                 sw_config="$config --enable-socket-wrapper"
641                 sw_config="$sw_config --enable-nss-wrapper"
642                 s4selftest_update "$tree" "$compiler" && {
643                         t="$s4selftest.$tree.$compiler/source"
644                         #sw_config="$sw_config --with-samba4srcdir=$t"
645                         t="$t/bin/smbtorture"
646                         sw_config="$sw_config --with-smbtorture4-path=$t"
647                 }
648                 ;;
649         samba-gtk)
650                 PKG_CONFIG_PATH="$test_root/prefix/samba4.$compiler/lib/pkgconfig"
651                 export PKG_CONFIG_PATH
652                 ;;
653         ldb)
654                 fetch_tree popt
655                 ;;
656         talloc)
657                 fetch_tree libreplace
658                 ;;
659         *)
660                 testsuite=testsuite
661                 ;;
662         esac
663
664         if [ "$LCOV_REPORT" = "yes" ]; then
665             GCOV_FLAGS="-ftest-coverage -fprofile-arcs"
666             GCOV_LIBS="-lgcov"
667             HOSTCC_CFLAGS="$HOSTCC_CFLAGS $GCOV_FLAGS" 
668             CFLAGS="$CFLAGS $GCOV_FLAGS" 
669             LDFLAGS="$LDFLAGS $GCOV_FLAGS $GCOV_LIBS" 
670             SHLD_FLAGS="$SHLD_FLAGS $GCOV_FLAGS $GCOV_LIBS"
671                 BNLD_FLAGS="$BNLD_FLAGS $GCOV_FLAGS $GCOV_LIBS"
672                 MDLD_FLAGS="$MDLD_FLAGS $GCOV_FLAGS $GCOV_LIBS"
673                 HOSTLD_FLAGS="$HOSTLD_FLAGS $GCOV_FLAGS $GCOV_LIBS"
674             export HOSTCC_CFLAGS CFLAGS LDFLAGS SHLD_FLAGS MDLD_FLAGS BNLD_FLAGS HOSTLD_FLAGS
675         fi
676
677         config_and_prefix="$sw_config --prefix=$prefix"
678
679         # see if we need to rebuild
680         sum_tree $test_root $tree $sum $scm
681         echo "CFLAGS=$CFLAGS $config_and_prefix" >> $sum
682
683         if cmp "$sum" "$sum.old" > /dev/null; then
684                 echo "skip: $tree.$compiler nothing changed"
685                 cd $test_root
686                 send_logs_skip "$log" "$err"
687                 unlock_file "$lck"
688                 echo "Ending build of $tree.$compiler in process $$ at `date`"
689                 return
690         fi
691
692         # we do need to rebuild - save the old sum
693         /bin/rm -f $sum.old
694         mv $sum $sum.old
695
696         actions="$*"
697         
698         if [ "$actions" = "" ]; then
699             actions="configure config_log build install test"
700         fi
701
702         # start the build
703         (
704                 # we all want to be able to read the output...
705                 LANG=C
706                 export LANG
707
708                 uname -a
709
710                 echo ""
711                 echo "build_test          : $build_test_id"
712                 echo "build_test.fns      : $build_test_fns_id"
713                 echo "local settings file : $build_test_settings_local_file"
714                 echo "local functions file: $build_test_fns_local_file"
715                 echo "used .fns file      : $build_test_used_fns_file"
716                 echo ""
717
718                 # we need to be able to see if a build farm machine is accumulating
719                 # stuck processes. We do this in two ways, as we don't know what style
720                 # of ps it will have
721                 ps xfuw 2> /dev/null
722                 ps -fu $USER 2> /dev/null
723
724                 echo "building $tree with CC=$compiler on $host at "`date`
725                 echo "builddir=$builddir"
726                 echo "prefix=$prefix"
727
728                 echo "Showing limits"
729                 ulimit -a 2> /dev/null
730
731                 # build the timelimit utility
732                 echo "Building timelimit"
733                 mkdir -p $builddir
734                 $compiler $TIMELIMIT_FLAGS -o $builddir/timelimit $test_root/timelimit.c || exit 1
735
736                 # the following is for non-samba builds only
737                 if [ -r $test_root/$tree.svn ]; then
738                   h_rev=`grep 'Revision: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
739                   if [ -n "$h_rev" ]; then
740                         echo "HIGHEST SVN REVISION: $h_rev"
741                   fi
742                   rev=`grep 'Last Changed Rev: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
743                   if [ -n "$rev" ]; then
744                         echo "BUILD REVISION: $rev"
745                   fi
746                 elif [ -r $test_root/$tree.git ]; then
747                   csha1=`cat $test_root/$tree.git |head -3 | tail -1`
748                   if [ -n "$csha1" ]; then
749                     echo "BUILD COMMIT REVISION: $csha1"
750                   fi
751                   cdate=`cat $test_root/$tree.git |head -4 | tail -1`
752                   if [ -n "$cdate" ]; then
753                     echo "BUILD COMMIT DATE: $cdate"
754                   fi
755                   ctime=`cat $test_root/$tree.git |head -2 | tail -1`
756                   if [ -n "$ctime" ]; then
757                     echo "BUILD COMMIT TIME: $ctime"
758                   fi
759                 fi
760
761                 if [ "$tree" = "pidl" ] 
762                 then
763                         cd $builddir
764                         perl ./Makefile.PL "$prefix"
765                 fi
766
767                 for action in $actions; do
768
769                     echo Running action $action
770
771                     date
772
773                     cd $builddir || exit 1
774                     export srcdir
775                     df .
776                     mount
777                     vmstat
778
779                     ( action_$action )
780                     action_status=$?
781                     
782                     if [ $action_status != 0 ]; then
783                         echo "ACTION FAILED: $action";
784                     else
785                         echo "ACTION PASSED: $action";
786                     fi
787                     
788                     if [ $action_status != 0 ]; then 
789                         break;
790                     fi
791
792                 done
793
794                 if [ "$LCOV_REPORT" = "yes" ]; then
795                     case "$tree" in
796                         lorikeet-heimdal*)
797                             lcov --directory $builddir --capture --output-file $builddir/$tree.lcov.info
798                             ;;
799                         *)
800                             # ugly hack for s4, as lcov is otherwise not able to find 
801                             # these files
802                             rm -f heimdal/lib/*/{lex,parse}.{gcda,gcno}
803                             lcov --base-directory $builddir --directory $builddir --capture --output-file $builddir/$tree.lcov.info
804                             ;;
805                     esac
806                     genhtml -o $builddir/coverage $builddir/$tree.lcov.info
807                 fi
808
809                 if [ "$noclean" = "yes" ]; then
810                     echo cleanup skipped!
811                 else
812                     echo cleaning up
813                     do_make clean
814                 fi
815                 date
816         ) > "$log" 2> "$err"
817
818         if [ "$LCOV_REPORT" = "yes" ]; then
819             chmod u=rwX,g=rX,o=rX -R $builddir/coverage
820             rsync -rct -q --password-file=.password -z --timeout=200 \
821                 $builddir/coverage/ $host@build.samba.org::lcov_data/$host/$tree/
822         fi
823
824         cd $test_root
825
826         /bin/rm -rf $prefix
827         if [ "$usingtmpbuild" = "1" ]; then
828             if [ "$noclean" = "yes" ]; then
829                 echo builddir cleanup skipped!
830             else
831                 /bin/rm -rf $builddir
832             fi
833         fi
834         # send the logs to the master site
835         send_logs "$log" "$err"
836
837         # cleanup
838         echo "Ending build of $tree.$compiler in process $$ at `date`"
839         unlock_file "$lck"
840 }
841
842 #########################################################
843 # if you want to build only one project at a time
844 # add 'global_lock' after 'per_run_hook' and
845 # 'global_unlock' to the end of the file
846 global_lock() {
847     lock_file "global.lck" || {
848         exit 0
849     }
850 }
851 global_unlock() {
852     unlock_file "global.lck"
853 }
854
855 #########################################################
856 # enable this on a per host basis only when needed please
857 # (at least for the moment)
858 kill_old_processes() {
859     # this should work on systems with linux like ps
860     (ps uxfw | grep /build | grep -v grep | egrep 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec' | awk '{print $2}' | xargs kill -9) 2> /dev/null
861     # and this should work on sysv style ps
862     (ps -fu $USER | grep /build | grep -v grep | egrep 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec' | awk '{print $2}' | xargs kill -9) 2> /dev/null
863 }
864
865 delete_old_svn_tree() {
866         otree=$1
867
868         test -z "$otree" && return 0;
869
870         rm -rf $otree
871         rm -rf $otree.svn
872         rm -rf $otree.*.svn
873         rm -rf s4selftest.$otree.*
874         rm -rf build.$otree.*
875 }
876
877 # this is a special fn that allows us to add a "special" hook to the build
878 # farm that we want to do to the build farm. never leave it empty. instead,
879 # use ":" as the fn body.
880 per_run_hook() {
881     # kill old processes on systems with a known problem
882     case $host in
883         nohost)
884             echo "just a placeholder";
885             ;;
886         tridge)
887             kill_old_processes
888             ;;
889         deckchair)
890             rm -f deckchair.fns
891             ;;
892     esac
893     # trim the log if too large
894     if [ "`wc -c < build.log`" -gt 2000000 ]; then
895         rm -f build.log
896     fi
897
898     delete_old_svn_tree "samba_3_2"
899 }
900
901
902 ######################################################
903 # main code that is run on each call to the build code
904 rsync --timeout=200 -q -az build.samba.org::build_farm/*.c .
905
906
907 # build.log can grow to an excessive size, trim it beyond 50M
908 if [ -f build.log ]; then
909   find build.log -size +100000 -exec /bin/rm '{}' \;
910 fi
911