#!/bin/bash # Copyright 2014-2017 Holger Levsen # © 2015 Reiner Herrmann # 2016-2017 Alexander Couzens # released under the GPLv=2 OPENWRT_GIT_REPO=https://git.lede-project.org/lede/lynxis/staging.git OPENWRT_GIT_BRANCH=master DEBUG=false LEDE_CONFIG= LEDE_TARGET= . /srv/jenkins/bin/common-functions.sh common_init "$@" # common code defining db access . /srv/jenkins/bin/reproducible_common.sh # common code defining functions for OpenWrt/LEDE . /srv/jenkins/bin/reproducible_lede_common.sh set -e echo "$0 got called with '$@'" # this script is called from positions # * it's called from the reproducible_wrapper when running on the master # * it's called from reproducible_opewnrt_common when doing remote builds case $1 in node) shift case $1 in openwrt_build |\ openwrt_download |\ openwrt_get_banner |\ node_create_tmpdirs |\ node_debug |\ node_save_logs |\ node_cleanup_tmpdirs) ;; # this is the allowed list *) echo "Unsupported remote node function $@" exit 1 ;; esac $@ trap - INT TERM EXIT exit 0 ;; master) # master code following LEDE_TARGET=$2 LEDE_CONFIG=$3 ;; *) echo "Unsupported mode $1. Arguments are $@" exit 1 ;; esac # # main # DATE=$(date -u +'%Y-%m-%d') START=$(date +'%s') TMPBUILDDIR=$(mktemp --tmpdir=/srv/workspace/chroots/ -d -t rbuild-lede-build-${DATE}-XXXXXXXX) # used to build on tmpfs RESULTSDIR=$(mktemp --tmpdir=/srv/reproducible-results -d -t rbuild-lede-results-XXXXXXXX) # accessable in schroots, used to compare results BANNER_HTML=$(mktemp --tmpdir=$RESULTSDIR) trap master_cleanup_tmpdirs INT TERM EXIT cd $TMPBUILDDIR create_results_dirs lede build_two_times lede "$LEDE_TARGET" "$LEDE_CONFIG" # for now we only build one architecture until it's at most reproducible #build_two_times x86_64 "CONFIG_TARGET_x86=y\nCONFIG_TARGET_x86_64=y\n" #build_two_times ramips_rt288x_RTN15 "CONFIG_TARGET_ramips=y\nCONFIG_TARGET_ramips_rt288x=y\nCONFIG_TARGET_ramips_rt288x_RTN15=y\n" # # create html about toolchain used # echo "=============================================================================" echo "$(date -u) - Creating Documentation HTML" echo "=============================================================================" # created & copied by build_two_times() TOOLCHAIN_HTML=$RESULTSDIR/toolchain.html # clean up builddir to save space on tmpfs rm -rf $TMPBUILDDIR/lede # run diffoscope on the results # (this needs refactoring rather badly) TIMEOUT="30m" DIFFOSCOPE="$(schroot --directory /tmp -c source:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --version 2>&1)" echo "=============================================================================" echo "$(date -u) - Running $DIFFOSCOPE on LEDE images and packages." echo "=============================================================================" DBD_HTML=$(mktemp --tmpdir=$RESULTSDIR) DBD_GOOD_PKGS_HTML=$(mktemp --tmpdir=$RESULTSDIR) DBD_BAD_PKGS_HTML=$(mktemp --tmpdir=$RESULTSDIR) # run diffoscope on the images GOOD_IMAGES=0 ALL_IMAGES=0 SIZE="" cd $RESULTSDIR/b1/targets tree . # call_diffoscope requires TMPDIR TMPDIR=$RESULTSDIR # iterate over all images (merge b1 and b2 images into one list) # call diffoscope on the images for target in * ; do cd $target for subtarget in * ; do cd $subtarget # search images in both paths to find non-existing ones IMGS1=$(find * -type f -name "*.bin" -o -name "*.squashfs" | sort -u ) pushd $RESULTSDIR/b2/targets/$target/$subtarget IMGS2=$(find * -type f -name "*.bin" -o -name "*.squashfs" | sort -u ) popd echo " " >> $DBD_HTML for image in $(printf "$IMGS1\n$IMGS2" | sort -u ) ; do let ALL_IMAGES+=1 if [ ! -f $RESULTSDIR/b1/targets/$target/$subtarget/$image -o ! -f $RESULTSDIR/b2/targets/$target/$subtarget/$image ] ; then echo " " >> $DBD_HTML rm -f $BASE/lede/dbd/targets/$target/$subtarget/$image.html # cleanup from previous (unreproducible) tests - if needed continue fi if [ "$(sha256sum "$RESULTSDIR/b1/targets/$target/$subtarget/$image" "$RESULTSDIR/b2/targets/$target/$subtarget/$image" \ | cut -f 1 -d ' ' | uniq -c | wc -l)" != "1" ] ; then call_diffoscope targets/$target/$subtarget $image else echo "$(date -u) - targets/$target/$subtarget/$image is reproducible, yip!" fi get_filesize $image if [ -f $RESULTSDIR/targets/$target/$subtarget/$image.html ] ; then mkdir -p $BASE/lede/dbd/targets/$target/$subtarget mv $RESULTSDIR/targets/$target/$subtarget/$image.html $BASE/lede/dbd/targets/$target/$subtarget/$image.html echo " " >> $DBD_HTML else SHASUM=$(sha256sum $image|cut -d " " -f1) echo " " >> $DBD_HTML let GOOD_IMAGES+=1 rm -f $BASE/lede/dbd/targets/$target/$subtarget/$image.html # cleanup from previous (unreproducible) tests - if needed fi done cd .. echo "
Images for $target/$subtarget
\"ftbfs $image (${SIZE}) failed to build.
\"unreproducible $image (${SIZE}) is unreproducible.
\"reproducible $image ($SHASUM, $SIZE) is reproducible.
" >> $DBD_HTML done cd .. done GOOD_PERCENT_IMAGES=$(echo "scale=1 ; ($GOOD_IMAGES*100/$ALL_IMAGES)" | bc) # run diffoscope on the packages GOOD_PACKAGES=0 ALL_PACKAGES=0 cd $RESULTSDIR/b1 for i in * ; do cd $i # search packages in both paths to find non-existing ones PKGS1=$(find * -type f -name "*.ipk" | sort -u ) pushd $RESULTSDIR/b2/$i PKGS2=$(find * -type f -name "*.ipk" | sort -u ) popd for j in $(printf "$PKGS1\n$PKGS2" | sort -u ) ; do let ALL_PACKAGES+=1 if [ ! -f $RESULTSDIR/b1/$i/$j -o ! -f $RESULTSDIR/b2/$i/$j ] ; then echo " \"ftbfs $j (${SIZE}) failed to build." >> $DBD_BAD_PKGS_HTML rm -f $BASE/lede/dbd/$i/$j.html # cleanup from previous (unreproducible) tests - if needed continue fi if [ "$(sha256sum $RESULTSDIR/b1/$i/$j $RESULTSDIR/b2/$i/$j | cut -f 1 -d ' ' | uniq -c | wc -l)" != "1" ] ; then call_diffoscope $i $j else echo "$(date -u) - $i/$j is reproducible, yip!" fi get_filesize $j if [ -f $RESULTSDIR/$i/$j.html ] ; then mkdir -p $BASE/lede/dbd/$i/$(dirname $j) mv $RESULTSDIR/$i/$j.html $BASE/lede/dbd/$i/$j.html echo " \"unreproducible $j ($SIZE) is unreproducible." >> $DBD_BAD_PKGS_HTML else SHASUM=$(sha256sum $j|cut -d " " -f1) echo " \"reproducible $j ($SHASUM, $SIZE) is reproducible." >> $DBD_GOOD_PKGS_HTML let GOOD_PACKAGES+=1 rm -f $BASE/lede/dbd/$i/$j.html # cleanup from previous (unreproducible) tests - if needed fi done cd .. done echo " " >> $DBD_HTML cat $DBD_BAD_PKGS_HTML >> $DBD_HTML echo "
Unreproducible and otherwise broken packages
" >> $DBD_HTML echo " " >> $DBD_HTML cat $DBD_GOOD_PKGS_HTML >> $DBD_HTML echo "
Reproducible packages
" >> $DBD_HTML GOOD_PERCENT_PACKAGES=$(echo "scale=1 ; ($GOOD_PACKAGES*100/$ALL_PACKAGES)" | bc) # are we there yet? if [ "$GOOD_PERCENT_IMAGES" = "100.0" ] || [ "$GOOD_PERCENT_PACKAGES" = "100.0" ]; then MAGIC_SIGN="!" else MAGIC_SIGN="?" fi # # finally create the webpage # cd $RESULTSDIR ; mkdir lede PAGE=lede/lede_$LEDE_TARGET.html cat > $PAGE <<- EOF Reproducible LEDE ?
EOF
cat $BANNER_HTML >> $PAGE
write_page "       
" write_page "
" write_page "

LEDE - reproducible wireless freedom$MAGIC_SIGN

" write_page_intro LEDE write_page "

$GOOD_IMAGES ($GOOD_PERCENT_IMAGES%) out of $ALL_IMAGES built images and $GOOD_PACKAGES ($GOOD_PERCENT_PACKAGES%) out of $ALL_PACKAGES built packages were reproducible in our test setup." write_page " These tests were last run on $DATE for version ${OPENWRT_VERSION} using ${DIFFOSCOPE}.

" write_variation_table LEDE cat $DBD_HTML >> $PAGE cat $TOOLCHAIN_HTML >> $PAGE write_page "
" write_page_footer LEDE publish_page rm -f $DBD_HTML $DBD_GOOD_PKGS_HTML $DBD_BAD_PKGS_HTML $TOOLCHAIN_HTML $BANNER_HTML # the end calculate_build_duration print_out_duration irc_message reproducible-builds "$REPRODUCIBLE_URL/$PAGE has been updated. ($GOOD_PERCENT_IMAGES% images and $GOOD_PERCENT_PACKAGES% packages reproducible)" echo "=============================================================================" # remove everything, we don't need it anymore... master_cleanup_tmpdirs success trap - INT TERM EXIT