reproducible_common.sh 39.7 KB
Newer Older
Holger Levsen's avatar
Holger Levsen committed
1
2
#!/bin/bash

Holger Levsen's avatar
Holger Levsen committed
3
4

# Copyright 2014-2016 Holger Levsen <holger@layer-acht.org>
5
#              © 2015 Mattia Rizzolo <mattia@mapreri.org>
Holger Levsen's avatar
Holger Levsen committed
6
7
8
9
10
11
12
# released under the GPLv=2
#
# included by all reproducible_*.sh scripts
#
# define db
PACKAGES_DB=/var/lib/jenkins/reproducible.db
INIT=/var/lib/jenkins/reproducible.init
13
MAINNODE="jenkins" # host which contains reproducible.db
Holger Levsen's avatar
Holger Levsen committed
14
if [ -f $PACKAGES_DB ] && [ -f $INIT ] ; then
Holger Levsen's avatar
Holger Levsen committed
15
	if [ -f ${PACKAGES_DB}.lock ] ; then
16
		for i in $(seq 0 200) ; do
Holger Levsen's avatar
Holger Levsen committed
17
			sleep 15
Holger Levsen's avatar
Holger Levsen committed
18
			echo "sleeping 15s, $PACKAGES_DB is locked."
Holger Levsen's avatar
Holger Levsen committed
19
			if [ ! -f ${PACKAGES_DB}.lock ] ; then
Holger Levsen's avatar
Holger Levsen committed
20
21
22
				break
			fi
		done
Holger Levsen's avatar
Holger Levsen committed
23
24
		if [ -f ${PACKAGES_DB}.lock ] ; then
			echo "${PACKAGES_DB}.lock still exist, exiting."
Holger Levsen's avatar
Holger Levsen committed
25
26
			exit 1
		fi
Holger Levsen's avatar
Holger Levsen committed
27
	fi
28
elif [ ! -f ${PACKAGES_DB} ] && [ "$HOSTNAME" = "$MAINNODE" ] ; then
Holger Levsen's avatar
Holger Levsen committed
29
	echo "Warning: $PACKAGES_DB doesn't exist, creating it now."
30
		/srv/jenkins/bin/reproducible_db_maintenance.py
31
	# 60 seconds timeout when trying to get a lock
Holger Levsen's avatar
Holger Levsen committed
32
	cat > $INIT <<-EOF
Holger Levsen's avatar
Holger Levsen committed
33
34
35
36
.timeout 60000
EOF
fi

37
# common variables
38
REPRODUCIBLE_URL=https://tests.reproducible-builds.org
39
REPRODUCIBLE_DOT_ORG_URL=https://reproducible-builds.org
40
41
# shop trailing slash
JENKINS_URL=${JENKINS_URL:0:-1}
Holger Levsen's avatar
Holger Levsen committed
42
DBDSUITE="unstable"
43

44
# Debian suites being tested
45
SUITES="testing unstable experimental"
46
# Debian architectures being tested
47
ARCHS="amd64 armhf"
Holger Levsen's avatar
Holger Levsen committed
48

49
# define Debian build nodes in use
50
51
52
. /srv/jenkins/bin/jenkins_node_definitions.sh

# variables on the nodes we are interested in
53
BUILD_ENV_VARS="ARCH NUM_CPU CPU_MODEL DATETIME KERNEL" # these also needs to be defined in bin/reproducible_info.sh
54

55
# existing usertags in the Debian BTS
56
USERTAGS="toolchain infrastructure timestamps fileordering buildpath username hostname uname randomness buildinfo cpu signatures environment umask ftbfs locale"
57

58
# common settings for testing Arch Linux
59
ARCHLINUX_BUILD_NODE=profitbricks-build3-amd64
60
ARCHLINUX_REPOS="core extra multilib community"
61
ARCHLINUX_PKGS=/srv/reproducible-results/.archlinux_pkgs
62

63
64
# common settings for testing rpm based distros
RPM_BUILD_NODE=profitbricks-build3-amd64
65
RPM_PKGS=/srv/reproducible-results/.rpm_pkgs
66

Holger Levsen's avatar
Holger Levsen committed
67
68
69
# number of cores to be used
NUM_CPU=$(grep -c '^processor' /proc/cpuinfo)

70
# we only this array for html creation but we cannot declare them in a function
71
declare -A SPOKENTARGET
Holger Levsen's avatar
Holger Levsen committed
72

73
BASE="/var/lib/jenkins/userContent/reproducible"
74
mkdir -p "$BASE"
75

76
77
# to hold reproducible temporary files/directories without polluting /tmp
TEMPDIR="/tmp/reproducible"
78
mkdir -p "$TEMPDIR"
79

80
81
# create subdirs for suites
for i in $SUITES ; do
82
	mkdir -p "$BASE/$i"
83
84
done

85
# table names and image names
Holger Levsen's avatar
Holger Levsen committed
86
87
88
89
90
91
92
93
TABLE[0]=stats_pkg_state
TABLE[1]=stats_builds_per_day
TABLE[2]=stats_builds_age
TABLE[3]=stats_bugs
TABLE[4]=stats_notes
TABLE[5]=stats_issues
TABLE[6]=stats_meta_pkg_state
TABLE[7]=stats_bugs_state
94
95
TABLE[8]=stats_bugs_sin_ftbfs
TABLE[9]=stats_bugs_sin_ftbfs_state
Holger Levsen's avatar
Holger Levsen committed
96

97
# known package sets
98
99
100
META_PKGSET[1]="essential"
META_PKGSET[2]="required"
META_PKGSET[3]="build-essential"
101
102
META_PKGSET[4]="build-essential-depends"
META_PKGSET[5]="popcon_top1337-installed-sources"
103
104
105
META_PKGSET[6]="key_packages"
META_PKGSET[7]="installed_on_debian.org"
META_PKGSET[8]="had_a_DSA"
106
107
108
109
110
111
112
113
114
115
116
META_PKGSET[9]="cii-census"
META_PKGSET[10]="gnome"
META_PKGSET[11]="gnome_build-depends"
META_PKGSET[12]="kde"
META_PKGSET[13]="kde_build-depends"
META_PKGSET[14]="xfce"
META_PKGSET[15]="xfce_build-depends"
META_PKGSET[16]="tails"
META_PKGSET[17]="tails_build-depends"
META_PKGSET[18]="grml"
META_PKGSET[19]="grml_build-depends"
117
118
META_PKGSET[20]="freedombox"
META_PKGSET[21]="freedombox_build-depends"
119
120
121
122
123
124
125
126
127
128
129
130
131
META_PKGSET[22]="subgraph_OS"
META_PKGSET[23]="subgraph_OS_build-depends"
META_PKGSET[24]="maint_pkg-perl-maintainers"
META_PKGSET[25]="maint_pkg-java-maintainers"
META_PKGSET[26]="maint_pkg-haskell-maintainers"
META_PKGSET[27]="maint_pkg-ruby-extras-maintainers"
META_PKGSET[28]="maint_pkg-golang-maintainers"
META_PKGSET[29]="maint_pkg-php-pear"
META_PKGSET[30]="maint_pkg-javascript-devel"
META_PKGSET[31]="maint_debian-boot"
META_PKGSET[32]="maint_debian-ocaml"
META_PKGSET[33]="maint_debian-x"
META_PKGSET[34]="maint_lua"
132

