17863: further cleanup in our rails postinst scripts and documentation:
[arvados.git] / build / run-build-packages.sh
1 #!/bin/bash
2 # Copyright (C) The Arvados Authors. All rights reserved.
3 #
4 # SPDX-License-Identifier: AGPL-3.0
5
6 . `dirname "$(readlink -f "$0")"`/run-library.sh || exit 1
7 . `dirname "$(readlink -f "$0")"`/libcloud-pin.sh || exit 1
8
9 read -rd "\000" helpmessage <<EOF
10 $(basename $0): Build Arvados packages
11
12 Syntax:
13         WORKSPACE=/path/to/arvados $(basename $0) [options]
14
15 Options:
16
17 --build-bundle-packages  (default: false)
18     Build api server and workbench packages with vendor/bundle included
19 --debug
20     Output debug information (default: false)
21 --target <target>
22     Distribution to build packages for (default: debian10)
23 --only-build <package>
24     Build only a specific package (or $ONLY_BUILD from environment)
25 --force-build
26     Build even if the package exists upstream or if it has already been
27     built locally
28 --command
29     Build command to execute (defaults to the run command defined in the
30     Docker image)
31
32 WORKSPACE=path         Path to the Arvados source tree to build packages from
33
34 EOF
35
36 # Begin of user configuration
37
38 # set to --no-cache-dir to disable pip caching
39 CACHE_FLAG=
40
41 MAINTAINER="Arvados Package Maintainers <packaging@arvados.org>"
42 VENDOR="The Arvados Project"
43
44 # End of user configuration
45
46 DEBUG=${ARVADOS_DEBUG:-0}
47 FORCE_BUILD=${FORCE_BUILD:-0}
48 EXITCODE=0
49 TARGET=debian10
50 COMMAND=
51
52 PARSEDOPTS=$(getopt --name "$0" --longoptions \
53     help,build-bundle-packages,debug,target:,only-build:,force-build \
54     -- "" "$@")
55 if [ $? -ne 0 ]; then
56     exit 1
57 fi
58
59 eval set -- "$PARSEDOPTS"
60 while [ $# -gt 0 ]; do
61     case "$1" in
62         --help)
63             echo >&2 "$helpmessage"
64             echo >&2
65             exit 1
66             ;;
67         --target)
68             TARGET="$2"; shift
69             ;;
70         --only-build)
71             ONLY_BUILD="$2"; shift
72             ;;
73         --force-build)
74             FORCE_BUILD=1
75             ;;
76         --debug)
77             DEBUG=1
78             ;;
79         --command)
80             COMMAND="$2"; shift
81             ;;
82         --)
83             if [ $# -gt 1 ]; then
84                 echo >&2 "$0: unrecognized argument '$2'. Try: $0 --help"
85                 exit 1
86             fi
87             ;;
88     esac
89     shift
90 done
91
92 if [[ "$COMMAND" != "" ]]; then
93   COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET"
94 fi
95
96 STDOUT_IF_DEBUG=/dev/null
97 STDERR_IF_DEBUG=/dev/null
98 DASHQ_UNLESS_DEBUG=-q
99 if [[ "$DEBUG" != 0 ]]; then
100     STDOUT_IF_DEBUG=/dev/stdout
101     STDERR_IF_DEBUG=/dev/stderr
102     DASHQ_UNLESS_DEBUG=
103 fi
104
105 declare -a PYTHON3_BACKPORTS
106
107 PYTHON3_VERSION=$(python3 -c 'import sys; print("{v.major}.{v.minor}".format(v=sys.version_info))')
108
109 ## These defaults are suitable for any Debian-based distribution.
110 # You can customize them as needed in distro sections below.
111 PYTHON3_PACKAGE=python$PYTHON3_VERSION
112 PYTHON3_PKG_PREFIX=python3
113 PYTHON3_PREFIX=/usr
114 PYTHON3_INSTALL_LIB=lib/python$PYTHON3_VERSION/dist-packages
115 ## End Debian Python defaults.
116
117 case "$TARGET" in
118     debian*)
119         FORMAT=deb
120         ;;
121     ubuntu*)
122         FORMAT=deb
123         ;;
124     centos*)
125         FORMAT=rpm
126         PYTHON3_PACKAGE=$(rpm -qf "$(which python$PYTHON3_VERSION)" --queryformat '%{NAME}\n')
127         PYTHON3_PKG_PREFIX=$PYTHON3_PACKAGE
128         PYTHON3_PREFIX=/usr
129         PYTHON3_INSTALL_LIB=lib/python$PYTHON3_VERSION/site-packages
130         export PYCURL_SSL_LIBRARY=nss
131         ;;
132     *)
133         echo -e "$0: Unknown target '$TARGET'.\n" >&2
134         exit 1
135         ;;
136 esac
137
138
139 if ! [[ -n "$WORKSPACE" ]]; then
140   echo >&2 "$helpmessage"
141   echo >&2
142   echo >&2 "Error: WORKSPACE environment variable not set"
143   echo >&2
144   exit 1
145 fi
146
147 # Test for fpm
148 fpm --version >/dev/null 2>&1
149
150 if [[ "$?" != 0 ]]; then
151   echo >&2 "$helpmessage"
152   echo >&2
153   echo >&2 "Error: fpm not found"
154   echo >&2
155   exit 1
156 fi
157
158 RUN_BUILD_PACKAGES_PATH="`dirname \"$0\"`"
159 RUN_BUILD_PACKAGES_PATH="`( cd \"$RUN_BUILD_PACKAGES_PATH\" && pwd )`"  # absolutized and normalized
160 if [ -z "$RUN_BUILD_PACKAGES_PATH" ] ; then
161   # error; for some reason, the path is not accessible
162   # to the script (e.g. permissions re-evaled after suid)
163   exit 1  # fail
164 fi
165
166 debug_echo "$0 is running from $RUN_BUILD_PACKAGES_PATH"
167 debug_echo "Workspace is $WORKSPACE"
168
169 if [[ -f /etc/profile.d/rvm.sh ]]; then
170     source /etc/profile.d/rvm.sh
171     GEM="rvm-exec default gem"
172 else
173     GEM=gem
174 fi
175
176 # Make all files world-readable -- jenkins runs with umask 027, and has checked
177 # out our git tree here
178 chmod o+r "$WORKSPACE" -R
179
180 # More cleanup - make sure all executables that we'll package are 755
181 cd "$WORKSPACE"
182 find -type d -name 'bin' |xargs -I {} find {} -type f |xargs -I {} chmod 755 {}
183
184 # Now fix our umask to something better suited to building and publishing
185 # gems and packages
186 umask 0022
187
188 debug_echo "umask is" `umask`
189
190 if [[ ! -d "$WORKSPACE/packages/$TARGET" ]]; then
191   mkdir -p $WORKSPACE/packages/$TARGET
192   chown --reference="$WORKSPACE" "$WORKSPACE/packages/$TARGET"
193 fi
194
195 # Perl packages
196 debug_echo -e "\nPerl packages\n"
197
198 if [[ -z "$ONLY_BUILD" ]] || [[ "libarvados-perl" = "$ONLY_BUILD" ]] ; then
199   cd "$WORKSPACE/sdk/perl"
200   libarvados_perl_version="$(version_from_git)"
201
202   cd $WORKSPACE/packages/$TARGET
203   test_package_presence libarvados-perl "$libarvados_perl_version"
204
205   if [[ "$?" == "0" ]]; then
206     cd "$WORKSPACE/sdk/perl"
207
208     if [[ -e Makefile ]]; then
209       make realclean >"$STDOUT_IF_DEBUG"
210     fi
211     find -maxdepth 1 \( -name 'MANIFEST*' -or -name "libarvados-perl*.$FORMAT" \) \
212         -delete
213     rm -rf install
214
215     perl Makefile.PL INSTALL_BASE=install >"$STDOUT_IF_DEBUG" && \
216         make install INSTALLDIRS=perl >"$STDOUT_IF_DEBUG" && \
217         fpm_build "$WORKSPACE/sdk/perl" install/lib/=/usr/share libarvados-perl \
218         dir "$(version_from_git)" install/man/=/usr/share/man \
219         "$WORKSPACE/apache-2.0.txt=/usr/share/doc/libarvados-perl/apache-2.0.txt" && \
220         mv --no-clobber libarvados-perl*.$FORMAT "$WORKSPACE/packages/$TARGET/"
221   fi
222 fi
223
224 # Ruby gems
225 debug_echo -e "\nRuby gems\n"
226
227 FPM_GEM_PREFIX=$($GEM environment gemdir)
228
229 cd "$WORKSPACE/sdk/ruby"
230 handle_ruby_gem arvados
231
232 cd "$WORKSPACE/sdk/cli"
233 handle_ruby_gem arvados-cli
234
235 cd "$WORKSPACE/services/login-sync"
236 handle_ruby_gem arvados-login-sync
237
238 # Python packages
239 debug_echo -e "\nPython packages\n"
240
241 # arvados-src
242 (
243     cd "$WORKSPACE"
244     COMMIT_HASH=$(format_last_commit_here "%H")
245     arvados_src_version="$(version_from_git)"
246
247     cd $WORKSPACE/packages/$TARGET
248     test_package_presence arvados-src $arvados_src_version src ""
249
250     if [[ "$?" == "0" ]]; then
251       cd "$WORKSPACE"
252       SRC_BUILD_DIR=$(mktemp -d)
253       # mktemp creates the directory with 0700 permissions by default
254       chmod 755 $SRC_BUILD_DIR
255       git clone $DASHQ_UNLESS_DEBUG "$WORKSPACE/.git" "$SRC_BUILD_DIR"
256       cd "$SRC_BUILD_DIR"
257
258       # go into detached-head state
259       git checkout $DASHQ_UNLESS_DEBUG "$COMMIT_HASH"
260       echo "$COMMIT_HASH" >git-commit.version
261
262       cd $WORKSPACE/packages/$TARGET
263       fpm_build "$WORKSPACE" $SRC_BUILD_DIR/=/usr/local/arvados/src arvados-src 'dir' "$arvados_src_version" "--exclude=usr/local/arvados/src/.git" "--url=https://arvados.org" "--license=GNU Affero General Public License, version 3.0" "--description=The Arvados source code" "--architecture=all"
264
265       rm -rf "$SRC_BUILD_DIR"
266     fi
267 )
268
269 # Go binaries
270 cd $WORKSPACE/packages/$TARGET
271 export GOPATH=$(mktemp -d)
272 package_go_binary cmd/arvados-client arvados-client \
273     "Arvados command line tool (beta)"
274 package_go_binary cmd/arvados-server arvados-server \
275     "Arvados server daemons"
276 package_go_binary cmd/arvados-server arvados-controller \
277     "Arvados cluster controller daemon"
278 package_go_binary cmd/arvados-server arvados-dispatch-cloud \
279     "Arvados cluster cloud dispatch"
280 package_go_binary services/arv-git-httpd arvados-git-httpd \
281     "Provide authenticated http access to Arvados-hosted git repositories"
282 package_go_binary services/crunch-dispatch-local crunch-dispatch-local \
283     "Dispatch Crunch containers on the local system"
284 package_go_binary services/crunch-dispatch-slurm crunch-dispatch-slurm \
285     "Dispatch Crunch containers to a SLURM cluster"
286 package_go_binary cmd/arvados-server crunch-run \
287     "Supervise a single Crunch container"
288 package_go_binary services/crunchstat crunchstat \
289     "Gather cpu/memory/network statistics of running Crunch jobs"
290 package_go_binary services/health arvados-health \
291     "Check health of all Arvados cluster services"
292 package_go_binary services/keep-balance keep-balance \
293     "Rebalance and garbage-collect data blocks stored in Arvados Keep"
294 package_go_binary services/keepproxy keepproxy \
295     "Make a Keep cluster accessible to clients that are not on the LAN"
296 package_go_binary services/keepstore keepstore \
297     "Keep storage daemon, accessible to clients on the LAN"
298 package_go_binary services/keep-web keep-web \
299     "Static web hosting service for user data stored in Arvados Keep"
300 package_go_binary cmd/arvados-server arvados-ws \
301     "Arvados Websocket server"
302 package_go_binary tools/sync-groups arvados-sync-groups \
303     "Synchronize remote groups into Arvados from an external source"
304 package_go_binary tools/keep-block-check keep-block-check \
305     "Verify that all data from one set of Keep servers to another was copied"
306 package_go_binary tools/keep-rsync keep-rsync \
307     "Copy all data from one set of Keep servers to another"
308 package_go_binary tools/keep-exercise keep-exercise \
309     "Performance testing tool for Arvados Keep"
310 package_go_so lib/pam pam_arvados.so libpam-arvados-go \
311     "Arvados PAM authentication module"
312
313 # The Python SDK - Python3 package
314 fpm_build_virtualenv "arvados-python-client" "sdk/python" "python3"
315
316 # Arvados cwl runner - Python3 package
317 fpm_build_virtualenv "arvados-cwl-runner" "sdk/cwl" "python3"
318
319 # The FUSE driver - Python3 package
320 fpm_build_virtualenv "arvados-fuse" "services/fuse" "python3"
321
322 # The Arvados crunchstat-summary tool
323 fpm_build_virtualenv "crunchstat-summary" "tools/crunchstat-summary" "python3"
324
325 # The Docker image cleaner
326 fpm_build_virtualenv "arvados-docker-cleaner" "services/dockercleaner" "python3"
327
328 # The Arvados user activity tool
329 fpm_build_virtualenv "arvados-user-activity" "tools/user-activity" "python3"
330
331 # The python->python3 metapackages
332 build_metapackage "arvados-fuse" "services/fuse"
333 build_metapackage "arvados-python-client" "services/fuse"
334 build_metapackage "arvados-cwl-runner" "sdk/cwl"
335 build_metapackage "crunchstat-summary" "tools/crunchstat-summary"
336 build_metapackage "arvados-docker-cleaner" "services/dockercleaner"
337 build_metapackage "arvados-user-activity" "tools/user-activity"
338
339 # The cwltest package, which lives out of tree
340 cd "$WORKSPACE"
341 if [[ -e "$WORKSPACE/cwltest" ]]; then
342         rm -rf "$WORKSPACE/cwltest"
343 fi
344 git clone https://github.com/common-workflow-language/cwltest.git
345 # signal to our build script that we want a cwltest executable installed in /usr/bin/
346 mkdir cwltest/bin && touch cwltest/bin/cwltest
347 fpm_build_virtualenv "cwltest" "cwltest" "python3"
348 # The python->python3 metapackage
349 build_metapackage "cwltest" "cwltest"
350 cd "$WORKSPACE"
351 rm -rf "$WORKSPACE/cwltest"
352
353 calculate_go_package_version arvados_server_version cmd/arvados-server
354 arvados_server_iteration=$(default_iteration "arvados-server" "$arvados_server_version" "go")
355
356 # Build the API server package
357 test_rails_package_presence arvados-api-server "$WORKSPACE/services/api"
358 if [[ "$?" == "0" ]]; then
359   handle_rails_package arvados-api-server "$WORKSPACE/services/api" \
360       "$WORKSPACE/agpl-3.0.txt" --url="https://arvados.org" \
361       --description="Arvados API server - Arvados is a free and open source platform for big data science." \
362       --license="GNU Affero General Public License, version 3.0" --depends "arvados-server = ${arvados_server_version}-${arvados_server_iteration}"
363 fi
364
365 # Build the workbench server package
366 test_rails_package_presence arvados-workbench "$WORKSPACE/apps/workbench"
367 if [[ "$?" == "0" ]] ; then
368   (
369       set -e
370
371       # The workbench package has a build-time dependency on the arvados-server
372       # package for config manipulation, so install it first.
373       cd $WORKSPACE/cmd/arvados-server
374       get_complete_package_name arvados_server_pkgname arvados-server ${arvados_server_version} go
375
376       arvados_server_pkg_path="$WORKSPACE/packages/$TARGET/${arvados_server_pkgname}"
377       if [[ ! -e ${arvados_server_pkg_path} ]]; then
378         arvados_server_pkg_path="$WORKSPACE/packages/$TARGET/processed/${arvados_server_pkgname}"
379       fi
380       if [[ "$FORMAT" == "deb" ]]; then
381         dpkg -i ${arvados_server_pkg_path}
382       else
383         rpm -i ${arvados_server_pkg_path}
384       fi
385
386       cd "$WORKSPACE/apps/workbench"
387
388       # We need to bundle to be ready even when we build a package without vendor directory
389       # because asset compilation requires it.
390       bundle install --system >"$STDOUT_IF_DEBUG"
391
392       # clear the tmp directory; the asset generation step will recreate tmp/cache/assets,
393       # and we want that in the package, so it's easier to not exclude the tmp directory
394       # from the package - empty it instead.
395       rm -rf tmp
396       mkdir tmp
397
398       # Set up an appropriate config.yml
399       arvados-server config-dump -config <(cat /etc/arvados/config.yml 2>/dev/null || echo  "Clusters: {zzzzz: {}}") > /tmp/x
400       mkdir -p /etc/arvados/
401       mv /tmp/x /etc/arvados/config.yml
402       perl -p -i -e 'BEGIN{undef $/;} s/WebDAV(.*?):\n( *)ExternalURL: ""/WebDAV$1:\n$2ExternalURL: "example.com"/g' /etc/arvados/config.yml
403
404       ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bin/rake npm:install >"$STDOUT_IF_DEBUG"
405       ARVADOS_CONFIG=none RAILS_ENV=production RAILS_GROUPS=assets bin/rake assets:precompile >"$STDOUT_IF_DEBUG"
406
407       # Remove generated configuration files so they don't go in the package.
408       rm -rf /etc/arvados/
409   )
410
411   if [[ "$?" != "0" ]]; then
412     echo "ERROR: Asset precompilation failed"
413     EXITCODE=1
414   else
415     handle_rails_package arvados-workbench "$WORKSPACE/apps/workbench" \
416         "$WORKSPACE/agpl-3.0.txt" --url="https://arvados.org" \
417         --description="Arvados Workbench - Arvados is a free and open source platform for big data science." \
418         --license="GNU Affero General Public License, version 3.0" --depends "arvados-server = ${arvados_server_version}-${arvados_server_iteration}"
419   fi
420 fi
421
422 # clean up temporary GOPATH
423 rm -rf "$GOPATH"
424
425 exit $EXITCODE