reproducible_freebsd.sh 10.8 KB
Newer Older
1 2 3 4 5
#!/bin/bash

# Copyright 2014-2015 Holger Levsen <holger@layer-acht.org>
# released under the GPLv=2

6
DEBUG=true
7 8 9 10 11 12 13
. /srv/jenkins/bin/common-functions.sh
common_init "$@"

# common code defining db access
. /srv/jenkins/bin/reproducible_common.sh

cleanup_tmpdirs() {
14
	set +e
15
	cd
16
	$RSSH "sudo chflags -R noschg $TMPDIR"
17
	$RSSH "rm -r $TMPDIR" || true
18
	rm $TMPDIR -r
19
	$RSSH 'sudo rm -rf /usr/src'
20 21 22 23 24 25
}

create_results_dirs() {
	mkdir -p $BASE/freebsd/dbd
}

26
save_freebsd_results() {
27
	local RUN=$1
28
	echo "============================================================================="
29
	echo "$(date -u) - Saving FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}) build results for $RUN run."
30
	echo "============================================================================="
31
	mkdir -p $TMPDIR/$RUN/
32
	# copy results over
33 34
	DUMMY_DATE="$(date -u +'%Y-%m-%d')T00:00:00Z"
	$RSSH "sudo find $TMPDIR -newer $TMPDIR -exec touch -d '$DUMMY_DATE' {} \;"
35
	$RSSH "sudo find $TMPDIR -print0 | LC_ALL=C sort -z | sudo tar --no-recursion --null -T - -cJf $TMPDIR.tar.xz"
36
	$RSCP:$TMPDIR.tar.xz $TMPDIR/$RUN/$TARGET_NAME.tar.xz
37 38
	# Copy packages back with a tar pipeline
	$RSSH "sudo tar -C /usr/obj/usr/src -cf - repo" | tar -x -C $TMPDIR/$RUN/ -f -
39
	$RSSH "sudo chflags -R noschg $TMPDIR ; sudo rm -r $TMPDIR $TMPDIR.tar.xz ; mkdir $TMPDIR"
40 41
}

42
run_diffoscope_on_results() {
43
	TIMEOUT="60m"
44
	DIFFOSCOPE="$(schroot --directory /tmp -c chroot:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --version 2>&1)"
45 46 47
	echo "============================================================================="
	echo "$(date -u) - Running $DIFFOSCOPE on FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION}) build results."
	echo "============================================================================="
48
	mkdir -p $TMPDIR
49 50 51 52 53 54 55 56 57 58 59 60
	FILES_HTML[$FREEBSD_TARGET]=$(mktemp --tmpdir=$TMPDIR)
	#echo "       <ul>" > ${FILES_HTML[$FREEBSD_TARGET]}
	GOOD_FILES[$FREEBSD_TARGET]=0
	ALL_FILES[$FREEBSD_TARGET]=0
	SIZE=""
	create_results_dirs
	echo "       <table><tr><th>Artifacts for <code>$TARGET_NAME</code></th></tr>" >> ${FILES_HTML[$FREEBSD_TARGET]}
	if [ ! -d $TMPDIR/b1 ] || [ ! -d $TMPDIR/b1 ] ; then
		echo "Warning, one of the two builds failed, not running diffoscope…"
		echo "<tr><td>$TARGET_NAME failed to build from source.</td></tr>" >> ${FILES_HTML[$FREEBSD_TARGET]}
		echo "</table>" >> ${FILES_HTML[$FREEBSD_TARGET]}
		GOOD_PERCENT[$FREEBSD_TARGET]="0"
61
		return
62 63 64
	fi
	cd $TMPDIR/b1
	tree .
65 66
	# maybe better remove that "freebsd_master_git?????????.tar.xz" from the tree first?
	for j in $(find * -type l -prune -o -type f -print |sort -u | egrep -v "freebsd_master_git?????????.tar.xz" ) ; do
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
		ALL_FILES[$FREEBSD_TARGET]=$(( ${ALL_FILES[$FREEBSD_TARGET]}+1 ))
		call_diffoscope . $j
		get_filesize $j
		if [ -f $TMPDIR/$j.html ] ; then
			mkdir -p $BASE/freebsd/dbd/$(dirname $j)
			mv $TMPDIR/$j.html $BASE/freebsd/dbd/$j.html
			echo "         <tr><td><a href=\"dbd/$j.html\"><img src=\"/userContent/static/weather-showers-scattered.png\" alt=\"unreproducible icon\" /> $j</a> ($SIZE) is unreproducible.</td></tr>" >> ${FILES_HTML[$FREEBSD_TARGET]}
		else
			SHASUM=$(sha256sum $j|cut -d " " -f1)
			echo "         <tr><td><img src=\"/userContent/static/weather-clear.png\" alt=\"reproducible icon\" /> $j ($SHASUM, $SIZE) is reproducible.</td></tr>" >> ${FILES_HTML[$FREEBSD_TARGET]}
			GOOD_FILES[$FREEBSD_TARGET]=$(( ${GOOD_FILES[$FREEBSD_TARGET]}+1 ))
			rm -f $BASE/freebsd/dbd/$j.html # cleanup from previous (unreproducible) tests - if needed
		fi
	done
	echo "       </table>" >> ${FILES_HTML[$FREEBSD_TARGET]}
	GOOD_PERCENT[$FREEBSD_TARGET]=$(echo "scale=1 ; (${GOOD_FILES[$FREEBSD_TARGET]}*100/${ALL_FILES[$FREEBSD_TARGET]})" | bc)
}