133
134
135
136
137
# sleep 1-23 secs to randomize start times
delay_start() {
	/bin/sleep $(echo "scale=1 ; $(shuf -i 1-230 -n 1)/10" | bc )
}

138
schedule_packages() {
139
140
141
142
143
	LC_USER="$REQUESTER" \
	LOCAL_CALL="true" \
	/srv/jenkins/bin/reproducible_remote_scheduler.py \
		--message "$REASON" \
		--no-notify \
144
		--suite "$SUITE" \
145
		--architecture "$ARCH" \
146
		$@
147
148
}

149
150
151
152
153
154
155
156
157
158
159
write_page() {
	echo "$1" >> $PAGE
}

set_icon() {
	# icons taken from tango-icon-theme (0.8.90-5)
	# licenced under http://creativecommons.org/licenses/publicdomain/
	STATE_TARGET_NAME="$1"
	case "$1" in
		reproducible)		ICON=weather-clear.png
					;;
160
		unreproducible|FTBR)	ICON=weather-showers-scattered.png
161
					STATE_TARGET_NAME="FTBR"
162
163
164
					;;
		FTBFS)			ICON=weather-storm.png
					;;
165
166
		depwait)		ICON=weather-snow.png
					;;
167
168
169
170
171
172
173
174
175
176
177
178
179
		404)			ICON=weather-severe-alert.png
					;;
		not_for_us|"not for us")	ICON=weather-few-clouds-night.png
					STATE_TARGET_NAME="not_for_us"
					;;
		blacklisted)		ICON=error.png
					;;
		*)			ICON=""
	esac
}

write_icon() {
	# ICON and STATE_TARGET_NAME are set by set_icon()
180
	write_page "<a href=\"/$SUITE/$ARCH/index_${STATE_TARGET_NAME}.html\" target=\"_parent\"><img src=\"/userContent/static/$ICON\" alt=\"${STATE_TARGET_NAME} icon\" /></a>"
181
182
183
184
}

write_page_header() {
	rm -f $PAGE
185
	MAINVIEW="dashboard"
186
	ALLSTATES="reproducible FTBR FTBFS depwait not_for_us 404 blacklisted"
187
188
	ALLVIEWS="issues notes no_notes scheduled last_24h last_48h all_abc notify dd-list pkg_sets suite_stats arch repositories dashboard"
	GLOBALVIEWS="issues scheduled notify repositories dashboard"
Holger Levsen's avatar
Holger Levsen committed
189
	SUITEVIEWS="dd-list suite_stats"
Holger Levsen's avatar
Holger Levsen committed
190
191
192
193
194
195
196
	SPOKENTARGET["issues"]="issues"
	SPOKENTARGET["notes"]="packages with notes"
	SPOKENTARGET["no_notes"]="packages without notes"
	SPOKENTARGET["scheduled"]="currently scheduled"
	SPOKENTARGET["last_24h"]="packages tested in the last 24h"
	SPOKENTARGET["last_48h"]="packages tested in the last 48h"
	SPOKENTARGET["all_abc"]="all tested packages (sorted alphabetically)"
197
	SPOKENTARGET["notify"]="⚑"
Holger Levsen's avatar
Holger Levsen committed
198
	SPOKENTARGET["dd-list"]="maintainers of unreproducible packages"
199
	SPOKENTARGET["pkg_sets"]="package sets"
Holger Levsen's avatar
Holger Levsen committed
200
	SPOKENTARGET["suite_stats"]="suite: $SUITE"
201
	SPOKENTARGET["repositories"]="repositories overview"
202
	SPOKENTARGET["dashboard"]="dashboard"
203
204
	write_page "<!DOCTYPE html><html><head>"
	write_page "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />"
205
	write_page "<link href=\"/userContent/static/style.css\" type=\"text/css\" rel=\"stylesheet\" />"
206
	write_page "<title>$2</title></head>"
207
	if [ "$1" != "$MAINVIEW" ] ; then
208
		write_page "<body><header><h2>$2</h2><nav>"
209
	else
Holger Levsen's avatar
Holger Levsen committed
210
		write_page "<body onload=\"selectSearch()\"><header><h2>$2</h2><nav>"
211
212
213
214
		write_page "<ul>"
		write_page "   A general website <li><a href=\"https://reproducible-builds.org\">Reproducible-builds.org</a></li> is available now."
		write_page "   We think that reproducible builds should become the norm, so we wrote <li><a href=\"https://reproducible-builds.org/howto\">How to make your software reproducible</a></li>."
		write_page "   Also aimed at the free software world at large, is the first specification we have written: the <li><a href=\"https://reproducible-builds.org/specs/source-date-epoch/\">SOURCE_DATE_EPOCH specification</a></li>."
215
216
		write_page "</ul>"
		write_page "<ul>"
217
		write_page "   These pages are showing the <em>prospects</em> of <li><a href=\"https://wiki.debian.org/ReproducibleBuilds\" target=\"_blank\">reproducible builds of Debian packages</a></li>."
Holger Levsen's avatar
Holger Levsen committed
218
		write_page "   The results shown were obtained by <a href=\"$JENKINS_URL/view/reproducible\">several jobs</a> running on"
219
220
221
		write_page "   <a href=\"$JENKINS_URL/userContent/about.html#_reproducible_builds_jobs\">jenkins.debian.net</a>."
		write_page "   Thanks to <a href=\"https://www.profitbricks.co.uk\">Profitbricks</a> for donating the virtual machines this is running on!"
		write_page "</ul>"
222
	fi
223
	if [ "$1" = "dd-list" ] || [ "$1" = "dashboard" ] ; then
224
		write_page "<ul>"
225
		write_page "   We are reachable via IRC (<code>#debian-reproducible</code> and <code>#reproducible-builds</code> on OFTC),"
226
227
228
		write_page "   or <a href="mailto:reproducible-builds@lists.alioth.debian.org">email</a>,"
		write_page "   and we care about free software in general,"
		write_page "   so whether you are an upstream developer or working on another distribution, or have any other feedback - we'd love to hear from you!"
229
		write_page "   Besides Debian we are also testing <li><a href=\"/coreboot/\">coreboot</a></li>, <li><a href=\"/openwrt/\">OpenWrt</a></li>, <li><a href=\"netbsd\">NetBSD</a></li>, <li><a href=\"/freebsd/\">FreeBSD</a></li> and <li><a href=\"archlinux\">Arch Linux</a></li> now, though not as thoroughly as Debian (yet?) - and testing of <li><a href=\"/rpms/fedora-23.html\">Fedora</a></li> has just begun, and there are plans to test <a href=\"https://jenkins.debian.net/userContent/todo.html#_reproducible_fdroid\">F-Droid</a> and <a href=\"https://jenkins.debian.net/userContent/todo.html#_reproducible_guix\">GNU Guix</a> too, and more, if you contribute!"
230
		write_page "</ul>"
231
	fi
232
	write_page "<ul><li>Have a look at:</li>"
233
	for MY_STATE in $ALLSTATES ; do
234
		set_icon $MY_STATE
235
236
237
238
		write_page "<li>"
		write_icon
		write_page "</li>"
	done
239
	for TARGET in $ALLVIEWS ; do
240
241
		if [ "$TARGET" = "pkg_sets" ] && [ "$SUITE" = "experimental" ] ; then
			# no pkg_sets are tested in experimental
242
243
			continue
		fi
244
		SPOKEN_TARGET=${SPOKENTARGET[$TARGET]}
245
		BASEURL="/$SUITE/$ARCH"
246
		local i
247
248
249
250
251
		for i in $GLOBALVIEWS ; do
			if [ "$TARGET" = "$i" ] ; then
				BASEURL=""
			fi
		done
252
253
254
255
256
		for i in ${SUITEVIEWS} ; do
			if [ "$TARGET" = "$i" ] ; then
				BASEURL="/$SUITE"
			fi
		done
257
258
		if [ "$TARGET" = "suite_stats" ] ; then
			for i in $SUITES ; do
259
				write_page "<li><a href=\"/$i/index_suite_${ARCH}_stats.html\">suite: $i</a></li>"
260
			done
261
262
		elif [ "$TARGET" = "scheduled" ] ; then
			write_page "<li><a href=\"/index_${ARCH}_scheduled.html\">${SPOKEN_TARGET}</a></li>"
263
264
		elif [ "$TARGET" = "notify" ] ; then
			write_page "<li><a href=\"$BASEURL/index_${TARGET}.html\" title=\"notify icon\">${SPOKEN_TARGET}</a></li>"
265
		elif [ "$TARGET" = "arch" ] ; then
Holger Levsen's avatar
Holger Levsen committed
266
			if [ "$ARCH"  = "amd64" ] ; then
267
				write_page "<li><a href=\"/unstable/index_suite_armhf_stats.html\">arch: armhf</a></li>"
268
			else
269
				write_page "<li><a href=\"/unstable/index_suite_amd64_stats.html\">arch: amd64</a></li>"
270
			fi
271
272
		else
			write_page "<li><a href=\"$BASEURL/index_${TARGET}.html\">${SPOKEN_TARGET}</a></li>"
273
274
		fi
	done
275
	write_page "<li><a href=\"https://wiki.debian.org/ReproducibleBuilds\" target=\"_blank\">wiki</a></li>"
276
	write_page "<li><a href=\"https://Reproducible-builds.org\" target=\"_blank\">Reproducible-builds.org</a></li>"
277
	write_page "</ul></nav>"
278
	if [ "$1" = "$MAINVIEW" ] ; then
Holger Levsen's avatar
Holger Levsen committed
279
		LATEST=$(sqlite3 -init $INIT ${PACKAGES_DB} "SELECT s.name FROM results AS r JOIN sources AS s ON r.package_id = s.id WHERE r.status IN ('unreproducible') AND s.suite = 'unstable' AND s.architecture = 'amd64' AND s.id NOT IN (SELECT package_id FROM notes) ORDER BY build_date DESC LIMIT 23"|sort -R|head -1)
280
		write_page "<form action=\"https://reproducible.debian.net/redirect\" method=\"GET\">https://reproducible.debian.net/"
281
		write_page "<input type=\"text\" name=\"SrcPkg\" placeholder=\"Type my friend..\" value=\"$LATEST\" />"
282
		write_page "<input type=\"submit\" value=\"submit source package name\" />"
283
		write_page "</form>"
284
	fi
285
286
287
	write_page "</header>"
}

