Merge branch '17389-keepproxy-storage-classes-confirmed'
[arvados.git] / tools / salt-install / provision.sh
1 #!/bin/bash -x
2
3 # Copyright (C) The Arvados Authors. All rights reserved.
4 #
5 # SPDX-License-Identifier: CC-BY-SA-3.0
6
7 # If you want to test arvados in a single host, you can run this script, which
8 # will install it using salt masterless
9 # This script is run by the Vagrant file when you run it with
10 #
11 # vagrant up
12
13 set -o pipefail
14
15 # capture the directory that the script is running from
16 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
17
18 usage() {
19   echo >&2
20   echo >&2 "Usage: ${0} [-h] [-h]"
21   echo >&2
22   echo >&2 "${0} options:"
23   echo >&2 "  -d, --debug                                 Run salt installation in debug mode"
24   echo >&2 "  -p <N>, --ssl-port <N>                      SSL port to use for the web applications"
25   echo >&2 "  -c <local.params>, --config <local.params>  Path to the local.params config file"
26   echo >&2 "  -t, --test                                  Test installation running a CWL workflow"
27   echo >&2 "  -r, --roles                                 List of Arvados roles to apply to the host, comma separated"
28   echo >&2 "                                              Possible values are:"
29   echo >&2 "                                                api"
30   echo >&2 "                                                controller"
31   echo >&2 "                                                dispatcher"
32   echo >&2 "                                                keepproxy"
33   echo >&2 "                                                keepstore"
34   echo >&2 "                                                keepweb"
35   echo >&2 "                                                shell"
36   echo >&2 "                                                webshell"
37   echo >&2 "                                                websocket"
38   echo >&2 "                                                workbench"
39   echo >&2 "                                                workbench2"
40   echo >&2 "                                              Defaults to applying them all"
41   echo >&2 "  -h, --help                                  Display this help and exit"
42   echo >&2 "  -v, --vagrant                               Run in vagrant and use the /vagrant shared dir"
43   echo >&2
44 }
45
46 arguments() {
47   # NOTE: This requires GNU getopt (part of the util-linux package on Debian-based distros).
48   TEMP=$(getopt -o c:dhp:r:tv \
49     --long config:,debug,help,ssl-port:,roles:,test,vagrant \
50     -n "${0}" -- "${@}")
51
52   if [ ${?} != 0 ] ; then echo "GNU getopt missing? Use -h for help"; exit 1 ; fi
53   # Note the quotes around `$TEMP': they are essential!
54   eval set -- "$TEMP"
55
56   while [ ${#} -ge 1 ]; do
57     case ${1} in
58       -c | --config)
59         CONFIG_FILE=${2}
60         shift 2
61         ;;
62       -d | --debug)
63         LOG_LEVEL="debug"
64         shift
65         ;;
66       -p | --ssl-port)
67         CONTROLLER_EXT_SSL_PORT=${2}
68         shift 2
69         ;;
70       -r | --roles)
71         for i in ${2//,/ }
72           do
73             # Verify the role exists
74             if [[ ! "database,api,controller,keepstore,websocket,keepweb,workbench2,webshell,keepproxy,shell,workbench,dispatcher" == *"$i"* ]]; then
75               echo "The role '${i}' is not a valid role"
76               usage
77               exit 1
78             fi
79             ROLES="${ROLES} ${i}"
80           done
81           shift 2
82         ;;
83       -t | --test)
84         TEST="yes"
85         shift
86         ;;
87       -v | --vagrant)
88         VAGRANT="yes"
89         shift
90         ;;
91       --)
92         shift
93         break
94         ;;
95       *)
96         usage
97         exit 1
98         ;;
99     esac
100   done
101 }
102
103 CONFIG_FILE="${SCRIPT_DIR}/local.params"
104 CONFIG_DIR="local_config_dir"
105 LOG_LEVEL="info"
106 CONTROLLER_EXT_SSL_PORT=443
107 TESTS_DIR="tests"
108
109 CLUSTER=""
110 DOMAIN=""
111
112 # Hostnames/IPs used for single-host deploys
113 HOSTNAME_EXT=""
114 HOSTNAME_INT="127.0.1.1"
115
116 # Initial user setup
117 INITIAL_USER=""
118 INITIAL_USER_EMAIL=""
119 INITIAL_USER_PASSWORD=""
120
121 CONTROLLER_EXT_SSL_PORT=8000
122 KEEP_EXT_SSL_PORT=25101
123 # Both for collections and downloads
124 KEEPWEB_EXT_SSL_PORT=9002
125 WEBSHELL_EXT_SSL_PORT=4202
126 WEBSOCKET_EXT_SSL_PORT=8002
127 WORKBENCH1_EXT_SSL_PORT=443
128 WORKBENCH2_EXT_SSL_PORT=3001
129
130 # For a stable release, change RELEASE "production" and VERSION to the
131 # package version (including the iteration, e.g. X.Y.Z-1) of the
132 # release.
133 RELEASE="development"
134 VERSION="latest"
135
136 # The arvados-formula version.  For a stable release, this should be a
137 # branch name (e.g. X.Y-dev) or tag for the release.
138 ARVADOS_TAG="main"
139
140 # Other formula versions we depend on
141 POSTGRES_TAG="v0.41.6"
142 NGINX_TAG="v2.7.4"
143 DOCKER_TAG="v1.0.0"
144 LOCALE_TAG="v0.3.4"
145 LETSENCRYPT_TAG="v2.1.0"
146
147 # Salt's dir
148 ## states
149 S_DIR="/srv/salt"
150 ## formulas
151 F_DIR="/srv/formulas"
152 ##pillars
153 P_DIR="/srv/pillars"
154
155 arguments ${@}
156
157 if [ -s ${CONFIG_FILE} ]; then
158   source ${CONFIG_FILE}
159 else
160   echo >&2 "Please create a '${CONFIG_FILE}' file with initial values, as described in"
161   echo >&2 "  * https://doc.arvados.org/install/salt-single-host.html#single_host, or"
162   echo >&2 "  * https://doc.arvados.org/install/salt-multi-host.html#multi_host_multi_hostnames"
163   exit 1
164 fi
165
166 if [ ! -d ${CONFIG_DIR} ]; then
167   echo >&2 "Please create a '${CONFIG_DIR}' with initial values, as described in"
168   echo >&2 "  * https://doc.arvados.org/install/salt-single-host.html#single_host, or"
169   echo >&2 "  * https://doc.arvados.org/install/salt-multi-host.html#multi_host_multi_hostnames"
170   exit 1
171 fi
172
173 if grep -q 'fixme_or_this_wont_work' ${CONFIG_FILE} ; then
174   echo >&2 "The config file ${CONFIG_FILE} has some parameters that need to be modified."
175   echo >&2 "Please, fix them and re-run the provision script."
176   exit 1
177 fi
178
179 if ! grep -E '^[[:alnum:]]{5}$' <<<${CLUSTER} ; then
180   echo >&2 "ERROR: <CLUSTER> must be exactly 5 alphanumeric characters long"
181   echo >&2 "Fix the cluster name in the 'local.params' file and re-run the provision script"
182   exit 1
183 fi
184
185 # Only used in single_host/single_name deploys
186 if [ "x${HOSTNAME_EXT}" = "x" ] ; then
187   HOSTNAME_EXT="${CLUSTER}.${DOMAIN}"
188 fi
189
190 apt-get update
191 apt-get install -y curl git jq
192
193 if which salt-call; then
194   echo "Salt already installed"
195 else
196   curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh
197   sh /tmp/bootstrap_salt.sh -XdfP -x python3
198   /bin/systemctl stop salt-minion.service
199   /bin/systemctl disable salt-minion.service
200 fi
201
202 # Set salt to masterless mode
203 cat > /etc/salt/minion << EOFSM
204 file_client: local
205 file_roots:
206   base:
207     - ${S_DIR}
208     - ${F_DIR}/*
209
210 pillar_roots:
211   base:
212     - ${P_DIR}
213 EOFSM
214
215 mkdir -p ${S_DIR} ${F_DIR} ${P_DIR}
216
217 # Get the formula and dependencies
218 cd ${F_DIR} || exit 1
219 git clone --branch "${ARVADOS_TAG}"     https://git.arvados.org/arvados-formula.git
220 git clone --branch "${DOCKER_TAG}"      https://github.com/saltstack-formulas/docker-formula.git
221 git clone --branch "${LOCALE_TAG}"      https://github.com/saltstack-formulas/locale-formula.git
222 git clone --branch "${NGINX_TAG}"       https://github.com/saltstack-formulas/nginx-formula.git
223 git clone --branch "${POSTGRES_TAG}"    https://github.com/saltstack-formulas/postgres-formula.git
224 git clone --branch "${LETSENCRYPT_TAG}" https://github.com/saltstack-formulas/letsencrypt-formula.git
225
226 # If we want to try a specific branch of the formula
227 if [ "x${BRANCH}" != "x" ]; then
228   cd ${F_DIR}/arvados-formula || exit 1
229   git checkout -t origin/"${BRANCH}" -b "${BRANCH}"
230   cd -
231 fi
232
233 if [ "x${VAGRANT}" = "xyes" ]; then
234   EXTRA_STATES_DIR="/home/vagrant/${CONFIG_DIR}/states"
235   SOURCE_PILLARS_DIR="/home/vagrant/${CONFIG_DIR}/pillars"
236   SOURCE_TESTS_DIR="/home/vagrant/${TESTS_DIR}"
237 else
238   EXTRA_STATES_DIR="${SCRIPT_DIR}/${CONFIG_DIR}/states"
239   SOURCE_PILLARS_DIR="${SCRIPT_DIR}/${CONFIG_DIR}/pillars"
240   SOURCE_TESTS_DIR="${SCRIPT_DIR}/${TESTS_DIR}"
241 fi
242
243 SOURCE_STATES_DIR="${EXTRA_STATES_DIR}"
244
245 # Replace variables (cluster,  domain, etc) in the pillars, states and tests
246 # to ease deployment for newcomers
247 if [ ! -d "${SOURCE_PILLARS_DIR}" ]; then
248   echo "${SOURCE_PILLARS_DIR} does not exist or is not a directory. Exiting."
249   exit 1
250 fi
251 for f in $(ls "${SOURCE_PILLARS_DIR}"/*); do
252   sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
253        s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
254        s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
255        s#__CLUSTER__#${CLUSTER}#g;
256        s#__DOMAIN__#${DOMAIN}#g;
257        s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
258        s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
259        s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
260        s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
261        s#__INITIAL_USER__#${INITIAL_USER}#g;
262        s#__LE_AWS_REGION__#${LE_AWS_REGION}#g;
263        s#__LE_AWS_SECRET_ACCESS_KEY__#${LE_AWS_SECRET_ACCESS_KEY}#g;
264        s#__LE_AWS_ACCESS_KEY_ID__#${LE_AWS_ACCESS_KEY_ID}#g;
265        s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
266        s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
267        s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
268        s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
269        s#__RELEASE__#${RELEASE}#g;
270        s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
271        s#__VERSION__#${VERSION}#g;
272        s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
273        s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
274        s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
275        s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
276        s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
277        s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
278        s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
279        s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
280        s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
281        s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
282        s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
283        s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
284        s#__SHELL_INT_IP__#${SHELL_INT_IP}#g;
285        s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
286        s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
287        s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
288        s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
289   "${f}" > "${P_DIR}"/$(basename "${f}")
290 done
291
292 if [ "x${TEST}" = "xyes" ] && [ ! -d "${SOURCE_TESTS_DIR}" ]; then
293   echo "You requested to run tests, but ${SOURCE_TESTS_DIR} does not exist or is not a directory. Exiting."
294   exit 1
295 fi
296 mkdir -p /tmp/cluster_tests
297 # Replace cluster and domain name in the test files
298 for f in $(ls "${SOURCE_TESTS_DIR}"/*); do
299   sed "s#__CLUSTER__#${CLUSTER}#g;
300        s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
301        s#__DOMAIN__#${DOMAIN}#g;
302        s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
303        s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
304        s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g
305        s#__INITIAL_USER__#${INITIAL_USER}#g;
306        s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
307        s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g" \
308   "${f}" > "/tmp/cluster_tests"/$(basename "${f}")
309 done
310 chmod 755 /tmp/cluster_tests/run-test.sh
311
312 # Replace helper state files that differ from the formula's examples
313 if [ -d "${SOURCE_STATES_DIR}" ]; then
314   mkdir -p "${F_DIR}"/extra/extra
315
316   for f in $(ls "${SOURCE_STATES_DIR}"/*); do
317     sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
318          s#__CLUSTER__#${CLUSTER}#g;
319          s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
320          s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
321          s#__DOMAIN__#${DOMAIN}#g;
322          s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
323          s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
324          s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
325          s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
326          s#__INITIAL_USER__#${INITIAL_USER}#g;
327          s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
328          s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
329          s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
330          s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
331          s#__RELEASE__#${RELEASE}#g;
332          s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
333          s#__VERSION__#${VERSION}#g;
334          s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
335          s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
336          s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
337          s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
338          s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
339          s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
340          s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
341          s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
342          s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
343          s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
344          s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
345          s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
346          s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
347          s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
348          s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
349          s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
350     "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}")
351   done
352 fi
353
354 # Now, we build the SALT states/pillars trees
355 # As we need to separate both states and pillars in case we want specific
356 # roles, we iterate on both at the same time
357
358 # States
359 cat > ${S_DIR}/top.sls << EOFTSLS
360 base:
361   '*':
362     - locale
363 EOFTSLS
364
365 # Pillars
366 cat > ${P_DIR}/top.sls << EOFPSLS
367 base:
368   '*':
369     - locale
370     - arvados
371 EOFPSLS
372
373 # States, extra states
374 if [ -d "${F_DIR}"/extra/extra ]; then
375   for f in $(ls "${F_DIR}"/extra/extra/*.sls); do
376   echo "    - extra.$(basename ${f} | sed 's/.sls$//g')" >> ${S_DIR}/top.sls
377   done
378 fi
379
380 # If we want specific roles for a node, just add the desired states
381 # and its dependencies
382 if [ -z "${ROLES}" ]; then
383   # States
384   echo "    - nginx.passenger" >> ${S_DIR}/top.sls
385   # Currently, only available on config_examples/multi_host/aws
386   if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
387     if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
388       grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
389     fi
390     grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
391   fi
392   echo "    - postgres" >> ${S_DIR}/top.sls
393   echo "    - docker.software" >> ${S_DIR}/top.sls
394   echo "    - arvados" >> ${S_DIR}/top.sls
395
396   # Pillars
397   echo "    - docker" >> ${P_DIR}/top.sls
398   echo "    - nginx_api_configuration" >> ${P_DIR}/top.sls
399   echo "    - nginx_controller_configuration" >> ${P_DIR}/top.sls
400   echo "    - nginx_keepproxy_configuration" >> ${P_DIR}/top.sls
401   echo "    - nginx_keepweb_configuration" >> ${P_DIR}/top.sls
402   echo "    - nginx_passenger" >> ${P_DIR}/top.sls
403   echo "    - nginx_websocket_configuration" >> ${P_DIR}/top.sls
404   echo "    - nginx_webshell_configuration" >> ${P_DIR}/top.sls
405   echo "    - nginx_workbench2_configuration" >> ${P_DIR}/top.sls
406   echo "    - nginx_workbench_configuration" >> ${P_DIR}/top.sls
407   echo "    - postgresql" >> ${P_DIR}/top.sls
408   # Currently, only available on config_examples/multi_host/aws
409   if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
410     if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
411       grep -q "aws_credentials" ${P_DIR}/top.sls || echo "    - aws_credentials" >> ${P_DIR}/top.sls
412     fi
413     grep -q "letsencrypt"     ${P_DIR}/top.sls || echo "    - letsencrypt" >> ${P_DIR}/top.sls
414   fi
415 else
416   # If we add individual roles, make sure we add the repo first
417   echo "    - arvados.repo" >> ${S_DIR}/top.sls
418   for R in ${ROLES}; do
419     case "${R}" in
420       "database")
421         # States
422         echo "    - postgres" >> ${S_DIR}/top.sls
423         # Pillars
424         echo '    - postgresql' >> ${P_DIR}/top.sls
425       ;;
426       "api")
427         # States
428         # FIXME: https://dev.arvados.org/issues/17352
429         grep -q "postgres.client" ${S_DIR}/top.sls || echo "    - postgres.client" >> ${S_DIR}/top.sls
430         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
431         ### If we don't install and run LE before arvados-api-server, it fails and breaks everything
432         ### after it so we add this here, as we are, after all, sharing the host for api and controller
433         # Currently, only available on config_examples/multi_host/aws
434         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
435           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
436             grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
437           fi
438           grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
439         fi
440         grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
441         # Pillars
442         grep -q "aws_credentials" ${P_DIR}/top.sls          || echo "    - aws_credentials" >> ${P_DIR}/top.sls
443         grep -q "docker" ${P_DIR}/top.sls                   || echo "    - docker" >> ${P_DIR}/top.sls
444         grep -q "postgresql" ${P_DIR}/top.sls               || echo "    - postgresql" >> ${P_DIR}/top.sls
445         grep -q "nginx_passenger" ${P_DIR}/top.sls          || echo "    - nginx_passenger" >> ${P_DIR}/top.sls
446         grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo "    - nginx_${R}_configuration" >> ${P_DIR}/top.sls
447       ;;
448       "controller" | "websocket" | "workbench" | "workbench2" | "webshell" | "keepweb" | "keepproxy")
449         # States
450         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
451         # Currently, only available on config_examples/multi_host/aws
452         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
453           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
454             grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
455           fi
456           grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
457         fi
458         # webshell role is just a nginx vhost, so it has no state
459         if [ "${R}" != "webshell" ]; then
460           grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
461         fi
462         # Pillars
463         grep -q "nginx_passenger" ${P_DIR}/top.sls          || echo "    - nginx_passenger" >> ${P_DIR}/top.sls
464         grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo "    - nginx_${R}_configuration" >> ${P_DIR}/top.sls
465         # Currently, only available on config_examples/multi_host/aws
466         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
467           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
468             grep -q "aws_credentials" ${P_DIR}/top.sls || echo "    - aws_credentials" >> ${P_DIR}/top.sls
469           fi
470           grep -q "letsencrypt"     ${P_DIR}/top.sls || echo "    - letsencrypt" >> ${P_DIR}/top.sls
471           grep -q "letsencrypt_${R}_configuration" ${P_DIR}/top.sls || echo "    - letsencrypt_${R}_configuration" >> ${P_DIR}/top.sls
472         fi
473       ;;
474       "shell")
475         # States
476         grep -q "docker" ${S_DIR}/top.sls       || echo "    - docker.software" >> ${S_DIR}/top.sls
477         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
478         # Pillars
479         grep -q "" ${P_DIR}/top.sls                             || echo "    - docker" >> ${P_DIR}/top.sls
480       ;;
481       "dispatcher")
482         # States
483         grep -q "docker" ${S_DIR}/top.sls       || echo "    - docker.software" >> ${S_DIR}/top.sls
484         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
485         # Pillars
486         # ATM, no specific pillar needed
487       ;;
488       "keepstore")
489         # States
490         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
491         # Pillars
492         # ATM, no specific pillar needed
493       ;;
494       *)
495         echo "Unknown role ${R}"
496         exit 1
497       ;;
498     esac
499   done
500 fi
501
502 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
503 if [ -e /root/.psqlrc ]; then
504   if ! ( grep 'pset pager off' /root/.psqlrc ); then
505     RESTORE_PSQL="yes"
506     cp /root/.psqlrc /root/.psqlrc.provision.backup
507   fi
508 else
509   DELETE_PSQL="yes"
510 fi
511
512 echo '\pset pager off' >> /root/.psqlrc
513 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
514
515 # Now run the install
516 salt-call --local state.apply -l ${LOG_LEVEL}
517
518 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
519 if [ "x${DELETE_PSQL}" = "xyes" ]; then
520   echo "Removing .psql file"
521   rm /root/.psqlrc
522 fi
523
524 if [ "x${RESTORE_PSQL}" = "xyes" ]; then
525   echo "Restoring .psql file"
526   mv -v /root/.psqlrc.provision.backup /root/.psqlrc
527 fi
528 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
529
530 # Leave a copy of the Arvados CA so the user can copy it where it's required
531 echo "Copying the Arvados CA certificate to the installer dir, so you can import it"
532 # If running in a vagrant VM, also add default user to docker group
533 if [ "x${VAGRANT}" = "xyes" ]; then
534   cp /etc/ssl/certs/arvados-snakeoil-ca.pem /vagrant/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
535
536   echo "Adding the vagrant user to the docker group"
537   usermod -a -G docker vagrant
538 else
539   cp /etc/ssl/certs/arvados-snakeoil-ca.pem ${SCRIPT_DIR}/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
540 fi
541
542 # Test that the installation finished correctly
543 if [ "x${TEST}" = "xyes" ]; then
544   cd /tmp/cluster_tests
545   ./run-test.sh
546 fi