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