288
write_page_intro() {
289
	write_page "       <p><em>Reproducible builds</em> enable anyone to reproduce bit by bit identical binary packages from a given source, so that anyone can verify that a given binary derived from the source it was said to be derived."
290
	write_page "         There is a lot more information about <a href=\"https://wiki.debian.org/ReproducibleBuilds\">reproducible builds on the Debian wiki</a> and on <a href=\"https://tests.reproducible-builds.org\">https://tests.reproducible-builds.org</a>."
291
	write_page "         The wiki explains in more depth why this is useful, what common issues exist and which workarounds and solutions are known."
292
	write_page "        </p>"
293
	local BUILD_ENVIRONMENT=" in a Debian environment"
294
	local BRANCH="master"
Holger Levsen's avatar
Holger Levsen committed
295
	if [ "$1" = "coreboot" ] ; then
296
		write_page "        <p><em>Reproducible Coreboot</em> is an effort to apply this to coreboot. Thus each coreboot.rom is build twice (without payloads), with a few varitations added and then those two ROMs are compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. Please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
297
298
299
		local PROJECTNAME="$1"
		local PROJECTURL="https://review.coreboot.org/p/coreboot.git"
	elif [ "$1" = "OpenWrt" ] ; then
300
		write_page "        <p><em>Reproducible OpenWrt</em> is an effort to apply this to OpenWrt. Thus each OpenWrt target is build twice, with a few varitations added and then the resulting images and packages from the two builds are compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. OpenWRT generates many different types of raw <code>.bin</code> files, and diffoscope does not know how to parse these. Thus the resulting diffoscope output is not nearly as clear as it could be - hopefully this limitation will be overcome eventually, but in the meanwhile the input components (uImage kernel file, rootfs.tar.gz, and/or rootfs squashfs) can be inspected. Also please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
301
302
		local PROJECTNAME="openwrt"
		local PROJECTURL="git://git.openwrt.org/openwrt.git"
303
	elif [ "$1" = "NetBSD" ] ; then
304
		write_page "        <p><em>Reproducible NetBSD</em> is an effort to apply this to NetBSD. Thus each NetBSD target is build twice, with a few varitations added and then the resulting files from the two builds are compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. Please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
305
		local PROJECTNAME="netbsd"
306
		local PROJECTURL="https://github.com/jsonn/src"
307
	elif [ "$1" = "FreeBSD" ] ; then
Holger Levsen's avatar
Holger Levsen committed
308
		write_page "        <p><em>Reproducible FreeBSD</em> is an effort to apply this to FreeBSD. Thus FreeBSD is build twice, with a few varitations added and then the resulting filesystems from the two builds are put into a compressed tar archive, which is finally compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. Please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
309
310
		local PROJECTNAME="freebsd"
		local PROJECTURL="https://github.com/freebsd/freebsd.git"
311
		local BUILD_ENVIRONMENT=", which via ssh triggers a build on a FreeBSD 10.2 system"
312
		local BRANCH="release/10.2.0"
313
314
	elif [ "$1" = "Arch Linux" ] ; then
		local PROJECTNAME="Arch Linux"
Holger Levsen's avatar
Holger Levsen committed
315
		write_page "        <p><em>Reproducible $PROJECTNAME</em> is an effort to apply this to $PROJECTNAME. Thus $PROJECTNAME packages are build twice, with a few varitations added and then the resulting packages from the two builds are compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. Please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
316
317
	elif [ "$1" = "fedora-23" ] ; then
		local PROJECTNAME="Fedora 23"
Holger Levsen's avatar
Holger Levsen committed
318
		write_page "        <p><em>Reproducible $PROJECTNAME</em> is an effort to apply this to $PROJECTNAME. Thus $PROJECTNAME packages are build twice, with a few varitations added and then the resulting packages from the two builds are compared using <a href=\"https://tracker.debian.org/diffoscope\">diffoscope</a>. Please note that the toolchain is not varied at all as the rebuild happens on exactly the same system. More variations are expected to be seen in the wild.</p>"
319
		write_page "        <p>Please note that this set up is as new as December 12th, so quite some things are still lacking, eg. https://github.com/kholia/ReproducibleBuilds is not followed at all yet and there are no variations introduced for the 2nd build. Also only a subset of all source packages is currently being tested. OTOH this setup is mature enough that it requires very few trivial changes to build all 17080 source packages in $PROJECTNAME, if it were sensible. Which it isn't right now, but should be soon.</p>"
320
	fi
321
	if [ "$1" != "Arch Linux" ] && [ "$1" != "fedora-23" ] ; then
322
		write_page "       <p>There is a weekly run <a href=\"https://jenkins.debian.net/view/reproducible/job/reproducible_$PROJECTNAME/\">jenkins job</a> to test the <code>$BRANCH</code> branch of <a href=\"$PROJECTURL\">$PROJECTNAME.git</a>. The jenkins job is running <a href=\"http://anonscm.debian.org/cgit/qa/jenkins.debian.net.git/tree/bin/reproducible_$PROJECTNAME.sh\">reproducible_$PROJECTNAME.sh</a>$BUILD_ENVIRONMENT and this script is solely responsible for creating this page. Feel invited to join <code>#debian-reproducible</code> (on irc.oftc.net) to request job runs whenever sensible. Patches and other <a href=\"mailto:reproducible-builds@lists.alioth.debian.org\">feedback</a> are very much appreciated - if you want to help, please start by looking at the <a href=\"https://jenkins.debian.net/userContent/todo.html#_reproducible_$(echo $1|tr '[:upper:]' '[:lower:]')\">ToDo list for $1</a>, you might find something easy to contribute."
323
324
325
		write_page "       <br />Thanks to <a href=\"https://www.profitbricks.co.uk\">Profitbricks</a> for donating the virtual machines this is running on!</p>"
	elif [ "$1" = "Arch Linux" ] ; then
		write_page "       <p>There is a weekly run <a href=\"https://jenkins.debian.net/view/reproducible/job/reproducible_$PROJECTNAME/\">jenkins job</a> to test the <code>$BRANCH</code> branch of <a href=\"$PROJECTURL\">$PROJECTNAME.git</a>. The jenkins job is running <a href=\"http://anonscm.debian.org/cgit/qa/jenkins.debian.net.git/tree/bin/reproducible_$PROJECTNAME.sh\">reproducible_$PROJECTNAME.sh</a>$BUILD_ENVIRONMENT and this script is solely responsible for creating this page. Feel invited to join <code>#debian-reproducible</code> (on irc.oftc.net) to request job runs whenever sensible. Patches and other <a href=\"mailto:reproducible-builds@lists.alioth.debian.org\">feedback</a> are very much appreciated - if you want to help, please start by looking at the <a href=\"https://jenkins.debian.net/userContent/todo.html#_reproducible_$(echo $1|tr '[:upper:]' '[:lower:]')\">ToDo list for $1</a>, you might find something easy to contribute."
326
		write_page "       <br />Thanks to <a href=\"https://www.profitbricks.co.uk\">Profitbricks</a> for donating the virtual machines this is running on!</p>"
327
	else
328
		write_page "       <p>FIXME: explain $PROJECTNAME test setup here.</p>"
329
330
331
	fi
}

