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