#!/bin/bash # Copyright 2014-2015 Holger Levsen # © 2015 Mattia Rizzolo # released under the GPLv=2 DEBUG=false . /srv/jenkins/bin/common-functions.sh common_init "$@" # common code defining db access . /srv/jenkins/bin/reproducible_common.sh set -e # build for different architectures ARCHS="i386-elf x86_64-elf armv7a-eabi aarch64-elf mipsel-elf riscv-elf" cleanup_tmpdir() { cd rm -r $TMPDIR } create_results_dirs() { mkdir -p $BASE/coreboot/dbd } call_debbindiff() { local TMPLOG=(mktemp --tmpdir=$TMPDIR) set +e ( timeout $TIMEOUT schroot \ --directory $TMPDIR \ -c source:jenkins-reproducible-${DBDSUITE}-debbindiff \ debbindiff -- \ --html $TMPDIR/$1.html \ $TMPDIR/b1/$1/coreboot.rom \ $TMPDIR/b2/$1/coreboot.rom 2>&1 \ ) 2>&1 >> $TMPLOG RESULT=$? if ! "$DEBUG" ; then set +x ; fi set -e cat $TMPLOG # print dbd output rm -f $TMPLOG case $RESULT in 0) echo "$(date -u) - $1/coreboot.rom is reproducible, yay!" ;; 1) echo "$(date -u) - $DBDVERSION found issues, please investigate $1/coreboot.rom" ;; 2) echo "$(date -u) - $DBDVERSION had trouble comparing the two builds. Please investigate $1/coreboot.rom" ;; 124) if [ ! -s $TMPDIR/$1.html ] ; then echo "$(date -u) - $DBDVERSION produced no output for $1/coreboot.rom and was killed after running into timeout after ${TIMEOUT}..." else local msg="$DBDVERSION was killed after running into timeout after $TIMEOUT" msg="$msg, but there is still $TMPDIR/$1.html" fi echo $msg ;; *) echo "$(date -u) - Something weird happened when running $DBDVERSION on $1/coreboot.rom (which exited with $RESULT) and I don't know how to handle it" ;; esac } # # main # TMPDIR=$(mktemp --tmpdir=/srv/reproducible-results -d) # where everything actually happens trap cleanup_tmpdir INT TERM EXIT cd $TMPDIR DATE=$(date -u +'%Y-%m-%d') START=$(date +'%s') mkdir b1 b2 echo "=============================================================================" echo "$(date -u) - Cloning the coreboot git repository with submodules now." echo "=============================================================================" git clone --recursive http://review.coreboot.org/p/coreboot.git cd coreboot # still required because coreboot moved submodules and to take care of old git versions git submodule update --init --checkout 3rdparty/blobs COREBOOT="$(git log -1)" COREBOOT_VERSION=$(git describe) NUM_CPU=$(cat /proc/cpuinfo |grep '^processor'|wc -l) echo "=============================================================================" echo "$(date -u) - Building cross compilers for ${ARCHS} now." echo "=============================================================================" GOT_XTOOLCHAIN=false set +e for ARCH in ${ARCHS} ; do echo "$(date -u) - Building cross compiler for ${ARCH}." # taken from util/crossgcc/Makefile: nice ionice -c 3 bash util/crossgcc/buildgcc -j $NUM_CPU -p $ARCH RESULT=$? if [ $RESULT -eq 0 ] ; then GOT_XTOOLCHAIN=true fi done set -e if ! $GOT_XTOOLCHAIN ; then echo "Need at least one cross toolchain, aborting." fi echo "=============================================================================" echo "$(date -u) - Building coreboot ${COREBOOT_VERSION} images now - first build run." echo "=============================================================================" export TZ="/usr/share/zoneinfo/Etc/GMT+12" # prevent failing using more than one CPU sed -i 's#MAKE=$i#MAKE=make#' util/abuild/abuild # use all cores for first build sed -i "s#cpus=1#cpus=$NUM_CPU#" util/abuild/abuild sed -i 's#USE_XARGS=1#USE_XARGS=0#g' util/abuild/abuild # actually build everything nice ionice -c 3 \ bash util/abuild/abuild || true # don't fail the full job just because some targets fail cd coreboot-builds for i in * ; do # abuild and sharedutils are build results but not the results we are looking for... if [ "$i" != "abuild" ] && [ "$i" != "sharedutils" ] ; then mkdir $TMPDIR/b1/$i if [ -f $i/coreboot.rom ] ; then cp -p $i/coreboot.rom $TMPDIR/b1/$i/ fi fi done cd .. rm coreboot-builds -rf echo "=============================================================================" echo "$(date -u) - Building coreboot images now - second build run." echo "=============================================================================" export TZ="/usr/share/zoneinfo/Etc/GMT-14" export LANG="fr_CH.UTF-8" export LC_ALL="fr_CH.UTF-8" export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" export CAPTURE_ENVIRONMENT="I capture the environment" umask 0002 # use allmost all cores for second build NEW_NUM_CPU=$(echo $NUM_CPU-1|bc) sed -i "s#cpus=$NUM_CPU#cpus=$NEW_NUM_CPU#" util/abuild/abuild nice ionice -c 3 \ linux64 --uname-2.6 \ bash util/abuild/abuild || true # don't fail the full job just because some targets fail # reset environment to default values again export LANG="en_GB.UTF-8" unset LC_ALL export TZ="/usr/share/zoneinfo/UTC" export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:" umask 0022 cd coreboot-builds for i in * ; do if [ -f $i/coreboot.rom ] ; then mkdir $TMPDIR/b2/$i cp -p $i/coreboot.rom $TMPDIR/b2/$i/ fi done cd .. rm coreboot-builds -r cd .. TIMEOUT="30m" DBDSUITE="unstable" DBDVERSION="$(schroot --directory /tmp -c source:jenkins-reproducible-${DBDSUITE}-debbindiff debbindiff -- --version 2>&1)" echo "=============================================================================" echo "$(date -u) - Running $DBDVERSION on coreboot images now" echo "=============================================================================" # and creating the webpage while we're at it PAGE=$PWD/coreboot/coreboot.html cat > $PAGE <<- EOF coreboot

 