332
write_page_footer() {
333
334
335
336
337
338
	write_page "<hr id=\"footer_separator\" /><p style=\"font-size:0.9em;\"><div id=\"page_footer\">"
	if [ -n "$JOB_URL" ] ; then
		write_page "This page was built by the jenkins job"
		write_page "<a href=\"$JOB_URL\">$(basename $JOB_URL)</a> which is configured"
		write_page "via this <a href=\"http://anonscm.debian.org/cgit/qa/jenkins.debian.net.git/\">git repo</a>."
	fi
339
	write_page "There is more information <a href=\"https://jenkins.debian.net/userContent/about.html\">about jenkins.debian.net</a> and about <a href=\"https://wiki.debian.org/ReproducibleBuilds\"> reproducible builds of Debian</a> available elsewhere."
Holger Levsen's avatar
Holger Levsen committed
340
	write_page "<br /> Last update: $(date +'%Y-%m-%d %H:%M %Z'). Copyright 2014-2016 <a href=\"mailto:holger@layer-acht.org\">Holger Levsen</a> and <a href=\"https://jenkins.debian.net//userContent/thanks.html\">many others</a>."
341
	write_page "The code of <a href=\"http://anonscm.debian.org/cgit/qa/jenkins.debian.net.git/\">jenkins.debian.net.git</a> is mostly GPL-2 licensed. The weather icons are public domain and have been taken from the <a href=\"http://tango.freedesktop.org/Tango_Icon_Library\" target=\"_blank\">Tango Icon Library</a>."
342
	write_page "<br />"
343
344
	if [ "$1" = "coreboot" ] ; then
		write_page "The <a href=\"http://www.coreboot.org\">Coreboot</a> logo is Copyright © 2008 by Konsult Stuge and coresystems GmbH and can be freely used to refer to the Coreboot project."
345
346
	elif [ "$1" = "NetBSD" ] ; then
		write_page "NetBSD® is a registered trademark of The NetBSD Foundation, Inc."
347
348
	elif [ "$1" = "FreeBSD" ] ; then
		write_page "FreeBSD is a registered trademark of The FreeBSD Foundation. The FreeBSD logo and The Power to Serve are trademarks of The FreeBSD Foundation."
349
	elif [ "$1" = "Arch Linux" ] ; then
350
		write_page "The <a href=\"https://www.archlinux.org\">Arch Linux</a> name and logo are recognized trademarks. Some rights reserved. The registered trademark Linux® is used pursuant to a sublicense from LMI, the exclusive licensee of Linus Torvalds, owner of the mark on a world-wide basis."
351
352
	elif [ "$1" = "fedora-23" ] ; then
		write_page "FIXME: add fedora copyright+trademark disclaimers here."
353
	fi
354
355
	write_page "</div></p>"
	write_page "</body></html>"
356
357
358
}

