Cleanup the build root as default action if build system is broken.
[tools/build.git] / build
1 #!/bin/bash
2 # Script to build a package.  It uses init_buildsystem to setup a chroot
3 # building tree.  This script needs a directory as parameter.  This directory
4 # has to include sources and a recipe file.
5 #
6 # BUILD_ROOT        here the packages will be built
7 #
8 ################################################################
9 #
10 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
11 #
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License version 2 or 3 as
14 # published by the Free Software Foundation.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program (see the file COPYING); if not, write to the
23 # Free Software Foundation, Inc.,
24 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 #
26 ################################################################
27
28 # some VMs do not allow to specify the init process...
29 if test "$0" = /sbin/init ; then
30     exec /.build/build "$@"
31 fi
32
33 test -z "$BUILD_DIR" -a -e /.build/build.data -a -z "$BUILD_IGNORE_2ND_STAGE" && BUILD_DIR=/.build
34 test -z "$BUILD_DIR" && BUILD_DIR=/usr/lib/build
35 test -z "$BUILD_ROOT" && BUILD_ROOT=/var/tmp/build-root
36 test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs"
37
38 export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG
39 export BUILD_DIST
40
41 icecream=0
42 definesnstuff=()
43 repos=()
44 old_packages=()
45
46 # slurp in vm support
47 . "$BUILD_DIR/build-vm"
48
49 # slurp in recipe support
50 . "$BUILD_DIR/build-recipe"
51
52 # slurp in package binary support
53 . "$BUILD_DIR/build-pkg"
54
55 # need to restore build root owner for non-root builds
56 browner=
57
58 # Default uid:gid for the build user
59 ABUILD_UID=399
60 ABUILD_GID=399
61
62 DO_INIT=true
63 DO_BUILD=true
64 DO_INIT_TOPDIR=true
65 DO_LINT=
66 DO_CHECKS=true
67 SHORT_CIRCUIT=false
68 NO_TOPDIR_CLEANUP=false
69 CLEAN_BUILD=
70 REMOVE_CCACHE=
71 KEEP_PACKS=
72 RECIPEFILES=()
73 SRCDIR=
74 BUILD_JOBS=
75 ABUILD_TARGET=
76 CREATE_BASELIBS=
77 USEUSEDFORBUILD=
78 LIST_STATE=
79
80 RUNNING_IN_VM=
81 RPMLIST=
82 RELEASE=
83 REASON=
84 NOROOTFORBUILD=
85 LOGFILE=
86 KILL=
87 CHANGELOG=
88 BUILD_DEBUG=
89 INCARNATION=
90 DISTURL=
91 LINKSOURCES=
92 OVERLAY=
93 RSYNCSRC=
94 RSYNCDEST=
95 RSYNCDONE=
96 SIGNDUMMY=
97 DO_STATISTICS=
98 RUN_SHELL=
99 CCACHE=
100 DLNOSIGNATURE=
101 CACHE_DIR=/var/cache/build
102 USEHIGHERDEPS=
103 PKG_CCACHE=
104 CCACHE_SETUP_START_TIME=
105 NOCUMULATE=
106
107 # This is for insserv
108 export YAST_IS_RUNNING=instsys
109
110 unset LANGUAGE
111 unset LANG
112 export LC_ALL=POSIX
113 umask 022
114
115 echo_help () {
116     cat << EOT
117
118 Some comments for build
119 -----------------------
120
121 With build you can create binary packages.  They will be built in a chroot
122 system.  This chroot system will be setup automatically.  Normally you can
123 simply call build with a spec file as parameter - nothing else has to be
124 set.
125
126 If you want to set the directory were the chroot system will be setup
127 (at the moment it uses $BUILD_ROOT),
128 simply set the the environment variable BUILD_ROOT.
129
130 Example:
131
132   export BUILD_ROOT=/var/tmp/mybuildroot
133
134
135 Normally build builds the complete package including src.rpm (rpmbuild -ba).
136 If you want let build only make the binary package, simply set
137
138    export BUILD_RPM_BUILD_STAGE=-bb
139
140 (or -bc, -bp, -bi, ...  see "Maximum RPM" for more details [*]).
141
142 When the build command succeeds, the rpm files can be found under
143 $BUILD_ROOT/usr/src/packages/RPMS/
144
145
146 Known Parameters:
147
148   --help      You already got it :)
149
150   --kill      Instead of starting a build kill the one currently
151               running.
152
153   --shell     Instead of starting a build start a root shell in
154               the build root.
155
156   --clean     Delete old build root before initializing it
157
158   --no-init   Skip initialization of build root and start with build
159               immediately.
160
161   --no-checks Do not run checks (postbuild and %check)
162
163   --lint      Run rpmlint after build.
164
165   --logfile logfile
166               Capture build output to logfile. Defaults to
167               .build.log in the build root for non-VM builds.
168
169   --repo PATH_OR_URL
170               Use package repository at PATH_OR_URL. Supported formats
171               are rpm-md, yast2, debian, and arch linux.
172               Alternatively zypp://NAME specifies the zypp
173               repository NAME. The repo must be refreshed with zypp
174               so package meta data is available locally. With emtpy
175               NAME all enabled repositories are used.
176
177   --rpms path1:path2:...
178               Specify path where to find the RPMs for the build system
179
180   --arch arch1:arch2:...
181               Specify what architectures to select from the RPMs
182
183   --verify    Run verify when initializing the build root
184
185   --extra-packs pack
186   -X pack
187               Also install package 'pack'
188
189   --root rootdir
190               Use 'rootdir' to setup chroot environment
191
192   --cachedir cachedir
193               Use 'cachedir' to cache remote repo's packages. The
194               default cache dir is /var/cache/build, every repo
195               given by --repo corresponds to a subdir named
196               as md5sum of its repo url, for example:
197                  /var/cache/build/3e8ea9b47808629414a0cebc33ea285e
198
199   --oldpackages oldpackagesdir
200               Define a directory with a former build
201
202   --baselibs  Create -32bit/-64bit/-x86 rpms for other architectures
203
204   --list-state
205               List rpms that would be used to create a fresh build root.
206               Does not create the build root or perform a build.
207
208   --dist dist
209               Distribution to use
210
211   --with X
212               Enable feature X for build
213
214   --without X
215               Disable feature X for build
216
217   --define 'X Y'
218               Define macro X with value Y
219
220   --release release
221               Override Release in spec file
222
223   --stage -bSTAGE
224               Set stage for rpmbuild. Defaults to -ba.
225
226   --target platform
227               Set target platform for rpmbuild
228
229   --jobs N    Use N parallel processes during build.
230               Sets %jobs and %_smp_mflags macros and
231               defines the number of CPUs to use for
232               VMs.
233
234   --threads N sets number of threads for VM
235
236   --ccache
237               Use ccache to speed up rebuilds
238
239   --pkg-ccache /path/to/ccache.tar.gz
240               path to archive of ccache directory content.
241               Its contents will be extracted to /.ccache
242
243   --icecream N
244               Use N parallel build jobs with icecream
245
246   --overlay OVERLAY
247               Copy overlay filesystem to buildroot after installing
248               all RPMs. This must be a valid directory.
249
250   --rsync-src RSYNCSRC
251               Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
252               inside the buildroot using rsync.
253               It will "%define RSYNCDONE 1" for handling %setup in your
254               specfile. E.g.:
255               %prep
256               %if 0%{?RSYNCDONE}
257               %setup -n aaa_base -T -D -b 5 -b 7
258               %else
259               %setup -n aaa_base -b 5 -b 7
260               %endif
261
262   --rsync-dest RSYNCDEST
263               Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
264               inside the buildroot using rsync.
265
266   --uid uid:gid
267               Specify the uid and gid to use for the abuild user.
268               This is useful if you are hacking in the buildroot.
269               This must be set to the same value if the buildroot is re-used.
270
271   --statistics
272               monitor used resources during build inside VM
273
274   --kvm
275               Use KVM to secure build process. Your hardware needs to support
276               virtualization
277
278   --xen
279               Use XEN to secure build process, you to run in a XEN Dom0 environment.
280
281   --lxc
282               Use Linux Containers to isolate the process. This may not be 100% safe.
283
284   --openstack 
285               Cloud build
286
287   --ec2 
288               Cloud build
289
290   --emulator 
291               Use any generic emulator to isolate the build process. You need to write
292               an emulator/emulator.sh script and put it next to the build script sources.
293
294   --emulator-script SCRIPT
295               specify another emulator instead of emulator.sh
296
297   --vm-type TYPE
298               Use virtual machine instead of chroot
299               TYPE is one of xen|kvm|uml|qemu|lxc|zvm|openstack|ec2|docker|pvm
300
301   --vm-worker GUEST
302               GUEST is a z/VM build worker controlled by the controlling
303               z/VM build machine. 
304
305   --vm-worker-nr N
306               Each worker in z/VM needs a uniq number. This is needed to 
307               calculate uniq device addresses for root and swap device.
308
309   --vm-region NAME
310               EC2 only: defines amazon control server
311
312   --vm-server NAME
313               openstack only: defines control server name
314
315   --vm-disk FILE
316               Use FILE as disk for virtual machine.
317               Defaults to \$BUILD_ROOT.img if unset
318
319   --vm-swap FILE
320               Use FILE as swap space for virtual machine. The swap space is
321               also used for retrieving packages from the VM so its size must
322               be sufficiently large
323
324   --vm-disk-size SIZEINMB
325   --vm-swap-size SIZEINMB
326   --vm-disk-filesystem TYPE
327               Defaults for automatic setup of VM root/swap files
328
329   --vm-memory SIZEINMB
330               Set amount of RAM for VMs
331
332   --vm-hugetlbfs HUGETLBFSPATH
333               Use hugetlb for memory management, path to mounted hugetlbfs.
334
335   --vm-kernel FILE
336   --vm-initrd FILE
337               Kernel and initrd to use for VM (kvm and qemu only)
338
339   --vm-user   USERNAME
340               User name to run qemu/kvm process
341
342   --vm-telnet PORT
343               Is forwarding PORT to a telnet session inside of the VM.
344               Specify also needed extra packages via -x parameter, usually:
345                  --vm-telnet 1234 -x telnet-server -x net-tools
346               And connect from the host via
347                  telnet 1234
348               NOTE: The telnet server gets started after all packages got installed.
349
350   --vm-net OPTION
351   --vm-netdev OPTION
352   --vm-device OPTION
353               KVM only: Attach kvm option
354               Available options are -net, -netdev, -device
355               (This options in kvm can not guarantee reproducible builds)
356   --debug
357               Enable creation of a debuginfo package
358   --nocumulate
359               Enable build without cumulative build.
360
361 Remember to have fun!
362
363 [*] Maximum RPM: http://www.rpm.org/max-rpm/
364 EOT
365 }
366
367 usage () {
368     echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|recipe-to-build]"
369     cleanup_and_exit 1
370 }
371
372 #
373 #  cleanup_and_exit
374 #  return values: 0 -> success, new packages built
375 #                 1 -> error, build failed
376 #                 2 -> successfull build, but no changes to former built packages
377 #                 3 -> something wrong with build host
378 #
379 cleanup_and_exit () {
380     trap EXIT
381     test -z "$1" && set 0
382         rm -f "$BUILD_ROOT"/.repo.config
383     rm -f "$BUILD_ROOT"/exit
384     if test "$1" -eq 1 -a -x /bin/df ; then
385         echo
386         echo "$HOST failed \"build $RECIPEFILE\" at `date --utc`."
387         echo
388         # okay, it failed, but maybe because disk space?
389         if df "$BUILD_ROOT" 2>/dev/null | grep -q "100%"; then
390             df "$BUILD_ROOT" 2>/dev/null
391             echo
392             echo "$HOST ran out of disk space. Please try again."
393             echo
394             set 3
395         fi
396     fi
397     if test -n "$RUNNING_IN_VM" ; then
398         echo "$1" >  /.build/_exitcode
399         test -n "$browner" && chown "$browner" "$BUILD_ROOT"
400         vm_shutdown "$1"
401     else
402         buildroot_umount /proc/sys/fs/binfmt_misc
403         buildroot_umount /proc
404         buildroot_umount /sys
405         buildroot_umount /dev/pts
406         buildroot_umount /dev/shm
407         test -n "$VM_IMAGE" -a "$VM_IMAGE" != 1 && umount "$BUILD_ROOT" 2>/dev/null || true
408         test -n "$VM_TYPE" && vm_cleanup
409     fi
410     exit $1
411 }
412
413 fail_exit() {
414     cleanup_and_exit 1
415 }
416
417 shellquote() {
418     for arg ; do
419         arg=${arg/\\/\\\\}
420         arg=${arg/\$/\\\$}
421         arg=${arg/\"/\\\"}
422         arg=${arg/\`/\\\`}
423         echo -n " \"$arg\""
424     done
425 }
426
427 # create a shell script from command line. Used for preserving arguments
428 # through /bin/su -c
429 toshellscript() {
430     echo "#!/bin/sh -x"
431     echo -n exec
432     shellquote "$@"
433     echo
434 }
435
436 setupccache() {
437     if test -n "$CCACHE" ; then
438         CCACHE_SETUP_START_TIME=`date +%s`
439         if mkdir -p "$BUILD_ROOT"/var/lib/build/ccache/bin; then
440                 for i in $(ls $BUILD_ROOT/usr/bin | grep -E '^(cc|gcc|[cg][+][+]|clang|clang[+][+])([-]?[.0-9])*$'); do
441                 rm -f "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
442                 test -e "$BUILD_ROOT"/usr/bin/$i || continue
443                 echo '#! /bin/sh' > "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
444                 echo "test -e /usr/bin/$i || exit 1" >> "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
445                 echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:/usr/bin:$PATH' >> "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
446                 echo "ccache $i \"\$@\"" >> "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
447                 chmod 755 "$BUILD_ROOT"/var/lib/build/ccache/bin/$i
448                 echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i"
449             done
450         fi
451         mkdir -p "$BUILD_ROOT/.ccache"
452         # overwrite /etc/profile.d/build_ccache.sh
453         echo 'export CCACHE_DIR=/.ccache' > "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
454         echo 'export PATH=/var/lib/build/ccache/bin:$PATH' >> "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
455
456         # Note
457         # Disable compression setting temporary
458         # Until ccache is applied to qemu-accel, it is very slow when using the function, so it will be applied later.
459         #
460         # https://ccache.dev/releasenotes.html#_ccache_4_0
461         # Changed compression algorithm from Deflate (zlib) to Zstandard, enabled by default.
462         enable_compression=false
463
464         local cconf="$BUILD_ROOT"/etc/ccache.conf
465         if test -e $cconf; then
466                 grep -q "^compression*" $cconf && sed -i "s:compression.*:compression = $enable_compression:g" $cconf || echo "compression = $enable_compression"   >> $cconf
467                 grep -q "^cache_dir*"   $cconf && sed -i "s:cache_dir.*:cache_dir = /.ccache:g" $cconf || echo "cache_dir = /.ccache" >> $cconf
468     else
469                 echo "compression = $enable_compression" >> $cconf
470                 echo "cache_dir = /.ccache" >> $cconf
471         fi
472                 local ccachetar="$BUILD_ROOT/.build.oldpackages/_ccache.tar"
473                 test -e $ccachetar && tar -xf $ccachetar -C "$BUILD_ROOT/.ccache/"
474                 rm -f $ccachetar
475                 chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.ccache"
476         else
477                 CCACHE_SETUP_START_TIME=
478                 rm -f "$BUILD_ROOT"/var/lib/build/ccache/bin/{gcc,g++,cc,c++,clang,clang++}
479     fi
480 }
481
482 setupicecream() {
483     local icecreamdir=/var/run/icecream
484     if test "$(readlink "$BUILD_ROOT/var/run")" = /run ; then
485         icecreamdir=/run/icecream
486     fi
487     if test "$icecream" -eq 0 ; then
488         rm -rf "$BUILD_ROOT$icecreamdir"
489         rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh"
490         return 0
491     fi
492
493     if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then
494         echo "*** icecream package not installed ***"
495         return 1
496     fi
497
498     echo "using icecream with $icecream jobs"
499
500     if test -z "$CCACHE" ; then
501         echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
502     else
503         echo 'export CCACHE_PATH=/usr/lib/icecc/bin:/opt/icecream/bin' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
504     fi
505
506     local icecc_vers=(`shopt -s nullglob; echo "$BUILD_ROOT"$icecreamdir/*.tar.{bz2,gz}`)
507     icecc_vers=${icecc_vers//"$BUILD_ROOT"/}
508
509     # XXX use changelog like autobuild does instead?
510     # only run create-env if compiler or glibc changed
511     if test -z "$icecc_vers" \
512         -o ! -e "$BUILD_ROOT/$icecc_vers" \
513         -o "$BUILD_ROOT/usr/bin/gcc" -nt "$BUILD_ROOT/$icecc_vers" \
514         -o "$BUILD_ROOT/usr/bin/g++" -nt "$BUILD_ROOT/$icecc_vers" \
515         -o "$BUILD_ROOT/usr/bin/as" -nt "$BUILD_ROOT/$icecc_vers" \
516         -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers"
517     then
518         rm -rf "$BUILD_ROOT$icecreamdir"
519         mkdir -p "$BUILD_ROOT$icecreamdir"
520         if test -e "$BUILD_ROOT"/usr/bin/create-env ; then
521             createenv=/usr/bin/create-env
522         elif test -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ; then
523             createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
524         elif test -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ; then
525             createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
526         else
527             echo "create-env not found"
528             return 1
529         fi
530         echo "creating new env in '$icecreamdir'"
531         chroot "$BUILD_ROOT" bash -c "cd $icecreamdir; $createenv" || cleanup_and_exit 1
532         icecc_vers=(`shopt -s nullglob; echo "$BUILD_ROOT"/$icecreamdir/*.tar.{bz2,gz}`)
533         icecc_vers=${icecc_vers//"$BUILD_ROOT"/}
534         echo "created icecream environment $icecc_vers"
535     else
536         echo "reusing existing icecream environment $icecc_vers"
537     fi
538     if test -n "$icecc_vers" ; then
539         echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
540     fi
541 }
542
543 setmemorylimit() {
544     if test -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ; then
545                 return
546     fi
547         arch=`uname -p`
548     if [ $arch == "x86_64" ];then
549         echo "on X86_64, no limit mem size"
550                 return
551     fi
552     local mem
553     local limit
554     while read mem; do
555     case "$mem" in
556         MemTotal:*)
557         set -- $mem
558         eval "limit=\$(($2/3*4))"
559         ;;
560         SwapTotal:*)
561         set -- $mem
562         eval "limit=\$(($2/3*4+$limit))"
563         ;;
564     esac
565     done < <(cat /proc/meminfo) # cat for proc stuff
566     ulimit -d $limit
567     echo "Memory limit set to ${limit}KB"
568 }
569
570 create_baselibs() {
571     local pkgs=()
572     local line
573
574     BASELIBS_CFG=
575
576     if test "$BUILDTYPE" == arch || test "$BUILDTYPE" = collax ; then
577         return
578     fi
579     if test "$BUILDTYPE" == dsc ; then
580         pkgs=($DEBS)
581     else # spec and kiwi
582         if test -e "$BUILD_ROOT"$TOPDIR/SOURCES/baselibs.conf ; then
583             BASELIBS_CFG="-c $TOPDIR/SOURCES/baselibs.conf"
584         fi
585         if test -e "$BUILD_ROOT"/usr/lib/build/baselibs_global.conf; then
586             BASELIBS_GLOBAL="-c /usr/lib/build/baselibs_global.conf"
587         fi
588         pkgs=($RPMS)
589     fi
590
591     mount -n -tproc none "$BUILD_ROOT"/proc 2> /dev/null
592     # don't use -R as extracted sources, build root etc might be below $TOPDIR
593     chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/RPMS/* || true
594
595     local mkbaselibs="/usr/lib/build/mkbaselibs"
596     local whichone=''
597     # $BUILD_DIR is set to /.build when using a vm. So we need to
598     # hardcode /usr/lib/build instead of $BUILD_DIR to prefer
599     # mkbaselibs from the distro.
600     if test -f "$BUILD_ROOT"$mkbaselibs; then
601         if test -z "$BASELIBS_CFG" -a -e "$BUILD_ROOT"/usr/lib/build/baselibs.conf ; then
602             BASELIBS_CFG="-c /usr/lib/build/baselibs.conf"
603         fi
604     else
605         if test "$CREATE_BASELIBS" = 'internal'; then
606             echo "Warning: mkbaselibs missing in build root, skipping baselibs"
607             return
608         fi
609         # use external version
610         whichone=" (external)"
611         mkbaselibs="/.mkbaselibs/mkbaselibs"
612         rm -rf "$BUILD_ROOT/.mkbaselibs"
613         mkdir -p "$BUILD_ROOT/.mkbaselibs"
614         cp -f $BUILD_DIR/mkbaselibs "$BUILD_ROOT"/.mkbaselibs/
615         if test "$BUILDTYPE" == "dsc" ; then
616             cp -f $BUILD_DIR/baselibs_global-deb.conf "$BUILD_ROOT"/.mkbaselibs/baselibs_g.conf
617             cp -f "$BUILD_ROOT"$TOPDIR/SOURCES/baselibs-deb.conf "$BUILD_ROOT"/.mkbaselibs/baselibs-deb.conf
618             BASELIBS_CFG="-c /.mkbaselibs/baselibs-deb.conf"
619         else
620             cp -f $BUILD_DIR/baselibs_global.conf "$BUILD_ROOT"/.mkbaselibs/baselibs_g.conf
621             if test -z "$BASELIBS_CFG" -a -e $BUILD_DIR/baselibs.conf; then
622                 cp -f $BUILD_DIR/baselibs.conf "$BUILD_ROOT"/.mkbaselibs/baselibs.conf
623                 BASELIBS_CFG="-c /.mkbaselibs/baselibs.conf"
624             fi
625         fi
626         if test -e "$BUILD_ROOT"/.mkbaselibs/baselibs_g.conf; then
627             BASELIBS_GLOBAL="-c /.mkbaselibs/baselibs_g.conf"
628         fi
629     fi
630     echo "... creating baselibs$whichone"
631     pkgs_origin=(`echo ${pkgs[*]} | sed 's/\"//g'`)
632     while read line
633     do
634         chroot "$BUILD_ROOT" su -c "$mkbaselibs $BASELIBS_GLOBAL $BASELIBS_CFG $line" - $BUILD_USER || cleanup_and_exit 1
635     done < <(IFS=$'\n'; echo "${pkgs_origin[*]#$BUILD_ROOT}" | xargs -n 1024)
636     rm -rf "$BUILD_ROOT/.mkbaselibs"
637 }
638
639 copy_oldpackages() {
640     local i=0
641     local d
642     local dest
643     test -z "$RUNNING_IN_VM" || return 0
644     if test -z "$old_packages" ; then
645         rm -rf "$BUILD_ROOT"/.build.oldpackages*
646         return 0
647     fi
648     for d in "${old_packages[@]}"; do
649         dest="$BUILD_ROOT/.build.oldpackages"
650         test "$i" = 0 || dest="$dest$i"
651         if test -d "$d" -a "$d" != "$dest" ; then
652             rm -rf "$dest"
653             mkdir -p "$dest"
654             cp -L $d/* "$dest"
655             : $((++i))
656         fi
657     done
658 }
659
660 become_root_or_fail() {
661     if test ! -w /root ; then
662         echo "You have to be root to use $0" >&2
663         exit 1
664     fi
665     cleanup_and_exit 1
666 }
667
668 mkdir_build_root() {
669     # strip trailing slash
670     test "$BUILD_ROOT" != / && BUILD_ROOT="${BUILD_ROOT%/}"
671     if test -d "$BUILD_ROOT" ; then
672         # check if it is owned by root
673         if test -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u "$BUILD_ROOT"`" -ne 0 ; then
674             echo "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..."
675             cleanup_and_exit 1
676         fi
677     else
678         test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}"
679         if ! mkdir "$BUILD_ROOT" ; then
680             echo "can not create BUILD_ROOT=$BUILD_ROOT. Exit..."
681             cleanup_and_exit 1
682         fi
683     fi
684
685     if test ! -w "$BUILD_ROOT" ; then
686         echo "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean."
687         cleanup_and_exit 3
688     fi
689
690     rm -rf "$BUILD_ROOT/.build.packages"
691     if test -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then
692          # don't touch this in VM
693          rm -rf "$BUILD_ROOT/.build"
694          mkdir -p "$BUILD_ROOT/.build"
695     fi
696 }
697
698 copy_overlay() {
699     if test -d "$OVERLAY"; then
700         pushd $OVERLAY
701         echo "Copying overlay to BUILD_ROOT"
702         tar -cpf - . | (cd "$BUILD_ROOT" ; tar -xvf -)
703         popd
704     else
705         echo "OVERLAY ($OVERLAY) is no directory - skipping"
706     fi
707 }
708
709 run_rsync() {
710     if test -n "$RSYNCDEST" ; then
711         if test -d "$RSYNCSRC" ; then
712             if ! test -d "$BUILD_ROOT/$RSYNCDEST" ; then
713                 echo "ATTENTION! Creating missing target directory ("$BUILD_ROOT"/$RSYNCDEST)."
714                 mkdir -p "$BUILD_ROOT"/$RSYNCDEST
715             fi
716             echo "Running rsync ..."
717             rsync -av $RSYNCSRC/* "$BUILD_ROOT"/$RSYNCDEST/
718             chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST"
719             RSYNCDONE=true
720             echo "... done"
721         else
722             echo "RSYNCSRC is not a directory - skipping"
723         fi
724     else
725         echo "RSYNCSRC given, but not RSYNCDEST - skipping"
726     fi
727 }
728
729 hide_passwords()
730 {
731     local i j
732     r=()
733     rm -f "$BUILD_ROOT"/.repo.config
734     for i in "${repos[@]}"; do
735         if [ "$i" == "--repo" -o "$i" == "--repository" ]; then
736             r=("${r[@]}" "$i")
737         else
738             echo $i |grep -E "^http[s]?:\/\/[^\/]*\/?" >/dev/null && echo $i >> "$BUILD_ROOT"/.repo.config
739             j=$(echo $i | sed -e "s#://[^@]*@#://#")
740             r=("${r[@]}" "$j")
741         fi
742     done
743     repos=("${r[@]}")
744 #    echo ${repos[@]}
745 }
746
747 #### main ####
748
749 trap fail_exit EXIT
750
751 shopt -s nullglob
752
753 export PATH=$BUILD_DIR:/sbin:/usr/sbin:/bin:/usr/bin:$PATH
754
755 if vm_detect_2nd_stage ; then
756     set "/.build-srcdir/$RECIPEFILE"
757     export PATH=/.build:$PATH
758 fi
759
760 . $BUILD_DIR/common_functions || exit 1
761
762 export HOST
763
764 needarg() {
765     if test -z "$ARG" ; then
766         echo "$PARAM needs an agrument" >&2
767         cleanup_and_exit 1
768     fi
769 }
770
771 while test -n "$1"; do
772     PARAM="$1"
773     ARG="$2"
774     test "$ARG" = "${ARG#-}" || ARG=
775     shift
776     case $PARAM in
777       *-*=*)
778         ARG=${PARAM#*=}
779         PARAM=${PARAM%%=*}
780         set -- "----noarg=$PARAM" "$@"
781         ;;
782     esac
783     case ${PARAM/#--/-} in
784       -help|-h)
785         echo_help
786         cleanup_and_exit
787       ;;
788       -noinit|-no-init)
789         test "$DO_INIT" = false && DO_INIT_TOPDIR=false
790         DO_INIT=false
791       ;;
792       -no-build)
793     DO_BUILD=false
794       ;;
795       -nochecks|-no-checks)
796         DO_CHECKS=false
797       ;;
798       -clean)
799         CLEAN_BUILD='--clean'
800         REMOVE_CCACHE="$CLEAN_BUILD"
801       ;;
802       -kill)
803         KILL=true
804       ;;
805       -rpms)
806         needarg
807         BUILD_RPMS="$ARG"
808         shift
809       ;;
810       -arch)
811         needarg
812         BUILD_ARCH="$ARG"
813         shift
814       ;;
815       -verify)
816         export VERIFY_BUILD_SYSTEM=true
817       ;;
818       -target)
819         needarg
820         ABUILD_TARGET="$ARG"
821         shift
822       ;;
823       -jobs)
824         needarg
825         BUILD_JOBS="$ARG"
826         shift
827       ;;
828       -threads)
829         needarg
830         BUILD_THREADS="$ARG"
831         shift
832       ;;
833       -extrapacks|-extra-packs|-X)
834         needarg
835         BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG"
836         shift
837       ;;
838       -lint)
839         DO_LINT=true
840         ;;
841       -baselibs)
842         CREATE_BASELIBS=true
843         ;;
844       -baselibs-internal)
845         CREATE_BASELIBS=internal
846         ;;
847       -keep-packs)
848     KEEP_PACKS="--keep-packs"
849         ;;
850       -root)
851         needarg
852         BUILD_ROOT="$ARG"
853         shift
854       ;;
855       -cachedir)
856         needarg
857         CACHE_DIR="$ARG"
858         shift
859       ;;
860       -oldpackages)
861         needarg
862         old_packages=("${old_packages[@]}" "$ARG")
863         shift
864       ;;
865       -dist)
866         needarg
867         BUILD_DIST="$ARG"
868         shift
869       ;;
870       -release)
871         needarg
872         RELEASE="$ARG"
873         shift
874       ;;
875       -logfile)
876         needarg
877         LOGFILE="$ARG"
878         shift
879       ;;
880       -reason)
881         needarg
882         REASON="$ARG"
883         shift
884       ;;
885       -norootforbuild)
886         NOROOTFORBUILD=true
887       ;;
888       -short-circuit)
889     SHORT_CIRCUIT=true
890       ;;
891       -no-topdir-cleanup)
892     NO_TOPDIR_CLEANUP=true
893       ;;
894       -useusedforbuild)
895         USEUSEDFORBUILD="--useusedforbuild"
896       ;;
897       -configdir)
898         needarg
899         CONFIG_DIR="$ARG"
900         shift
901       ;;
902       -list*state)
903         LIST_STATE=true
904       ;;
905       -define|-with|-without)
906         needarg
907         PARAM="-${PARAM/#--/-}"
908         definesnstuff[${#definesnstuff[@]}]="$PARAM"
909         definesnstuff[${#definesnstuff[@]}]="$ARG"
910         shift
911       ;;
912       -repository|-repo)
913         needarg
914         repos[${#repos[@]}]="--repository"
915         repos[${#repos[@]}]="$ARG"
916         shift
917       ;;
918       -icecream)
919         needarg
920         icecream="$ARG"
921         test "$icecream" -gt 0 && BUILD_JOBS="$ARG"
922         shift
923       ;;
924       -nocumulate)
925         NOCUMULATE="--nocumulate"
926       ;;
927       -ccache)
928         CCACHE=true
929       ;;
930       -pkg-ccache)
931         needarg
932         PKG_CCACHE="$ARG"
933         shift
934         CCACHE=true
935       ;;
936       -statistics)
937         DO_STATISTICS=1
938       ;;
939       -debug)
940         BUILD_DEBUG=1
941       ;;
942       -incarnation)
943         needarg
944         INCARNATION=$ARG
945         shift
946       ;;
947       -disturl)
948         needarg
949         DISTURL=$ARG
950         shift
951       ;;
952       -linksources)
953         LINKSOURCES=true
954       ;;
955       -changelog)
956         CHANGELOG=true
957       ;;
958       -overlay)
959         needarg
960         OVERLAY=$ARG
961         shift
962       ;;
963       -rsync-src)
964         needarg
965         RSYNCSRC=$ARG
966         shift
967       ;;
968       -rsync-dest)
969         needarg
970         RSYNCDEST=$ARG
971         shift
972       ;;
973       -uid)
974         needarg
975         ABUILD_ID="$ARG"
976         if test -n "${ABUILD_ID//[0-9:]/}" ; then
977             echo "--uid argument must be uid:gid"
978             cleanup_and_exit
979         fi
980         ABUILD_UID=${ABUILD_ID%:*}
981         ABUILD_GID=${ABUILD_ID#*:}
982         shift
983       ;;
984       -rpmlist)
985         needarg
986         RPMLIST="--rpmlist $ARG"
987         BUILD_RPMS=
988         shift
989       ;;  
990       -shell)
991         RUN_SHELL=1
992         shift
993       ;;
994       -signdummy)
995         SIGNDUMMY=1
996       ;;
997       -nosignature)
998         DLNOSIGNATURE="--nosignature"
999       ;;
1000       ---noarg)
1001         echo "$ARG does not take an argument"
1002         cleanup_and_exit
1003       ;;
1004           -use-higher-deps)
1005         USEHIGHERDEPS="--use-higher-deps"
1006           ;;
1007       -*)
1008         if vm_parse_options "$@" ; then
1009             set -- "${nextargs[@]}"
1010         elif recipe_parse_options "$@" ; then
1011             set -- "${nextargs[@]}"
1012         else
1013             echo "Unknown option '$PARAM'. Exit."
1014             cleanup_and_exit 1
1015         fi
1016       ;;
1017       *)
1018         RECIPEFILES[${#RECIPEFILES[@]}]="$PARAM"
1019       ;;
1020     esac
1021 done
1022
1023 if [ "$SHORT_CIRCUIT" = true -a -z "$BUILD_RPM_BUILD_STAGE" ]; then
1024     echo "--short-circuit needs a stage (use --stage)"
1025     cleanup_and_exit 1
1026 fi
1027
1028 if test -n "$KILL" ; then
1029     test -z "$SRCDIR" || usage
1030     if test -n "$VM_IMAGE" -a -n "$VM_SWAP" -a -n "$VM_TYPE"; then
1031         # mark job as failed so that we don't extract packages
1032         if test "$VM_TYPE" != zvm ; then
1033             echo -n "BUILDSTATUS1" >"$VM_SWAP"
1034         fi
1035     fi
1036     (set -C; > "$BUILD_ROOT/exit" 2>/dev/null || true)
1037     if test -n "$VM_TYPE" ; then
1038         vm_kill
1039     else
1040         if ! $BUILD_DIR/killchroot -s 9 "$BUILD_ROOT" ; then
1041             echo "could not kill build in $BUILD_ROOT"
1042             cleanup_and_exit 1
1043         fi
1044     fi
1045     cleanup_and_exit 0
1046 fi
1047
1048 if test -n "$CLEAN_BUILD" ; then
1049     DO_INIT=true
1050     DO_INIT_TOPDIR=true
1051 fi
1052
1053 if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then
1054     vm_verify_options
1055 fi
1056
1057 if test -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ; then
1058     if test -z "$repos" -a -z "$BUILD_RPMS" ; then
1059         repos=(--repository 'zypp://')
1060     fi
1061 else
1062     repos=()
1063 fi
1064
1065 set_build_arch
1066
1067 expand_recipe_directories
1068
1069 if test -n "$LIST_STATE" ; then
1070     BUILD_ROOT=`mktemp -d /var/tmp/build-list-state-XXXXXX`
1071     test -d "$BUILD_ROOT" || cleanup_and_exit 3
1072     RECIPEFILE=$RECIPEFILES # only one specified anyways
1073     if test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" ; then
1074         MYSRCDIR="$BUILD_ROOT/usr/src/packages/SOURCES"
1075         recipe_unpack_srcrpm
1076         RECIPEFILE="$MYSRCDIR/$RECIPEFILE"
1077     fi
1078     init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $DLNOSIGNATURE $KEEP_PACKS $NOCUMULATE $USEHIGHERDEPS $USEUSEDFORBUILD $RECIPEFILE $BUILD_EXTRA_PACKS
1079     ERR=$?
1080     rm -rf "$BUILD_ROOT"
1081     cleanup_and_exit $ERR
1082 fi
1083
1084 # do vm setup if needed
1085 if test -z "$RUNNING_IN_VM" -a -n "$VM_TYPE" -a -n "$VM_IMAGE" ; then
1086     vm_setup
1087 fi
1088
1089 mkdir_build_root
1090 hide_passwords
1091 if test "$BUILD_ROOT" = / ; then
1092     browner="$(stat -c %u /)"
1093 fi
1094
1095 rm -f "$BUILD_ROOT"/exit
1096
1097 if test -w /root ; then
1098     mkdir -p "$BUILD_ROOT"/proc
1099     mkdir -p "$BUILD_ROOT"/sys
1100     mkdir -p "$BUILD_ROOT"/dev/pts
1101     mount -n -tproc none "$BUILD_ROOT"/proc || true
1102     mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT"/dev/pts
1103 fi
1104
1105 if test -z "$VM_IMAGE" -a -z "$LOGFILE" ; then
1106     if test -z "$RUNNING_IN_VM"; then
1107         LOGFILE="$BUILD_ROOT/.build.log"
1108     else
1109         # lxc and docker are special cases: vm shares logfile with host
1110         case "$VM_TYPE" in
1111         lxc|docker)
1112             ;;
1113         *)
1114             LOGFILE="$BUILD_ROOT/.build.log"
1115             ;;
1116         esac
1117     fi
1118 fi
1119
1120 if test -n "$LOGFILE" -a -z "$RUN_SHELL" ; then
1121     echo "logging output to $LOGFILE..."
1122     rm -f $LOGFILE
1123     touch $LOGFILE
1124     # set start time, to be substracted for build log timestamps
1125     STARTTIME=`perl -e 'print time()'`
1126
1127     if test -n "$RUNNING_IN_VM" ; then
1128         # no additional timestamps in inner vm build system
1129         exec 1> >(exec -a 'build logging' tee -a $LOGFILE) 2>&1
1130     elif test -n "$VM_IMAGE" ; then
1131         # external run of virtualization build
1132         exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;s/^\r//s;s/\r\n/\n/gs;print F $p.$_}' $LOGFILE) 2>&1
1133     else
1134         # plain chroot
1135         exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;print F $p.$_}' $LOGFILE) 2>&1
1136     fi
1137 fi
1138
1139 setmemorylimit
1140
1141 #
1142 # say hello
1143 #
1144 test -z "$HOST" && HOST=`hostname`
1145
1146 if test -z "$RUNNING_IN_VM" ; then
1147     echo Using BUILD_ROOT=$BUILD_ROOT
1148     test -n "$BUILD_RPMS" && echo Using BUILD_RPMS=$BUILD_RPMS
1149     echo Using BUILD_ARCH=$BUILD_ARCH
1150     test -n "$VM_TYPE" && echo "Doing $VM_TYPE build${VM_IMAGE:+ in $VM_IMAGE}"
1151     echo
1152 fi
1153
1154 test "$BUILD_ARCH" = all && BUILD_ARCH=
1155 BUILD_USER_ABUILD_USED=
1156
1157 for RECIPEFILE in "${RECIPEFILES[@]}" ; do
1158
1159     SRCDIR="${RECIPEFILE%/*}"
1160     RECIPEFILE="${RECIPEFILE##*/}"
1161
1162     recipe_set_buildtype
1163
1164     if test -z "$RUNNING_IN_VM" ; then
1165         echo
1166         echo "$HOST started \"build $RECIPEFILE\" at `date --utc`."
1167         echo
1168         test -n "$REASON" && echo "$REASON"
1169         echo
1170         TIME_START_TIME=`date +%s` # for statistics
1171     fi
1172
1173     #
1174     # first setup building directory...
1175     #
1176     cd "$SRCDIR"
1177     if ! test -s "$RECIPEFILE" ; then
1178          echo "$RECIPEFILE is empty.  This should not happen..."
1179          cleanup_and_exit 1
1180     fi
1181     MYSRCDIR="$SRCDIR"
1182
1183     # special hack to build from a .src.rpm
1184     test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" && recipe_unpack_srcrpm
1185
1186     echo "processing recipe $MYSRCDIR/$RECIPEFILE ..."
1187
1188     ADDITIONAL_PACKS=
1189     test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS"
1190     test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build"
1191     test -z "$CCACHE" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache"
1192     test "$icecream" = 0 || ADDITIONAL_PACKS="$ADDITIONAL_PACKS icecream gcc-c++"
1193     test -z "$DO_LINT" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS rpmlint-Factory"
1194     test "$VMDISK_FILESYSTEM" = xfs && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1"
1195     test "$VM_TYPE" = zvm && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2"
1196
1197     # we need to do this before the vm is started
1198     if test -n "$CHANGELOG" -a -z "$RUNNING_IN_VM" ; then
1199         rm -f "$BUILD_ROOT"/.build-changelog
1200         case $RECIPEFILE in
1201             *.dsc) CFFORMAT=debian ;;
1202             *) CFFORMAT=rpm ;;
1203         esac
1204         echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$RECIPEFILE"
1205         if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$RECIPEFILE" > "$BUILD_ROOT"/.build-changelog ; then
1206             rm -f "$BUILD_ROOT"/.build-changelog
1207         fi
1208     fi
1209
1210     if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM"; then
1211         vm_first_stage
1212         cleanup_and_exit 0
1213     fi
1214
1215     if test "$DO_INIT" = true ; then
1216         start_time=`date +%s`
1217         #
1218         # create legacy .buildenv file
1219         #
1220         test -z "$INCARNATION" && INCARNATION=0
1221         echo "BUILD_INCARNATION=$INCARNATION" > "$BUILD_ROOT"/.buildenv
1222         CREATE_BUILD_BINARIES=
1223         test "$BUILDTYPE" = preinstallimage && mkdir -p "$BUILD_ROOT"/.preinstall_image
1224         egrep '^#[       ]*needsbinariesforbuild[       ]*$' >/dev/null <$MYSRCDIR/$RECIPEFILE && CREATE_BUILD_BINARIES=--create-build-binaries
1225         test "$BUILDTYPE" = mock && CREATE_BUILD_BINARIES=--create-build-binaries
1226         test "$BUILDTYPE" = debootstrap && CREATE_BUILD_BINARIES=--create-build-binaries
1227         test "$BUILDTYPE" = livebuild && CREATE_BUILD_BINARIES=--create-build-binaries
1228         test "$BUILDTYPE" = snapcraft && CREATE_BUILD_BINARIES=--create-build-binaries
1229         set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $DLNOSIGNATURE $KEEP_PACKS $NOCUMULATE $USEHIGHERDEPS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS
1230         echo "$* ..."
1231         start_time=`date +%s`
1232         "$@" || cleanup_and_exit 1
1233         check_exit
1234         TIME_INSTALL=$(( `date +%s` - $start_time ))
1235         unset start_time
1236         # arbitrary limit of 10MB
1237         if test $((`stat -f -c "%a*%S/1024/1024" "$BUILD_ROOT"`)) -lt 10; then
1238             # ensure that old stat is not failing (RHEL4)
1239             if df "$BUILD_ROOT" 2>/dev/null | grep -q "100%"; then
1240                 df -h "$BUILD_ROOT"
1241                 echo "build does not work on a completely full filesystem"
1242                 cleanup_and_exit 1
1243             fi
1244         fi
1245         mount -n -tproc none "$BUILD_ROOT"/proc || true
1246         mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT"/dev/pts
1247
1248         copy_oldpackages
1249         # chroot based builds
1250         # rsync as source and dest could be same
1251         test -n "$PKG_CCACHE" -a -e "$PKG_CCACHE" && \
1252                 mkdir -p "$BUILD_ROOT/.build.oldpackages/" && \
1253                 rsync -v "$PKG_CCACHE" "$BUILD_ROOT/.build.oldpackages/_ccache.tar"
1254     fi
1255
1256     # hack to process preinstallimages early
1257     if test "$BUILDTYPE" = preinstallimage ; then
1258         recipe_build
1259         continue
1260     fi
1261
1262     if test -z "$BUILD_DIST" -a -e "$BUILD_ROOT/.guessed_dist" ; then
1263         read BUILD_DIST < "$BUILD_ROOT"/.guessed_dist
1264     fi
1265
1266     #
1267     # install dummy sign program if needed
1268     #
1269     test -f "$BUILD_ROOT"/usr/bin/sign_installed && mv "$BUILD_ROOT"/usr/bin/sign_installed "$BUILD_ROOT"/usr/bin/sign
1270     if test -n "$SIGNDUMMY" ; then
1271         test -f "$BUILD_ROOT"/usr/bin/sign && mv "$BUILD_ROOT"/usr/bin/sign "$BUILD_ROOT"/usr/bin/sign_installed
1272         cp "$BUILD_DIR"/signdummy "$BUILD_ROOT"/usr/bin/sign
1273         chmod 755 "$BUILD_ROOT"/usr/bin/sign
1274     fi
1275
1276     #
1277     # check if we want to build with the abuild user
1278     #
1279     BUILD_USER=abuild
1280     if test -x "$BUILD_ROOT"/bin/rpm ; then
1281         SUSE_VERSION=`chroot "$BUILD_ROOT" /bin/rpm --eval '%{?suse_version}' 2>/dev/null`
1282         test -n "$SUSE_VERSION" -a "${SUSE_VERSION:-0}" -le 1020 && BUILD_USER=root
1283     fi
1284     if test "$BUILD_USER" = abuild ; then
1285         egrep '^#[       ]*needsrootforbuild[       ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=root
1286     else
1287         egrep '^#[       ]*norootforbuild[       ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=abuild
1288     fi
1289     test -n "$NOROOTFORBUILD" && BUILD_USER=abuild
1290
1291     # appliance builds must run as root
1292     if test "$BUILDTYPE" = kiwi ; then
1293         imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $RECIPEFILE imagetype)
1294         test "$imagetype" = product || BUILD_USER=root
1295     fi
1296
1297     # fixup passwd/group
1298     if test $BUILD_USER = abuild ; then
1299         if ! egrep '^abuild:' >/dev/null <"$BUILD_ROOT"/etc/passwd ; then
1300             echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>"$BUILD_ROOT"/etc/passwd
1301             echo 'abuild:*:::::::' >>"$BUILD_ROOT"/etc/shadow # This is needed on Mandriva 2009
1302             echo 'abuild:*::' >>"$BUILD_ROOT"/etc/gshadow # This is needed on Ubuntu
1303             echo "abuild:x:${ABUILD_GID}:" >>"$BUILD_ROOT"/etc/group
1304             mkdir -p "$BUILD_ROOT"/home/abuild
1305             chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT"/home/abuild
1306         else
1307             if ! egrep "^abuild:x?:${ABUILD_UID}:${ABUILD_GID}" >/dev/null <"$BUILD_ROOT"/etc/passwd ; then
1308                     sed -i '/^abuild:/d' "$BUILD_ROOT"/etc/passwd
1309                     sed -i '/^abuild:/d' "$BUILD_ROOT"/etc/group
1310                     echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>"$BUILD_ROOT"/etc/passwd
1311                     echo "abuild:x:${ABUILD_GID}:" >>"$BUILD_ROOT"/etc/group
1312                     chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT"/home/abuild -R
1313             fi
1314         fi
1315         if test -f "$BUILD_ROOT"/etc/shadow ; then
1316             sed -i -e "s@^root::@root:*:@" "$BUILD_ROOT"/etc/shadow
1317         fi
1318         if test -f "$BUILD_ROOT"/etc/gshadow ; then
1319             sed -i -e "s@^root::@root:*:@" "$BUILD_ROOT"/etc/gshadow
1320         fi
1321         BUILD_USER_ABUILD_USED=true
1322     else
1323         # building as root
1324         ABUILD_UID=0
1325         ABUILD_GID=0
1326         if egrep '^abuild:' >/dev/null <"$BUILD_ROOT"/etc/passwd ; then
1327             rm -rf "$BUILD_ROOT/home/abuild"
1328             sed -i -e '/^abuild:/d' "$BUILD_ROOT"/etc/passwd
1329             sed -i -e '/^abuild:/d' "$BUILD_ROOT"/etc/group
1330             if test -f "$BUILD_ROOT"/etc/shadow ; then
1331                 sed -i -e '/^abuild:/d' "$BUILD_ROOT"/etc/shadow
1332             fi
1333             if test -f "$BUILD_ROOT"/etc/gshadow ; then
1334                 sed -i -e '/^abuild:/d' "$BUILD_ROOT"/etc/gshadow
1335             fi
1336         fi
1337     fi
1338
1339     mount -n -tproc none "$BUILD_ROOT"/proc 2> /dev/null
1340     mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT"/dev/pts 2> /dev/null
1341     # needed for POSIX semaphores
1342     test -d "$BUILD_ROOT"/dev/shm || rm -f "$BUILD_ROOT"/dev/shm
1343     mkdir -p "$BUILD_ROOT"/dev/shm
1344     mount -n -ttmpfs none "$BUILD_ROOT"/dev/shm 2> /dev/null
1345
1346     if test -n "$RUNNING_IN_VM" ; then
1347         if test -x /sbin/ip ; then
1348             ip addr add 127.0.0.1/8 dev lo
1349             ip addr add ::1/128 dev lo
1350             ip link set lo up
1351         else
1352             ifconfig lo 127.0.0.1 up
1353             ifconfig lo add ::1/128
1354         fi
1355         if test -n "$VM_TELNET"; then
1356             VM_TELNET_DEVICE=$( cd /sys/class/net/; echo * )
1357             VM_TELNET_DEVICE=${VM_TELNET_DEVICE#lo }
1358             VM_TELNET_DEVICE=${VM_TELNET_DEVICE%% *}
1359             if test -z "$VM_TELNET_DEVICE"; then
1360                    echo "ERROR: no network device found for telnet server"
1361                    cleanup_and_exit 1
1362             fi
1363             if test -x /sbin/ip ; then
1364                    ip addr add 10.0.2.15/8 dev ${VM_TELNET_DEVICE}
1365                    ip addr add ::1/24 dev ${VM_TELNET_DEVICE}
1366                    ip link set ${VM_TELNET_DEVICE} up
1367             else
1368                    if ! test -x /sbin/ifconfig ; then
1369                       echo "ERROR: /usr/sbin/in.telnetd is not running, please specify right package via -x option"
1370                       cleanup_and_exit 1
1371                    fi
1372                    ifconfig ${VM_TELNET_DEVICE} 10.0.2.15 up
1373                    ifconfig ${VM_TELNET_DEVICE} add ::1/24
1374             fi  
1375         fi
1376         if test -n "$VM_NETDEVOPT"; then
1377             let LASTIP="${VM_WORKER_NR:-0}"+10
1378             if test -x /sbin/ip ; then
1379                 ip addr add 10.0.2.$LASTIP/24 dev eth0
1380                 ip link set eth0 up
1381             else
1382                 ifconfig eth0 10.0.2.$LASTIP netmask 255.255.255.0 up
1383             fi
1384             route add default gw 10.0.2.2 eth0
1385         fi
1386         if test -n "$MYHOSTNAME" ; then
1387             hostname "$MYHOSTNAME"
1388         fi
1389         if test -n "$VM_TELNET"; then
1390             echo WARNING: telnet option used, setting up telnet server ${VM_TELNET_DEVICE}
1391             if test -x /usr/sbin/in.telnetd; then
1392                ( /usr/sbin/in.telnetd -L /.build/telnet_login_wrapper -debug 23 & )
1393             else
1394                 echo "ERROR: /usr/sbin/in.telnetd is not running, please specify right package via -x option"
1395                 cleanup_and_exit 1
1396             fi
1397         fi
1398     fi
1399
1400     setupicecream
1401     setupccache
1402
1403     # fill build directories with sources. Also sets TOPDIR
1404     recipe_setup
1405
1406     # strip prefix from autogenerated files of source services.
1407     for i in "$BUILD_ROOT"$TOPDIR/SOURCES/_service\:* ; do
1408         mv "$i" "${i%/*}/${i##*:}"
1409     done
1410     RECIPEFILE="${RECIPEFILE##*:}"
1411
1412     # create .build.packages link
1413     rm -f "$BUILD_ROOT"/.build.packages
1414     ln -s ${TOPDIR#/} "$BUILD_ROOT"/.build.packages
1415
1416     # nasty hack to prevent rpath on known paths
1417     # FIXME: do this only for suse
1418     if test -d "$BUILD_ROOT/etc/profile.d" ; then
1419         echo "export SUSE_IGNORED_RPATHS=/etc/ld.so.conf" > "$BUILD_ROOT/etc/profile.d/buildsystem.sh"
1420     fi
1421
1422     cd "$BUILD_ROOT"$TOPDIR/SOURCES || cleanup_and_exit 1
1423     for i in *.obscpio ; do
1424         test -e "$i" || continue
1425         echo "Unpacking $i ..."
1426         echo "#!/bin/sh -e" > "$BUILD_ROOT"/.unpack.command
1427         shellquote cd "$TOPDIR/SOURCES" >> "$BUILD_ROOT"/.unpack.command
1428         echo >> "$BUILD_ROOT"/.unpack.command
1429         echo -n 'cpio --extract --owner="'$BUILD_USER'" --unconditional --preserve-modification-time --make-directories <' >> "$BUILD_ROOT"/.unpack.command
1430         shellquote "$i" >> "$BUILD_ROOT"/.unpack.command
1431         echo >> "$BUILD_ROOT"/.unpack.command
1432         shellquote rm -f "$i" >> "$BUILD_ROOT"/.unpack.command
1433         echo >> "$BUILD_ROOT"/.unpack.command
1434         chmod 0755 "$BUILD_ROOT"/.unpack.command
1435         chroot "$BUILD_ROOT" su -c /.unpack.command - $BUILD_USER
1436         rm -f "$BUILD_ROOT"/.unpack.command
1437     done
1438
1439     if  test -e _service; then
1440         echo "Running build time source services..."
1441         $BUILD_DIR/runservices --buildroot "$BUILD_ROOT" || cleanup_and_exit 1
1442     fi
1443
1444     # get rid of old src dir, it is no longer needed and just wastes space
1445     test "$MYSRCDIR" = "$BUILD_ROOT"/.build-srcdir && rm -rf "$MYSRCDIR"
1446
1447     # patch recipes
1448     recipe_prepare
1449
1450     # hmmm
1451     chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
1452
1453     echo -----------------------------------------------------------------
1454     if test "$BUILD_USER" = root ; then
1455         echo ----- building $RECIPEFILE
1456     else
1457         echo ----- building $RECIPEFILE "(user $BUILD_USER)"
1458     fi
1459     echo -----------------------------------------------------------------
1460     echo -----------------------------------------------------------------
1461     BUILD_SUCCEEDED=false
1462
1463     if test -n "$OVERLAY" ; then
1464         copy_overlay
1465     fi
1466
1467     if test -n "$RSYNCSRC" ; then
1468         run_rsync
1469     fi
1470
1471     start_time=`date +%s`
1472     recipe_build
1473     if test "$DO_STATISTICS" = 1; then
1474         mkdir -p $TOPDIR/OTHER
1475         echo "TIME_main_build: $(( `date +%s` - $start_time ))"  >> $TOPDIR/OTHER/_statistics
1476     fi
1477     unset start_time
1478
1479     test "$BUILD_SUCCEEDED" = true || cleanup_and_exit 1
1480     test -d "$SRCDIR" && cd "$SRCDIR"
1481 done
1482
1483 if test -n "$RUNNING_IN_VM" -a -n "$DO_STATISTICS" ; then
1484     touch /.build/_statistics.exit
1485 fi
1486
1487 RPMS=`find "$BUILD_ROOT"/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null | sed 's/.*/\"&\"/g' || true`
1488 DEBS=`find "$BUILD_ROOT"/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null | sed 's/.*/\"&\"/g' || true`
1489 if test -n "$RPMS" -a -n "$BUILD_USER_ABUILD_USED" ; then
1490     recipe_check_file_owners
1491 fi
1492 if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then
1493     export DO_RPM_REMOVE=true
1494     # find package name
1495     export PNAME=
1496     for SRPM in "$BUILD_ROOT"/$TOPDIR/SRPMS/*src.rpm ; do
1497         test -f "$SRPM" && PNAME=`rpm --nodigest --nosignature -qp --qf "%{NAME}" $SRPM`
1498     done
1499     mount -n -tproc none "$BUILD_ROOT"/proc 2> /dev/null
1500     for CHECKSCRIPT in "$BUILD_ROOT"/usr/lib/build/checks/* ; do
1501         echo "... running ${CHECKSCRIPT##*/}"
1502         $CHECKSCRIPT || cleanup_and_exit 1
1503     done
1504     umount -n "$BUILD_ROOT"/proc 2>/dev/null || true
1505 fi
1506
1507 # checkscripts may have deleted some binaries
1508 RPMS=`find "$BUILD_ROOT"/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null | sed 's/.*/\"&\"/g' || true`
1509 DEBS=`find "$BUILD_ROOT"/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null | sed 's/.*/\"&\"/g' || true`
1510
1511 if test -n "$RPMS" -a "$DO_CHECKS" != false ; then
1512     recipe_run_rpmlint
1513 fi
1514
1515 if test -n "$CCACHE" ; then
1516     if test -n "$REMOVE_CCACHE" ; then
1517         echo "... cleaning ccache"
1518         test_cmd="ccache -h | grep -c evict-older-than"
1519         clean_cmd="ccache --evict-older-than $(($(date +%s) - $CCACHE_SETUP_START_TIME))s"
1520         chroot $BUILD_ROOT su -c "$test_cmd && $clean_cmd" - $BUILD_USER
1521     fi
1522     echo "... saving ccache"
1523     tar ${REMOVE_CCACHE:+--remove-files} -cf "$BUILD_ROOT/$TOPDIR/OTHER/_ccache.tar" -C "$BUILD_ROOT/.ccache/" .
1524 fi
1525
1526 if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then
1527     create_baselibs
1528 fi
1529
1530 exitcode=0
1531
1532 # post build work
1533 # TODO: don't hardcode. instead run scripts in a directory as it's done for the checks
1534 if test -n "$RPMS" -a -d "$BUILD_ROOT/.build.oldpackages" ; then
1535     recipe_compare_oldpackages
1536     # no need to create deltas if the build is the same
1537     if test ! -e "$BUILD_ROOT"/.build/.same_result_marker ; then
1538     recipe_create_deltarpms
1539     fi
1540 fi
1541 if test -n "$RUNNING_IN_VM" ; then
1542     vm_wrapup_build $(recipe_resultdirs) OTHER
1543 fi
1544 echo
1545 echo "$HOST finished \"build $RECIPEFILE\" at `date --utc`."
1546 echo
1547
1548 cleanup_and_exit "$exitcode"