coreboot

coreboot™: fast, flexible and reproducible Open Source firmware?

EOF write_page "

Reproducible Coreboot

" write_page "

Reproducible builds enable anyone to reproduce bit by bit identical binary packages from a given source, si that anyone can verify that a given binary derived from the source it was said to be derived. There is a lot more information about reproducible builds on the Debian wiki and on https://reproducible.debian.net.
" write_page " Reproducible Coreboot is an effort to apply this to coreboot. Thus each coreboot.rom is build twice, with a few varitations added and then those two ROMs are compared using debbindiff. Please note that more variations are to be expected in the wild.

" write_page "

There is a monthly ru jenkins job to test the master branch of coreboot.git, but as this is brand new, this job is currently triggered more often. This job runs reproducible_coreboot.sh which is solely responsible for creating this page. Please join #debian-reproducible (on irc.oftc.net) to request job runs whenever sensible. Patches are very much welcome!

" write_page "

These tests were last run on $DATE for version ${COREBOOT_VERSION}.

"
echo -n "$COREBOOT" >> $PAGE
write_page "       

" write_explaination_table coreboot write_page "
    " BAD_ROMS=0 GOOD_ROMS=0 ALL_ROMS=0 create_results_dirs cd b1 for i in * ; do let ALL_ROMS+=1 if [ -f $i/coreboot.rom ] ; then call_debbindiff $i SIZE="$(du -h -b $i/coreboot.rom | cut -f1)" SIZE="$(echo $SIZE/1024|bc)" if [ -f $TMPDIR/$i.html ] ; then mv $TMPDIR/$i.html $BASE/coreboot/dbd/$i.html write_page "
  • \"unreproducible $i (${SIZE}K) is unreproducible.
  • " else SHASUM=$(sha256sum $i/coreboot.rom|cut -d " " -f1) write_page "
  • \"reproducible $i ($SHASUM, ${SIZE}K) had no debbindiff output so it's probably reproducible :)
  • " let GOOD_ROMS+=1 fi else write_page "
  • \"FTBFS $i failed to build from source.
  • " let BAD_ROMS+=1 fi done GOOD_PERCENT=$(echo "scale=1 ; ($GOOD_ROMS*100/$ALL_ROMS)" | bc) BAD_PERCENT=$(echo "scale=1 ; ($BAD_ROMS*100/$ALL_ROMS)" | bc) write_page "

$GOOD_ROMS ($GOOD_PERCENT%) out of $ALL_ROMS built coreboot images were reproducible, while $BAD_ROMS ($BAD_PERCENT%) failed to built from source.

" cat >> $PAGE <<- EOF
EOF write_page_footer coreboot cd .. PAGE=coreboot/coreboot.html publish_page # the end calculate_build_duration print_out_duration irc_message "$REPRODUCIBLE_URL/coreboot/ has been updated." # remove coreboot tree, we don't need it anymore... rm coreboot -r cleanup_tmpdir trap - INT TERM EXIT