write_page_meta_sign() {
359
	write_page "<p style=\"font-size:0.9em;\">A package name displayed with a <span style=\"font-weight: bold;\">bold font</span> is an indication that this package has a note. Visited packages are linked in green, those which have not been visited are linked in blue.</br>"
360
	write_page "A <code><span class=\"bug\">&#35;</span></code> sign after the name of a package indicates that a bug is filed against it. Likewise, a <code><span class=\"bug-patch\">&#43;</span></code> sign indicates there is a patch available, a <code><span class="bug-pending">P</span></code> means a pending bug while <code><span class=\"bug-done\">&#35;</span></code> indicates a closed bug. In cases of several bugs, the symbol is repeated.</p>"
361
362
}

363
364
write_explaination_table() {
	write_page "<p style=\"clear:both;\">"
365
366
367
368
	if [ "$1" = "fedora-23" ] ; then
		write_page "There are no variations introduced in the $1 builds yet. Stay tuned.</p>"
		return
	fi
369
	write_page "<table class=\"main\" id=\"variation\"><tr><th>variation</th><th width=\"40%\">first build</th><th width=\"40%\">second build</th></tr>"
370
	if [ "$1" = "debian" ] ; then
371
		write_page "<tr><td>hostname</td><td>one of:"
372
		local FIRST=""
373
		for a in ${ARCHS} ; do
374
375
			local ARCH_NODES=""
			write_page "<br />&nbsp;&nbsp;"
376
377
			for i in $(echo $BUILD_NODES | sed -s 's# #\n#g' | sort -u) ; do
				if [ "$(echo $i | grep $a)" ] ; then
378
379
380
381
382
383
					ARCH_NODES="${ARCH_NODES}$(echo $i | cut -d '.' -f1 | sed -s 's# ##g')"
					if [ -z $FIRST ] ; then
						FIRST=", "
					else
						ARCH_NODES="${ARCH_NODES}$FIRST"
					fi
384
385
				fi
			done
386
			write_page "${ARCH_NODES}"
387
388
		done
		write_page "</td><td>i-capture-the-hostname</td></tr>"
389
		write_page "<tr><td>domainname</td><td>$(hostname -d)</td><td>i-capture-the-domainname</td></tr>"
390
	else
391
392
		write_page "<tr><td>hostname</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
		write_page "<tr><td>domainname</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
393
	fi
394
	if [ "$1" != "FreeBSD" ] && [ "$1" != "Arch Linux" ] && [ "$1" != "fedora-23" ] ; then
395
396
		write_page "<tr><td>env CAPTURE_ENVIRONMENT</td><td><em>not set</em></td><td>CAPTURE_ENVIRONMENT=\"I capture the environment\"</td></tr>"
	fi
397
	write_page "<tr><td>env TZ</td><td>TZ=\"/usr/share/zoneinfo/Etc/GMT+12\"</td><td>TZ=\"/usr/share/zoneinfo/Etc/GMT-14\"</td></tr>"
398
	if [ "$1" = "debian" ]  ; then
399
		write_page "<tr><td>env LANG</td><td>LANG=C</td><td>LANG=\"fr_CH.UTF-8\"</td></tr>"
400
	elif [ "$1" = "Arch Linux" ]  ; then
401
		write_page "<tr><td>env LANG</td><td><em>not set</em></td><td>LANG=\"fr_CH.UTF-8\"</td></tr>"
402
	else
403
404
405
		write_page "<tr><td>env LANG</td><td>LANG=\"en_GB.UTF-8\"</td><td>LANG=\"fr_CH.UTF-8\"</td></tr>"
	fi
	write_page "<tr><td>env LC_ALL</td><td><em>not set</em></td><td>LC_ALL=\"fr_CH.UTF-8\"</td></tr>"
406
	if [ "$1" != "FreeBSD" ] && [ "$1" != "Arch Linux" ]  ; then
407
408
		write_page "<tr><td>env PATH</td><td>PATH=\"/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:\"</td><td>PATH=\"/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path\"</td></tr>"
	else
409
		write_page "<tr><td>env PATH</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
410
	fi
411
412
413
414
415
416
	if [ "$1" = "debian" ] ; then
		write_page "<tr><td>env BUILDUSERID</td><td>BUILDUSERID=\"1111\"</td><td>BUILDUSERID=\"2222\"</td></tr>"
		write_page "<tr><td>env BUILDUSERNAME</td><td>BUILDUSERNAME=\"pbuilder1\"</td><td>BUILDUSERNAME=\"pbuilder2\"</td></tr>"
		write_page "<tr><td>env USER</td><td>USER=\"pbuilder1\"</td><td>USER=\"pbuilder2\"</td></tr>"
		write_page "<tr><td>uid</td><td>uid=1111</td><td>uid=2222</td></tr>"
		write_page "<tr><td>gid</td><td>gid=1111</td><td>gid=2222</td></tr>"
417
		write_page "<tr><td>env DEB_BUILD_OPTIONS</td><td>DEB_BUILD_OPTIONS=\"parallel=XXX\"<br />&nbsp;&nbsp;XXX for amd64: 18 or 17<br />&nbsp;&nbsp;XXX for armhf: 8, 4 or 2</td><td>DEB_BUILD_OPTIONS=\"parallel=YYY\"<br />&nbsp;&nbsp;YYY for amd64: 17 or 18 (!= the first build)<br />&nbsp;&nbsp;YYY for armhf: 8, 4, or 2 (not varied systematically)</td></tr>"
418
		write_page "<tr><td>UTS namespace</td><td><em>shared with the host</em></td><td><em>modified using</em> /usr/bin/unshare --uts</td></tr>"
419
	else
420
421
422
		write_page "<tr><td>env USER</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
		write_page "<tr><td>uid</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
		write_page "<tr><td>gid</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
423
424
425
426
427
		if [ "$1" != "FreeBSD" ] ; then
			write_page "<tr><td>UTS namespace</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
		fi
	fi
	if [ "$1" != "FreeBSD" ] ; then
428
		if [ "$1" = "debian" ] ; then
429
			write_page "<tr><td>kernel version</td></td><td>one of:"
430
431
			write_page " $(cat /srv/reproducible-results/node-information/* | grep KERNEL | grep amd64 | cut -d '=' -f2- | sort -u | tr '\n' '\0' | xargs -0 -n1 echo '<br />&nbsp;&nbsp;')"
			write_page " $(cat /srv/reproducible-results/node-information/* | grep KERNEL | grep -v amd64 | cut -d '=' -f2- | sort -u | tr '\n' '\0' | xargs -0 -n1 echo '<br />&nbsp;&nbsp;')"
432
433
			write_page "</td>"
			write_page "<td>(on amd64 systematically varied, on armhf not yet)<br />"
434
435
			write_page "one of: $(cat /srv/reproducible-results/node-information/* | grep KERNEL | grep amd64 | cut -d '=' -f2- | sort -u | tr '\n' '\0' | xargs -0 -n1 echo '<br />&nbsp;&nbsp;')"
			write_page "one of: $(cat /srv/reproducible-results/node-information/* | grep KERNEL | grep -v amd64 | cut -d '=' -f2- | sort -u | tr '\n' '\0' | xargs -0 -n1 echo '<br />&nbsp;&nbsp;')"
436
			write_page "</td></tr>"
437
		elif [ "$1" != "Arch Linux" ]  ; then
438
			write_page "<tr><td>kernel version, modified using /usr/bin/linux64 --uname-2.6</td><td>$(uname -sr)</td><td>$(/usr/bin/linux64 --uname-2.6 uname -sr)</td></tr>"
439
		else
Holger Levsen's avatar
Holger Levsen committed
440
			write_page "<tr><td>kernel version</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
441
		fi
442
		write_page "<tr><td>umask</td><td>0022<td>0002</td><tr>"
443
444
445
	else
		write_page "<tr><td>FreeBSD kernel version</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
		write_page "<tr><td>umask</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td><tr>"
446
	fi
447
	FUTURE=$(date --date="${DATE}+398 days" +'%Y-%m-%d')
448
	if [ "$1" = "debian" ] ; then
449
		write_page "<tr><td>CPU type</td><td>one of: $(cat /srv/reproducible-results/node-information/* | grep CPU_MODEL | cut -d '=' -f2- | sort -u | tr '\n' '\0' | xargs -0 -n1 echo '<br />&nbsp;&nbsp;')</td><td>on amd64: same for both builds (currently, work in progress<br />on armhf: sometimes varied (depending on the build job)</td></tr>"
450
		write_page "<tr><td>/bin/sh</td><td>/bin/dash</td><td>/bin/bash</td></tr>"
Holger Levsen's avatar
Holger Levsen committed
451
		write_page "<tr><td>year, month, date</td><td>today ($DATE) or on amd64 also: $FUTURE</td><td>on amd64: varied (398 days difference)<br />on armhf: same for both builds (currently, work in progress)</td></tr>"
452
453
	else
		write_page "<tr><td>CPU type</td><td>$(cat /proc/cpuinfo|grep 'model name'|head -1|cut -d ":" -f2-)</td><td>same for both builds</td></tr>"
454
		write_page "<tr><td>/bin/sh</td><td colspan=\"2\"> is not yet varied between rebuilds of $1.</td></tr>"
455
456
457
458
459
		if [ "$1" != "FreeBSD" ] ; then
			write_page "<tr><td>year, month, date</td><td>today ($DATE)</td><td>same for both builds (currently, work in progress)</td></tr>"
		else
			write_page "<tr><td>year, month, date</td><td>today ($DATE)</td><td>398 days in the future ($FUTURE)</td></tr>"
		fi
460
	fi
461
	if [ "$1" != "FreeBSD" ] ; then
462
		if [ "$1" = "debian" ] ; then
463
			write_page "<tr><td>hour, minute</td><td>hour and minute will probably vary between two builds...</td><td>on amd64 only: additionally the \"future builds\" also run 6h and 23min ahead</td></tr>"
464
		        write_page "<tr><td>filesystem</td><td>tmpfs</td><td><em>temporarily not</em> varied using <a href=\"https://tracker.debian.org/disorderfs\">disorderfs</a> (<a href=\"https://sources.debian.net/src/disorderfs/sid/disorderfs.1.txt/\">manpage</a>)</td></tr>"
465
		else
466
			write_page "<tr><td>hour, minute</td><td>hour and minute will probably vary between two builds...</td><td>but this is not enforced systematically... (currently, work in progress)</td></tr>"
467
468
			write_page "<tr><td>Filesystem</td><td>tmpfs</td><td>same for both builds (currently, this could be varied using <a href=\"https://tracker.debian.org/disorderfs\">disorderfs</a>)</td></tr>"
		fi
469
	else
470
		write_page "<tr><td>year, month, date</td><td>today ($DATE)</td><td>the 2nd build is done with the build node set 1 year, 1 month and 1 day in the future</td></tr>"
471
		write_page "<tr><td>hour, minute</td><td>hour and minute will vary between two builds</td><td>additionally the \"future build\" also runs 6h and 23min ahead</td></tr>"
472
		write_page "<tr><td>filesystem of the build directory</td><td>ufs</td><td>same for both builds</td></tr>"
473
	fi
474
475
476
477
478
479
480
481
	if [ "$1" = "debian" ] ; then
		write_page "<tr><td><em>everything else...</em></td><td colspan=\"2\">is likely the same. So far, this is just about the <em>prospects</em> of <a href=\"https://wiki.debian.org/ReproducibleBuilds\">reproducible builds of Debian</a> - there will be more variations in the wild.</td></tr>"
	else
		write_page "<tr><td><em>everything else...</em></td><td colspan=\"2\">is likely the same. There will be more variations in the wild.</td></tr>"
	fi
	write_page "</table></p>"
}

