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 RELEASE="production"
167 VERSION="2.2.2-1"
168
169 # These are arvados-formula-related parameters
170 # An arvados-formula tag. For a stable release, this should be a
171 # branch name (e.g. X.Y-dev) or tag for the release.
172 ARVADOS_TAG="2.2-dev"
173
174 # Other formula versions we depend on
175 POSTGRES_TAG="v0.41.6"
176 NGINX_TAG="temp-fix-missing-statements-in-pillar"
177 DOCKER_TAG="v1.0.0"
178 LOCALE_TAG="v0.3.4"
179 LETSENCRYPT_TAG="v2.1.0"
180
181 # Salt's dir
182 DUMP_SALT_CONFIG_DIR=""
183 ## states
184 S_DIR="/srv/salt"
185 ## formulas
186 F_DIR="/srv/formulas"
187 ## pillars
188 P_DIR="/srv/pillars"
189 ## tests
190 T_DIR="/tmp/cluster_tests"
191
192 arguments ${@}
193
194 if [ -s ${CONFIG_FILE} ]; then
195   source ${CONFIG_FILE}
196 else
197   echo >&2 "You don't seem to have a config file with initial values."
198   echo >&2 "Please create a '${CONFIG_FILE}' file as described in"
199   echo >&2 "  * https://doc.arvados.org/install/salt-single-host.html#single_host, or"
200   echo >&2 "  * https://doc.arvados.org/install/salt-multi-host.html#multi_host_multi_hostnames"
201   exit 1
202 fi
203
204 if [ ! -d ${CONFIG_DIR} ]; then
205   echo >&2 "You don't seem to have a config directory with pillars and states."
206   echo >&2 "Please create a '${CONFIG_DIR}' directory (as configured in your '${CONFIG_FILE}'). Please see"
207   echo >&2 "  * https://doc.arvados.org/install/salt-single-host.html#single_host, or"
208   echo >&2 "  * https://doc.arvados.org/install/salt-multi-host.html#multi_host_multi_hostnames"
209   exit 1
210 fi
211
212 if grep -q 'fixme_or_this_wont_work' ${CONFIG_FILE} ; then
213   echo >&2 "The config file ${CONFIG_FILE} has some parameters that need to be modified."
214   echo >&2 "Please, fix them and re-run the provision script."
215   exit 1
216 fi
217
218 if ! grep -qE '^[[:alnum:]]{5}$' <<<${CLUSTER} ; then
219   echo >&2 "ERROR: <CLUSTER> must be exactly 5 alphanumeric characters long"
220   echo >&2 "Fix the cluster name in the 'local.params' file and re-run the provision script"
221   exit 1
222 fi
223
224 # Only used in single_host/single_name deploys
225 if [ "x${HOSTNAME_EXT}" = "x" ] ; then
226   HOSTNAME_EXT="${CLUSTER}.${DOMAIN}"
227 fi
228
229 if [ "${DUMP_CONFIG}" = "yes" ]; then
230   echo "The provision installer will just dump a config under ${DUMP_SALT_CONFIG_DIR} and exit"
231 else
232   apt-get update
233   apt-get install -y curl git jq
234
235   if which salt-call; then
236     echo "Salt already installed"
237   else
238     curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh
239     sh /tmp/bootstrap_salt.sh -XdfP -x python3
240     /bin/systemctl stop salt-minion.service
241     /bin/systemctl disable salt-minion.service
242   fi
243
244   # Set salt to masterless mode
245   cat > /etc/salt/minion << EOFSM
246 file_client: local
247 file_roots:
248   base:
249     - ${S_DIR}
250     - ${F_DIR}/*
251
252 pillar_roots:
253   base:
254     - ${P_DIR}
255 EOFSM
256 fi
257
258 mkdir -p ${S_DIR} ${F_DIR} ${P_DIR} ${T_DIR}
259
260 # Get the formula and dependencies
261 cd ${F_DIR} || exit 1
262 echo "Cloning formulas"
263 rm -rf ${F_DIR}/* || exit 1
264 git clone --quiet https://github.com/saltstack-formulas/docker-formula.git ${F_DIR}/docker
265 ( cd docker && git checkout --quiet tags/"${DOCKER_TAG}" -b "${DOCKER_TAG}" )
266
267 git clone --quiet https://github.com/saltstack-formulas/locale-formula.git ${F_DIR}/locale
268 ( cd locale && git checkout --quiet tags/"${LOCALE_TAG}" -b "${LOCALE_TAG}" )
269
270 git clone --quiet https://github.com/netmanagers/nginx-formula.git ${F_DIR}/nginx
271 ( cd nginx && git checkout --quiet tags/"${NGINX_TAG}" -b "${NGINX_TAG}" )
272
273 git clone --quiet https://github.com/saltstack-formulas/postgres-formula.git ${F_DIR}/postgres
274 ( cd postgres && git checkout --quiet tags/"${POSTGRES_TAG}" -b "${POSTGRES_TAG}" )
275
276 git clone --quiet https://github.com/saltstack-formulas/letsencrypt-formula.git ${F_DIR}/letsencrypt
277 ( cd letsencrypt && git checkout --quiet tags/"${LETSENCRYPT_TAG}" -b "${LETSENCRYPT_TAG}" )
278
279 git clone --quiet https://git.arvados.org/arvados-formula.git ${F_DIR}/arvados
280
281 # If we want to try a specific branch of the formula
282 if [ "x${BRANCH}" != "x" ]; then
283   ( cd ${F_DIR}/arvados && git checkout --quiet -t origin/"${BRANCH}" -b "${BRANCH}" )
284 elif [ "x${ARVADOS_TAG}" != "x" ]; then
285 ( cd ${F_DIR}/arvados && git checkout --quiet tags/"${ARVADOS_TAG}" -b "${ARVADOS_TAG}" )
286 fi
287
288 if [ "x${VAGRANT}" = "xyes" ]; then
289   EXTRA_STATES_DIR="/home/vagrant/${CONFIG_DIR}/states"
290   SOURCE_PILLARS_DIR="/home/vagrant/${CONFIG_DIR}/pillars"
291   SOURCE_TESTS_DIR="/home/vagrant/${TESTS_DIR}"
292 else
293   EXTRA_STATES_DIR="${SCRIPT_DIR}/${CONFIG_DIR}/states"
294   SOURCE_PILLARS_DIR="${SCRIPT_DIR}/${CONFIG_DIR}/pillars"
295   SOURCE_TESTS_DIR="${SCRIPT_DIR}/${TESTS_DIR}"
296 fi
297
298 SOURCE_STATES_DIR="${EXTRA_STATES_DIR}"
299
300 echo "Writing pillars and states"
301
302 # Replace variables (cluster,  domain, etc) in the pillars, states and tests
303 # to ease deployment for newcomers
304 if [ ! -d "${SOURCE_PILLARS_DIR}" ]; then
305   echo "${SOURCE_PILLARS_DIR} does not exist or is not a directory. Exiting."
306   exit 1
307 fi
308 for f in $(ls "${SOURCE_PILLARS_DIR}"/*); do
309   sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
310        s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
311        s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
312        s#__CLUSTER__#${CLUSTER}#g;
313        s#__DOMAIN__#${DOMAIN}#g;
314        s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
315        s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
316        s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
317        s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
318        s#__INITIAL_USER__#${INITIAL_USER}#g;
319        s#__LE_AWS_REGION__#${LE_AWS_REGION}#g;
320        s#__LE_AWS_SECRET_ACCESS_KEY__#${LE_AWS_SECRET_ACCESS_KEY}#g;
321        s#__LE_AWS_ACCESS_KEY_ID__#${LE_AWS_ACCESS_KEY_ID}#g;
322        s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
323        s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
324        s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
325        s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
326        s#__RELEASE__#${RELEASE}#g;
327        s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
328        s#__VERSION__#${VERSION}#g;
329        s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
330        s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
331        s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
332        s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
333        s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
334        s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
335        s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
336        s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
337        s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
338        s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
339        s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
340        s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
341        s#__SHELL_INT_IP__#${SHELL_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#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
346   "${f}" > "${P_DIR}"/$(basename "${f}")
347 done
348
349 if [ "x${TEST}" = "xyes" ] && [ ! -d "${SOURCE_TESTS_DIR}" ]; then
350   echo "You requested to run tests, but ${SOURCE_TESTS_DIR} does not exist or is not a directory. Exiting."
351   exit 1
352 fi
353 mkdir -p ${T_DIR}
354 # Replace cluster and domain name in the test files
355 for f in $(ls "${SOURCE_TESTS_DIR}"/*); do
356   sed "s#__CLUSTER__#${CLUSTER}#g;
357        s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
358        s#__DOMAIN__#${DOMAIN}#g;
359        s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
360        s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
361        s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g
362        s#__INITIAL_USER__#${INITIAL_USER}#g;
363        s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
364        s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g" \
365   "${f}" > ${T_DIR}/$(basename "${f}")
366 done
367 chmod 755 ${T_DIR}/run-test.sh
368
369 # Replace helper state files that differ from the formula's examples
370 if [ -d "${SOURCE_STATES_DIR}" ]; then
371   mkdir -p "${F_DIR}"/extra/extra
372
373   for f in $(ls "${SOURCE_STATES_DIR}"/*); do
374     sed "s#__ANONYMOUS_USER_TOKEN__#${ANONYMOUS_USER_TOKEN}#g;
375          s#__CLUSTER__#${CLUSTER}#g;
376          s#__BLOB_SIGNING_KEY__#${BLOB_SIGNING_KEY}#g;
377          s#__CONTROLLER_EXT_SSL_PORT__#${CONTROLLER_EXT_SSL_PORT}#g;
378          s#__DOMAIN__#${DOMAIN}#g;
379          s#__HOSTNAME_EXT__#${HOSTNAME_EXT}#g;
380          s#__HOSTNAME_INT__#${HOSTNAME_INT}#g;
381          s#__INITIAL_USER_EMAIL__#${INITIAL_USER_EMAIL}#g;
382          s#__INITIAL_USER_PASSWORD__#${INITIAL_USER_PASSWORD}#g;
383          s#__INITIAL_USER__#${INITIAL_USER}#g;
384          s#__DATABASE_PASSWORD__#${DATABASE_PASSWORD}#g;
385          s#__KEEPWEB_EXT_SSL_PORT__#${KEEPWEB_EXT_SSL_PORT}#g;
386          s#__KEEP_EXT_SSL_PORT__#${KEEP_EXT_SSL_PORT}#g;
387          s#__MANAGEMENT_TOKEN__#${MANAGEMENT_TOKEN}#g;
388          s#__RELEASE__#${RELEASE}#g;
389          s#__SYSTEM_ROOT_TOKEN__#${SYSTEM_ROOT_TOKEN}#g;
390          s#__VERSION__#${VERSION}#g;
391          s#__CLUSTER_INT_CIDR__#${CLUSTER_INT_CIDR}#g;
392          s#__CONTROLLER_INT_IP__#${CONTROLLER_INT_IP}#g;
393          s#__WEBSOCKET_INT_IP__#${WEBSOCKET_INT_IP}#g;
394          s#__KEEP_INT_IP__#${KEEP_INT_IP}#g;
395          s#__KEEPSTORE0_INT_IP__#${KEEPSTORE0_INT_IP}#g;
396          s#__KEEPSTORE1_INT_IP__#${KEEPSTORE1_INT_IP}#g;
397          s#__KEEPWEB_INT_IP__#${KEEPWEB_INT_IP}#g;
398          s#__WEBSHELL_INT_IP__#${WEBSHELL_INT_IP}#g;
399          s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
400          s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
401          s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
402          s#__WEBSHELL_EXT_SSL_PORT__#${WEBSHELL_EXT_SSL_PORT}#g;
403          s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
404          s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
405          s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
406          s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
407     "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}")
408   done
409 fi
410
411 # Now, we build the SALT states/pillars trees
412 # As we need to separate both states and pillars in case we want specific
413 # roles, we iterate on both at the same time
414
415 # States
416 cat > ${S_DIR}/top.sls << EOFTSLS
417 base:
418   '*':
419     - locale
420 EOFTSLS
421
422 # Pillars
423 cat > ${P_DIR}/top.sls << EOFPSLS
424 base:
425   '*':
426     - locale
427     - arvados
428 EOFPSLS
429
430 # States, extra states
431 if [ -d "${F_DIR}"/extra/extra ]; then
432   for f in $(ls "${F_DIR}"/extra/extra/*.sls); do
433   echo "    - extra.$(basename ${f} | sed 's/.sls$//g')" >> ${S_DIR}/top.sls
434   done
435 fi
436
437 # If we want specific roles for a node, just add the desired states
438 # and its dependencies
439 if [ -z "${ROLES}" ]; then
440   # States
441   echo "    - nginx.passenger" >> ${S_DIR}/top.sls
442   # Currently, only available on config_examples/multi_host/aws
443   if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
444     if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
445       grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
446     fi
447     grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
448   fi
449   echo "    - postgres" >> ${S_DIR}/top.sls
450   echo "    - docker.software" >> ${S_DIR}/top.sls
451   echo "    - arvados" >> ${S_DIR}/top.sls
452
453   # Pillars
454   echo "    - docker" >> ${P_DIR}/top.sls
455   echo "    - nginx_api_configuration" >> ${P_DIR}/top.sls
456   echo "    - nginx_controller_configuration" >> ${P_DIR}/top.sls
457   echo "    - nginx_keepproxy_configuration" >> ${P_DIR}/top.sls
458   echo "    - nginx_keepweb_configuration" >> ${P_DIR}/top.sls
459   echo "    - nginx_passenger" >> ${P_DIR}/top.sls
460   echo "    - nginx_websocket_configuration" >> ${P_DIR}/top.sls
461   echo "    - nginx_webshell_configuration" >> ${P_DIR}/top.sls
462   echo "    - nginx_workbench2_configuration" >> ${P_DIR}/top.sls
463   echo "    - nginx_workbench_configuration" >> ${P_DIR}/top.sls
464   echo "    - postgresql" >> ${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   fi
472 else
473   # If we add individual roles, make sure we add the repo first
474   echo "    - arvados.repo" >> ${S_DIR}/top.sls
475   for R in ${ROLES}; do
476     case "${R}" in
477       "database")
478         # States
479         echo "    - postgres" >> ${S_DIR}/top.sls
480         # Pillars
481         echo '    - postgresql' >> ${P_DIR}/top.sls
482       ;;
483       "api")
484         # States
485         # FIXME: https://dev.arvados.org/issues/17352
486         grep -q "postgres.client" ${S_DIR}/top.sls || echo "    - postgres.client" >> ${S_DIR}/top.sls
487         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
488         ### If we don't install and run LE before arvados-api-server, it fails and breaks everything
489         ### after it so we add this here, as we are, after all, sharing the host for api and controller
490         # Currently, only available on config_examples/multi_host/aws
491         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
492           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
493             grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
494           fi
495           grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
496         fi
497         grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
498         # Pillars
499         grep -q "aws_credentials" ${P_DIR}/top.sls          || echo "    - aws_credentials" >> ${P_DIR}/top.sls
500         grep -q "docker" ${P_DIR}/top.sls                   || echo "    - docker" >> ${P_DIR}/top.sls
501         grep -q "postgresql" ${P_DIR}/top.sls               || echo "    - postgresql" >> ${P_DIR}/top.sls
502         grep -q "nginx_passenger" ${P_DIR}/top.sls          || echo "    - nginx_passenger" >> ${P_DIR}/top.sls
503         grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo "    - nginx_${R}_configuration" >> ${P_DIR}/top.sls
504       ;;
505       "controller" | "websocket" | "workbench" | "workbench2" | "webshell" | "keepweb" | "keepproxy")
506         # States
507         grep -q "nginx.passenger" ${S_DIR}/top.sls || echo "    - nginx.passenger" >> ${S_DIR}/top.sls
508         # Currently, only available on config_examples/multi_host/aws
509         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
510           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
511             grep -q "aws_credentials" ${S_DIR}/top.sls || echo "    - aws_credentials" >> ${S_DIR}/top.sls
512           fi
513           grep -q "letsencrypt"     ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
514         fi
515         # webshell role is just a nginx vhost, so it has no state
516         if [ "${R}" != "webshell" ]; then
517           grep -q "arvados.${R}" ${S_DIR}/top.sls    || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
518         fi
519         # Pillars
520         grep -q "nginx_passenger" ${P_DIR}/top.sls          || echo "    - nginx_passenger" >> ${P_DIR}/top.sls
521         grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo "    - nginx_${R}_configuration" >> ${P_DIR}/top.sls
522         # Currently, only available on config_examples/multi_host/aws
523         if [ "x${USE_LETSENCRYPT}" = "xyes" ]; then
524           if [ "x${USE_LETSENCRYPT_IAM_USER}" = "xyes" ]; then
525             grep -q "aws_credentials" ${P_DIR}/top.sls || echo "    - aws_credentials" >> ${P_DIR}/top.sls
526           fi
527           grep -q "letsencrypt"     ${P_DIR}/top.sls || echo "    - letsencrypt" >> ${P_DIR}/top.sls
528           grep -q "letsencrypt_${R}_configuration" ${P_DIR}/top.sls || echo "    - letsencrypt_${R}_configuration" >> ${P_DIR}/top.sls
529         fi
530       ;;
531       "shell")
532         # States
533         grep -q "docker" ${S_DIR}/top.sls       || echo "    - docker.software" >> ${S_DIR}/top.sls
534         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
535         # Pillars
536         grep -q "" ${P_DIR}/top.sls                             || echo "    - docker" >> ${P_DIR}/top.sls
537       ;;
538       "dispatcher")
539         # States
540         grep -q "docker" ${S_DIR}/top.sls       || echo "    - docker.software" >> ${S_DIR}/top.sls
541         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
542         # Pillars
543         # ATM, no specific pillar needed
544       ;;
545       "keepstore")
546         # States
547         grep -q "arvados.${R}" ${S_DIR}/top.sls || echo "    - arvados.${R}" >> ${S_DIR}/top.sls
548         # Pillars
549         # ATM, no specific pillar needed
550       ;;
551       *)
552         echo "Unknown role ${R}"
553         exit 1
554       ;;
555     esac
556   done
557 fi
558
559 if [ "${DUMP_CONFIG}" = "yes" ]; then
560   # We won't run the rest of the script because we're just dumping the config
561   exit 0
562 fi
563
564 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
565 if [ -e /root/.psqlrc ]; then
566   if ! ( grep 'pset pager off' /root/.psqlrc ); then
567     RESTORE_PSQL="yes"
568     cp /root/.psqlrc /root/.psqlrc.provision.backup
569   fi
570 else
571   DELETE_PSQL="yes"
572 fi
573
574 echo '\pset pager off' >> /root/.psqlrc
575 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
576
577 # Now run the install
578 salt-call --local state.apply -l ${LOG_LEVEL}
579
580 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
581 if [ "x${DELETE_PSQL}" = "xyes" ]; then
582   echo "Removing .psql file"
583   rm /root/.psqlrc
584 fi
585
586 if [ "x${RESTORE_PSQL}" = "xyes" ]; then
587   echo "Restoring .psql file"
588   mv -v /root/.psqlrc.provision.backup /root/.psqlrc
589 fi
590 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
591
592 # Leave a copy of the Arvados CA so the user can copy it where it's required
593 echo "Copying the Arvados CA certificate to the installer dir, so you can import it"
594 # If running in a vagrant VM, also add default user to docker group
595 if [ "x${VAGRANT}" = "xyes" ]; then
596   cp /etc/ssl/certs/arvados-snakeoil-ca.pem /vagrant/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
597
598   echo "Adding the vagrant user to the docker group"
599   usermod -a -G docker vagrant
600 else
601   cp /etc/ssl/certs/arvados-snakeoil-ca.pem ${SCRIPT_DIR}/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
602 fi
603
604 # Test that the installation finished correctly
605 if [ "x${TEST}" = "xyes" ]; then
606   cd ${T_DIR}
607   ./run-test.sh
608 fi