reproducible_debstrap.sh 4.96 KB
Newer Older
1
2
3
4
5
6
#!/bin/bash
# vim: set noexpandtab:

# Copyright 2021-2022 Holger Levsen <holger@layer-acht.org>
# released under the GPLv2

7
DEBUG=false
8
9
10
11
12
13
14
15
16
17
18
. /srv/jenkins/bin/common-functions.sh
common_init "$@"

# common code for tests.reproducible-builds.org
. /srv/jenkins/bin/reproducible_common.sh
set -e
set -o pipefail # see eg http://petereisentraut.blogspot.com/2010/11/pipefail.html

cleanup() {
	local RESULT=$1
	output_echo "Cleanup ${RESULT}"
19
	# Cleanup the workspace and results directory
20
21
22
23
24
25
26
27
	if [ ! -z "$BUILDDIR" ]; then
		output_echo "Removing ${BUILDDIR}"
		sudo rm -rf --one-file-system ${BUILDDIR}
	fi
	if [ ! -z "$RESULTSDIR" ]; then
		output_echo "Removing ${RESULTSDIR}"
		rm -rf --one-file-system ${RESULTSDIR}
	fi
28
29
}

30
cleanup_unreproducible_file(){
31
32
	local TYPE=$1
	local FILE=$2
33
34
	if sudo file -E $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}/$FILE >/dev/null 2>&1 ; then
		output_echo "Warning: modifying $TOOL result, deleting unreproducible $TYPE $FILE"
35
36
		sudo rm -rf --one-file-system $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}/$FILE
	else
37
		sudo file $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}/$FILE
38
39
40
		output_echo "Warning: shall remove $FILE but it does not exist. Maybe $TOOL was improved."
	fi
}
41
42

# Init some variables
43
44
export TOOL="$1"
export SUITE="$2"
45
output_echo "About to bootstrap $SUITE using $TOOL version $(dpkg-query  --showformat='${Version}' --show $TOOL)."
46
47
48
49
50
51
52

if [ "$SUITE" != "unstable" ] ; then
	CODENAME=$SUITE
else
	CODENAME=sid
fi

53
54
55
56
mkdir -p /srv/workspace/tempdir/
BUILDDIR=$(mktemp --tmpdir=/srv/workspace/tempdir/ -d -t "debstrap_${TOOL}-${SUITE}.XXXXXXXX")
RESULTSDIR=$(mktemp --tmpdir=/srv/reproducible-results -d -t "${TOOL}-${SUITE}.XXXXXXXX") # accessible in schroots, used to compare results
export BUILDDIR RESULTSDIR
57
58
59
60
61
62
63

# Cleanup if something goes wrong
trap cleanup INT TERM EXIT

# Randomize start time
delay_start

64
65
66
67
68
# SOURCE_DATE_EPOCH needs to be set to allow clamping file timestamps newer than this.
S_D_E_DATE="$(grep $CODENAME /usr/share/distro-info/debian.csv | awk  -F',' '{print $4}')"
export SOURCE_DATE_EPOCH="$(date +%s -d $S_D_E_DATE)"
output_echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH that is $S_D_E_DATE which is when $SUITE was created."

69
# Actual run ${TOOL} twice
70
71
72
73
74
for LOOP in "first" "second" ; do
	case $LOOP in
		first)	SUBDIR=b1
			ACTION="Verbosely running"
			REALTOOL=$TOOL
75
			;;
76
77
78
79
80
		second)	SUBDIR=b2
			ACTION="Running"
			case $TOOL in
				mmdebstrap)	REALTOOL="mmdebstrap -v" ;;
				debootstrap)	REALTOOL="debootstrap --verbose" ;;
81
				cdebootstrap)	REALTOOL="cdebootstrap --verbose" ;;
82
			esac
83
			;;
84
85
	esac
	output_echo "$ACTION ${TOOL} $SUITE for the $LOOP run."
86
	mkdir -p $BUILDDIR/$SUBDIR/${TOOL}
87
88
	case ${TOOL} in
		mmdebstrap)	sudo $REALTOOL $SUITE > $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}.tar
89
				# josch> | h01ger: should you ever try --variant=standard, remember that that is not reproducible in stable because of #864082, #1004557, #1004558
90
				;;
91
92
		debootstrap|cdebootstrap)
				sudo $REALTOOL $SUITE $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}
93
				# work around unreproducible artifacts
94
				BAD_FILES="/etc/machine-id /var/cache/ldconfig/aux-cache"
95
				case ${TOOL} in
96
					debootstrap)	BAD_LOGFILES="/var/log/dpkg.log /var/log/alternatives.log /var/log/bootstrap.log"
97
							;;
98
					cdebootstrap)	BAD_LOGFILES="/var/log/dpkg.log /var/log/alternatives.log /var/log/bootstrap.log /var/log/apt/history.log /var/log/apt/term.log"
99
100
							;;
				esac
101
102
				for i in $BAD_LOGFILES ; do
					cleanup_unreproducible_file logfile "$i"
103
				done
104
105
				for i in $BAD_FILES ; do
					cleanup_unreproducible_file file "$i"
106
				done
107
				sudo tar --mtime="@$SOURCE_DATE_EPOCH" --clamp-mtime -C $BUILDDIR/$SUBDIR/${TOOL}/ -cf $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}.tar ${SUITE}
108
109
				sudo rm -rf --one-file-system $BUILDDIR/$SUBDIR/${TOOL}/${SUITE}
				;;
110
		*)		output_echo "Failure: ${TOOL} is unsupported."
111
112
113
				exit 1
				;;
	esac
114
	mv $BUILDDIR/$SUBDIR $RESULTSDIR/ 1>/dev/null
115
done
116

117
output_echo "Done running ${TOOL} twice."
118

119
# show sha256sum results
120
sha256sum $RESULTSDIR/b1/${TOOL}/${SUITE}.tar $RESULTSDIR/b2/${TOOL}/${SUITE}.tar
121

122
# show human readable results
123
124
if diff $RESULTSDIR/b1/${TOOL}/${SUITE}.tar $RESULTSDIR/b2/${TOOL}/${SUITE}.tar ; then
	output_echo "Success: ${TOOL} of $SUITE is reproducible today."
125
else
126
	output_echo "Warning: ${TOOL} of $SUITE is not reproducible."
127
128
129
130
131
	# Run diffoscope on the images
	output_echo "Calling diffoscope on the results."
	TIMEOUT="240m"
	DIFFOSCOPE="$(schroot --directory /tmp -c chroot:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --version 2>&1)"
	TMPDIR=${RESULTSDIR}
132
133
	#call_diffoscope ${TOOL} ${SUITE}.tar
	# the previous, temporarily disabled line is only useful if we also make the .html file visible...
134
	schroot --directory /tmp -c chroot:jenkins-reproducible-${DBDSUITE}-diffoscope diffoscope -- --restructured-text $RESULTSDIR/${TOOL}_${SUITE}.txt $RESULTSDIR/b1/${TOOL}/${SUITE}.tar $RESULTSDIR/b2/${TOOL}/${SUITE}.tar || true # diffoscope will exi with error...
135
	cat $RESULTSDIR/${TOOL}_${SUITE}.txt
136
fi
137
138
139
140
141
142
143

cleanup success
# Turn off the trap
trap - INT TERM EXIT

# We reached the end, return with PASS
exit 0