482
publish_page() {
483
484
485
486
	if [ "$1" = "" ] ; then
		TARGET=$PAGE
	else
		TARGET=$1/$PAGE
487
	fi
488
	cp $PAGE $BASE/$TARGET
489
	rm $PAGE
490
	echo "Enjoy $REPRODUCIBLE_URL/$TARGET"
491
492
493
}

link_packages() {
494
	set +x
495
        local i
496
497
498
	for (( i=1; i<$#+1; i=i+400 )) ; do
		local string='['
		local delimiter=''
499
		local j
500
501
502
		for (( j=0; j<400; j++)) ; do
			local item=$(( $j+$i ))
			if (( $item < $#+1 )) ; then
503
504
				string+="${delimiter}\"${!item}\""
				delimiter=','
505
506
			fi
		done
507
		string+=']'
Holger Levsen's avatar
Holger Levsen committed
508
509
		cd /srv/jenkins/bin
		DATA=" $(python3 -c "from reproducible_common import link_packages; \
510
				print(link_packages(${string}, '$SUITE', '$ARCH'))" 2> /dev/null)"
Holger Levsen's avatar
Holger Levsen committed
511
512
		cd - > /dev/null
		write_page "$DATA"
513
	done
514
	if "$DEBUG" ; then set -x ; fi
515
516
}

517
gen_package_html() {
518
	cd /srv/jenkins/bin
519
520
521
522
	python3 -c "import reproducible_html_packages as rep
pkg = rep.Package('$1', no_notes=True)
rep.gen_packages_html([pkg], no_clean=True)" || echo "Warning: cannot update html pages for $1"
	cd - > /dev/null
523
524
}

525
526
527
528
529
530
calculate_build_duration() {
	END=$(date +'%s')
	DURATION=$(( $END - $START ))
}

print_out_duration() {
531
532
533
	if [ -z "$DURATION" ]; then
		return
	fi
534
535
536
	local HOUR=$(echo "$DURATION/3600"|bc)
	local MIN=$(echo "($DURATION-$HOUR*3600)/60"|bc)
	local SEC=$(echo "$DURATION-$HOUR*3600-$MIN*60"|bc)
Holger Levsen's avatar
Holger Levsen committed
537
	echo "$(date -u) - total duration: ${HOUR}h ${MIN}m ${SEC}s." | tee -a ${RBUILDLOG}
538
539
}

540
541
542
543
544
irc_message() {
	local MESSAGE="$@"
	kgb-client --conf /srv/jenkins/kgb/debian-reproducible.conf --relay-msg "$MESSAGE" || true # don't fail the whole job
}

545
call_diffoscope() {
546
547
548
549
	mkdir -p $TMPDIR/$1/$(dirname $2)
	local TMPLOG=(mktemp --tmpdir=$TMPDIR)
	local msg=""
	set +e
550
	# remember to also modify the retry diffoscope call 15 lines below
551
	( timeout $TIMEOUT nice schroot \
552
		--directory $TMPDIR \
553
554
		-c source:jenkins-reproducible-${DBDSUITE}-diffoscope \
		diffoscope -- \
555
556
557
558
559
			--html $TMPDIR/$1/$2.html \
			$TMPDIR/b1/$1/$2 \
			$TMPDIR/b2/$1/$2 2>&1 \
	) 2>&1 >> $TMPLOG
	RESULT=$?
Holger Levsen's avatar
Holger Levsen committed
560
	LOG_RESULT=$(grep '^E: 15binfmt: update-binfmts: unable to open' $TMPLOG || true)
Holger Levsen's avatar
Holger Levsen committed
561
	if [ ! -z "$LOG_RESULT" ] ; then
562
		rm -f $TMPLOG $TMPDIR/$1/$2.html
Holger Levsen's avatar
Holger Levsen committed
563
		echo "$(date -u) - schroot jenkins-reproducible-${DBDSUITE}-diffoscope not available, will sleep 2min and retry."
564
565
		sleep 2m
		# remember to also modify the retry diffoscope call 15 lines above
566
		( timeout $TIMEOUT nice schroot \
567
568
569
570
571
572
573
574
575
			--directory $TMPDIR \
			-c source:jenkins-reproducible-${DBDSUITE}-diffoscope \
			diffoscope -- \
				--html $TMPDIR/$1/$2.html \
				$TMPDIR/b1/$1/$2 \
				$TMPDIR/b2/$1/$2 2>&1 \
			) 2>&1 >> $TMPLOG
		RESULT=$?
	fi
576
577
578
579
580
581
582
583
	if ! "$DEBUG" ; then set +x ; fi
	set -e
	cat $TMPLOG # print dbd output
	rm -f $TMPLOG
	case $RESULT in
		0)	echo "$(date -u) - $1/$2 is reproducible, yay!"
			;;
		1)
584
			echo "$(date -u) - $DIFFOSCOPE found issues, please investigate $1/$2"
585
586
			;;
		2)
587
			msg="$(date -u) - $DIFFOSCOPE had trouble comparing the two builds. Please investigate $1/$2"
588
589
590
			;;
		124)
			if [ ! -s $TMPDIR/$1.html ] ; then
591
				msg="$(date -u) - $DIFFOSCOPE produced no output for $1/$2 and was killed after running into timeout after ${TIMEOUT}..."
592
			else
593
				msg="$DIFFOSCOPE was killed after running into timeout after $TIMEOUT, but there is still $TMPDIR/$1/$2.html"
594
595
596
			fi
			;;
		*)
597
			msg="$(date -u) - Something weird happened when running $DIFFOSCOPE on $1/$2 (which exited with $RESULT) and I don't know how to handle it."
598
599
600
601
602
603
			;;
	esac
	if [ ! -z "$msg" ] ; then
		echo $msg | tee -a $TMPDIR/$1/$2.html
	fi
}
604
605
606

get_filesize() {
		local BYTESIZE="$(du -h -b $1 | cut -f1)"
607
608
		# numbers below 16384K are understood and more meaningful than 16M...
		if [ $BYTESIZE -gt 16777216 ] ; then
609
610
611
612
			SIZE="$(echo $BYTESIZE/1048576|bc)M"
		elif [ $BYTESIZE -gt 1024 ] ; then
			SIZE="$(echo $BYTESIZE/1024|bc)K"
		else
613
			SIZE="$BYTESIZE bytes"
614
615
		fi
}
616

617
cleanup_pkg_files() {
618
619
	rm -vf $BASE/rbuild/${SUITE}/${ARCH}/${SRCPACKAGE}_*.rbuild.log{,.gz}
	rm -vf $BASE/logs/${SUITE}/${ARCH}/${SRCPACKAGE}_*.build?.log{,.gz}
620
621
	rm -vf $BASE/dbd/${SUITE}/${ARCH}/${SRCPACKAGE}_*.diffoscope.html
	rm -vf $BASE/dbdtxt/${SUITE}/${ARCH}/${SRCPACKAGE}_*.diffoscope.txt{,.gz}
622
623
624
625
	rm -vf $BASE/buildinfo/${SUITE}/${ARCH}/${SRCPACKAGE}_*.buildinfo
	rm -vf $BASE/logdiffs/${SUITE}/${ARCH}/${SRCPACKAGE}_*.diff{,.gz}
}

