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