85 86 87
#
# main
#
88
#FREEBSD_TARGETS="master stable/11 release/11.0"
89 90
# temporarily just build one branch…
FREEBSD_TARGETS="master"
91
# arrays to save results
92 93 94 95
declare -A ALL_FILES
declare -A GOOD_FILES
declare -A GOOD_PERCENT
declare -A FREEBSD
96
declare -A FREEBSD_VERSION
97 98
declare -A FILES_HTML
for FREEBSD_TARGET in ${FREEBSD_TARGETS} ;do
99
	set -e
100
	RSSH="ssh -o Batchmode=yes freebsd-jenkins.debian.net"
101 102 103
	RSCP="scp -r freebsd-jenkins.debian.net"
	TMPBUILDDIR=/usr/src
	$RSSH 'sudo rm -rf /usr/src ; sudo mkdir /usr/src ; sudo chown jenkins /usr/src'  ### this is tmpfs on linux, we should move this to tmpfs on FreeBSD too
104
	# Ensure we start with the correct time on the target
105 106
	$RSSH 'sudo service ntpd stop ; sudo ntpdate -b pool.ntp.org ; sudo service ntpd start'
	$RSSH 'sudo service ntpd status ; date -u'
107
	TMPDIR=$($RSSH 'TMPDIR=/srv/reproducible-results mktemp -d -t rbuild-freebsd')  # used to compare results
108 109 110 111 112 113 114
	DATE=$(date -u +'%Y-%m-%d')
	START=$(date +'%s')
	trap cleanup_tmpdirs INT TERM EXIT
	echo "============================================================================="
	echo "$(date -u) - FreeBSD host info"
	echo "============================================================================="
	$RSSH freebsd-version
115

116 117 118
	echo "============================================================================="
	echo "$(date -u) - Cloning FreeBSD git repository."
	echo "============================================================================="
119
	$RSSH git clone --depth 1 --branch $FREEBSD_TARGET https://github.com/freebsd/freebsd.git $TMPBUILDDIR
120
	FREEBSD[$FREEBSD_TARGET]=$($RSSH "cd $TMPBUILDDIR ; git log -1")
121 122
	FREEBSD_VERSION[$FREEBSD_TARGET]=$($RSSH "cd $TMPBUILDDIR ; git describe --always")
	echo "This is FreeBSD branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}."
123 124
	echo
	$RSSH "cd $TMPBUILDDIR ; git log -1"
125
	TARGET_NAME=$(echo "freebsd_${FREEBSD_TARGET}_git${FREEBSD_VERSION[$FREEBSD_TARGET]}" | sed "s#/#-#g")
126

127
	echo "============================================================================="
128
	echo "$(date -u) - Building FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}) - first build run."
129 130 131
	echo "============================================================================="
	export TZ="/usr/share/zoneinfo/Etc/GMT+12"
	export LANG="en_GB.UTF-8"
132
	NUM_CPU=$($RSSH sysctl -n hw.ncpu)
133
	# actually build everything