626
627
628
629
630
631
632
633
634
635
636
#
# create the png (and query the db to populate a csv file...)
#
create_png_from_table() {
	echo "Checking whether to update $2..."
	# $1 = id of the stats table
	# $2 = image file name
	# $3 = meta package set, only sensible if $1=6
	echo "${FIELDS[$1]}" > ${TABLE[$1]}.csv
	# prepare query
	WHERE_EXTRA="WHERE suite = '$SUITE'"
637
638
639
640
641
642
	if [ "$ARCH" = "armhf" ] ; then
		# armhf was only build since 2015-08-30
		WHERE2_EXTRA="WHERE s.datum >= '2015-08-30'"
	else
		WHERE2_EXTRA=""
	fi
643
644
	if [ $1 -eq 3 ] || [ $1 -eq 4 ] || [ $1 -eq 5 ] || [ $1 -eq 8 ] ; then
		# TABLE[3+4+5] don't have a suite column: (and TABLE[8] (and 9) is faked, based on 3)
645
646
		WHERE_EXTRA=""
	fi
647
648
	if [ $1 -eq 0 ] || [ $1 -eq 2 ] || [ $1 -eq 6 ] ; then
		# TABLE[0+2+6] have a architecture column:
Holger Levsen's avatar
Holger Levsen committed
649
		WHERE_EXTRA="$WHERE_EXTRA AND architecture = \"$ARCH\""
650
651
		if [ "$ARCH" = "armhf" ]  ; then
			if [ $1 -eq 2 ] ; then
652
				# unstable/armhf was only build since 2015-08-30 (and experimental/armhf since 2015-12-19 and testing/armhf since 2016-01-01)
653
654
				WHERE_EXTRA="$WHERE_EXTRA AND datum >= '2015-08-30'"
			elif [ $1 -eq 6 ] ; then
655
				# armhf only has pkg sets for unstable since 2015-12-22 and since 2016-02-13 for testing
656
				WHERE_EXTRA="$WHERE_EXTRA AND datum >= '2015-12-22'"
657
			fi
658
		fi
659
660
661
662
		# testing/amd64 was only build since...
		# WHERE2_EXTRA="WHERE s.datum >= '2015-03-08'"
		# experimental/amd64 was only build since...
		# WHERE2_EXTRA="WHERE s.datum >= '2015-02-28'"
Holger Levsen's avatar
Holger Levsen committed
663
	fi
664
665
666
667
	if [ $1 -eq 6 ] ; then
		# 6 is very special too...
		WHERE_EXTRA="$WHERE_EXTRA and meta_pkg = '$3'"
	fi
668
669
670
	# run query
	if [ $1 -eq 1 ] ; then
		# not sure if it's worth to generate the following query...
671
		WHERE_EXTRA="AND architecture='$ARCH'"
672
		sqlite3 -init ${INIT} --nullvalue 0 -csv ${PACKAGES_DB} "SELECT s.datum,
673
674
675
			 COALESCE((SELECT e.reproducible FROM stats_builds_per_day AS e WHERE s.datum=e.datum AND suite='testing' $WHERE_EXTRA),0) AS reproducible_testing,
			 COALESCE((SELECT e.reproducible FROM stats_builds_per_day AS e WHERE s.datum=e.datum AND suite='unstable' $WHERE_EXTRA),0) AS reproducible_unstable,
			 COALESCE((SELECT e.reproducible FROM stats_builds_per_day AS e WHERE s.datum=e.datum AND suite='experimental' $WHERE_EXTRA),0) AS reproducible_experimental,
676
677
678
679
680
681
682
683
684
			 (SELECT e.unreproducible FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='testing' $WHERE_EXTRA) AS unreproducible_testing,
			 (SELECT e.unreproducible FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='unstable' $WHERE_EXTRA) AS unreproducible_unstable,
			 (SELECT e.unreproducible FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='experimental' $WHERE_EXTRA) AS unreproducible_experimental,
			 (SELECT e.FTBFS FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='testing' $WHERE_EXTRA) AS FTBFS_testing,
			 (SELECT e.FTBFS FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='unstable' $WHERE_EXTRA) AS FTBFS_unstable,
			 (SELECT e.FTBFS FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='experimental' $WHERE_EXTRA) AS FTBFS_experimental,
			 (SELECT e.other FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='testing' $WHERE_EXTRA) AS other_testing,
			 (SELECT e.other FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='unstable' $WHERE_EXTRA) AS other_unstable,
			 (SELECT e.other FROM stats_builds_per_day e WHERE s.datum=e.datum AND suite='experimental' $WHERE_EXTRA) AS other_experimental
685
			 FROM stats_builds_per_day AS s $WHERE2_EXTRA GROUP BY s.datum" >> ${TABLE[$1]}.csv
686
687
688
689
690
	elif [ $1 -eq 2 ] ; then
		# just make a graph of the oldest reproducible build (ignore FTBFS and unreproducible)
		sqlite3 -init ${INIT} -csv ${PACKAGES_DB} "SELECT datum, oldest_reproducible FROM ${TABLE[$1]} ${WHERE_EXTRA} ORDER BY datum" >> ${TABLE[$1]}.csv
	elif [ $1 -eq 7 ] ; then
		sqlite3 -init ${INIT} -csv ${PACKAGES_DB} "SELECT datum, $SUM_DONE, $SUM_OPEN from ${TABLE[3]} ORDER BY datum" >> ${TABLE[$1]}.csv
691
692
693
694
	elif [ $1 -eq 8 ] ; then
		sqlite3 -init ${INIT} -csv ${PACKAGES_DB} "SELECT ${FIELDS[$1]} from ${TABLE[3]} ${WHERE_EXTRA} ORDER BY datum" >> ${TABLE[$1]}.csv
	elif [ $1 -eq 9 ] ; then
		sqlite3 -init ${INIT} -csv ${PACKAGES_DB} "SELECT datum, $REPRODUCIBLE_DONE, $REPRODUCIBLE_OPEN from ${TABLE[3]} ORDER BY datum" >> ${TABLE[$1]}.csv
695
696
697
698
699
700
701
702
703
704
705
706
707
	else
		sqlite3 -init ${INIT} -csv ${PACKAGES_DB} "SELECT ${FIELDS[$1]} from ${TABLE[$1]} ${WHERE_EXTRA} ORDER BY datum" >> ${TABLE[$1]}.csv
	fi
	# this is a gross hack: normally we take the number of colors a table should have...
	#  for the builds_age table we only want one color, but different ones, so this hack:
	COLORS=${COLOR[$1]}
	if [ $1 -eq 2 ] ; then
		case "$SUITE" in
			testing)	COLORS=40 ;;
			unstable)	COLORS=41 ;;
			experimental)	COLORS=42 ;;
		esac
	fi
708
709
	local WIDTH=1920
	local HEIGHT=960
710
711
712
713
714
715
	# only generate graph if the query returned data
	if [ $(cat ${TABLE[$1]}.csv | wc -l) -gt 1 ] ; then
		echo "Updating $2..."
		DIR=$(dirname $2)
		mkdir -p $DIR
		echo "Generating $2."
716
		/srv/jenkins/bin/make_graph.py ${TABLE[$1]}.csv $2 ${COLORS} "${MAINLABEL[$1]}" "${YLABEL[$1]}" $WIDTH $HEIGHT
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
		mv $2 $BASE/$DIR
		[ "$DIR" = "." ] || rmdir $(dirname $2)
	# create empty dummy png if there havent been any results ever
	elif [ ! -f $BASE/$DIR/$(basename $2) ] ; then
		DIR=$(dirname $2)
		mkdir -p $DIR
		echo "Creating $2 dummy."
		convert -size 1920x960 xc:#aaaaaa -depth 8 $2
		if [ "$3" != "" ] ; then
			local THUMB="${TABLE[1]}_${3}-thumbnail.png"
			convert $2 -adaptive-resize 160x80 ${THUMB}
			mv ${THUMB} $BASE/$DIR
		fi
		mv $2 $BASE/$DIR
		[ "$DIR" = "." ] || rmdir $(dirname $2)
	fi
	rm ${TABLE[$1]}.csv
}