Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:adrianSuSE
build
build
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File build of Package build
#!/bin/bash # Script to build a package. It uses init_buildsystem to setup a chroot # building tree. This script needs a directory as parameter. This directory # has to include sources and a recipe file. # # BUILD_ROOT here the packages will be built # ################################################################ # # Copyright (c) 1995-2014 SUSE Linux Products GmbH # Copyright (c) 2022 Andreas Stieger <Andreas.Stieger@gmx.de> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or 3 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program (see the file COPYING); if not, write to the # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # ################################################################ # some VMs do not allow to specify the init process... if test "$0" = /sbin/init ; then exec /.build/build "$@" fi BUILD_CONF=/etc/build.conf # ignore BUILD_DIR if we have a config test -e "$BUILD_CONF" && BUILD_DIR=/usr/lib/build test -z "$BUILD_DIR" -a -e /.build/build.data -a -z "$BUILD_IGNORE_2ND_STAGE" && BUILD_DIR=/.build test -z "$BUILD_DIR" && BUILD_DIR=/usr/lib/build test -z "$BUILD_ROOT" && BUILD_ROOT=/var/tmp/build-root test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs" export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG export BUILD_DIST ABUILD_UID ABUILD_GID icecream=0 definesnstuff=() repos=() old_packages=() # slurp in vm support . "$BUILD_DIR/build-vm" # slurp in recipe support . "$BUILD_DIR/build-recipe" # slurp in package binary support . "$BUILD_DIR/build-pkg" # slurp in validation support . "$BUILD_DIR/build-validate-params" # need to restore build root owner for non-root builds browner= # Default uid:gid for the build user ABUILD_UID=399 ABUILD_GID=399 BUILD_OPTIONS_PARSED= DO_INIT=true DO_INIT_TOPDIR=true DO_LINT= DO_CHECKS=true CLEAN_BUILD= GENBUILDREQS_CLEAN_BUILD= RECIPEFILES=() RECIPEPATH= SRCDIR= BUILD_JOBS= BUILD_THREADS= ABUILD_TARGET= CREATE_BASELIBS= USEUSEDFORBUILD= LIST_STATE= RUNNING_IN_VM= RPMLIST= RELEASE= REASON= NOROOTFORBUILD= LOGFILE= KILL= DO_WIPE= SEND_SYSRQ= CHANGELOG= BUILD_DEBUG= INCARNATION= DISTURL= LINKSOURCES= OVERLAY= RSYNCSRC= RSYNCDEST= RSYNCDONE= SIGNDUMMY= DO_STATISTICS= RUN_SHELL= RUN_SHELL_AFTER_FAIL= RUN_SHELL_CMD= CCACHE= CCACHE_ARCHIVE= CCACHE_CREATE_ARCHIVE= CCACHE_TYPE= CCACHE_CLEAN= DLNOSIGNATURE= BUILD_FLAVOR= OBS_PACKAGE= OBSURL= NO_TIMESTAMPS= CACHE_DIR= BUILD_DIST_TMP= BUILD_SUCCEEDED= COPY_SOURCES_ASIS= RECIPE_BUILD_START_TIME= CCACHE_SETUP_START_TIME= # set all verbose modes to off by default BUILD_VERBOSE_VM= # This is for insserv export YAST_IS_RUNNING=instsys # https://github.com/systemd/systemd/blob/master/docs/ENVIRONMENT.md export SYSTEMD_OFFLINE=1 unset LANGUAGE unset LANG export LC_ALL=POSIX umask 022 echo_help () { cat << EOT Some comments for build ----------------------- With build you can create binary packages. They will be built in a chroot system. This chroot system will be setup automatically. Normally you can simply call build with a spec file as parameter - nothing else has to be set. If you want to set the directory where the chroot system will be setup (at the moment it uses $BUILD_ROOT), simply set the the environment variable BUILD_ROOT. Example: export BUILD_ROOT=/var/tmp/mybuildroot Normally build builds the complete package including src.rpm (rpmbuild -ba). If you want to let build only make the binary package, simply set export BUILD_RPM_BUILD_STAGE=-bb (or -bc, -bp, -bi, ... see "Maximum RPM" for more details [*]). When the build command succeeds, the rpm files can be found under $BUILD_ROOT/usr/src/packages/RPMS/ Known Parameters: --help You already got it :) --kill Instead of starting a build kill the one currently running. --shell Instead of starting a build start a root shell in the build root. --shell-cmd CMD Run the command CMD instead of giving a root shell --shell option is implicit set. --sysrq $ Sends a single specifed char as sysrq to the running kernel of the build. --clean Delete old build root before initializing it --wipe Completely removes build environment and exits. --no-init Skip initialization of build root and start with build immediately. --no-checks Do not run checks (postbuild and %check) --logfile logfile Capture build output to logfile. Defaults to .build.log in the build root for non-VM builds. --no-timestamps Hide the time prefix in output and logfile. --repo PATH_OR_URL Use package repository at PATH_OR_URL. Supported formats are rpm-md, yast2, debian, and arch linux. Alternatively zypp://NAME specifies the zypp repository NAME. The repo must be refreshed with zypp so package meta data is available locally. With emtpy NAME all enabled repositories are used. --rpms path1:path2:... Specify path where to find the RPMs for the build system --arch arch1:arch2:... Specify what architectures to select from the RPMs --verify Run verify when initializing the build root --extra-packs pack -X pack Also install package 'pack' --root rootdir Use 'rootdir' to setup chroot environment --cachedir cachedir Use 'cachedir' to cache remote repo's packages. The default cache dir is /var/cache/build, every repo given by --repo corresponds to a subdir named as md5sum of its repo url, for example: /var/cache/build/3e8ea9b47808629414a0cebc33ea285e --oldpackages oldpackagesdir Define a directory with a former build --baselibs Create -32bit/-64bit/-x86 rpms for other architectures --list-state List rpms that would be used to create a fresh build root. Does not create the build root or perform a build. --dist dist Distribution to use --with X Enable feature X for build --without X Disable feature X for build --define 'X Y' Define macro X with value Y --release RELEASE Override the Release line in the spec file --stage STAGE Set stage for rpmbuild. Defaults to 'a'. Append a trailing '=' to only run the specified stage. Append a trailing '+' to run the specified stage and all stages coming after it. With no suffix, stages up to and included the specified stage are run. --target platform Set target platform for rpmbuild --jobs N Use N parallel processes during build. Sets %jobs and %_smp_mflags macros and defines the number of CPUs to use for VMs. --threads N sets number of threads for VM --ccache Use ccache to speed up rebuilds --ccache=sccache Use sccache to speed up rebuilds --ccache-archive /path/to/ccache.tar Path to archive of ccache directory content. Its contents will be extracted to /.ccache Implies --ccache. --icecream N Use N parallel build jobs with icecream --overlay OVERLAY Copy overlay filesystem to buildroot after installing all RPMs. This must be a valid directory. --rsync-src RSYNCSRC Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST) inside the buildroot using rsync. It will "%define RSYNCDONE 1" for handling %setup in your specfile. E.g.: %prep %if 0%{?RSYNCDONE} %setup -n aaa_base -T -D -b 5 -b 7 %else %setup -n aaa_base -b 5 -b 7 %endif --rsync-dest RSYNCDEST Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST) inside the buildroot using rsync. --uid uid:gid Specify the uid and gid to use for the abuild user. This is useful if you are hacking in the buildroot. This must be set to the same value if the buildroot is re-used. --statistics monitor used resources during build inside VM --kvm Use KVM to secure build process. Your hardware needs to support virtualization --xen Use XEN to secure build process, you to run in a XEN Dom0 environment. --lxc Use Linux Containers to isolate the process. This may not be 100% safe. --openstack Cloud build --ec2 Cloud build --emulator Use any generic emulator to isolate the build process. You need to write an emulator/emulator.sh script and put it next to the build script sources. --emulator-script SCRIPT specify another emulator instead of emulator.sh --verbose CLASS Verbose output, CLASS can be 'all' or a specific one: vm: includes kernel and initrd messages --vm-type TYPE Use virtual machine instead of chroot TYPE is one of xen|kvm|uml|qemu|lxc|zvm|openstack|ec2|docker|pvm|nspawn --vm-args ARGS Pass extra arguments to virtual machine To pass multiple arguments, separate them with spaces Use regular shell quotes if arguments contain spaces --vm-worker GUEST GUEST is a z/VM build worker controlled by the controlling z/VM build machine. --vm-worker-nr N Each worker in z/VM needs a uniq number. This is needed to calculate uniq device addresses for root and swap device. --vm-region NAME EC2 only: defines amazon control server --vm-server NAME openstack only: defines control server name --vm-disk FILE Use FILE as disk for virtual machine. Defaults to \$BUILD_ROOT.img if unset --vm-swap FILE Use FILE as swap space for virtual machine. The swap space is also used for retrieving packages from the VM so its size must be sufficiently large --vm-disk-size SIZEINMB --vm-swap-size SIZEINMB --vm-disk-filesystem TYPE Defaults for automatic setup of VM root/swap files. May get overruled by build config vmfstype build flag. --vm-disk-filesystem-options OPTIONS nodirindex: disable dir indexing on ext filesystems. Slower, but more reproducible builds --vm-use-mkfs-copyin Avoid mounting in the preinstall phase for VM builds. Instead, copy files into the filesystem during filesystem creation time. Currently limited to the ext filesystems. --vm-memory SIZEINMB Set amount of RAM for VMs --vm-hugetlbfs HUGETLBFSPATH Use hugetlb for memory management, path to mounted hugetlbfs. --vm-kernel FILE --vm-initrd FILE --vm-cmdline STRING Kernel and initrd to use for VM (kvm and qemu only) Cmdline to specify additional arguments --vm-user USERNAME User name to run qemu/kvm process --vm-telnet PORT Forward the PORT to a telnet session inside of the VM. Specify the needed extra packages via -x parameter, usually: --vm-telnet 1234 -x telnet-server -x net-tools And connect from the host via telnet 1234 The telnet server is started after all packages got installed. --vm-network Enable network inside of VM with the default qemu SLIRP user network. WARNING: this breaks reproducibility and allows to attack your network when building untrusted content. --vm-net OPTION --vm-netdev OPTION --vm-device OPTION KVM only: Attach kvm option Available options are -net, -netdev, -device (This options in kvm can not guarantee reproducible builds) --debuginfo Enable creation of debuginfo packages --buildflavor FLAVOR Specify the flavor to build. For rpm builds, it replaces the @BUILD_FLAVOR@ macro in the spec file. --changelog Append the rpm changelog from a SUSE .changes file to the spec file --norootforbuild Force building with user 'abuild', ignore the "needsrootforbuild" hint from the recipe file Remember to have fun! [*] Maximum RPM: http://www.rpm.org/max-rpm/ EOT } usage () { cleanup_and_exit 1 "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|recipe-to-build]" } # # cleanup_and_exit # return values: 0 -> success, new packages built # 1 -> error, build failed # 2 -> successfull build, but no changes to former built packages # 3 -> something wrong with build or the host, leads to a retry # 4 -> something FATAL with build or the host, leads to a retry, but do not build on this host anymore # cleanup_and_exit () { trap EXIT test -z "$1" && set 0 if test -n "$2" ; then if test "$1" -ne 0 ; then echo "$2" >&2 else echo "$2" fi fi test -n "$BUILD_DIST_TMP" && rm -f "$BUILD_DIST_TMP" if test -z "$BUILD_OPTIONS_PARSED" ; then # if we have not yet parsed the options we do # not know the correct build root. just exit. exit $1 fi rm -f $BUILD_ROOT/exit # run a shell in failure case if wanted by user if test -n "$RUN_SHELL_AFTER_FAIL" -a "$BUILD_SUCCEEDED" = false -a "$1" = 1 ; then unset BUILD_SUCCEEDED run_shell $1 fi # add build time statistics recipe_build_time_statistics # Never inside of VM # but for chroot or the filesystem hosting the root file if test -z "$RUNNING_IN_VM" ; then # check for disk full for an automatic build retry if test "$1" -eq 1 -a -x /bin/df ; then echo echo "$HOST failed \"build $RECIPEFILE\" at `date --utc`." echo # okay, it failed, but maybe because disk space? if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then df $BUILD_ROOT 2>/dev/null echo echo "$HOST ran out of disk space. Please try again." echo set 3 fi fi fi if test -z "$VM_TYPE" -o -n "$RUNNING_IN_VM" ; then # run recipe cleanup code test -n "$BUILDTYPE" && recipe_cleanup fi # shutdown if test -n "$RUNNING_IN_VM" ; then echo "$1" > /.build/_exitcode test -n "$browner" && chown "$browner" $BUILD_ROOT vm_shutdown "$1" else buildroot_umount /proc/sys/fs/binfmt_misc buildroot_umount /proc buildroot_umount /sys buildroot_umount /dev/pts buildroot_umount /dev/shm test -n "$VM_ROOT" -a "$VM_ROOT" != 1 && umount $BUILD_ROOT 2>/dev/null || true test -n "$VM_TYPE" && vm_cleanup fi exit $1 } fail_exit() { cleanup_and_exit 1 } shellquote() { for arg ; do arg=${arg//\\/\\\\} arg=${arg//\$/\\\$} arg=${arg//\"/\\\"} arg=${arg//\`/\\\`} echo -n " \"$arg\"" done } # create a shell script from command line. Used for preserving arguments # through /bin/su -c toshellscript() { echo "#!/bin/sh -x" echo -n exec shellquote "$@" echo } ccache_unpack() { local dir="$1" local ty="$2" echo "Unpacking $ty archive" tar -xf "$CCACHE_ARCHIVE" -C "$dir/" if test -s "$dir/.build.ccache.type" ; then local t read t < "$dir/.build.ccache.type" if test "$ty" != "$t" ; then echo "$ty archive is of type $t, cleaning cache" rm -rf "$dir" mkdir -p "$dir" fi rm -f "$dir/.build.ccache.type" fi } ccache_pack() { local dir="$1" local ty="$2" echo "... saving $ty archive" rm -rf "$dir/.build.ccache.type" local remove_files test -n "$RUNNING_IN_VM" -a -n "$CCACHE_CLEAN" && remove_files="--remove-files" echo "$ty" > "$dir/.build.ccache.type" tar $remove_files -cf "$BUILD_ROOT/$TOPDIR/OTHER/_ccache.tar" -C "$dir/" . rm -f "$dir/.build.ccache.type" } ccache_setup() { CCACHE_SETUP_START_TIME= if test -n "$CCACHE" -a "$CCACHE_TYPE" = sccache ; then sccache_setup return fi if test -n "$CCACHE" -a "$CCACHE_TYPE" = ccache ; then CCACHE_SETUP_START_TIME=$SECONDS if mkdir -p $BUILD_ROOT/var/lib/build/ccache/bin; then for i in $(ls $BUILD_ROOT/usr/bin | grep -E '^(cc|gcc|[cg][+][+]|clang|clang[+][+])([-]?[.0-9])*$'); do rm -f $BUILD_ROOT/var/lib/build/ccache/bin/$i test -e $BUILD_ROOT/usr/bin/$i || continue echo '#! /bin/sh' > $BUILD_ROOT/var/lib/build/ccache/bin/$i echo "test -e /usr/bin/$i || exit 1" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:/usr/bin:$PATH' >> $BUILD_ROOT/var/lib/build/ccache/bin/$i echo "ccache $i \"\$@\"" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i chmod 755 $BUILD_ROOT/var/lib/build/ccache/bin/$i echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i" done fi mkdir -p "$BUILD_ROOT/.ccache" echo 'export PATH=/var/lib/build/ccache/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_ccache.sh local cconf="$BUILD_ROOT"/etc/ccache.conf if test -e $cconf; then grep -q "^compression*" $cconf && sed -i "s:compression.*:compression = true:g" $cconf || echo "compression = true" >> $cconf grep -q "^cache_dir*" $cconf && sed -i "s:cache_dir.*:cache_dir = /.ccache:g" $cconf || echo "cache_dir = /.ccache" >> $cconf else echo "compression = true" >> $cconf echo "cache_dir = /.ccache" >> $cconf fi test -n "$CCACHE_ARCHIVE" -a -e "$CCACHE_ARCHIVE" && ccache_unpack "$BUILD_ROOT/.ccache" ccache chown -hR "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.ccache" else rm -f "$BUILD_ROOT"/var/lib/build/ccache/bin/{gcc,g++,cc,c++,clang,clang++} fi } ccache_wrapup() { if test -n "$CCACHE" -a "$CCACHE_TYPE" = sccache ; then sccache_wrapup return fi if test -n "$CCACHE" -a "$CCACHE_TYPE" = ccache ; then if test -n "$CCACHE_CLEAN" ; then echo "... cleaning ccache" test_cmd="ccache -h | grep -c evict-older-than" clean_cmd="ccache --evict-older-than $(( $SECONDS - $CCACHE_SETUP_START_TIME ))s" chroot $BUILD_ROOT su -c "$test_cmd && $clean_cmd" - $BUILD_USER fi test -n "$CCACHE_CREATE_ARCHIVE" && ccache_pack "$BUILD_ROOT/.ccache" ccache fi } sccache_setup() { if test -n "$CCACHE" -a "$CCACHE_TYPE" = sccache ; then CCACHE_SETUP_START_TIME=$SECONDS # This first redir clears the file. echo 'export CARGO_INCREMENTAL=false' > "$BUILD_ROOT"/etc/profile.d/build_sccache.sh echo 'export RUSTC_WRAPPER=sccache' >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh echo 'export CC="sccache cc"' >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh echo 'export CXX="sccache c++"' >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh if test "$CCACHE_ARCHIVE" != "${CCACHE_ARCHIVE#redis://}" ; then echo "export SCCACHE_REDIS=${CCACHE_ARCHIVE}" >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh else echo 'export SCCACHE_DIR="/.sccache"' >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh echo 'export SCCACHE_CACHE_SIZE="1280M"' >> "$BUILD_ROOT"/etc/profile.d/build_sccache.sh mkdir -p "$BUILD_ROOT/.sccache" test -n "$CCACHE_ARCHIVE" -a -e "$CCACHE_ARCHIVE" && ccache_unpack "$BUILD_ROOT/.sccache" sccache chown -hR "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.sccache" fi # Display sccache status at the start of the build. chroot $BUILD_ROOT su -c "sccache -s" - $BUILD_USER fi } sccache_wrapup() { if test -n "$CCACHE" -a "$CCACHE_TYPE" = sccache ; then # Display sccache statistics post build. chroot $BUILD_ROOT su -c "sccache -s" - $BUILD_USER # Pack archive unless redis was used if test -n "$CCACHE_CREATE_ARCHIVE" ; then if test "$CCACHE_ARCHIVE" = "${CCACHE_ARCHIVE#redis://}" ; then ccache_pack "$BUILD_ROOT/.sccache" sccache fi fi fi } setupicecream() { local icecreamdir=/var/run/icecream if test "$(readlink "$BUILD_ROOT/var/run")" = /run ; then icecreamdir=/run/icecream fi if test "$icecream" -eq 0 ; then rm -rf "$BUILD_ROOT$icecreamdir" rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh" return 0 fi if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then echo "*** icecream package not installed ***" return 1 fi echo "using icecream with $icecream jobs" if test -z "$CCACHE" ; then echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh else echo 'export CCACHE_PATH=/usr/lib/icecc/bin:/opt/icecream/bin' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh fi local icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT$icecreamdir/*.tar.{bz2,gz}`) icecc_vers=${icecc_vers//$BUILD_ROOT/} # XXX use changelog like autobuild does instead? # only run create-env if compiler or glibc changed if test -z "$icecc_vers" \ -o ! -e "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/gcc" -nt "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/g++" -nt "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/as" -nt "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers" then rm -rf "$BUILD_ROOT$icecreamdir" mkdir -p "$BUILD_ROOT$icecreamdir" if test -e "$BUILD_ROOT"/usr/bin/create-env ; then createenv=/usr/bin/create-env elif test -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ; then createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX elif test -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ; then createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX else echo "create-env not found" return 1 fi echo "creating new env in '$icecreamdir'" chroot $BUILD_ROOT bash -c "cd $icecreamdir; $createenv" || cleanup_and_exit 1 icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/$icecreamdir/*.tar.{bz2,gz}`) icecc_vers=${icecc_vers//$BUILD_ROOT/} echo "created icecream environment $icecc_vers" else echo "reusing existing icecream environment $icecc_vers" fi if test -n "$icecc_vers" ; then echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh fi } setmemorylimit() { if test -n "$VM_ROOT" -o -n "$RUNNING_IN_VM" ; then return fi local mem local limit while read mem; do case "$mem" in MemTotal:*) set -- $mem eval "limit=\$(($2/3*2))" ;; SwapTotal:*) set -- $mem eval "limit=\$(($2/3*2+$limit))" ;; esac done < <(cat /proc/meminfo) # cat for proc stuff ulimit -d $limit echo "Memory limit set to ${limit}KB" } create_baselibs() { local pkgs=() local line BASELIBS_CFG= if test "$BUILDTYPE" == arch || test "$BUILDTYPE" = collax ; then return fi if test "$BUILDTYPE" == dsc ; then pkgs=($DEBS) else # spec and kiwi if test -e $BUILD_ROOT$TOPDIR/SOURCES/baselibs.conf ; then BASELIBS_CFG="-c $TOPDIR/SOURCES/baselibs.conf" fi if test -e $BUILD_ROOT/usr/lib/build/baselibs_global.conf; then BASELIBS_GLOBAL="-c /usr/lib/build/baselibs_global.conf" fi pkgs=($RPMS) fi # don't use -R as extracted sources, build root etc might be below $TOPDIR chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/RPMS/* || true local mkbaselibs="/usr/lib/build/mkbaselibs" local whichone='' # $BUILD_DIR is set to /.build when using a vm. So we need to # hardcode /usr/lib/build instead of $BUILD_DIR to prefer # mkbaselibs from the distro. if test -f $BUILD_ROOT$mkbaselibs; then if test -z "$BASELIBS_CFG" -a -e $BUILD_ROOT/usr/lib/build/baselibs.conf ; then BASELIBS_CFG="-c /usr/lib/build/baselibs.conf" fi else if test "$CREATE_BASELIBS" = 'internal'; then echo "Warning: mkbaselibs missing in build root, skipping baselibs" return fi # use external version whichone=" (external)" mkbaselibs="/.mkbaselibs/mkbaselibs" rm -rf "$BUILD_ROOT/.mkbaselibs" mkdir -p "$BUILD_ROOT/.mkbaselibs" cp -f $BUILD_DIR/mkbaselibs $BUILD_ROOT/.mkbaselibs/ if test "$BUILDTYPE" == "dsc" ; then cp -f $BUILD_DIR/baselibs_global-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf cp -f $BUILD_ROOT$TOPDIR/SOURCES/baselibs-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs-deb.conf BASELIBS_CFG="-c /.mkbaselibs/baselibs-deb.conf" else cp -f $BUILD_DIR/baselibs_global.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf if test -z "$BASELIBS_CFG" -a -e $BUILD_DIR/baselibs.conf; then cp -f $BUILD_DIR/baselibs.conf $BUILD_ROOT/.mkbaselibs/baselibs.conf BASELIBS_CFG="-c /.mkbaselibs/baselibs.conf" fi fi if test -e $BUILD_ROOT/.mkbaselibs/baselibs_g.conf; then BASELIBS_GLOBAL="-c /.mkbaselibs/baselibs_g.conf" fi fi echo "... creating baselibs$whichone" while read line; do chroot $BUILD_ROOT su -c "$mkbaselibs $BASELIBS_GLOBAL $BASELIBS_CFG $line" - $BUILD_USER || cleanup_and_exit 1 done < <(IFS=$'\n'; echo "${pkgs[*]#$BUILD_ROOT}" | xargs -n 1024) rm -rf "$BUILD_ROOT/.mkbaselibs" } copy_oldpackages() { local i=0 local d local dest test -z "$RUNNING_IN_VM" || return 0 if test -z "$old_packages" ; then rm -rf "$BUILD_ROOT"/.build.oldpackages* return 0 fi for d in "${old_packages[@]}"; do dest="$BUILD_ROOT/.build.oldpackages" test "$i" = 0 || dest="$dest$i" if test -d "$d" -a "$d" != "$dest" ; then rm -rf "$dest" mkdir -p "$dest" cp -L $d/* "$dest" : $((++i)) fi done } copy_sources() { local include_directories if test -n "$RUNNING_IN_VM" -o "$BUILDTYPE" = kiwi -o "$BUILDTYPE" = docker -o "$BUILDTYPE" = fissile -o "$BUILDTYPE" = podman ; then include_directories=true fi if test -n "$RUNNING_IN_VM" -o -n "$COPY_SOURCES_ASIS" -o -n "$RPM_BUILD_IN_PLACE" ; then ( shopt -s nullglob ; cp -pRd "$1/".[^.]* "$1/"..?* "$1"/* "$2" ) elif test -n "$include_directories" ; then cp -pRL "$1"/* "$2" elif test -e "$1/.git" ; then # check which directory belongs to the git repository and only copy those type -p git >& /dev/null || cleanup_and_exit 1 "need git to check file status" for i in "$1/".* "$1"/* ; do local ii="${i##*/}" test "$ii" = . -o "$ii" = .. -o "$ii" = .git && continue if test -L "$i" -o -d "$i" -o "${ii#.}" != "$ii" ; then if test -e "$i/.build.asset" || git -C "$1" --noglob-pathspecs ls-files --error-unmatch -- "$ii" >& /dev/null ; then cp -pRd "$i" "$2" continue fi test "${ii#.}" != "$ii" && continue fi cp -p "$i" "$2" done if test -f "$1/debian/control" ; then echo "exporting debian orig tarballs" $BUILD_DIR/export_debian_orig_from_git "$1" "$2/build.origtar" || cleanup_and_exit 1 "export_debian_orig_from_git failed" fi else cp -p "$1"/* "$2" fi test -n "$RPM_BUILD_IN_PLACE" -a -z "$RUNNING_IN_VM" && cp -f "$RECIPEPATH" "$2" } mkdir_build_root() { # strip trailing slash test "$BUILD_ROOT" != / && BUILD_ROOT="${BUILD_ROOT%/}" if test -d "$BUILD_ROOT" ; then # check if it is owned by root if test -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ; then cleanup_and_exit 1 "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..." fi else test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}" if ! mkdir $BUILD_ROOT ; then cleanup_and_exit 1 "can not create BUILD_ROOT=$BUILD_ROOT. Exit..." fi fi if test ! -w "$BUILD_ROOT" ; then cleanup_and_exit 4 "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean." fi rm -rf "$BUILD_ROOT/.build.packages" if test -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then # don't touch this in VM rm -rf "$BUILD_ROOT/.build" mkdir -p "$BUILD_ROOT/.build" fi } copy_overlay() { if test -d "$OVERLAY"; then pushd $OVERLAY echo "Copying overlay to BUILD_ROOT" tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -) popd else echo "OVERLAY ($OVERLAY) is no directory - skipping" fi } run_rsync() { if test -n "$RSYNCDEST" ; then if test -d "$RSYNCSRC" ; then if ! test -d "$BUILD_ROOT/$RSYNCDEST" ; then echo "ATTENTION! Creating missing target directory ($BUILD_ROOT/$RSYNCDEST)." mkdir -p $BUILD_ROOT/$RSYNCDEST fi echo "Running rsync ..." rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/ chown -hR "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST" RSYNCDONE=true echo "... done" else echo "RSYNCSRC is not a directory - skipping" fi else echo "RSYNCSRC given, but not RSYNCDEST - skipping" fi } wipe_build_environment() { if test -n "$VM_TYPE" ; then vm_img_wipe else echo "Wiping build root: '$BUILD_ROOT'" # unmount all mounts still in the build root path for m in $(cat /proc/mounts | grep "$BUILD_ROOT" | awk '{ print $2 }'); do if ! umount -n "$m" 2>/dev/null ; then echo "Failed to umount "$m", cannot wipe buildroot" exit 1 fi done rm -rf "$BUILD_ROOT" fi } sysrq_running_build() { test -z "$SRCDIR" || usage if test -n "$VM_TYPE" ; then vm_sysrq "$1" else cleanup_and_exit 1 "can not send a sysrq to chroot builds" fi } kill_running_build() { test -z "$SRCDIR" || usage (set -C; > "$BUILD_ROOT/exit" || true) 2>/dev/null if test -n "$VM_TYPE" ; then # mark job as failed so that we don't extract packages vm_set_buildstatus 1 vm_kill else if ! $BUILD_DIR/killchroot -s 9 $BUILD_ROOT ; then cleanup_and_exit 1 "could not kill build in $BUILD_ROOT" fi fi } mount_stuff() { if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm mkdir -p $BUILD_ROOT/proc mkdir -p $BUILD_ROOT/sys mkdir -p $BUILD_ROOT/dev/pts mkdir -p $BUILD_ROOT/dev/shm mount -n -tproc none $BUILD_ROOT/proc mount -n -tsysfs none $BUILD_ROOT/sys mount -n -tdevpts -omode=0620,ptmxmode=0666,gid=5 none $BUILD_ROOT/dev/pts mount -n -ttmpfs none $BUILD_ROOT/dev/shm fi } umount_stuff() { if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then buildroot_umount /proc/sys/fs/binfmt_misc buildroot_umount /proc buildroot_umount /sys buildroot_umount /dev/pts buildroot_umount /dev/shm fi } #### main #### trap fail_exit EXIT . $BUILD_DIR/common_functions || exit 1 detect_cache_dir shopt -s nullglob export PATH=$BUILD_DIR:/sbin:/usr/sbin:/bin:/usr/bin:$PATH if vm_detect_2nd_stage ; then set "/.build-srcdir/$RECIPEFILE" export PATH=/.build:$PATH fi export HOST needarg() { if test -z "$ARG" ; then cleanup_and_exit 1 "$PARAM needs an agrument" fi } run_shell() { local ex="$1" echo "Executing interactive shell..." if test -n "$RUN_SHELL_CMD"; then chroot $BUILD_ROOT "$RUN_SHELL_CMD" cleanup_and_exit ${ex:-$?} else chroot $BUILD_ROOT su - $BUILD_USER cleanup_and_exit ${ex:-$?} fi } validate_init "$BUILD_CONF" while test -n "$1"; do PARAM="$1" ARG="$2" test "$ARG" = "${ARG#-}" || ARG= shift case $PARAM in *-*=*) ARG=${PARAM#*=} PARAM=${PARAM%%=*} set -- "----noarg=$PARAM" "$@" ;; esac case ${PARAM/#--/-} in -help|-h) echo_help cleanup_and_exit ;; -noinit|-no-init) test "$DO_INIT" = false && DO_INIT_TOPDIR=false DO_INIT=false ;; -nochecks|-no-checks) DO_CHECKS=false ;; -clean) test "$CLEAN_BUILD" = '--clean' && GENBUILDREQS_CLEAN_BUILD='--clean' CLEAN_BUILD='--clean' CCACHE_CLEAN="$CLEAN_BUILD" ;; -wipe) DO_WIPE=true ;; -kill) KILL=true ;; -rpms) needarg BUILD_RPMS="$ARG" shift ;; -arch) needarg BUILD_ARCH="$ARG" shift ;; -hostarch|-host-arch) needarg BUILD_HOST_ARCH="$ARG" shift ;; -verify) export VERIFY_BUILD_SYSTEM=true ;; -target) needarg ABUILD_TARGET="$ARG" shift ;; -jobs) needarg BUILD_JOBS="$ARG" shift ;; -threads) needarg BUILD_THREADS="$ARG" shift ;; -extrapacks|-extra-packs|-X) needarg BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG" shift ;; -lint) # OBSOLETE: just keeping it for compability DO_LINT=true ;; -baselibs) CREATE_BASELIBS=true ;; -baselibs-internal) CREATE_BASELIBS=internal ;; -root) needarg BUILD_ROOT="$ARG" shift ;; -cachedir) needarg CACHE_DIR="$ARG" shift ;; -oldpackages) needarg old_packages=("${old_packages[@]}" "$ARG") shift ;; -dist) needarg BUILD_DIST="$ARG" shift ;; -release) needarg RELEASE="$ARG" shift ;; -logfile) needarg LOGFILE="$ARG" shift ;; -no-timestamps) NO_TIMESTAMPS=true ;; -reason) needarg REASON="$ARG" shift ;; -norootforbuild) NOROOTFORBUILD=true ;; -useusedforbuild) USEUSEDFORBUILD="--useusedforbuild" ;; -configdir) needarg CONFIG_DIR="$ARG" shift ;; -list*state) LIST_STATE=true ;; -define|-with|-without) needarg PARAM="-${PARAM/#--/-}" definesnstuff[${#definesnstuff[@]}]="$PARAM" definesnstuff[${#definesnstuff[@]}]="$ARG" shift ;; -repository|-repo) needarg repos[${#repos[@]}]="--repository" repos[${#repos[@]}]="$ARG" shift ;; -icecream) needarg icecream="$ARG" test "$icecream" -gt 0 && BUILD_JOBS="$ARG" shift ;; -ccache) CCACHE=true if test "$1" != "${1#--noarg=}" ; then needarg CCACHE_TYPE="$ARG" shift fi ;; -ccache-type) needarg CCACHE_TYPE="$ARG" shift ;; -pkg-ccache|-ccache-archive) needarg CCACHE_ARCHIVE="$ARG" shift CCACHE=true ;; -ccache-create-archive) CCACHE_CREATE_ARCHIVE=true ;; -sccache) CCACHE=true CCACHE_TYPE=sccache shift ;; -sccache-uri|-sccache-archive) needarg CCACHE_ARCHIVE="$ARG" shift CCACHE=true CCACHE_TYPE=sccache ;; -statistics) DO_STATISTICS=1 ;; -debug|-debuginfo) BUILD_DEBUG=1 ;; -incarnation) needarg INCARNATION=$ARG shift ;; -disturl) needarg DISTURL=$ARG shift ;; -linksources) LINKSOURCES=true ;; -changelog) CHANGELOG=true ;; -overlay) needarg OVERLAY=$ARG shift ;; -rsync-src) needarg RSYNCSRC=$ARG shift ;; -rsync-dest) needarg RSYNCDEST=$ARG shift ;; -verbose) needarg case "$ARG" in all) BUILD_VERBOSE_VM=true ;; vm) BUILD_VERBOSE_VM=true ;; *) echo "WARNING: unknown verbose option $ARGS" ;; esac shift ;; -uid) needarg if test -n "${ARG//[0-9:]/}" ; then cleanup_and_exit 1 "--uid argument must be uid:gid" fi ABUILD_UID=${ARG%:*} ABUILD_GID=${ARG#*:} shift ;; -rpmlist) needarg RPMLIST="--rpmlist $ARG" BUILD_RPMS= shift ;; -sysrq) needarg SEND_SYSRQ="${ARG:0:1}" shift ;; -shell) RUN_SHELL=1 ;; -shell-after-fail) RUN_SHELL_AFTER_FAIL=1 ;; -shell-cmd) needarg RUN_SHELL=1 RUN_SHELL_CMD="$ARG" shift ;; -signdummy) SIGNDUMMY=1 ;; -nosignature) DLNOSIGNATURE="--nosignature" ;; -obsmultibuild|-obs-multibuild|-buildflavor|-build-flavor) needarg BUILD_FLAVOR=$ARG shift ;; -obspackage|-obs-package) needarg OBS_PACKAGE=$ARG shift ;; -obs) needarg OBSURL=$ARG shift ;; -copy-sources-asis) COPY_SOURCES_ASIS=true ;; ---noarg) cleanup_and_exit 1 "$ARG does not take an argument" ;; -*) if vm_parse_options "$@" ; then set -- "${nextargs[@]}" elif recipe_parse_options "$@" ; then set -- "${nextargs[@]}" else cleanup_and_exit 1 "Unknown option '$PARAM'. Exit." fi ;; *) RECIPEFILES[${#RECIPEFILES[@]}]="$PARAM" # skip validation PARAM= ;; esac if test -n "$PARAM" ; then validate_param "$PARAM" "$ARG" fi done # validate params coming from the environment test -n "$BUILD_ARCH" && validate_param "--arch" "$BUILD_ARCH" BUILD_ARCH test -n "$BUILD_HOST_ARCH" && validate_param "--hostarch" "$BUILD_HOST_ARCH" BUILD_HOST_ARCH test -n "$BUILD_RPMS" && validate_param "--rpms" "$BUILD_RPMS" BUILD_RPMS test -n "$BUILD_EXTRA_PACKS" && validate_param "--extrapacks" "$BUILD_EXTRA_PACKS" BUILD_EXTRA_PACKS test -n "$BUILD_DIST" && validate_param "--dist" "$BUILD_DIST" BUILD_DIST test -n "$VERIFY_BUILD_SYSTEM" && validate_param "--verify" "$VERIFY_BUILD_SYSTEM" VERIFY_BUILD_SYSTEM test -n "$BUILD_RPM_BUILD_STAGE" && validate_param "--stage" "$BUILD_RPM_BUILD_STAGE" BUILD_RPM_BUILD_STAGE test "$BUILD_ROOT" != /var/tmp/build-root && validate_param "--root" "$BUILD_ROOT" BUILD_ROOT test "$CONFIG_DIR" != "$BUILD_DIR/configs" && validate_param "--configdir" "$CONFIG_DIR" CONFIG_DIR # validate the buildroot validate_buildroot "$BUILD_ROOT" if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then vm_verify_options vm_set_defaults fi initbuildsysstuff=() if test -n "$BUILD_FLAVOR" ; then initbuildsysstuff[${#initbuildsysstuff[@]}]="--buildflavor" initbuildsysstuff[${#initbuildsysstuff[@]}]="$BUILD_FLAVOR" fi if test -n "$OBS_PACKAGE" ; then initbuildsysstuff[${#initbuildsysstuff[@]}]="--obspackage" initbuildsysstuff[${#initbuildsysstuff[@]}]="$OBS_PACKAGE" fi if test -n "$OBSURL" ; then initbuildsysstuff[${#initbuildsysstuff[@]}]="--obs" initbuildsysstuff[${#initbuildsysstuff[@]}]="$OBSURL" fi if test -n "$RPM_BUILD_IN_PLACE"; then initbuildsysstuff[${#initbuildsysstuff[@]}]="--define" initbuildsysstuff[${#initbuildsysstuff[@]}]="_build_in_place 1" fi if test -n "$DO_WIPE" ; then wipe_build_environment cleanup_and_exit fi if test -n "$KILL" ; then kill_running_build cleanup_and_exit fi if test -n "$SEND_SYSRQ" ; then sysrq_running_build "$SEND_SYSRQ" cleanup_and_exit fi # done option parsing BUILD_OPTIONS_PARSED=true if test -n "$CLEAN_BUILD" ; then DO_INIT=true DO_INIT_TOPDIR=true fi if test -n "$CCACHE" ; then test -z "$CCACHE_TYPE" && CCACHE_TYPE=ccache # automatically use ccache archive from an old build if test -z "$CCACHE_ARCHIVE" -a -n "${old_packages[0]}" -a -e "${old_packages[0]}/_ccache.tar" ; then CCACHE_ARCHIVE="${old_packages[0]}/_ccache.tar" fi fi if test -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ; then if test -z "$repos" -a -z "$BUILD_RPMS" -a "$BUILD_DIST" = "${BUILD_DIST#obs:/}"; then repos=(--repository 'zypp://') fi else repos=() fi set_build_arch if test "$DO_INIT" = false -a -n "$RUN_SHELL" -a -z "$VM_TYPE"; then mount_stuff BUILD_USER=root test -n "$NOROOTFORBUILD" && BUILD_USER=abuild chroot $BUILD_ROOT su - $BUILD_USER cleanup_and_exit $? fi expand_recipe_directories if test -n "$LIST_STATE" ; then BUILD_ROOT=`mktemp -d /var/tmp/build-list-state-XXXXXX` test -d "$BUILD_ROOT" || cleanup_and_exit 3 RECIPEPATH=$RECIPEFILES # only one specified anyways test "$RECIPEPATH" != "${RECIPEPATH%.src.rpm}" && recipe_unpack_srcrpm "$RECIPEPATH" init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${initbuildsysstuff[@]}" "${definesnstuff[@]}" "${repos[@]}" $DLNOSIGNATURE $USEUSEDFORBUILD $RECIPEPATH $BUILD_EXTRA_PACKS ERR=$? rm -rf "$BUILD_ROOT" cleanup_and_exit $ERR fi # do vm setup if needed if test -z "$RUNNING_IN_VM" -a -n "$VM_TYPE" -a -n "$VM_ROOT" ; then vm_setup fi mkdir_build_root if test "$BUILD_ROOT" = / ; then browner="$(stat -c %u /)" fi rm -f $BUILD_ROOT/exit if test -z "$VM_ROOT" -a -z "$LOGFILE" ; then if test -z "$RUNNING_IN_VM"; then LOGFILE="$BUILD_ROOT/.build.log" else # lxc, docker and nspawn are special cases: vm shares logfile with host case "$VM_TYPE" in lxc|docker|nspawn) ;; *) LOGFILE="$BUILD_ROOT/.build.log" ;; esac fi fi if test -n "$LOGFILE" -a -z "$RUN_SHELL" ; then echo "logging output to $LOGFILE..." rm -f "$LOGFILE" "$LOGFILE.pid" touch $LOGFILE # set start time, to be substracted for build log timestamps STARTTIME=`perl -e 'print time()'` if test -n "$RUN_SHELL_AFTER_FAIL" ; then # we may run a shell, so no stdout wrapper : elif test -n "$RUNNING_IN_VM" -o -n "$NO_TIMESTAMPS" ; then # no additional timestamps in inner vm build system exec 1> >(echo "$BASHPID" > $LOGFILE.pid ; exec -a 'build logging' tee -a $LOGFILE) 2>&1 elif test -n "$VM_ROOT" ; then # external run of virtualization build 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 else # plain chroot 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 fi fi setmemorylimit case $BUILD_DIST in obs:/*) test -n "$OBSURL" || cleanup_and_exit 1 "Please use the --obs option to specify the url of the obs instance" BUILD_DIST_TMP=$(mktemp) $BUILD_DIR/queryobs config --obs "$OBSURL" "$BUILD_DIST" > "$BUILD_DIST_TMP" if test -z "$repos" ; then for repo in $($BUILD_DIR/queryobs expandpath --obs "$OBSURL" "$BUILD_DIST") ; do repos[${#repos[@]}]="--repository" repos[${#repos[@]}]="$repo" done fi BUILD_DIST="$BUILD_DIST_TMP" ;; esac # # say hello # test -z "$HOST" && HOST=`hostname` if test -z "$RUNNING_IN_VM" ; then echo Using BUILD_ROOT=$BUILD_ROOT test -n "$BUILD_RPMS" && echo Using BUILD_RPMS=$BUILD_RPMS echo Using BUILD_ARCH=$BUILD_ARCH test -n "$VM_TYPE" && echo "Doing $VM_TYPE build${VM_ROOT:+ in $VM_ROOT}" echo fi test "$BUILD_ARCH" = all && BUILD_ARCH= BUILD_USER_ABUILD_USED= MODULEMDFILE= for RECIPEPATH in "${RECIPEFILES[@]}" ; do if test -n "$RPM_BUILD_IN_PLACE" -a -n "$RPM_RECIPE_IN_SUBDIR" -a -z "$RUNNING_IN_VM" ; then SRCDIR=${RECIPEPATH%/*} SRCDIR=${SRCDIR%/*} RECIPEFILE="${RECIPEPATH##*/}" elif test -n "$RPM_BUILD_IN_PLACE" -a -z "$RUNNING_IN_VM" ; then SRCDIR="$PWD" RECIPEFILE="${RECIPEPATH##*/}" elif test "$RECIPEPATH" != "${RECIPEPATH%/debian/control}" ; then SRCDIR="${RECIPEPATH%/debian/control}" RECIPEFILE="debian/control" else SRCDIR="${RECIPEPATH%/*}" RECIPEFILE="${RECIPEPATH##*/}" fi if test "$RECIPEFILE" = "_slsa_provenance.json" -o "$RECIPEFILE" != "${RECIPEFILE%.slsa_provenance.json}" ; then MYSRCDIR="$BUILD_ROOT/.build-srcdir" rm -rf "$MYSRCDIR" mkdir -p "$MYSRCDIR" cd "$MYSRCDIR" || cleanup_and_exit 1 $BUILD_DIR/unpack_slsa_provenance "$RECIPEPATH" "$MYSRCDIR" || cleanup_and_exit 1 "Could not unpack slsa provenance file" SRCDIR="$MYSRCDIR" RECIPEFILE= while read k ; do case $k in recipe=*) RECIPEFILE="${k#*=}" ;; release=*) test -z "$RELEASE" && RELEASE="${k#*=}" ;; debuginfo=*) BUILD_DEBUG=1 ;; esac done < .build.params test -z "$RECIPEFILE" && cleanup_and_exit 1 "recipe not set in build parameters" RECIPEPATH="$SRCDIR/$RECIPEFILE" RPMLIST="--rpmlist $MYSRCDIR/.build.rpmlist" BUILD_RPMS= BUILD_DIST="$SRCDIR/.build.config" repos=() fi recipe_set_buildtype if test -z "$RUNNING_IN_VM" ; then echo echo "$HOST started \"build $RECIPEFILE\" at `date --utc`." echo test -n "$REASON" && echo "$REASON" echo TIME_START_TIME=$SECONDS # for statistics fi # # first setup building directory... # cd "$SRCDIR" if ! test -s "$RECIPEPATH" ; then cleanup_and_exit 1 "$RECIPEFILE is empty. This should not happen..." fi MYSRCDIR="$SRCDIR" # remember the modulemd file if we have one test -s _modulemd.yml && MODULEMDFILE="$SRCDIR/_modulemd.yml" test -s _modulemd.yaml && MODULEMDFILE="$SRCDIR/_modulemd.yaml" test -s _modulemd.pst && MODULEMDFILE="$SRCDIR/_modulemd.pst" # special hack to build from a .src.rpm (modifies MYSRCDIR) test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" && recipe_unpack_srcrpm "$RECIPEPATH" echo "processing recipe $RECIPEPATH ..." ADDITIONAL_PACKS= test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS" test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build" test -z "$CCACHE" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $CCACHE_TYPE" test "$icecream" = 0 || ADDITIONAL_PACKS="$ADDITIONAL_PACKS icecream gcc-c++" test -z "$DO_LINT" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS rpmlint-Factory" test "$VMDISK_FILESYSTEM" = xfs && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1" test "$VM_TYPE" = zvm && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2" # we need to do this before the vm is started if test -n "$CHANGELOG" -a -z "$RUNNING_IN_VM" -a -z "$RUN_SHELL" ; then recipe_create_changelog "$RECIPEPATH" fi if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then vm_first_stage cleanup_and_exit fi if test "$DO_INIT" = true ; then start_time=$SECONDS # # create legacy .buildenv file # test -z "$INCARNATION" && INCARNATION=0 echo "BUILD_INCARNATION=$INCARNATION" > $BUILD_ROOT/.buildenv Q="'\''" test -n "$DISTURL" && echo "BUILD_DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.buildenv test "$BUILDTYPE" = preinstallimage && mkdir -p $BUILD_ROOT/.preinstall_image CREATE_BUILD_BINARIES= if recipe_needs_build_binaries "$RECIPEPATH" ; then CREATE_BUILD_BINARIES=--create-build-binaries fi set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${initbuildsysstuff[@]}" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $DLNOSIGNATURE $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$RECIPEPATH" $ADDITIONAL_PACKS echo "$* ..." start_time=$SECONDS "$@" || cleanup_and_exit 1 check_exit TIME_INSTALL=$(( $SECONDS - $start_time )) unset start_time # arbitrary limit of 10MB if test $((`stat -f -c "%a*%S/1024/1024" $BUILD_ROOT`)) -lt 10; then # ensure that old stat is not failing (RHEL4) if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then df -h $BUILD_ROOT cleanup_and_exit 1 "build does not work on a completely full filesystem" fi fi copy_oldpackages fi mount_stuff # hack to process preinstallimages early if test "$BUILDTYPE" = preinstallimage ; then recipe_build continue fi if test -z "$BUILD_DIST" -a -e "$BUILD_ROOT/.guessed_dist" ; then read BUILD_DIST < $BUILD_ROOT/.guessed_dist fi # # install dummy sign program if needed # test -f $BUILD_ROOT/usr/bin/sign_installed && mv $BUILD_ROOT/usr/bin/sign_installed $BUILD_ROOT/usr/bin/sign if test -n "$SIGNDUMMY" ; then test -f $BUILD_ROOT/usr/bin/sign && mv $BUILD_ROOT/usr/bin/sign $BUILD_ROOT/usr/bin/sign_installed cp $BUILD_DIR/signdummy $BUILD_ROOT/usr/bin/sign chmod 755 $BUILD_ROOT/usr/bin/sign fi # # check if we want to build with the abuild user # BUILD_USER=abuild if test -x $BUILD_ROOT/bin/rpm ; then SUSE_VERSION=`chroot $BUILD_ROOT /bin/rpm --eval '%{?suse_version}' 2>/dev/null` test -n "$SUSE_VERSION" -a "${SUSE_VERSION:-0}" -le 1020 && BUILD_USER=root fi if test "$BUILD_USER" = abuild ; then grep -E '^#[[:blank:]]*needsrootforbuild[[:blank:]]*$' >/dev/null <$RECIPEPATH && BUILD_USER=root else grep -E '^#[[:blank:]]*norootforbuild[[:blank:]]*$' >/dev/null <$RECIPEPATH && BUILD_USER=abuild fi test -n "$NOROOTFORBUILD" && BUILD_USER=abuild # appliance builds must run as root if test "$BUILDTYPE" = kiwi ; then imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $RECIPEPATH imagetype) test "$imagetype" = product || BUILD_USER=root fi # same with docker, fissile and livebuild builds if test "$BUILDTYPE" = docker -o "$BUILDTYPE" = fissile -o "$BUILDTYPE" = podman -o "$BUILDTYPE" = livebuild ; then BUILD_USER=root fi # fixup passwd/group if test $BUILD_USER = abuild ; then if ! grep -E '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/etc/passwd echo 'abuild:*:::::::' >>$BUILD_ROOT/etc/shadow # This is needed on Mandriva 2009 echo 'abuild:*::' >>$BUILD_ROOT/etc/gshadow # This is needed on Ubuntu echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/etc/group mkdir -p $BUILD_ROOT/home/abuild chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/home/abuild else if ! grep -E "^abuild:x?:${ABUILD_UID}:${ABUILD_GID}" >/dev/null <$BUILD_ROOT/etc/passwd ; then echo "abuild user present in the buildroot ($BUILD_ROOT) but uid:gid does not match" echo "buildroot currently using:" grep -E "^abuild:" <$BUILD_ROOT/etc/passwd echo "build script attempting to use:" echo "abuild::${ABUILD_UID}:${ABUILD_GID}:..." echo "build aborting" cleanup_and_exit 1 fi fi if test -f $BUILD_ROOT/etc/shadow ; then sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/shadow fi if test -f $BUILD_ROOT/etc/gshadow ; then sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/gshadow fi BUILD_USER_ABUILD_USED=true else # building as root ABUILD_UID=0 ABUILD_GID=0 if grep -E '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then rm -rf "$BUILD_ROOT/home/abuild" sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/passwd sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/group if test -f $BUILD_ROOT/etc/shadow ; then sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/shadow fi if test -f $BUILD_ROOT/etc/gshadow ; then sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/gshadow fi fi fi if test -n "$RUNNING_IN_VM" ; then vm_setup_network fi setupicecream ccache_setup test -n "$RUN_SHELL" && run_shell # fill build directories with sources. Also sets TOPDIR recipe_setup RECIPEPATH= # strip prefix from autogenerated files of source services. # sorted by line length to let the latest run service win perl -e 'print "$_\n" for sort { length($a) <=> length($b) } @ARGV' $BUILD_ROOT$TOPDIR/SOURCES/_service\:* | while read i ; do mv "$i" "${i%/*}/${i##*:}" done RECIPEFILE="${RECIPEFILE##*:}" # create .build.packages link rm -f $BUILD_ROOT/.build.packages ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages # nasty hack to prevent rpath on known paths # FIXME: do this only for suse if test -d "$BUILD_ROOT/etc/profile.d" ; then echo "export SUSE_IGNORED_RPATHS=/etc/ld.so.conf" > "$BUILD_ROOT/etc/profile.d/buildsystem.sh" fi cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1 for i in *.obscpio ; do test -e "$i" || continue echo "Unpacking $i ..." echo "#!/bin/sh -e" > $BUILD_ROOT/.unpack.command shellquote cd "$TOPDIR/SOURCES" >> $BUILD_ROOT/.unpack.command echo >> $BUILD_ROOT/.unpack.command echo -n 'cpio --extract --owner="'$BUILD_USER'" --unconditional --preserve-modification-time --make-directories <' >> $BUILD_ROOT/.unpack.command shellquote "$i" >> $BUILD_ROOT/.unpack.command echo >> $BUILD_ROOT/.unpack.command shellquote rm -f "$i" >> $BUILD_ROOT/.unpack.command echo >> $BUILD_ROOT/.unpack.command chmod 0755 $BUILD_ROOT/.unpack.command chroot $BUILD_ROOT su -c /.unpack.command - $BUILD_USER || cleanup_and_exit 1 rm -f $BUILD_ROOT/.unpack.command done # macros may be used by buildtime servies recipe_setup_macros if test -e _service; then echo "Running build time source services..." HOME=/root $BUILD_DIR/runservices --buildroot "$BUILD_ROOT" || cleanup_and_exit 1 fi # get rid of old src dir, it is no longer needed and just wastes space test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir && rm -rf "$MYSRCDIR" # patch recipes recipe_prepare # hmmm chown -hR "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" echo ----------------------------------------------------------------- if test "$BUILD_USER" = root ; then echo ----- building $RECIPEFILE else echo ----- building $RECIPEFILE "(user $BUILD_USER)" fi echo ----------------------------------------------------------------- echo ----------------------------------------------------------------- BUILD_SUCCEEDED=false if test -n "$OVERLAY" ; then copy_overlay fi if test -n "$RSYNCSRC" ; then run_rsync fi RECIPE_BUILD_START_TIME=`date +%s` GEN_BUILDREQS_PACKS=() recipe_build if test "$BUILD_SUCCEEDED" = genbuildreqs -a "$DO_INIT" = true -a -z "$RPMLIST" -a -z "$RUNNING_IN_VM" -a -n "${GEN_BUILDREQS_PACKS[*]}" ; then # re-expand deps with GEN_BUILDREQS_PACKS extra packages umount_stuff set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${initbuildsysstuff[@]}" "${definesnstuff[@]}" "${repos[@]}" $DLNOSIGNATURE $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS "${GEN_BUILDREQS_PACKS[@]}" echo "$* ..." "$@" || cleanup_and_exit 1 check_exit mount_stuff BUILD_SUCCEEDED=false recipe_build fi if test "$BUILD_SUCCEEDED" = genbuildreqs ; then recipe_cleanup if test -n "$RUNNING_IN_VM" ; then vm_exit_statistics vm_wrapup_build OTHER fi cleanup_and_exit 9 fi test "$BUILD_SUCCEEDED" = true || cleanup_and_exit 1 BUILD_SUCCEEDED= recipe_build_time_statistics recipe_gendiff recipe_cleanup test -d "$SRCDIR" && cd "$SRCDIR" umount_stuff done if test -n "$RUNNING_IN_VM" ; then vm_exit_statistics fi # mount /proc again for the post processing steps if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then mount -n -tproc none $BUILD_ROOT/proc fi RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true` DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f "(" -name "*.deb" -o -name "*.ddeb" -o -name "*.udeb" ")" 2>/dev/null || true` if test -n "$RPMS" -a -n "$BUILD_USER_ABUILD_USED" ; then recipe_check_file_owners fi TIME_POSTCHECKS=0 TIME_RPMLINT=0 TIME_BUILDCMP=0 TIME_DELTARPMS=0 # set BUILD_SUCCEEDED to false again so that --shell-after-fail # works if there is an check/rpmlint error BUILD_SUCCEEDED=false ###### Post build checks TIME_POSTCHECKS=$SECONDS # RPM specific post checks are in /usr/lib/build/checks if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then # workaround for broken 13.1 check scripts which umount /proc if test -n "$RUNNING_IN_VM" -a "$BUILD_ROOT" = / ; then umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2>/dev/null fi # find package name export PNAME= for SRPM in $BUILD_ROOT/$TOPDIR/SRPMS/*src.rpm ; do test -f "$SRPM" && PNAME=`env LC_ALL=C rpm --macros=/dev/null --nodigest --nosignature -qp --qf "%{NAME}" $SRPM` done if test -z "$PNAME" ; then for SRPM in $RPMS ; do test -f "$SRPM" && PNAME=`rpm --nodigest --nosignature -qp --qf "%{SOURCERPM}" $SRPM` done PNAME="${PNAME%-*-*.*.rpm}" fi for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/checks/* ; do echo "... running ${CHECKSCRIPT##*/}" BUILD_ROOT=/ HOME=/root chroot "$BUILD_ROOT" "/usr/lib/build/checks/${CHECKSCRIPT##*/}" || cleanup_and_exit 1 done # workaround for broken 13.1 check scripts which umount /proc test -e "$BUILD_ROOT/proc/self" || mount -n -tproc none $BUILD_ROOT/proc fi # Generic post-build-checks are in /usr/lib/build/post-build-checks for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/post-build-checks/* ; do if test -x "$CHECKSCRIPT"; then echo "... running ${CHECKSCRIPT##*/}" BUILD_ROOT=/ HOME=/root chroot "$BUILD_ROOT" "/usr/lib/build/post-build-checks/${CHECKSCRIPT##*/}" || cleanup_and_exit 1 fi done ###### End Post build checks TIME_POSTCHECKS=$(( $SECONDS - $TIME_POSTCHECKS )) # checkscripts may have deleted some binaries RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true` DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true` if test -n "$RPMS" -a "$DO_CHECKS" != false ; then TIME_RPMLINT=$SECONDS recipe_run_rpmlint TIME_RPMLINT=$(( SECONDS - $TIME_RPMLINT )) fi BUILD_SUCCEEDED= if test -n "$CCACHE" ; then ccache_wrapup fi if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then create_baselibs fi for SCRIPT in $BUILD_ROOT/usr/lib/build/post-mkbaselibs-checks/* ; do if test -x "$SCRIPT"; then echo "... running ${SCRIPT##*/}" BUILD_ROOT=/ HOME=/root chroot "$BUILD_ROOT" "/usr/lib/build/post-mkbaselibs-checks/${SCRIPT##*/}" || cleanup_and_exit 1 fi done if test -n "$MODULEMDFILE" ; then mkdir -p "$BUILD_ROOT/$TOPDIR/OTHER" find "$BUILD_ROOT/$TOPDIR/RPMS" "$BUILD_ROOT/$TOPDIR/SRPMS" -type f -name "*.rpm" | sort | $BUILD_DIR/writemodulemd ${DISTURL:+--disturl "$DISTURL"} "$MODULEMDFILE" - > "$BUILD_ROOT/$TOPDIR/OTHER/_modulemd.yaml" test -s "$BUILD_ROOT/$TOPDIR/OTHER/_modulemd.yaml" || rm -f "$BUILD_ROOT/$TOPDIR/OTHER/_modulemd.yaml" fi exitcode=0 # post build work # TODO: don't hardcode. instead run scripts in a directory as it's done for the checks if test -n "$RPMS" -a -d "$BUILD_ROOT/.build.oldpackages" ; then TIME_BUILDCMP=$SECONDS recipe_compare_oldpackages TIME_BUILDCMP=$(( $SECONDS - $TIME_BUILDCMP )) # no need to create deltas if the build is the same if test ! -e $BUILD_ROOT/.build/.same_result_marker ; then TIME_DELTARPMS=$SECONDS recipe_create_deltarpms TIME_DELTARPMS=$(( $SECONDS - $TIME_DELTARPMS )) fi fi if test -n "$RUNNING_IN_VM" ; then vm_wrapup_build $(recipe_resultdirs) OTHER else if test "$BUILDTYPE" = "preinstallimage" ; then preinstallimage_compress "$BUILD_ROOT/$TOPDIR/OTHER" fi fi echo echo "$HOST finished \"build $RECIPEFILE\" at `date --utc`." echo cleanup_and_exit "$exitcode"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor