From 49cc1830343050e9da932fdb90d99b751678d456 Mon Sep 17 00:00:00 2001 From: Holger Levsen Date: Thu, 10 Dec 2015 12:08:11 +0100 Subject: reproducible archlinux: s#arch#archlinux# in script and job names --- bin/jenkins_node_wrapper.sh | 8 +- bin/reproducible_arch_schroot_setup.sh | 102 ------------ bin/reproducible_build_arch_pkg.sh | 233 ---------------------------- bin/reproducible_build_archlinux_pkg.sh | 233 ++++++++++++++++++++++++++++ bin/reproducible_setup_archlinux_schroot.sh | 102 ++++++++++++ job-cfg/reproducible.yaml | 16 +- 6 files changed, 347 insertions(+), 347 deletions(-) delete mode 100755 bin/reproducible_arch_schroot_setup.sh delete mode 100755 bin/reproducible_build_arch_pkg.sh create mode 100755 bin/reproducible_build_archlinux_pkg.sh create mode 100755 bin/reproducible_setup_archlinux_schroot.sh diff --git a/bin/jenkins_node_wrapper.sh b/bin/jenkins_node_wrapper.sh index 4d41a256..5c2d24b9 100755 --- a/bin/jenkins_node_wrapper.sh +++ b/bin/jenkins_node_wrapper.sh @@ -103,12 +103,12 @@ elif [[ "$*" =~ reproducible_netbsd ]] ; then exec /srv/jenkins/bin/reproducible_netbsd.sh ; croak "Exec failed"; elif [[ "$*" =~ reproducible_freebsd ]] ; then exec /srv/jenkins/bin/reproducible_freebsd.sh ; croak "Exec failed"; -elif [[ "$*" =~ reproducible_setup_schroot_arch ]] ; then - exec /srv/jenkins/bin/reproducible_arch_schroot_setup.sh ; croak "Exec failed"; +elif [[ "$*" =~ reproducible_setup_schroot_archlinux ]] ; then + exec /srv/jenkins/bin/reproducible_setup_archlinux_schroot.sh ; croak "Exec failed"; elif [[ "$*" =~ reproducible_setup_mock_fedora23_x86_64 ]] ; then exec /srv/jenkins/bin/reproducible_setup_mock.sh fedora-23 x86_64 ; croak "Exec failed"; -elif [ "$1" = "/srv/jenkins/bin/reproducible_build_arch_pkg.sh" ] && ( [ "$2" = "1" ] || [ "$2" = "2" ] ) ; then - exec /srv/jenkins/bin/reproducible_build_arch_pkg.sh "$2" "$3" "$4" ; croak "Exec failed"; +elif [ "$1" = "/srv/jenkins/bin/reproducible_build_archlinux_pkg.sh" ] && ( [ "$2" = "1" ] || [ "$2" = "2" ] ) ; then + exec /srv/jenkins/bin/reproducible_build_archlinux_pkg.sh "$2" "$3" "$4" ; croak "Exec failed"; elif [ "$*" = "some_jenkins_job_name" ] ; then exec echo run any commands here ; croak "Exec failed"; fi diff --git a/bin/reproducible_arch_schroot_setup.sh b/bin/reproducible_arch_schroot_setup.sh deleted file mode 100755 index c2022b6f..00000000 --- a/bin/reproducible_arch_schroot_setup.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash - -# Copyright 2015 Holger Levsen -# released under the GPLv=2 - -# -# downloads an arch bootstrap chroot archive, then turns it into an schroot, -# then configures pacman and abs -# - -DEBUG=false -. /srv/jenkins/bin/common-functions.sh -common_init "$@" - -# define archlinux mirror to be used -ARCH_MIRROR=http://mirror.one.com/archlinux/ - -bootstrap() { - # define URL for bootstrap.tgz - BOOTSTRAP_BASE=$ARCH_MIRROR/iso/ - echo "$(date -u) - downloading Arch Linux latest/sha1sums.txt" - BOOTSTRAP_DATE=$(curl $BOOTSTRAP_BASE/latest/sha1sums.txt 2>/dev/null| grep x86_64.tar.gz| cut -d " " -f3|cut -d "-" -f3|egrep '[0-9.]{9}') - if [ -z $BOOTSTRAP_DATE ] ; then - echo "Cannot determine version of boostrap file, aborting." - curl $BOOTSTRAP_BASE/latest/sha1sums.txt | grep x86_64.tar.gz - exit 1 - fi - BOOTSTRAP_TAR_GZ=$BOOTSTRAP_DATE/archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz - echo "$(date -u) - downloading Arch Linux bootstrap.tar.gz." - curl -O $BOOTSTRAP_BASE/$BOOTSTRAP_TAR_GZ - tar xzf archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz - mv root.x86_64/* $SCHROOT_TARGET || true # proc and sys have 0555 perms, thus mv will fail... also see below - rm archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz root.x86_64 -rf - # write the schroot config - echo "$(date -u ) - writing schroot configuration for $TARGET." - sudo tee /etc/schroot/chroot.d/jenkins-"$TARGET" <<-__END__ - [jenkins-$TARGET] - description=Jenkins schroot $TARGET - directory=$SCHROOT_BASE/$TARGET - type=directory - root-users=jenkins - source-root-users=jenkins - union-type=aufs - __END__ - # finally, put it in place - mv $SCHROOT_TARGET $SCHROOT_BASE/$TARGET - mkdir $SCHROOT_BASE/$TARGET/proc $SCHROOT_BASE/$TARGET/sys - chmod 555 $SCHROOT_BASE/$TARGET/proc $SCHROOT_BASE/$TARGET/sys - # mktemp creates directories with 700 perms - chmod 755 $SCHROOT_BASE/$TARGET -} - -cleanup() { - if [ -d $SCHROOT_TARGET ]; then - rm -rf --one-file-system $SCHROOT_TARGET || ( echo "Warning: $SCHROOT_TARGET could not be fully removed on forced cleanup." ; ls $SCHROOT_TARGET -la ) - fi - rm -f $TMPLOG -} - -SCHROOT_TARGET=$(mktemp -d -p $SCHROOT_BASE/ schroot-install-$TARGET-XXXX) -trap cleanup INT TERM EXIT -TARGET=reproducible-arch -bootstrap -trap - INT TERM EXIT - -ROOTCMD="schroot --directory /tmp -c source:jenkins-reproducible-arch -u root --" -USERCMD="schroot --directory /tmp -c source:jenkins-reproducible-arch -u jenkins --" - -# configure proxy everywhere -tee $SCHROOT_BASE/$TARGET/etc/profile.d/proxy.sh <<-__END__ - export http_proxy=$http_proxy - export https_proxy=$http_proxy - export ftp_proxy=$http_proxy - export HTTP_PROXY=$http_proxy - export HTTPS_PROXY=$http_proxy - export FTP_PROXY=$http_proxy - export no_proxy="localhost,127.0.0.1" - __END__ -chmod 755 $SCHROOT_BASE/$TARGET/etc/profile.d/proxy.sh - -# configure root user to use this for shells and login shells… -echo ". /etc/profile.d/proxy.sh" | tee -a $SCHROOT_BASE/$TARGET/root/.bashrc - -# configure pacman -$ROOTCMD bash -l -c 'pacman-key --init' -$ROOTCMD bash -l -c 'pacman-key --populate archlinux' -echo "Server = $ARCH_MIRROR/\$repo/os/\$arch" | tee -a $SCHROOT_BASE/$TARGET/etc/pacman.d/mirrorlist -$ROOTCMD bash -l -c 'pacman -Syu --noconfirm' -$ROOTCMD bash -l -c 'pacman -S --noconfirm base-devel devtools abs' -# configure abs -$ROOTCMD bash -l -c 'abs core extra' -# configure sudo -echo 'jenkins ALL= NOPASSWD: /usr/sbin/pacman *' | $ROOTCMD tee -a /etc/sudoers - -# configure jenkins user -$ROOTCMD mkdir /var/lib/jenkins -$ROOTCMD chown -R jenkins:jenkins /var/lib/jenkins -echo ". /etc/profile.d/proxy.sh" | tee -a $SCHROOT_BASE/$TARGET/var/lib/jenkins/.bashrc -$USERCMD bash -l -c 'gpg --check-trustdb' # first run will create ~/.gnupg/gpg.conf -$USERCMD bash -l -c 'gpg --recv-keys 0x091AB856069AAA1C' - -echo "schroot $TARGET set up successfully in $SCHROOT_BASE/$TARGET - exiting now." diff --git a/bin/reproducible_build_arch_pkg.sh b/bin/reproducible_build_arch_pkg.sh deleted file mode 100755 index bb1658d1..00000000 --- a/bin/reproducible_build_arch_pkg.sh +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/bash - -# Copyright 2015 Holger Levsen -# released under the GPLv=2 - -DEBUG=false -. /srv/jenkins/bin/common-functions.sh -common_init "$@" - -# common code -. /srv/jenkins/bin/reproducible_common.sh - -set -e - -cleanup_all() { - cd - # delete session if it still exists - if [ "$MODE" != "master" ] ; then - schroot --end-session -c arch-$SRCPACKAGE-$(basename $TMPDIR) > /dev/null 2>&1 || true - fi - # delete makepkg build dir - if [ ! -z $SRCPACKAGE ] && [ -d /tmp/$SRCPACKAGE-$(basename $TMPDIR) ] ; then - rm -r /tmp/$SRCPACKAGE-$(basename $TMPDIR) - fi - # delete main work dir (only on master) - if [ "$MODE" = "master" ] ; then - rm $TMPDIR -r - echo "$(date -u) - $TMPDIR deleted." - fi -} - -handle_remote_error() { - MESSAGE="${BUILD_URL}console got remote error $1" - echo "$(date -u ) - $MESSAGE" | tee -a /var/log/jenkins/reproducible-remote-error.log - echo "Sleeping 5m before aborting the job." - sleep 5m - exec /srv/jenkins/bin/abort.sh - exit 0 -} - -first_build() { - echo "=============================================================================" - echo "Building ${SRCPACKAGE} for Arch Linux on $(hostname -f) now." - echo "Date: $(date)" - echo "Date UTC: $(date -u)" - echo "=============================================================================" - set -x - local SESSION="arch-$SRCPACKAGE-$(basename $TMPDIR)" - local BUILDDIR="/tmp/$SRCPACKAGE-$(basename $TMPDIR)" - local LOG=$TMPDIR/b1/$SRCPACKAGE/build1.log - schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch - echo "MAKEFLAGS=-j$NUM_CPU" | schroot --run-session -c $SESSION --directory /tmp -u root -- tee -a /etc/makepkg.conf - schroot --run-session -c $SESSION --directory /tmp -- mkdir $BUILDDIR - schroot --run-session -c $SESSION --directory /tmp -- cp -r /var/abs/core/$SRCPACKAGE $BUILDDIR/ - # just set timezone in the 1st build - echo 'export TZ="/usr/share/zoneinfo/Etc/GMT+12"' | schroot --run-session -c $SESSION --directory /tmp -- tee -a /var/lib/jenkins/.bashrc - # nicely run makepkg with a timeout of 4h - timeout -k 4.1h 4h /usr/bin/ionice -c 3 /usr/bin/nice \ - schroot --run-session -c $SESSION --directory $BUILDDIR/$SRCPACKAGE -- bash -l -c 'makepkg --syncdeps --noconfirm --skippgpcheck 2>&1' | tee -a $LOG - PRESULT=${PIPESTATUS[0]} - if [ $PRESULT -eq 124 ] ; then - echo "$(date -u) - makepkg was killed by timeout after 4h." | tee -a $LOG - fi - schroot --end-session -c $SESSION - if ! "$DEBUG" ; then set +x ; fi -} - -second_build() { - echo "=============================================================================" - echo "Re-Building ${SRCPACKAGE} for Arch Linux on $(hostname -f) now." - echo "Date: $(date)" - echo "Date UTC: $(date -u)" - echo "=============================================================================" - set -x - local SESSION="arch-$SRCPACKAGE-$(basename $TMPDIR)" - local BUILDDIR="/tmp/$SRCPACKAGE-$(basename $TMPDIR)" - local LOG=$TMPDIR/b2/$SRCPACKAGE/build2.log - NEW_NUM_CPU=$(echo $NUM_CPU-1|bc) - schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch - echo "MAKEFLAGS=-j$NEW_NUM_CPU" | schroot --run-session -c $SESSION --directory /tmp -u root -- tee -a /etc/makepkg.conf - schroot --run-session -c $SESSION --directory /tmp -- mkdir $BUILDDIR - schroot --run-session -c $SESSION --directory /tmp -- cp -r /var/abs/core/$SRCPACKAGE $BUILDDIR/ - # add more variations in the 2nd build: TZ, LANG, LC_ALL, umask - schroot --run-session -c $SESSION --directory /tmp -- tee -a /var/lib/jenkins/.bashrc <<-__END__ - export TZ="/usr/share/zoneinfo/Etc/GMT-14" - export LANG="fr_CH.UTF-8" - export LC_ALL="fr_CH.UTF-8" - umask 0002 - __END__ - # nicely run makepkg with a timeout of 4h - timeout -k 4.1h 4h /usr/bin/ionice -c 3 /usr/bin/nice \ - schroot --run-session -c $SESSION --directory $BUILDDIR/$SRCPACKAGE -- bash -l -c 'makepkg --syncdeps --noconfirm --skippgpcheck 2>&1' | tee -a $LOG - PRESULT=${PIPESTATUS[0]} - if [ $PRESULT -eq 124 ] ; then - echo "$(date -u) - makepkg was killed by timeout after 4h." | tee -a $LOG - fi - schroot --end-session -c $SESSION - if ! "$DEBUG" ; then set +x ; fi -} - -remote_build() { - local BUILDNR=$1 - local NODE=profitbricks-build3-amd64.debian.net - local PORT=22 - set +e - ssh -p $PORT $NODE /bin/true - RESULT=$? - # abort job if host is down - if [ $RESULT -ne 0 ] ; then - SLEEPTIME=$(echo "$BUILDNR*$BUILDNR*5"|bc) - echo "$(date -u) - $NODE seems to be down, sleeping ${SLEEPTIME}min before aborting this job." - sleep ${SLEEPTIME}m - exec /srv/jenkins/bin/abort.sh - fi - ssh -p $PORT $NODE /srv/jenkins/bin/reproducible_build_arch_pkg.sh $BUILDNR ${SRCPACKAGE} ${TMPDIR} - RESULT=$? - if [ $RESULT -ne 0 ] ; then - ssh -p $PORT $NODE "rm -r $TMPDIR" || true - handle_remote_error "with exit code $RESULT from $NODE for build #$BUILDNR for ${SRCPACKAGE}" - fi - rsync -e "ssh -p $PORT" -r $NODE:$TMPDIR/b$BUILDNR $TMPDIR/ - RESULT=$? - if [ $RESULT -ne 0 ] ; then - echo "$(date -u ) - rsync from $NODE failed, sleeping 2m before re-trying..." - sleep 2m - rsync -e "ssh -p $PORT" -r $NODE:$TMPDIR/b$BUILDNR $TMPDIR/ - RESULT=$? - if [ $RESULT -ne 0 ] ; then - handle_remote_error "when rsyncing remote build #$BUILDNR results from $NODE" - fi - fi - ls -R $TMPDIR - ssh -p $PORT $NODE "rm -r $TMPDIR" - set -e -} - -# -# below is what controls the world -# - -TMPDIR=$(mktemp --tmpdir=/srv/reproducible-results -d) # where everything actually happens -trap cleanup_all INT TERM EXIT -cd $TMPDIR - -DATE=$(date -u +'%Y-%m-%d %H:%M') -START=$(date +'%s') -BUILDER="${JOB_NAME#reproducible_builder_}/${BUILD_ID}" - -# -# determine mode -# -if [ "$1" = "" ] ; then - MODE="master" -elif [ "$1" = "1" ] || [ "$1" = "2" ] ; then - MODE="$1" - SRCPACKAGE="$2" - TMPDIR="$3" - [ -d $TMPDIR ] || mkdir -p $TMPDIR - cd $TMPDIR - mkdir -p b$MODE/$SRCPACKAGE - if [ "$MODE" = "1" ] ; then - first_build - else - second_build - fi - # preserve results and delete build directory - mv -v /tmp/$SRCPACKAGE-$(basename $TMPDIR)/$SRCPACKAGE/*.pkg.tar.xz $TMPDIR/b$MODE/$SRCPACKAGE/ || ls /tmp/$SRCPACKAGE-$(basename $TMPDIR)/$SRCPACKAGE/ - rm -r /tmp/$SRCPACKAGE-$(basename $TMPDIR)/ - echo "$(date -u) - build #$MODE for $SRCPACKAGE on $HOSTNAME done." - exit 0 -fi - -# -# main - only used in master-mode -# -delay_start # randomize start times -# first, we need to choose a package… -#SESSION="arch-scheduler-$RANDOM" -#schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch -#PACKAGES="$(schroot --run-session -c $SESSION --directory /var/abs/core -- ls -1|sort -R|xargs echo)" -#schroot --end-session -c $SESSION -#SRCPACKAGE="" -PACKAGES="acl archlinux-keyring attr autoconf automake b43-fwcutter bash binutils bison bridge-utils btrfs-progs bzip2 ca-certificates ca-certificates-cacert coreutils cracklib crda cronie cryptsetup curl dash db dbus dhcpcd dialog diffutils ding-libs dmraid dnssec-anchors dosfstools e2fsprogs ed efibootmgr efivar elfutils expat fakeroot file filesystem findutils flex gawk gcc gdbm gettext glib2 glibc gmp gnupg gnutls gpgme gpm grep groff grub gssproxy gzip hdparm hwids iana-etc ifenslave inetutils iproute2 iptables iputils ipw2100-fw ipw2200-fw isdn4k-utils iw jfsutils kbd keyutils kmod krb5 ldns less libaio libarchive libassuan libcap libedit libevent libffi libgcrypt libgpg-error libgssglue libidn libksba libmpc libnl libpcap libpipeline librpcsecgss libsasl libseccomp libssh2 libtasn1 libtirpc libtool libunistring libusb licenses links linux linux-api-headers linux-atm linux-firmware linux-lts logrotate lvm2 lz4 lzo m4 make man-db man-pages mdadm mkinitcpio mkinitcpio-busybox mkinitcpio-nfs-utils mlocate mpfr nano ncurses net-tools netctl nettle nfs-utils nfsidmap nilfs-utils npth nspr nss openldap openresolv openssh openssl openvpn p11-kit pacman pacman-mirrorlist pam pambase patch pciutils pcmciautils pcre perl pinentry pkg-config popt ppp pptpclient procinfo-ng procps-ng psmisc pth readline reiserfsprogs rfkill rpcbind run-parts s-nail sdparm sed shadow sqlite sudo sysfsutils syslinux systemd tar texinfo thin-provisioning-tools traceroute tzdata usbutils util-linux vi which wireless-regdb wireless_tools wpa_actiond wpa_supplicant xfsprogs xinetd xz zd1211-firmware zlib" # this is hard coded here, because of running jobs on remote nodes, basically… WIP :) -for PKG in $PACKAGES ; do - # build package if it has never build or at least a week ago - if [ ! -d $BASE/archlinux/$PKG ] || [ ! -z $(find $BASE/archlinux/ -name $PKG -mtime +6) ] ; then - SRCPACKAGE=$PKG - echo "Building $PKG now..." - # very simple locking… - mkdir -p $BASE/archlinux/$PKG - touch $BASE/archlinux/$PKG - break - fi -done -if [ -z $SRCPACKAGE ] ; then - echo "$(date -u ) - no package found to be build, sleeping 6h." - for i in $(seq 1 12) ; do - sleep 30m - echo "$(date -u ) - still sleeping..." - done - echo "$(date -u ) - exiting cleanly now." - exit 0 -fi -# build package twice -mkdir b1 b2 -remote_build 1 -# only do the 2nd build if the 1st produced some results -if [ ! -z "$(ls $TMPDIR/b1/$SRCPACKAGE/*.pkg.tar.xz 2>/dev/null|| true)" ] ; then - remote_build 2 - # run diffoscope on the results - TIMEOUT="30m" - DIFFOSCOPE="$(schroot --directory /tmp -c source:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --version 2>&1)" - echo "$(date -u) - Running $DIFFOSCOPE now..." - cd $TMPDIR/b1/$SRCPACKAGE - for ARTIFACT in *.pkg.tar.xz ; do - [ -f $ARTIFACT ] || continue - call_diffoscope $SRCPACKAGE $ARTIFACT - # publish page - if [ -f $TMPDIR/$SRCPACKAGE/$ARTIFACT.html ] ; then - cp $TMPDIR/$SRCPACKAGE/$ARTIFACT.html $BASE/archlinux/$SRCPACKAGE/ - fi - done -fi -# publish logs -cd $TMPDIR/b1/$SRCPACKAGE -cp build1.log $BASE/archlinux/$SRCPACKAGE/ -[ ! -f $TMPDIR/b2/$SRCPACKAGE/build2.log ] || cp $TMPDIR/b2/$SRCPACKAGE/build2.log $BASE/archlinux/$SRCPACKAGE/ -echo "$(date -u) - $REPRODUCIBLE_URL/archlinux/$SRCPACKAGE/ updated." - -cd -cleanup_all -trap - INT TERM EXIT - diff --git a/bin/reproducible_build_archlinux_pkg.sh b/bin/reproducible_build_archlinux_pkg.sh new file mode 100755 index 00000000..5cd509d8 --- /dev/null +++ b/bin/reproducible_build_archlinux_pkg.sh @@ -0,0 +1,233 @@ +#!/bin/bash + +# Copyright 2015 Holger Levsen +# released under the GPLv=2 + +DEBUG=false +. /srv/jenkins/bin/common-functions.sh +common_init "$@" + +# common code +. /srv/jenkins/bin/reproducible_common.sh + +set -e + +cleanup_all() { + cd + # delete session if it still exists + if [ "$MODE" != "master" ] ; then + schroot --end-session -c arch-$SRCPACKAGE-$(basename $TMPDIR) > /dev/null 2>&1 || true + fi + # delete makepkg build dir + if [ ! -z $SRCPACKAGE ] && [ -d /tmp/$SRCPACKAGE-$(basename $TMPDIR) ] ; then + rm -r /tmp/$SRCPACKAGE-$(basename $TMPDIR) + fi + # delete main work dir (only on master) + if [ "$MODE" = "master" ] ; then + rm $TMPDIR -r + echo "$(date -u) - $TMPDIR deleted." + fi +} + +handle_remote_error() { + MESSAGE="${BUILD_URL}console got remote error $1" + echo "$(date -u ) - $MESSAGE" | tee -a /var/log/jenkins/reproducible-remote-error.log + echo "Sleeping 5m before aborting the job." + sleep 5m + exec /srv/jenkins/bin/abort.sh + exit 0 +} + +first_build() { + echo "=============================================================================" + echo "Building ${SRCPACKAGE} for Arch Linux on $(hostname -f) now." + echo "Date: $(date)" + echo "Date UTC: $(date -u)" + echo "=============================================================================" + set -x + local SESSION="arch-$SRCPACKAGE-$(basename $TMPDIR)" + local BUILDDIR="/tmp/$SRCPACKAGE-$(basename $TMPDIR)" + local LOG=$TMPDIR/b1/$SRCPACKAGE/build1.log + schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch + echo "MAKEFLAGS=-j$NUM_CPU" | schroot --run-session -c $SESSION --directory /tmp -u root -- tee -a /etc/makepkg.conf + schroot --run-session -c $SESSION --directory /tmp -- mkdir $BUILDDIR + schroot --run-session -c $SESSION --directory /tmp -- cp -r /var/abs/core/$SRCPACKAGE $BUILDDIR/ + # just set timezone in the 1st build + echo 'export TZ="/usr/share/zoneinfo/Etc/GMT+12"' | schroot --run-session -c $SESSION --directory /tmp -- tee -a /var/lib/jenkins/.bashrc + # nicely run makepkg with a timeout of 4h + timeout -k 4.1h 4h /usr/bin/ionice -c 3 /usr/bin/nice \ + schroot --run-session -c $SESSION --directory $BUILDDIR/$SRCPACKAGE -- bash -l -c 'makepkg --syncdeps --noconfirm --skippgpcheck 2>&1' | tee -a $LOG + PRESULT=${PIPESTATUS[0]} + if [ $PRESULT -eq 124 ] ; then + echo "$(date -u) - makepkg was killed by timeout after 4h." | tee -a $LOG + fi + schroot --end-session -c $SESSION + if ! "$DEBUG" ; then set +x ; fi +} + +second_build() { + echo "=============================================================================" + echo "Re-Building ${SRCPACKAGE} for Arch Linux on $(hostname -f) now." + echo "Date: $(date)" + echo "Date UTC: $(date -u)" + echo "=============================================================================" + set -x + local SESSION="arch-$SRCPACKAGE-$(basename $TMPDIR)" + local BUILDDIR="/tmp/$SRCPACKAGE-$(basename $TMPDIR)" + local LOG=$TMPDIR/b2/$SRCPACKAGE/build2.log + NEW_NUM_CPU=$(echo $NUM_CPU-1|bc) + schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch + echo "MAKEFLAGS=-j$NEW_NUM_CPU" | schroot --run-session -c $SESSION --directory /tmp -u root -- tee -a /etc/makepkg.conf + schroot --run-session -c $SESSION --directory /tmp -- mkdir $BUILDDIR + schroot --run-session -c $SESSION --directory /tmp -- cp -r /var/abs/core/$SRCPACKAGE $BUILDDIR/ + # add more variations in the 2nd build: TZ, LANG, LC_ALL, umask + schroot --run-session -c $SESSION --directory /tmp -- tee -a /var/lib/jenkins/.bashrc <<-__END__ + export TZ="/usr/share/zoneinfo/Etc/GMT-14" + export LANG="fr_CH.UTF-8" + export LC_ALL="fr_CH.UTF-8" + umask 0002 + __END__ + # nicely run makepkg with a timeout of 4h + timeout -k 4.1h 4h /usr/bin/ionice -c 3 /usr/bin/nice \ + schroot --run-session -c $SESSION --directory $BUILDDIR/$SRCPACKAGE -- bash -l -c 'makepkg --syncdeps --noconfirm --skippgpcheck 2>&1' | tee -a $LOG + PRESULT=${PIPESTATUS[0]} + if [ $PRESULT -eq 124 ] ; then + echo "$(date -u) - makepkg was killed by timeout after 4h." | tee -a $LOG + fi + schroot --end-session -c $SESSION + if ! "$DEBUG" ; then set +x ; fi +} + +remote_build() { + local BUILDNR=$1 + local NODE=profitbricks-build3-amd64.debian.net + local PORT=22 + set +e + ssh -p $PORT $NODE /bin/true + RESULT=$? + # abort job if host is down + if [ $RESULT -ne 0 ] ; then + SLEEPTIME=$(echo "$BUILDNR*$BUILDNR*5"|bc) + echo "$(date -u) - $NODE seems to be down, sleeping ${SLEEPTIME}min before aborting this job." + sleep ${SLEEPTIME}m + exec /srv/jenkins/bin/abort.sh + fi + ssh -p $PORT $NODE /srv/jenkins/bin/reproducible_build_archlinux_pkg.sh $BUILDNR ${SRCPACKAGE} ${TMPDIR} + RESULT=$? + if [ $RESULT -ne 0 ] ; then + ssh -p $PORT $NODE "rm -r $TMPDIR" || true + handle_remote_error "with exit code $RESULT from $NODE for build #$BUILDNR for ${SRCPACKAGE}" + fi + rsync -e "ssh -p $PORT" -r $NODE:$TMPDIR/b$BUILDNR $TMPDIR/ + RESULT=$? + if [ $RESULT -ne 0 ] ; then + echo "$(date -u ) - rsync from $NODE failed, sleeping 2m before re-trying..." + sleep 2m + rsync -e "ssh -p $PORT" -r $NODE:$TMPDIR/b$BUILDNR $TMPDIR/ + RESULT=$? + if [ $RESULT -ne 0 ] ; then + handle_remote_error "when rsyncing remote build #$BUILDNR results from $NODE" + fi + fi + ls -R $TMPDIR + ssh -p $PORT $NODE "rm -r $TMPDIR" + set -e +} + +# +# below is what controls the world +# + +TMPDIR=$(mktemp --tmpdir=/srv/reproducible-results -d) # where everything actually happens +trap cleanup_all INT TERM EXIT +cd $TMPDIR + +DATE=$(date -u +'%Y-%m-%d %H:%M') +START=$(date +'%s') +BUILDER="${JOB_NAME#reproducible_builder_}/${BUILD_ID}" + +# +# determine mode +# +if [ "$1" = "" ] ; then + MODE="master" +elif [ "$1" = "1" ] || [ "$1" = "2" ] ; then + MODE="$1" + SRCPACKAGE="$2" + TMPDIR="$3" + [ -d $TMPDIR ] || mkdir -p $TMPDIR + cd $TMPDIR + mkdir -p b$MODE/$SRCPACKAGE + if [ "$MODE" = "1" ] ; then + first_build + else + second_build + fi + # preserve results and delete build directory + mv -v /tmp/$SRCPACKAGE-$(basename $TMPDIR)/$SRCPACKAGE/*.pkg.tar.xz $TMPDIR/b$MODE/$SRCPACKAGE/ || ls /tmp/$SRCPACKAGE-$(basename $TMPDIR)/$SRCPACKAGE/ + rm -r /tmp/$SRCPACKAGE-$(basename $TMPDIR)/ + echo "$(date -u) - build #$MODE for $SRCPACKAGE on $HOSTNAME done." + exit 0 +fi + +# +# main - only used in master-mode +# +delay_start # randomize start times +# first, we need to choose a package… +#SESSION="arch-scheduler-$RANDOM" +#schroot --begin-session --session-name=$SESSION -c jenkins-reproducible-arch +#PACKAGES="$(schroot --run-session -c $SESSION --directory /var/abs/core -- ls -1|sort -R|xargs echo)" +#schroot --end-session -c $SESSION +#SRCPACKAGE="" +PACKAGES="acl archlinux-keyring attr autoconf automake b43-fwcutter bash binutils bison bridge-utils btrfs-progs bzip2 ca-certificates ca-certificates-cacert coreutils cracklib crda cronie cryptsetup curl dash db dbus dhcpcd dialog diffutils ding-libs dmraid dnssec-anchors dosfstools e2fsprogs ed efibootmgr efivar elfutils expat fakeroot file filesystem findutils flex gawk gcc gdbm gettext glib2 glibc gmp gnupg gnutls gpgme gpm grep groff grub gssproxy gzip hdparm hwids iana-etc ifenslave inetutils iproute2 iptables iputils ipw2100-fw ipw2200-fw isdn4k-utils iw jfsutils kbd keyutils kmod krb5 ldns less libaio libarchive libassuan libcap libedit libevent libffi libgcrypt libgpg-error libgssglue libidn libksba libmpc libnl libpcap libpipeline librpcsecgss libsasl libseccomp libssh2 libtasn1 libtirpc libtool libunistring libusb licenses links linux linux-api-headers linux-atm linux-firmware linux-lts logrotate lvm2 lz4 lzo m4 make man-db man-pages mdadm mkinitcpio mkinitcpio-busybox mkinitcpio-nfs-utils mlocate mpfr nano ncurses net-tools netctl nettle nfs-utils nfsidmap nilfs-utils npth nspr nss openldap openresolv openssh openssl openvpn p11-kit pacman pacman-mirrorlist pam pambase patch pciutils pcmciautils pcre perl pinentry pkg-config popt ppp pptpclient procinfo-ng procps-ng psmisc pth readline reiserfsprogs rfkill rpcbind run-parts s-nail sdparm sed shadow sqlite sudo sysfsutils syslinux systemd tar texinfo thin-provisioning-tools traceroute tzdata usbutils util-linux vi which wireless-regdb wireless_tools wpa_actiond wpa_supplicant xfsprogs xinetd xz zd1211-firmware zlib" # this is hard coded here, because of running jobs on remote nodes, basically… WIP :) +for PKG in $PACKAGES ; do + # build package if it has never build or at least a week ago + if [ ! -d $BASE/archlinux/$PKG ] || [ ! -z $(find $BASE/archlinux/ -name $PKG -mtime +6) ] ; then + SRCPACKAGE=$PKG + echo "Building $PKG now..." + # very simple locking… + mkdir -p $BASE/archlinux/$PKG + touch $BASE/archlinux/$PKG + break + fi +done +if [ -z $SRCPACKAGE ] ; then + echo "$(date -u ) - no package found to be build, sleeping 6h." + for i in $(seq 1 12) ; do + sleep 30m + echo "$(date -u ) - still sleeping..." + done + echo "$(date -u ) - exiting cleanly now." + exit 0 +fi +# build package twice +mkdir b1 b2 +remote_build 1 +# only do the 2nd build if the 1st produced some results +if [ ! -z "$(ls $TMPDIR/b1/$SRCPACKAGE/*.pkg.tar.xz 2>/dev/null|| true)" ] ; then + remote_build 2 + # run diffoscope on the results + TIMEOUT="30m" + DIFFOSCOPE="$(schroot --directory /tmp -c source:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --version 2>&1)" + echo "$(date -u) - Running $DIFFOSCOPE now..." + cd $TMPDIR/b1/$SRCPACKAGE + for ARTIFACT in *.pkg.tar.xz ; do + [ -f $ARTIFACT ] || continue + call_diffoscope $SRCPACKAGE $ARTIFACT + # publish page + if [ -f $TMPDIR/$SRCPACKAGE/$ARTIFACT.html ] ; then + cp $TMPDIR/$SRCPACKAGE/$ARTIFACT.html $BASE/archlinux/$SRCPACKAGE/ + fi + done +fi +# publish logs +cd $TMPDIR/b1/$SRCPACKAGE +cp build1.log $BASE/archlinux/$SRCPACKAGE/ +[ ! -f $TMPDIR/b2/$SRCPACKAGE/build2.log ] || cp $TMPDIR/b2/$SRCPACKAGE/build2.log $BASE/archlinux/$SRCPACKAGE/ +echo "$(date -u) - $REPRODUCIBLE_URL/archlinux/$SRCPACKAGE/ updated." + +cd +cleanup_all +trap - INT TERM EXIT + diff --git a/bin/reproducible_setup_archlinux_schroot.sh b/bin/reproducible_setup_archlinux_schroot.sh new file mode 100755 index 00000000..c2022b6f --- /dev/null +++ b/bin/reproducible_setup_archlinux_schroot.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +# Copyright 2015 Holger Levsen +# released under the GPLv=2 + +# +# downloads an arch bootstrap chroot archive, then turns it into an schroot, +# then configures pacman and abs +# + +DEBUG=false +. /srv/jenkins/bin/common-functions.sh +common_init "$@" + +# define archlinux mirror to be used +ARCH_MIRROR=http://mirror.one.com/archlinux/ + +bootstrap() { + # define URL for bootstrap.tgz + BOOTSTRAP_BASE=$ARCH_MIRROR/iso/ + echo "$(date -u) - downloading Arch Linux latest/sha1sums.txt" + BOOTSTRAP_DATE=$(curl $BOOTSTRAP_BASE/latest/sha1sums.txt 2>/dev/null| grep x86_64.tar.gz| cut -d " " -f3|cut -d "-" -f3|egrep '[0-9.]{9}') + if [ -z $BOOTSTRAP_DATE ] ; then + echo "Cannot determine version of boostrap file, aborting." + curl $BOOTSTRAP_BASE/latest/sha1sums.txt | grep x86_64.tar.gz + exit 1 + fi + BOOTSTRAP_TAR_GZ=$BOOTSTRAP_DATE/archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz + echo "$(date -u) - downloading Arch Linux bootstrap.tar.gz." + curl -O $BOOTSTRAP_BASE/$BOOTSTRAP_TAR_GZ + tar xzf archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz + mv root.x86_64/* $SCHROOT_TARGET || true # proc and sys have 0555 perms, thus mv will fail... also see below + rm archlinux-bootstrap-$BOOTSTRAP_DATE-x86_64.tar.gz root.x86_64 -rf + # write the schroot config + echo "$(date -u ) - writing schroot configuration for $TARGET." + sudo tee /etc/schroot/chroot.d/jenkins-"$TARGET" <<-__END__ + [jenkins-$TARGET] + description=Jenkins schroot $TARGET + directory=$SCHROOT_BASE/$TARGET + type=directory + root-users=jenkins + source-root-users=jenkins + union-type=aufs + __END__ + # finally, put it in place + mv $SCHROOT_TARGET $SCHROOT_BASE/$TARGET + mkdir $SCHROOT_BASE/$TARGET/proc $SCHROOT_BASE/$TARGET/sys + chmod 555 $SCHROOT_BASE/$TARGET/proc $SCHROOT_BASE/$TARGET/sys + # mktemp creates directories with 700 perms + chmod 755 $SCHROOT_BASE/$TARGET +} + +cleanup() { + if [ -d $SCHROOT_TARGET ]; then + rm -rf --one-file-system $SCHROOT_TARGET || ( echo "Warning: $SCHROOT_TARGET could not be fully removed on forced cleanup." ; ls $SCHROOT_TARGET -la ) + fi + rm -f $TMPLOG +} + +SCHROOT_TARGET=$(mktemp -d -p $SCHROOT_BASE/ schroot-install-$TARGET-XXXX) +trap cleanup INT TERM EXIT +TARGET=reproducible-arch +bootstrap +trap - INT TERM EXIT + +ROOTCMD="schroot --directory /tmp -c source:jenkins-reproducible-arch -u root --" +USERCMD="schroot --directory /tmp -c source:jenkins-reproducible-arch -u jenkins --" + +# configure proxy everywhere +tee $SCHROOT_BASE/$TARGET/etc/profile.d/proxy.sh <<-__END__ + export http_proxy=$http_proxy + export https_proxy=$http_proxy + export ftp_proxy=$http_proxy + export HTTP_PROXY=$http_proxy + export HTTPS_PROXY=$http_proxy + export FTP_PROXY=$http_proxy + export no_proxy="localhost,127.0.0.1" + __END__ +chmod 755 $SCHROOT_BASE/$TARGET/etc/profile.d/proxy.sh + +# configure root user to use this for shells and login shells… +echo ". /etc/profile.d/proxy.sh" | tee -a $SCHROOT_BASE/$TARGET/root/.bashrc + +# configure pacman +$ROOTCMD bash -l -c 'pacman-key --init' +$ROOTCMD bash -l -c 'pacman-key --populate archlinux' +echo "Server = $ARCH_MIRROR/\$repo/os/\$arch" | tee -a $SCHROOT_BASE/$TARGET/etc/pacman.d/mirrorlist +$ROOTCMD bash -l -c 'pacman -Syu --noconfirm' +$ROOTCMD bash -l -c 'pacman -S --noconfirm base-devel devtools abs' +# configure abs +$ROOTCMD bash -l -c 'abs core extra' +# configure sudo +echo 'jenkins ALL= NOPASSWD: /usr/sbin/pacman *' | $ROOTCMD tee -a /etc/sudoers + +# configure jenkins user +$ROOTCMD mkdir /var/lib/jenkins +$ROOTCMD chown -R jenkins:jenkins /var/lib/jenkins +echo ". /etc/profile.d/proxy.sh" | tee -a $SCHROOT_BASE/$TARGET/var/lib/jenkins/.bashrc +$USERCMD bash -l -c 'gpg --check-trustdb' # first run will create ~/.gnupg/gpg.conf +$USERCMD bash -l -c 'gpg --recv-keys 0x091AB856069AAA1C' + +echo "schroot $TARGET set up successfully in $SCHROOT_BASE/$TARGET - exiting now." diff --git a/job-cfg/reproducible.yaml b/job-cfg/reproducible.yaml index 7d282fdc..8888cf1b 100644 --- a/job-cfg/reproducible.yaml +++ b/job-cfg/reproducible.yaml @@ -755,7 +755,7 @@ - job-template: defaults: reproducible_other_projects - name: '{name}_setup_schroot_arch' + name: '{name}_setup_schroot_archlinux' - job-template: defaults: reproducible_other_projects @@ -763,11 +763,11 @@ - job-template: defaults: reproducible_builder_trigger - name: '{name}_builder_arch_1' + name: '{name}_builder_archlinux_1' - job-template: defaults: reproducible_builder_trigger - name: '{name}_builder_arch_2' + name: '{name}_builder_archlinux_2' - job-template: defaults: reproducible @@ -1519,7 +1519,7 @@ my_shell: '/srv/jenkins/bin/reproducible_freebsd.sh' my_recipients: 'qa-jenkins-scm@lists.alioth.debian.org' my_node: '' - - '{name}_setup_schroot_arch': + - '{name}_setup_schroot_archlinux': my_description: 'Setup an Arch Linux schroot to test Arch Linux packages for reproducibility.' my_timed: '42 23 1 1 *' my_shell: '/srv/jenkins/bin/jenkins_master_wrapper.sh' @@ -1531,18 +1531,18 @@ my_shell: '/srv/jenkins/bin/jenkins_master_wrapper.sh' my_recipients: 'qa-jenkins-scm@lists.alioth.debian.org' my_node: 'profitbricks3' - - '{name}_builder_arch_1': + - '{name}_builder_archlinux_1': my_description: 'Try to reproducibly build an Arch Linux package.' my_timed: '* * * * *' my_trigger: 'reproducible_html_archlinux' - my_shell: '/srv/jenkins/bin/reproducible_build_arch_pkg.sh' + my_shell: '/srv/jenkins/bin/reproducible_build_archlinux_pkg.sh' my_recipients: 'qa-jenkins-scm@lists.alioth.debian.org' my_node: '' - - '{name}_builder_arch_2': + - '{name}_builder_archlinux_2': my_description: 'Try to reproducibly build an Arch Linux package.' my_timed: '* * * * *' my_trigger: 'reproducible_html_archlinux' - my_shell: '/srv/jenkins/bin/reproducible_build_arch_pkg.sh' + my_shell: '/srv/jenkins/bin/reproducible_build_archlinux_pkg.sh' my_recipients: 'qa-jenkins-scm@lists.alioth.debian.org' my_node: '' - '{name}_html_archlinux': -- cgit v1.2.3-54-g00ecf