From efa47a2fa9eddf50d74eb766b5f78a7e70d1b18d Mon Sep 17 00:00:00 2001 From: Holger Levsen Date: Sun, 30 Aug 2015 17:44:45 +0200 Subject: reproducible: first version of build script which supports remote building (but dont use that feature yet) --- TODO | 20 +------- bin/reproducible_build.sh | 116 +++++++++++++++++++++++++++++++++------------- 2 files changed, 84 insertions(+), 52 deletions(-) diff --git a/TODO b/TODO index e5bfab2f..2a79ae35 100644 --- a/TODO +++ b/TODO @@ -247,12 +247,11 @@ properties: * open questions: ** save build-host in build_duration table too? (and change to saving the time of a single build, not both combined) -** i believe "reproducible_build.sh 1" should immediatly move /srv/workspace/reproducible-builds/$NODE/$SUITE/$ARCH/$PKG/$VERSION to /srv/workspace/reproducible-builds/pending/$SUITE/$ARCH/$PKG/$VERSION (on the node) so it's only build once and so that we can detect stale builds ** maintenance is general, cleanup of started but interrupted builds... * reproducible_build.sh behaviour change: ** called without param: behave as always -** called with a single param, "1" or "2": do first or second build (as specified below) +** called with the first param being "1" or "2" (and two more params, srcpkg and suite): do first or second build ** called with two params: $node1 and $node2 where the build should happen. * reproducible_build.sh (with two params) will be still always be run on the main node, that is the one holding reproducible.db, so jenkins.d.n atm @@ -276,23 +275,6 @@ properties: ** this script is run on all nodes, but each run is triggered by a single job running on the main node (jenkins atm), so the results can be captured in /srv/reproducible-results/node-information/$NODE and then eg be used by reproducible_html_dashboard.sh to create the table with the differences between 1st and 2nd build... ** /srv/reproducible-results/node-information/$NODE could also be read by reproducible_build.sh to determine the dpkg-architecture a node is captable of building, but I think we also want that info to be encoded in the build job names, so probably there's no need to read it... -* how to build remotely, some terms and remarks: -** main node = the one running reproducible_build.sh with two params, so jenkins.d.n atm -** node = generic term for node1 or node2 -** please note the difference between /srv/workspace/reproducible-builds and /srv/workspace/reproducible-results and /srv/workspace/reproducible-builds/$NODE and /srv/workspace/reproducible-builds/pending and whether these are on a node or on the main node. - - -1. reproducible_build.sh on main node determines what to build, -2. downloads the sources, and put's the sha256sum of the .dsc file into /srv/workspace/reproducible-builds/$NODE/$SUITE/$ARCH/$PKG/$VERSION on the main node -3. throws the source files away -4. scp's /srv/workspace/reproducible-builds/$NODE/$SUITE/$ARCH/$PKG/$VERSION on the node where this should be build 1st -5. runs "ssh $NODE1 /srv/jenkins/bin/reproducible_build.sh 1" -6. this causes a 1st build, which downloads the sources as specified in /srv/workspace/reproducible-builds/$NODE/$SUITE/$ARCH/$PKG/$VERSION and compares the sha256sum and builds it and copies the result to /srv/workspace/reproducible-results/$NODE/$SUITE/$ARCH/$PKG/$VERSION and exits. -7. reproducible_build.sh on the main node then tries to scp the result from $NODE:/srv/workspace/reproducible-results/$NODE... -8. reproducible_build.sh on the main node then triggers the 2nd build as the 1st. -9. voila - - ==== reproducible Debian armhf * then: armhf building - run the job on jenkins.d.n and build1 on one host and build2 on another and then run debbindiff on jenkins.d.n… diff --git a/bin/reproducible_build.sh b/bin/reproducible_build.sh index e067ea8c..6f8671d4 100755 --- a/bin/reproducible_build.sh +++ b/bin/reproducible_build.sh @@ -13,9 +13,6 @@ common_init "$@" set -e -# support for different architectures -ARCH="$(dpkg --print-architecture)" - # sleep 1-12 secs to randomize start times delay_start() { /bin/sleep $(echo "scale=1 ; $(shuf -i 1-120 -n 1)/10" | bc ) @@ -345,7 +342,7 @@ choose_package () { ruby-patron|xxxxxxx) export DEBUG=true set -x - irc_message "$BUILD_URL/console available to debug $SRCPACKAGE build in $SUITE" + irc_message "$BUILD_URL/console available to debug $SRCPACKAGE build in $SUITE/$ARCH" ;; *) ;; esac @@ -355,7 +352,7 @@ choose_package () { NOTIFY_MAINTAINER=$(echo $RESULT|cut -d "|" -f7) local DEBUG_URL=$(echo $RESULT|cut -d "|" -f8) if [ "$DEBUG_URL" = "TBD" ] ; then - irc_message "The build of $SRCPACKAGE/$SUITE is starting at ${BUILD_URL}consoleFull" + irc_message "The build of $SRCPACKAGE/$SUITE/$ARCH is starting at ${BUILD_URL}consoleFull" fi if [ -z "$RESULT" ] ; then echo "No packages scheduled, sleeping 30m." @@ -405,7 +402,11 @@ get_source_package() { RESULT=$? fi if [ $RESULT != 0 ] || [ "$(ls ${SRCPACKAGE}_*.dsc 2> /dev/null)" = "" ] ; then - handle_404 + if [ "$MODE" = "legacy" ] || [ "$MODE" = "ng" ] ; then + handle_404 + else + exit 404 # FIXME: this is unhandled atm + fi fi } @@ -428,9 +429,9 @@ check_suitability() { if ! $SUITABLE ; then handle_not_for_us $ARCHITECTURES ; fi } -first_build(){ - local TMPCFG=$(mktemp -t pbuilderrc_XXXX --tmpdir=$TMPDIR) +first_build() { set -x + local TMPCFG=$(mktemp -t pbuilderrc_XXXX --tmpdir=$TMPDIR) cat > "$TMPCFG" << EOF BUILDUSERID=1111 BUILDUSERNAME=pbuilder1 @@ -451,6 +452,33 @@ EOF rm $TMPCFG } +second_build() { + set -x + local TMPCFG=$(mktemp -t pbuilderrc_XXXX --tmpdir=$TMPDIR) + cat > "$TMPCFG" << EOF +BUILDUSERID=2222 +BUILDUSERNAME=pbuilder2 +export DEB_BUILD_OPTIONS="parallel=$(echo $NUM_CPU-1|bc)" +export TZ="/usr/share/zoneinfo/Etc/GMT-14" +export LANG="fr_CH.UTF-8" +export LC_ALL="fr_CH.UTF-8" +umask 0002 +EOF + # remember to change the sudoers setting if you change the following command + sudo timeout -k 12.1h 12h /usr/bin/ionice -c 3 /usr/bin/nice \ + /usr/bin/linux64 --uname-2.6 \ + /usr/bin/unshare --uts -- \ + /usr/sbin/pbuilder --build \ + --configfile $TMPCFG \ + --hookdir /etc/pbuilder/rebuild-hooks \ + --debbuildopts "-b" \ + --basetgz /var/cache/pbuilder/$SUITE-reproducible-base.tgz \ + --buildresult b2 \ + --logfile b2/build.log \ + ${SRCPACKAGE}_${EVERSION}.dsc || true # exit with 1 when ftbfs + if ! "$DEBUG" ; then set +x ; fi +} + check_buildinfo() { local TMPFILE1=$(mktemp --tmpdir=$TMPDIR) local TMPFILE2=$(mktemp --tmpdir=$TMPDIR) @@ -485,37 +513,26 @@ check_buildinfo() { build_rebuild() { FTBFS=1 mkdir b1 b2 - first_build + if [ "$MODE" = "legacy" ] ; then + first_build + else + ssh $NODE1 /srv/jenkins/bin/reproducible_build.sh 1 ${SRCPACKAGE} ${SUITE} + scp -r $NODE1:$PWD/b1 . + ssh $NODE1 "rm -r $PWD/b1" + fi if [ -f b1/${SRCPACKAGE}_${EVERSION}_${ARCH}.changes ] ; then # the first build did not FTBFS, try rebuild it. check_for_race_conditions echo "=============================================================================" echo "Re-building ${SRCPACKAGE}/${VERSION} in ${SUITE} on ${ARCH} now." echo "=============================================================================" - set -x - local TMPCFG=$(mktemp -t pbuilderrc_XXXX --tmpdir=$TMPDIR) - cat > "$TMPCFG" << EOF -BUILDUSERID=2222 -BUILDUSERNAME=pbuilder2 -export DEB_BUILD_OPTIONS="parallel=$(echo $NUM_CPU-1|bc)" -export TZ="/usr/share/zoneinfo/Etc/GMT-14" -export LANG="fr_CH.UTF-8" -export LC_ALL="fr_CH.UTF-8" -umask 0002 -EOF - # remember to change the sudoers setting if you change the following command - sudo timeout -k 12.1h 12h /usr/bin/ionice -c 3 /usr/bin/nice \ - /usr/bin/linux64 --uname-2.6 \ - /usr/bin/unshare --uts -- \ - /usr/sbin/pbuilder --build \ - --configfile $TMPCFG \ - --hookdir /etc/pbuilder/rebuild-hooks \ - --debbuildopts "-b" \ - --basetgz /var/cache/pbuilder/$SUITE-reproducible-base.tgz \ - --buildresult b2 \ - --logfile b2/build.log \ - ${SRCPACKAGE}_${EVERSION}.dsc || true # exit with 1 when ftbfs - if ! "$DEBUG" ; then set +x ; fi + if [ "$MODE" = "legacy" ] ; then + second_build + else + ssh $NODE1 /srv/jenkins/bin/reproducible_build.sh 2 + scp -r $NODE1:$PWD/b2 . + ssh $NODE1 "rm -r $PWD/b2" + fi if [ -f b2/${SRCPACKAGE}_${EVERSION}_${ARCH}.changes ] ; then # both builds were fine, i.e., they did not FTBFS. FTBFS=0 @@ -540,6 +557,39 @@ START=$(date +'%s') RBUILDLOG=$(mktemp --tmpdir=$TMPDIR) BAD_LOCKFILE=false BUILDER="${JOB_NAME#reproducible_builder_}/${BUILD_ID}" +ARCH="$(dpkg --print-architecture)" + +# determine mode +if [ "$1" = "" ] ; then + MODE="legacy" +elif [ "$1" = "1" ] || [ "$1" = "2" ] ; then + MODE="$1" + SRCPACKAGE="$2" + SUITE="$3" + get source_package + mkdir b$MODE + if [ "$MODE" = "1" ] ; then + first_build + else + second_build + fi + exit 0 +elif [ "$2" != "" ] ; then + MODE="ng" + NODE1="$1" + NODE2="$2" + # overwrite ARCH for remote builds + for i in $ARCHS ; do + # try to match ARCH in nodenames + if [[ "$NODE1" =~ .*-$i.* ]] ; then + ARCH=i + fi + done + if [ -z "$ARCH" ] ; then + echo "Error: could not detect architecture, exiting." + exit 1 + fi +fi choose_package # defines SUITE, PKGID, SRCPACKAGE, SCHEDULED_DATE, SAVE_ARTIFACTS, NOTIFY -- cgit v1.2.3-54-g00ecf