134 135
	if ( $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG sudo make -j $NUM_CPU WITH_REPRODUCIBLE_BUILD=yes buildworld" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG sudo make -j $NUM_CPU WITH_REPRODUCIBLE_BUILD=yes buildkernel" && \
136
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG SOURCE_DATE_EPOCH=$START sudo make -j $NUM_CPU PKG_VERSION=current packages" && \
137 138 139 140 141 142 143
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG DESTDIR=$TMPDIR sudo make -j $NUM_CPU installworld" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG DESTDIR=$TMPDIR sudo make -j $NUM_CPU installkernel" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG DESTDIR=$TMPDIR sudo make -j $NUM_CPU distribution" ) ; then
		# save results in b1
		save_freebsd_results b1
	else
		cleanup_tmpdirs
144
		echo "$(date -u ) - failed to build FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}) in the first run, stopping."
145
		run_diffoscope_on_results
146
		continue
147
	fi
148

149
	# set time forward 398 days and some
150 151
	FUTURE_DATE=$(expr $(date +%s) + 34410180)
	$RSSH "sudo service ntpd stop ; sudo date -f %s $FUTURE_DATE ; date"
Holger Levsen's avatar
Holger Levsen committed
152
	echo "$(date -u) - system is running in the future now."
153

154
	echo "============================================================================="
155
	echo "$(date -u) - Building FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}) - second build run."
156 157 158 159 160 161 162 163 164
	echo "============================================================================="
	export TZ="/usr/share/zoneinfo/Etc/GMT-14"
	export LANG="fr_CH.UTF-8"
	export LC_ALL="fr_CH.UTF-8"
	###export PATH="$PATH:/i/capture/the/path"
	###umask 0002
	# use allmost all cores for second build
	NEW_NUM_CPU=$(echo $NUM_CPU-1|bc)
	# actually build everything
165 166
	if ( $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL sudo make -j $NEW_NUM_CPU WITH_REPRODUCIBLE_BUILD=yes buildworld" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL sudo make -j $NEW_NUM_CPU WITH_REPRODUCIBLE_BUILD=yes buildkernel" && \
167
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL SOURCE_DATE_EPOCH=$START sudo make -j $NEW_NUM_CPU PKG_VERSION=current packages" && \
168 169 170 171 172 173 174
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL DESTDIR=$TMPDIR sudo make -j $NEW_NUM_CPU installworld" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL DESTDIR=$TMPDIR sudo make -j $NEW_NUM_CPU installkernel" && \
	  $RSSH "cd $TMPBUILDDIR ; TZ=$TZ LANG=$LANG LC_ALL=$LC_ALL DESTDIR=$TMPDIR sudo make -j $NEW_NUM_CPU distribution" ) ; then
		# save results in b2
		save_freebsd_results b2
	else
		cleanup_tmpdirs
175
		echo "$(date -u ) - failed to build FreeBSD (branch $FREEBSD_TARGET at ${FREEBSD_VERSION[$FREEBSD_TARGET]}) in the second run."
176
	fi
177 178

	# set time back to today
179
	$RSSH "sudo ntpdate -b pool.ntp.org ; sudo service ntpd start ; sudo service ntpd status ; date"
Holger Levsen's avatar
Holger Levsen committed
180
	echo "$(date -u) - system is running at the current date now."
181 182 183 184 185 186 187

	# 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
188
	run_diffoscope_on_results
189 190

done
191 192 193 194 195 196 197 198 199 200 201 202

#
#  finally create the webpage
#
cd $TMPDIR ; mkdir freebsd
PAGE=freebsd/freebsd.html
cat > $PAGE <<- EOF
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
203
    <title>Reproducible FreeBSD ?</title>
204 205 206 207
    <link rel='stylesheet' href='global.css' type='text/css' media='all' />
  </head>
  <body>
    <div id="logo">
208
      <img src="320px-Freebsd_logo.svg.png" />
209
      <h1>Reproducible FreeBSD ?</h1>
210 211 212 213 214
    </div>
    <div class="content">
      <div class="page-content">
EOF
write_page_intro FreeBSD
215 216 217 218 219 220 221
for FREEBSD_TARGET in ${FREEBSD_TARGETS} ;do
	write_page "       <p>${GOOD_FILES[$FREEBSD_TARGET]} (${GOOD_PERCENT[$FREEBSD_TARGET]}%) out of ${ALL_FILES[$FREEBSD_TARGET]} FreeBSD files were reproducible in our test setup"
	if [ "${GOOD_PERCENT[$FREEBSD_TARGET]}" = "100.0" ] ; then
		write_page "!"
	else
		write_page "."
	fi
222
	write_page "        These tests were last run on $DATE for the branch $FREEBSD_TARGET at commit ${FREEBSD_VERSION[$FREEBSD_TARGET]} using ${DIFFOSCOPE}.</p>"
223
done
224
write_variation_table FreeBSD
225
set -x
226
for FREEBSD_TARGET in ${FREEBSD_TARGETS} ;do
227
	ls ${FILES_HTML[$FREEBSD_TARGET]}
228 229 230 231 232 233 234
	cat ${FILES_HTML[$FREEBSD_TARGET]} >> $PAGE
	write_page "     <p><pre>"
	echo -n "${FREEBSD[$FREEBSD_TARGET]}" >> $PAGE
	write_page "     </pre></p>"
	write_page "    </div></div>"
	rm -f ${FILES_HTML[$FREEBSD_TARGET]}
done
235
set +x
236 237 238 239 240 241
write_page_footer FreeBSD
publish_page

# the end
calculate_build_duration
print_out_duration
242
FREEBSD_TARGET="master"
243
irc_message reproducible-builds "$REPRODUCIBLE_URL/freebsd/ has been updated. (${GOOD_PERCENT[$FREEBSD_TARGET]}% reproducible)"
244 245 246 247 248
echo "============================================================================="

# remove everything, we don't need it anymore...
cleanup_tmpdirs
trap - INT TERM EXIT