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