-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathbuild.sh
executable file
·309 lines (257 loc) · 8.82 KB
/
build.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#! /bin/bash
# Minimalist version of ngfw_pkgtools.git/make-build.sh so TravisCI
# and Jenkins can build packages.
#
# This is meant to be run in a disposable container.
## constants
PKGTOOLS=$(dirname $(readlink -f $0))
PKGTOOLS_VERSION=$(pushd $PKGTOOLS > /dev/null ; git describe --tags --always --long --dirty ; popd > /dev/null)
VERSION_FILE=debian/version
## env
export CCACHE_DISABLE=true
export CCACHE_DIR=/tmp
# arch default to the build arch
BUILD_ARCHITECTURE=$(dpkg-architecture -qDEB_BUILD_ARCH)
ARCHITECTURE=${ARCHITECTURE:-${BUILD_ARCHITECTURE}}
# the following variable re-assignments are no-ops, and are here just
# for documentation
REPOSITORY=${REPOSITORY}
DISTRIBUTION=${DISTRIBUTION}
TRAVIS_BRANCH=${TRAVIS_BRANCH}
TRAVIS_PULL_REQUEST_BRANCH=${TRAVIS_PULL_REQUEST_BRANCH}
TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG}
PACKAGE=${PACKAGE} # empty default means "all"
VERBOSE=${VERBOSE} # empty means "not verbose"
UPLOAD=${UPLOAD} # empty default means "no upload"
FORCE=${FORCE} # emtpy means "do not force build"
DEBUG=${DEBUG} # emtpy means "no debugging"
SSH_KEY=${SSH_KEY} # empty means "no key"
NO_CLEAN=${NO_CLEAN} # empty default means "perform cleaning post build"
if [[ -n "$DEBUG" ]] ; then
set -x
VERBOSE=1 # also force VERBOSE
fi
# use http_proxy if defined for apt
export http_proxy=$(perl -pe 's/.*"(.*?)".*/$1/' 2> /dev/null < /etc/apt/apt.conf.d/01proxy)
## functions
log() {
echo "=== " $@
}
is-official-branch() {
echo $1 | grep -qP '^(main|master|((ngfw|waf)-)?release-[\d.]+)$'
}
wait-for-pid() {
pid=$1
delay=1
delay_msg=30
i=0
while ps hp $pid > /dev/null ; do
let i=i+1
if [[ $(( $i % $delay_msg )) = 0 ]] ; then
echo "... still waiting for PID ${pid} every ${delay}s, next message in ${delay_msg}s"
fi
sleep $delay
done
}
install-build-deps() {
pkg=$1
profiles=$2
if [[ "$pkg" =~ "/d-i" ]] && [[ $ARCHITECTURE != $BUILD_ARCHITECTURE ]] ; then
# when cross-building d-i, build-dep chokes trying to install the
# following packages
apt install -y apt-utils bf-utf-source mklibs win32-loader
elif [[ -n "$profiles" ]] ; then
apt -o Dpkg::Options::="--force-overwrite" build-dep -y --build-profiles $profiles --host-architecture $ARCHITECTURE .
else
apt -o Dpkg::Options::="--force-overwrite" build-dep -y --host-architecture $ARCHITECTURE .
fi
}
do-build() {
pkg=$1
shift
dpkg_buildpackage_options="$@"
source_name=$(dpkg-parsechangelog -S source)
# bring resources/ from pkgtools into the source directory we cd'ed
# in
cp -r ${PKGTOOLS}/resources ./
# bump version, except for kernels where it's manually managed
if ! [[ "$pkg" =~ "/linux-" ]] ; then
bash ${PKGTOOLS}/set-version.sh $TARGET_DISTRIBUTION $REPOSITORY
fi
# store this version
version=$(dpkg-parsechangelog -S Version)
echo $version >| $VERSION_FILE
# collect existing versions
is_present=0
if [[ -z "$FORCE" ]] ; then
is_present=1
for binary_pkg in $(DEB_HOST_ARCH="$ARCHITECTURE" dh_listpackages $pkg) ; do
output=$(apt-show-versions -p '^'${binary_pkg}'$' -a -R)
if ! echo "$output" | grep -qP ":(all|${ARCHITECTURE}) ${version//+/.}" ; then
is_present=0
break
fi
done
fi
# ... and build only if needed
if [[ $is_present == 1 ]] ; then
reason="ALREADY-PRESENT"
else # build it
reason="SUCCESS"
# for kernels, we already have a source tarball; for other
# packages, create an ad-hoc one
if ! [[ "$pkg" =~ "/linux-" ]] ; then
quilt pop -a 2> /dev/null || true
tar ca --exclude="*stamp*.txt" \
--exclude="*-stamp" \
--exclude="./debian" \
--exclude="todo" \
--exclude="staging" \
--exclude=".git" \
-f ../${source_name}_$(echo $version | perl -pe 's/(^\d+:|-.*)//').orig.tar.xz ../$(basename $pkg)
fi
# set profiles, if any
if [[ $ARCHITECTURE != $BUILD_ARCHITECTURE ]] ; then
build_profiles="cross"
fi
if [[ -f debian/untangle-build-profiles ]] ; then
build_profiles="${build_profiles},$(cat debian/untangle-build-profiles)"
fi
if [[ -n "$build_profiles" ]] ; then
dpkg_buildpackage_options="$dpkg_buildpackage_options --build-profiles=$build_profiles"
fi
# install build dependencies, and build package
install-build-deps $pkg "$build_profiles" \
&& dpkg-buildpackage --host-arch $ARCHITECTURE -i.* $dpkg_buildpackage_options --no-sign \
|| reason=FAILURE
# upload: never for d-i, and only if successful and UPLOAD specified
if [[ "$pkg" != "d-i" && $reason != "FAILURE" && -n "$UPLOAD" && "$UPLOAD" != 0 ]] ; then
changes_file=../${source_name}_$(perl -pe 's/^.+://' ${VERSION_FILE})*.changes
if [[ "$UPLOAD" =~ "local" ]] ; then
dput_profile=${UPLOAD}
else
dput_profile=${DPUT_BASE_PROFILE}_${REPOSITORY}_${UPLOAD}
fi
if [[ -n "$dput_profile" ]] ; then
apt install -y dput
dput -c ${PKGTOOLS}/dput.cf $dput_profile $changes_file || reason="FAILURE"
fi
fi
fi
# clean
if [[ "$UPLOAD" != "local" ]] ; then
find .. -maxdepth 1 -name "*$(perl -pe 's/(^.+:|-.*)//' ${VERSION_FILE})*" -regextype posix-extended -regex ".*[._](upload|changes|udeb|deb|upload|dsc|build|buildinfo|diff.gz|debian.tar\..z|orig\.tar\..z|${ARCHITECTURE}\.tar\..z)" -delete
fi
if [[ "$NO_CLEAN" != 1 ]] ; then
git checkout -- debian/changelog 2>&1 || true
rm -f $VERSION_FILE
fakeroot debian/rules clean
quilt pop -a 2> /dev/null || true
find . -type f -regex '\(.*-modules?-3.\(2\|16\).0-4.*\.deb\|core\)' -exec rm -f "{}" \;
fi
rm -fr resources
# so it can be extracted by the calling shell when do-build is piped
# into tee in VERBOSE mode
echo $reason $version
}
## main
echo "pkgtools version ${PKGTOOLS_VERSION}"
# only allow Travis to upload packages if it's building from official
# branches, or from PRs targetting those
if ! is-official-branch $TRAVIS_BRANCH ; then
UPLOAD=
fi
# set base distribution if none was passed
if [[ -z "$DISTRIBUTION" ]] ; then
DISTRIBUTION=$(cat $PKGTOOLS/resources/DISTRIBUTION)
fi
# set target distribution for PRs
if [[ -n "$TRAVIS_PULL_REQUEST_BRANCH" ]] ; then
DPUT_BASE_PROFILE=package-server-dev
# replace _ (not allowed in a distribution name) with .
REPO_NAME=$(basename $TRAVIS_REPO_SLUG | perl -pe 's/_/./g')
TARGET_DISTRIBUTION="${REPO_NAME}.$TRAVIS_PULL_REQUEST_BRANCH"
else
DPUT_BASE_PROFILE=package-server
TARGET_DISTRIBUTION=$DISTRIBUTION
fi
# add mirrors for base and target distributions
echo "deb http://package-server/public/$REPOSITORY $DISTRIBUTION main non-free" > /etc/apt/sources.list.d/${DISTRIBUTION}.list
if [[ $DISTRIBUTION != $TARGET_DISTRIBUTION ]] ; then
echo "deb http://package-server/dev/$REPOSITORY $TARGET_DISTRIBUTION main non-free" > /etc/apt/sources.list.d/${TARGET_DISTRIBUTION}.list
fi
apt-get update -q
# ssh
mkdir -p ~/.ssh
if [[ -n "$SSH_KEY" ]] ; then
eval $(ssh-agent)
ssh-add $SSH_KEY
cat >> ~/.ssh/config <<EOF
Host *
IdentityFile ${SSH_KEY}
StrictHostKeyChecking no
EOF
else # ssh-agent is handled by the caller
cat >> ~/.ssh/config <<EOF
Host *
StrictHostKeyChecking no
EOF
fi
if [[ $1 = "-s" ]] || [[ "$1" == "setup-only" ]] ; then
# we're not interested in building packages
exit 0
fi
# update apt-show-versions cache
apt-show-versions -i
# main return code
rc=0
# iterate over packages to build
for pkg in $(awk -v repo=$REPOSITORY '$2 ~ repo && ! /^(#|$)/ {print $1}' build-order.txt) ; do
log "BEGIN $pkg"
if [[ -n "$PACKAGE" ]] && ! [[ $pkg = $PACKAGE ]] ; then
log "NO-PKG-MATCH $pkg"
continue
fi
# the kernel source tree needs to be prepared
if [[ "$pkg" =~ "/linux-" ]] ; then
pushd $(dirname "$pkg") > /dev/null
make patch control-real
popd > /dev/null
fi
# to build or not to build, depending on target architecture and
# package specs
arches_to_build="${ARCHITECTURE}|any" # always build arch-dep
if [[ $ARCHITECTURE == "amd64" ]] ; then
# also build arch-indep packages
arches_to_build="${arches_to_build}|all"
# build source *and* binary packages
DPKG_BUILDPACKAGE_OPTIONS="-sa"
else
# only build binary packages
DPKG_BUILDPACKAGE_OPTIONS="-B"
fi
if ! grep -qE "^Architecture:.*(${arches_to_build})" ${pkg}/debian/control ; then
log "NO-ARCHITECTURE-MATCH $pkg"
continue
fi
pushd $pkg > /dev/null
logfile=/tmp/${REPOSITORY}-${DISTRIBUTION}-${pkg//\//_}.log
if [[ -n "$VERBOSE" && "$VERBOSE" != 0 ]] ; then
do-build $pkg $DPKG_BUILDPACKAGE_OPTIONS 2>&1 | tee $logfile
else
do-build $pkg $DPKG_BUILDPACKAGE_OPTIONS > $logfile 2>&1 &
wait-for-pid $!
fi
# always extract reason & version from logfile
set $(tail -n 1 $logfile)
reason=$1
version=$2
if [[ $reason == "FAILURE" ]] ; then
let rc=rc+1 # global failure count
[[ -n "$VERBOSE" && "$VERBOSE" != 0 ]] || cat $logfile
fi
rm -f $logfile
log "$reason $pkg $version"
popd > /dev/null
done
exit $rc