2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
6 read -rd "\000" helpmessage <<EOF
7 $(basename $0): Orchestrate run-build-packages.sh for one target
10 WORKSPACE=/path/to/arvados $(basename $0) [options]
13 Distribution to build packages for (default: debian10)
15 Build command to execute (default: use built-in Docker image command)
17 Run package install test script "test-packages-[target].sh"
19 Output debug information (default: false)
20 --only-build <package>
21 Build only a specific package
23 Test only a specific package
25 Build a specific architecture (amd64 or arm64, defaults to native architecture)
27 Build even if the package exists upstream or if it has already been
30 Test even if there is no new untested package
31 --build-version <string>
32 Version to build (default:
33 \$ARVADOS_BUILDING_VERSION-\$ARVADOS_BUILDING_ITERATION or
34 0.1.timestamp.commithash)
36 Don't try to build Docker images
38 WORKSPACE=path Path to the Arvados source tree to build packages from
44 if ! [[ -n "$WORKSPACE" ]]; then
45 echo >&2 "$helpmessage"
47 echo >&2 "Error: WORKSPACE environment variable not set"
52 if ! [[ -d "$WORKSPACE" ]]; then
53 echo >&2 "$helpmessage"
55 echo >&2 "Error: $WORKSPACE is not a directory"
60 PARSEDOPTS=$(getopt --name "$0" --longoptions \
61 help,debug,test-packages,target:,command:,only-test:,force-test,only-build:,force-build,arch:,build-version:,skip-docker-build \
72 eval set -- "$PARSEDOPTS"
73 while [ $# -gt 0 ]; do
76 echo >&2 "$helpmessage"
95 ONLY_BUILD="$2"; shift
111 if [[ -z "$2" ]]; then
113 elif ! [[ "$2" =~ (.*)-(.*) ]]; then
114 echo >&2 "FATAL: --build-version '$2' does not include an iteration. Try '${2}-1'?"
116 elif ! [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+|)(~rc[0-9]+|~dev[0-9]+|)-[0-9]+$ ]]; then
117 echo >&2 "FATAL: --build-version '$2' is invalid, must match pattern ^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+|)(~rc[0-9]+|~dev[0-9]+|)-[0-9]+$"
120 [[ "$2" =~ (.*)-(.*) ]]
121 ARVADOS_BUILDING_VERSION="${BASH_REMATCH[1]}"
122 ARVADOS_BUILDING_ITERATION="${BASH_REMATCH[2]}"
130 if [ $# -gt 1 ]; then
131 echo >&2 "$0: unrecognized argument '$2'. Try: $0 --help"
141 if [[ -n "$ARVADOS_BUILDING_VERSION" ]]; then
142 echo "build version='$ARVADOS_BUILDING_VERSION', package iteration='$ARVADOS_BUILDING_ITERATION'"
145 if [[ -n "$test_packages" ]]; then
146 if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.rpm')" ]] ; then
147 CREATEREPO="$(command -v createrepo createrepo_c | tail -n1)"
148 if [[ -z "$CREATEREPO" ]]; then
150 echo >&2 "Error: please install createrepo. E.g. sudo apt install createrepo-c"
154 "$CREATEREPO" $WORKSPACE/packages/$TARGET
157 if [[ -n "$(find $WORKSPACE/packages/$TARGET -name '*.deb')" ]] ; then
159 /usr/bin/which dpkg-scanpackages >/dev/null
160 if [[ "$?" != "0" ]]; then
162 echo >&2 "Error: please install dpkg-dev. E.g. sudo apt-get install dpkg-dev"
166 /usr/bin/which apt-ftparchive >/dev/null
167 if [[ "$?" != "0" ]]; then
169 echo >&2 "Error: please install apt-utils. E.g. sudo apt-get install apt-utils"
174 (cd $WORKSPACE/packages/$TARGET
175 dpkg-scanpackages --multiversion . 2> >(grep -v 'warning' 1>&2) | tee Packages | gzip -c > Packages.gz
176 apt-ftparchive -o APT::FTPArchive::Release::Origin=Arvados release . > Release
180 COMMAND="/jenkins/package-testing/test-packages-$TARGET.sh"
181 IMAGE="arvados/package-test:$TARGET"
183 IMAGE="arvados/build:$TARGET"
184 if [[ "$COMMAND" != "" ]]; then
185 COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET$DEBUG"
189 JENKINS_DIR=$(dirname "$(readlink -e "$0")")
191 if [[ "$SKIP_DOCKER_BUILD" != 1 ]] ; then
192 if [[ -n "$test_packages" ]]; then
193 pushd "$JENKINS_DIR/package-test-dockerfiles"
194 make "$TARGET/generated"
196 pushd "$JENKINS_DIR/package-build-dockerfiles"
197 make "$TARGET/generated"
200 GOVERSION=$(grep 'const goversion =' $WORKSPACE/lib/install/deps.go |awk -F'"' '{print $2}')
204 time docker build --tag "$IMAGE" \
205 --build-arg HOSTTYPE=$HOSTTYPE \
206 --build-arg BRANCH=$(git rev-parse --abbrev-ref HEAD) \
207 --build-arg GOVERSION=$GOVERSION --no-cache .
211 if test -z "$packages" ; then
212 packages="arvados-api-server
215 arvados-dispatch-cloud
217 arvados-docker-cleaner
227 crunch-dispatch-local
228 crunch-dispatch-slurm
242 python3-arvados-python-client
243 python3-arvados-cwl-runner
244 python3-crunchstat-summary
245 python3-arvados-user-activity"
252 mkdir -p "$WORKSPACE/apps/workbench/vendor/cache-$TARGET"
253 mkdir -p "$WORKSPACE/services/api/vendor/cache-$TARGET"
256 -v "$JENKINS_DIR:/jenkins"
257 -v "$WORKSPACE:/arvados"
258 -v /arvados/services/api/vendor/bundle
259 -v /arvados/apps/workbench/vendor/bundle
260 -v "$WORKSPACE/services/api/vendor/cache-$TARGET:/arvados/services/api/vendor/cache"
261 -v "$WORKSPACE/apps/workbench/vendor/cache-$TARGET:/arvados/apps/workbench/vendor/cache"
264 if [[ -n "$test_packages" ]]; then
265 for p in $packages ; do
266 if [[ -n "$ONLY_BUILD" ]] && [[ "$p" != "$ONLY_BUILD" ]]; then
269 if [[ -e "${WORKSPACE}/packages/.last_test_${TARGET}" ]] && [[ -z "$FORCE_TEST" ]]; then
270 MATCH=`find ${WORKSPACE}/packages/ -newer ${WORKSPACE}/packages/.last_test_${TARGET} -regex .*${TARGET}/$p.*`
271 if [[ "$MATCH" == "" ]]; then
272 # No new package has been built that needs testing
273 echo "Skipping $p test because no new package was built since the last test."
277 # If we're testing all packages, we should not error out on packages that don't exist.
278 # If we are testing one specific package only (i.e. --only-test was given), we should
279 # error out if that package does not exist.
280 if [[ -z "$testing_one_package" ]]; then
281 MATCH=`find ${WORKSPACE}/packages/ -regextype posix-extended -regex .*${TARGET}/$p.*\\(deb\\|rpm\\)`
282 if [[ "$MATCH" == "" ]]; then
283 # No new package has been built that needs testing
284 echo "Skipping $p test because no package file is available to test."
289 echo "START: $p test on $IMAGE" >&2
292 "${docker_volume_args[@]}" \
293 --env ARVADOS_DEBUG=$ARVADOS_DEBUG \
294 --env "TARGET=$TARGET" \
295 --env "WORKSPACE=/arvados" \
298 echo "OK: $p test on $IMAGE succeeded" >&2
301 package_fails="$package_fails $p"
302 echo "ERROR: $p test on $IMAGE failed with exit status $FINAL_EXITCODE" >&2
306 if [[ "$FINAL_EXITCODE" == "0" ]]; then
307 touch ${WORKSPACE}/packages/.last_test_${TARGET}
311 echo "START: build packages on $IMAGE" >&2
312 # Move existing packages and other files into the processed/ subdirectory
313 if [[ ! -e "${WORKSPACE}/packages/${TARGET}/processed" ]]; then
314 mkdir -p "${WORKSPACE}/packages/${TARGET}/processed"
317 mv -f ${WORKSPACE}/packages/${TARGET}/* ${WORKSPACE}/packages/${TARGET}/processed/ 2>/dev/null
319 # give bundle (almost) all the cores. See also the MAKE env var that is passed into the
320 # docker run command below.
321 # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/
322 tmpfile=$(mktemp /tmp/run-build-packages-one-target.XXXXXX)
323 cores=$(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a)
324 printf -- "---\nBUNDLE_JOBS: \"$cores\"" > $tmpfile
328 "${docker_volume_args[@]}" \
329 -v $tmpfile:/root/.bundle/config \
330 --env ARVADOS_BUILDING_VERSION="$ARVADOS_BUILDING_VERSION" \
331 --env ARVADOS_BUILDING_ITERATION="$ARVADOS_BUILDING_ITERATION" \
332 --env ARVADOS_DEBUG=$ARVADOS_DEBUG \
333 --env "ONLY_BUILD=$ONLY_BUILD" \
334 --env "FORCE_BUILD=$FORCE_BUILD" \
336 --env "MAKE=make --jobs $cores" \
340 echo "OK: build packages on $IMAGE succeeded" >&2
343 echo "ERROR: build packages on $IMAGE failed with exit status $FINAL_EXITCODE" >&2
345 # Clean up the bundle config file
349 if test -n "$package_fails" ; then
350 echo "Failed package tests:$package_fails" >&2