3 # Copyright (C) The Arvados Authors. All rights reserved.
5 # SPDX-License-Identifier: CC-BY-SA-3.0
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
15 # capture the directory that the script is running from
16 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
20 echo >&2 "Usage: ${0} [-h] [-h]"
22 echo >&2 "${0} options:"
23 echo >&2 " -d, --debug Run salt installation in debug mode"
24 echo >&2 " -p <N>, --ssl-port <N> SSL port to use for the web applications"
25 echo >&2 " -c <local.params>, --config <local.params> Path to the local.params config file"
26 echo >&2 " -t, --test Test installation running a CWL workflow"
27 echo >&2 " -r, --roles List of Arvados roles to apply to the host, comma separated"
28 echo >&2 " Possible values are:"
30 echo >&2 " controller"
34 echo >&2 " workbench2"
38 echo >&2 " dispatcher"
39 echo >&2 " Defaults to applying them all"
40 echo >&2 " -h, --help Display this help and exit"
41 echo >&2 " -v, --vagrant Run in vagrant and use the /vagrant shared dir"
46 # NOTE: This requires GNU getopt (part of the util-linux package on Debian-based distros).
47 TEMP=$(getopt -o c:dhp:r:tv \
48 --long config:,debug,help,ssl-port:,roles:,test,vagrant \
51 if [ ${?} != 0 ] ; then echo "GNU getopt missing? Use -h for help"; exit 1 ; fi
52 # Note the quotes around `$TEMP': they are essential!
55 while [ ${#} -ge 1 ]; do
66 CONTROLLER_EXT_SSL_PORT=${2}
72 # Verify the role exists
73 if [[ ! "database,api,controller,keepstore,websocket,keepweb,workbench2,keepproxy,shell,workbench,dispatcher" == *"$i"* ]]; then
74 echo "The role '${i}' is not a valid role"
102 CONFIG="${SCRIPT_DIR}/local.params"
103 CONFIG_DIR="config_examples/single_host/multiple_hostnames"
105 CONTROLLER_EXT_SSL_PORT=443
111 HOSTNAME_INT="127.0.1.1"
113 INITIAL_USER_EMAIL=""
114 INITIAL_USER_PASSWORD=""
116 CONTROLLER_EXT_SSL_PORT=8000
117 KEEP_EXT_SSL_PORT=25101
118 # Both for collections and downloads
119 KEEPWEB_EXT_SSL_PORT=9002
120 WEBSHELL_EXT_SSL_PORT=4202
121 WEBSOCKET_EXT_SSL_PORT=8002
122 WORKBENCH1_EXT_SSL_PORT=443
123 WORKBENCH2_EXT_SSL_PORT=3001
128 POSTGRES_TAG="v0.41.3"
137 F_DIR="/srv/formulas"
143 if [ -s ${CONFIG_FILE} ]; then
144 source ${CONFIG_FILE}
146 echo >&2 "Please create a '${CONFIG_FILE}' file with initial values, as described in FIXME_URL_TO_DESCR"
150 if ! grep -E '^[[:alnum:]]{5}$' <<<${CLUSTER} ; then
151 echo >&2 "ERROR: <CLUSTER> must be exactly 5 alphanumeric characters long"
152 echo >&2 "Fix the cluster name in the 'local.params' file and re-run the provision script"
157 apt-get install -y curl git jq
159 if [ which salt-call ]; then
160 echo "Salt already installed"
162 curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh
163 sh /tmp/bootstrap_salt.sh -XdfP -x python3
164 /bin/systemctl stop salt-minion.service
165 /bin/systemctl disable salt-minion.service
168 # Set salt to masterless mode
169 cat > /etc/salt/minion << EOFSM
181 mkdir -p ${S_DIR} ${F_DIR} ${P_DIR}
183 # Get the formula and dependencies
184 cd ${F_DIR} || exit 1
185 git clone --branch "${ARVADOS_TAG}" https://github.com/arvados/arvados-formula.git
186 git clone --branch "${DOCKER_TAG}" https://github.com/saltstack-formulas/docker-formula.git
187 git clone --branch "${LOCALE_TAG}" https://github.com/saltstack-formulas/locale-formula.git
188 git clone --branch "${NGINX_TAG}" https://github.com/saltstack-formulas/nginx-formula.git
189 git clone --branch "${POSTGRES_TAG}" https://github.com/saltstack-formulas/postgres-formula.git
191 if [ "x${BRANCH}" != "x" ]; then
192 cd ${F_DIR}/arvados-formula || exit 1
193 git checkout -t origin/"${BRANCH}"
197 if [ "x${VAGRANT}" = "xyes" ]; then
198 SOURCE_PILLARS_DIR="/vagrant/${CONFIG_DIR}/pillars"
199 TESTS_DIR="/vagrant/${TESTS_DIR}"
201 SOURCE_PILLARS_DIR="${SCRIPT_DIR}/${CONFIG_DIR}/pillars"
202 TESTS_DIR="${SCRIPT_DIR}/${TESTS_DIR}"
205 SOURCE_STATES_DIR="${EXTRA_STATES_DIR}"
207 # Replace variables (cluster, domain, etc) in the pillars, states and tests
208 # to ease deployment for newcomers
209 for f in "${SOURCE_PILLARS_DIR}"/*; do
210 sed "s/__ANONYMOUS_USER_TOKEN__/${ANONYMOUS_USER_TOKEN}/g;
211 s/__BLOB_SIGNING_KEY__/${BLOB_SIGNING_KEY}/g;
212 s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
213 s/__CLUSTER__/${CLUSTER}/g;
214 s/__DOMAIN__/${DOMAIN}/g;
215 s/__HOSTNAME_EXT__/${HOSTNAME_EXT}/g;
216 s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
217 s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
218 s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g;
219 s/__INITIAL_USER__/${INITIAL_USER}/g;
220 s/__KEEPWEB_EXT_SSL_PORT__/${KEEPWEB_EXT_SSL_PORT}/g;
221 s/__KEEP_EXT_SSL_PORT__/${KEEP_EXT_SSL_PORT}/g;
222 s/__MANAGEMENT_TOKEN__/${MANAGEMENT_TOKEN}/g;
223 s/__RELEASE__/${RELEASE}/g;
224 s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g;
225 s/__VERSION__/${VERSION}/g;
226 s/__WEBSHELL_EXT_SSL_PORT__/${WEBSHELL_EXT_SSL_PORT}/g;
227 s/__WEBSOCKET_EXT_SSL_PORT__/${WEBSOCKET_EXT_SSL_PORT}/g;
228 s/__WORKBENCH1_EXT_SSL_PORT__/${WORKBENCH1_EXT_SSL_PORT}/g;
229 s/__WORKBENCH2_EXT_SSL_PORT__/${WORKBENCH2_EXT_SSL_PORT}/g;
230 s/__WORKBENCH_SECRET_KEY__/${WORKBENCH_SECRET_KEY}/g" \
231 "${f}" > "${P_DIR}"/$(basename "${f}")
234 mkdir -p /tmp/cluster_tests
235 # Replace cluster and domain name in the test files
236 for f in "${TESTS_DIR}"/*; do
237 sed "s/__CLUSTER__/${CLUSTER}/g;
238 s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
239 s/__DOMAIN__/${DOMAIN}/g;
240 s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
241 s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
242 s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g
243 s/__INITIAL_USER__/${INITIAL_USER}/g;
244 s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g" \
245 "${f}" > "/tmp/cluster_tests"/$(basename "${f}")
247 chmod 755 /tmp/cluster_tests/run-test.sh
249 # Replace helper state files that differ from the formula's examples
250 if [ -d "${SOURCE_STATES_DIR}" ]; then
251 mkdir -p "${F_DIR}"/extra/extra
253 for f in "${SOURCE_STATES_DIR}"/*; do
254 sed "s/__ANONYMOUS_USER_TOKEN__/${ANONYMOUS_USER_TOKEN}/g;
255 s/__CLUSTER__/${CLUSTER}/g;
256 s/__BLOB_SIGNING_KEY__/${BLOB_SIGNING_KEY}/g;
257 s/__CONTROLLER_EXT_SSL_PORT__/${CONTROLLER_EXT_SSL_PORT}/g;
258 s/__DOMAIN__/${DOMAIN}/g;
259 s/__HOSTNAME_EXT__/${HOSTNAME_EXT}/g;
260 s/__HOSTNAME_INT__/${HOSTNAME_INT}/g;
261 s/__INITIAL_USER_EMAIL__/${INITIAL_USER_EMAIL}/g;
262 s/__INITIAL_USER_PASSWORD__/${INITIAL_USER_PASSWORD}/g;
263 s/__INITIAL_USER__/${INITIAL_USER}/g;
264 s/__KEEPWEB_EXT_SSL_PORT__/${KEEPWEB_EXT_SSL_PORT}/g;
265 s/__KEEP_EXT_SSL_PORT__/${KEEP_EXT_SSL_PORT}/g;
266 s/__MANAGEMENT_TOKEN__/${MANAGEMENT_TOKEN}/g;
267 s/__RELEASE__/${RELEASE}/g;
268 s/__SYSTEM_ROOT_TOKEN__/${SYSTEM_ROOT_TOKEN}/g;
269 s/__VERSION__/${VERSION}/g;
270 s/__WEBSHELL_EXT_SSL_PORT__/${WEBSHELL_EXT_SSL_PORT}/g;
271 s/__WEBSOCKET_EXT_SSL_PORT__/${WEBSOCKET_EXT_SSL_PORT}/g;
272 s/__WORKBENCH1_EXT_SSL_PORT__/${WORKBENCH1_EXT_SSL_PORT}/g;
273 s/__WORKBENCH2_EXT_SSL_PORT__/${WORKBENCH2_EXT_SSL_PORT}/g;
274 s/__WORKBENCH_SECRET_KEY__/${WORKBENCH_SECRET_KEY}/g" \
275 "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}")
279 # Now, we build the SALT states/pillars trees
281 cat > ${S_DIR}/top.sls << EOFTSLS
287 if [ -d "${SOURCE_STATES_DIR}" ]; then
288 for f in "${F_DIR}"/extra/extra/*.sls; do
289 echo " - extra.$(basename ${f} | sed 's/.sls$//g')" >> ${S_DIR}/top.sls
293 # If we want specific roles for a node, just add the desired states
294 # and its dependencies
295 if [ -z "${ROLES}" ]; then
296 echo ' - nginx.passenger' >> ${S_DIR}/top.sls
297 echo ' - postgres' >> ${S_DIR}/top.sls
298 echo ' - docker' >> ${S_DIR}/top.sls
299 echo ' - arvados' >> ${S_DIR}/top.sls
301 # If we add individual roles, make sure we add the repo first
302 echo " - arvados.repo" >> ${S_DIR}/top.sls
303 for R in ${ROLES}; do
306 echo " - postgres" >> ${S_DIR}/top.sls
309 # FIXME: https://dev.arvados.org/issues/17352
310 grep -q "postgres.client" ${S_DIR}/top.sls || echo " - postgres.client" >> ${S_DIR}/top.sls
311 grep -q "nginx.passenger" ${S_DIR}/top.sls || echo " - nginx.passenger" >> ${S_DIR}/top.sls
312 echo " - arvados.${R}" >> ${S_DIR}/top.sls
314 "workbench" | "workbench2" | "keepweb" | "keepproxy")
315 grep -q "nginx.passenger" ${S_DIR}/top.sls || echo " - nginx.passenger" >> ${S_DIR}/top.sls
316 echo " - arvados.${R}" >> ${S_DIR}/top.sls
318 "shell" | "dispatcher")
319 grep -q "docker" ${S_DIR}/top.sls || echo " - docker" >> ${S_DIR}/top.sls
320 echo " - arvados.${R}" >> ${S_DIR}/top.sls
323 echo " - arvados.${R}" >> ${S_DIR}/top.sls
330 cat > ${P_DIR}/top.sls << EOFPSLS
336 - nginx_api_configuration
337 - nginx_controller_configuration
338 - nginx_keepproxy_configuration
339 - nginx_keepweb_configuration
341 - nginx_websocket_configuration
342 - nginx_webshell_configuration
343 - nginx_workbench2_configuration
344 - nginx_workbench_configuration
348 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
349 if [ -e /root/.psqlrc ]; then
350 if ! ( grep 'pset pager off' /root/.psqlrc ); then
352 cp /root/.psqlrc /root/.psqlrc.provision.backup
358 echo '\pset pager off' >> /root/.psqlrc
359 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
361 # Now run the install
362 salt-call --local state.apply -l ${LOG_LEVEL}
364 # FIXME! #16992 Temporary fix for psql call in arvados-api-server
365 if [ "x${DELETE_PSQL}" = "xyes" ]; then
366 echo "Removing .psql file"
370 if [ "x${RESTORE_PSQL}" = "xyes" ]; then
371 echo "Restoring .psql file"
372 mv -v /root/.psqlrc.provision.backup /root/.psqlrc
374 # END FIXME! #16992 Temporary fix for psql call in arvados-api-server
376 # Leave a copy of the Arvados CA so the user can copy it where it's required
377 echo "Copying the Arvados CA certificate to the installer dir, so you can import it"
378 # If running in a vagrant VM, also add default user to docker group
379 if [ "x${VAGRANT}" = "xyes" ]; then
380 cp /etc/ssl/certs/arvados-snakeoil-ca.pem /vagrant/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
382 echo "Adding the vagrant user to the docker group"
383 usermod -a -G docker vagrant
385 cp /etc/ssl/certs/arvados-snakeoil-ca.pem ${SCRIPT_DIR}/${CLUSTER}.${DOMAIN}-arvados-snakeoil-ca.pem
388 # Test that the installation finished correctly
389 if [ "x${TEST}" = "xyes" ]; then
390 cd /tmp/cluster_tests