X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/c9f861e832edf6dd03433b576218f2e56d9e3a36..eb6f1aca749391e603911b92f6f04ae9c24cbffb:/tools/salt-install/provision.sh diff --git a/tools/salt-install/provision.sh b/tools/salt-install/provision.sh index f90386652b..7f17cf8c00 100755 --- a/tools/salt-install/provision.sh +++ b/tools/salt-install/provision.sh @@ -10,6 +10,7 @@ # # vagrant up +set -eu set -o pipefail # capture the directory that the script is running from @@ -26,6 +27,7 @@ usage() { echo >&2 " -r, --roles List of Arvados roles to apply to the host, comma separated" echo >&2 " Possible values are:" echo >&2 " api" + echo >&2 " balancer" echo >&2 " controller" echo >&2 " dispatcher" echo >&2 " keepproxy" @@ -109,12 +111,12 @@ arguments() { for i in ${2//,/ } do # Verify the role exists - if [[ ! "database,api,controller,keepstore,websocket,keepweb,workbench2,webshell,keepbalance,keepproxy,shell,workbench,dispatcher,monitoring" == *"$i"* ]]; then + if [[ ! "database,api,balancer,controller,keepstore,websocket,keepweb,workbench2,webshell,keepbalance,keepproxy,shell,workbench,dispatcher,monitoring" == *"$i"* ]]; then echo "The role '${i}' is not a valid role" usage exit 1 fi - ROLES="${ROLES} ${i}" + ROLES="${ROLES:-} ${i}" done shift 2 ;; @@ -240,16 +242,10 @@ T_DIR="/tmp/cluster_tests" arguments ${@} declare -A NODES +declare -A ROLES +declare NODELIST -if [ -s ${CONFIG_FILE} ]; then - source ${CONFIG_FILE} -else - echo >&2 "You don't seem to have a config file with initial values." - echo >&2 "Please create a '${CONFIG_FILE}' file as described in" - echo >&2 " * https://doc.arvados.org/install/salt-single-host.html#single_host, or" - echo >&2 " * https://doc.arvados.org/install/salt-multi-host.html#multi_host_multi_hostnames" - exit 1 -fi +source common.sh if [ ! -d ${CONFIG_DIR} ]; then echo >&2 "You don't seem to have a config directory with pillars and states." @@ -259,8 +255,8 @@ if [ ! -d ${CONFIG_DIR} ]; then exit 1 fi -if grep -rni 'fixme' ${CONFIG_FILE} ${CONFIG_DIR} ; then - echo >&2 "The config file ${CONFIG_FILE} has some parameters that need to be modified." +if grep -rni 'fixme' ${CONFIG_FILE}.secrets ${CONFIG_FILE} ${CONFIG_DIR} ; then + echo >&2 "The config files has some parameters that need to be modified." echo >&2 "Please, fix them and re-run the provision script." exit 1 fi @@ -272,7 +268,7 @@ if ! grep -qE '^[[:alnum:]]{5}$' <<<${CLUSTER} ; then fi # Only used in single_host/single_name deploys -if [ ! -z "${HOSTNAME_EXT}" ] ; then +if [ ! -z "${HOSTNAME_EXT:-}" ] ; then # We need to add some extra control vars to manage a single certificate vs. multiple USE_SINGLE_HOSTNAME="yes" # Make sure that the value configured as IP_INT is a real IP on the system. @@ -318,7 +314,7 @@ else echo "Salt already installed" else curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh - sh /tmp/bootstrap_salt.sh -XdfP -x python3 stable ${SALT_VERSION} + sh /tmp/bootstrap_salt.sh -XdfP -x python3 old-stable ${SALT_VERSION} /bin/systemctl stop salt-minion.service /bin/systemctl disable salt-minion.service fi @@ -387,13 +383,13 @@ echo "...arvados" test -d arvados || git clone --quiet https://git.arvados.org/arvados-formula.git ${F_DIR}/arvados # If we want to try a specific branch of the formula -if [ "x${BRANCH}" != "x" ]; then +if [ "x${BRANCH:-}" != "x" ]; then ( cd ${F_DIR}/arvados && git checkout --quiet -t origin/"${BRANCH}" -b "${BRANCH}" ) -elif [ "x${ARVADOS_TAG}" != "x" ]; then +elif [ "x${ARVADOS_TAG:-}" != "x" ]; then ( cd ${F_DIR}/arvados && git checkout --quiet tags/"${ARVADOS_TAG}" -b "${ARVADOS_TAG}" ) fi -if [ "x${VAGRANT}" = "xyes" ]; then +if [ "x${VAGRANT:-}" = "xyes" ]; then EXTRA_STATES_DIR="/home/vagrant/${CONFIG_DIR}/states" SOURCE_PILLARS_DIR="/home/vagrant/${CONFIG_DIR}/pillars" SOURCE_TOFS_DIR="/home/vagrant/${CONFIG_DIR}/tofs" @@ -455,17 +451,32 @@ for f in $(ls "${SOURCE_PILLARS_DIR}"/*); do s#__SSL_KEY_ENCRYPTED__#${SSL_KEY_ENCRYPTED}#g; s#__SSL_KEY_AWS_REGION__#${SSL_KEY_AWS_REGION}#g; s#__SSL_KEY_AWS_SECRET_NAME__#${SSL_KEY_AWS_SECRET_NAME}#g; - s#__CONTROLLER_NGINX_WORKERS__#${CONTROLLER_NGINX_WORKERS}#g; - s#__CONTROLLER_MAX_CONCURRENT_REQUESTS__#${CONTROLLER_MAX_CONCURRENT_REQUESTS}#g; + s#__CONTROLLER_NGINX_WORKERS__#${CONTROLLER_NGINX_WORKERS:-}#g; + s#__CONTROLLER_MAX_CONCURRENT_REQUESTS__#${CONTROLLER_MAX_CONCURRENT_REQUESTS:-}#g; s#__MONITORING_USERNAME__#${MONITORING_USERNAME}#g; s#__MONITORING_EMAIL__#${MONITORING_EMAIL}#g; - s#__MONITORING_PASSWORD__#${MONITORING_PASSWORD}#g" \ + s#__MONITORING_PASSWORD__#${MONITORING_PASSWORD}#g; + s#__DISPATCHER_SSH_PRIVKEY__#${DISPATCHER_SSH_PRIVKEY//$'\n'/\\n}#g; + s#__ENABLE_BALANCER__#${ENABLE_BALANCER}#g; + s#__DISABLED_CONTROLLER__#${DISABLED_CONTROLLER}#g; + s#__BALANCER_NODENAME__#${ROLE2NODES['balancer']}#g; + s#__PROMETHEUS_NODENAME__#${ROLE2NODES['monitoring']}#g; + s#__CONTROLLER_NODES__#${ROLE2NODES['controller']}#g; + s#__NODELIST__#${NODELIST}#g; + s#__DISPATCHER_INT_IP__#${DISPATCHER_INT_IP}#g; + s#__KEEPBALANCE_INT_IP__#${KEEPBALANCE_INT_IP}#g; + s#__COMPUTE_AMI__#${COMPUTE_AMI}#g; + s#__COMPUTE_SG__#${COMPUTE_SG}#g; + s#__COMPUTE_SUBNET__#${COMPUTE_SUBNET}#g; + s#__COMPUTE_AWS_REGION__#${COMPUTE_AWS_REGION}#g; + s#__COMPUTE_USER__#${COMPUTE_USER}#g; + s#__KEEP_AWS_REGION__#${KEEP_AWS_REGION}#g" \ "${f}" > "${P_DIR}"/$(basename "${f}") done if [ ! -d "${SOURCE_TESTS_DIR}" ]; then echo "WARNING: The tests directory was not copied to \"${SOURCE_TESTS_DIR}\"." - if [ "x${TEST}" = "xyes" ]; then + if [ "x${TEST:-}" = "xyes" ]; then echo "WARNING: Disabling tests for this installation." fi TEST="no" @@ -534,11 +545,26 @@ if [ -d "${SOURCE_STATES_DIR}" ]; then s#__SSL_KEY_ENCRYPTED__#${SSL_KEY_ENCRYPTED}#g; s#__SSL_KEY_AWS_REGION__#${SSL_KEY_AWS_REGION}#g; s#__SSL_KEY_AWS_SECRET_NAME__#${SSL_KEY_AWS_SECRET_NAME}#g; - s#__CONTROLLER_NGINX_WORKERS__#${CONTROLLER_NGINX_WORKERS}#g; - s#__CONTROLLER_MAX_CONCURRENT_REQUESTS__#${CONTROLLER_MAX_CONCURRENT_REQUESTS}#g; + s#__CONTROLLER_NGINX_WORKERS__#${CONTROLLER_NGINX_WORKERS:-}#g; + s#__CONTROLLER_MAX_CONCURRENT_REQUESTS__#${CONTROLLER_MAX_CONCURRENT_REQUESTS:-}#g; s#__MONITORING_USERNAME__#${MONITORING_USERNAME}#g; s#__MONITORING_EMAIL__#${MONITORING_EMAIL}#g; - s#__MONITORING_PASSWORD__#${MONITORING_PASSWORD}#g" \ + s#__MONITORING_PASSWORD__#${MONITORING_PASSWORD}#g; + s#__DISPATCHER_SSH_PRIVKEY__#${DISPATCHER_SSH_PRIVKEY//$'\n'/\\n}#g; + s#__ENABLE_BALANCER__#${ENABLE_BALANCER}#g; + s#__DISABLED_CONTROLLER__#${DISABLED_CONTROLLER}#g; + s#__BALANCER_NODENAME__#${ROLE2NODES['balancer']}#g; + s#__PROMETHEUS_NODENAME__#${ROLE2NODES['monitoring']}#g; + s#__CONTROLLER_NODES__#${ROLE2NODES['controller']}#g; + s#__NODELIST__#${NODELIST}#g; + s#__DISPATCHER_INT_IP__#${DISPATCHER_INT_IP}#g; + s#__KEEPBALANCE_INT_IP__#${KEEPBALANCE_INT_IP}#g; + s#__COMPUTE_AMI__#${COMPUTE_AMI}#g; + s#__COMPUTE_SG__#${COMPUTE_SG}#g; + s#__COMPUTE_SUBNET__#${COMPUTE_SUBNET}#g; + s#__COMPUTE_AWS_REGION__#${COMPUTE_AWS_REGION}#g; + s#__COMPUTE_USER__#${COMPUTE_USER}#g; + s#__KEEP_AWS_REGION__#${KEEP_AWS_REGION}#g" \ "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}") done fi @@ -753,7 +779,7 @@ else if [ "${SSL_MODE}" = "lets-encrypt" ]; then grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls - if [ "x${USE_LETSENCRYPT_ROUTE53}" = "xyes" ]; then + if [ "x${USE_LETSENCRYPT_ROUTE53:-}" = "xyes" ]; then grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls fi elif [ "${SSL_MODE}" = "bring-your-own" ]; then @@ -801,17 +827,19 @@ else echo " - extra.passenger_rvm" >> ${S_DIR}/top.sls ### If we don't install and run LE before arvados-api-server, it fails and breaks everything ### after it. So we add this here as we are, after all, sharing the host for api and controller - if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then - grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls - fi - grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls - else - # Use custom certs - if [ "${SSL_MODE}" = "bring-your-own" ]; then - copy_custom_cert ${CUSTOM_CERTS_DIR} controller + if [ "${ENABLE_BALANCER}" == "no" ]; then + if [ "${SSL_MODE}" = "lets-encrypt" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then + grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls + fi + grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls + else + # Use custom certs + if [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} controller + fi + grep -q controller ${P_DIR}/extra_custom_certs.sls || echo " - controller" >> ${P_DIR}/extra_custom_certs.sls fi - grep -q controller ${P_DIR}/extra_custom_certs.sls || echo " - controller" >> ${P_DIR}/extra_custom_certs.sls fi grep -q "arvados.${R}" ${S_DIR}/top.sls || echo " - arvados.${R}" >> ${S_DIR}/top.sls # Pillars @@ -825,8 +853,89 @@ else NGINX_INSTALL_SOURCE="install_from_phusionpassenger" sed -i "s/__NGINX_INSTALL_SOURCE__/${NGINX_INSTALL_SOURCE}/g" ${P_DIR}/nginx_passenger.sls ;; - "controller" | "websocket" | "workbench" | "workbench2" | "webshell" | "keepweb" | "keepproxy") - # States + "balancer") + ### States ### + grep -q "\- nginx$" ${S_DIR}/top.sls || echo " - nginx" >> ${S_DIR}/top.sls + + if [ "${SSL_MODE}" = "lets-encrypt" ]; then + grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls + if [ "x${USE_LETSENCRYPT_ROUTE53:-}" = "xyes" ]; then + grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls + fi + elif [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} ${R} + fi + + ### Pillars ### + grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo " - nginx_${R}_configuration" >> ${P_DIR}/top.sls + + if [ "${SSL_MODE}" = "lets-encrypt" ]; then + grep -q "letsencrypt" ${P_DIR}/top.sls || echo " - letsencrypt" >> ${P_DIR}/top.sls + + grep -q "letsencrypt_${R}_configuration" ${P_DIR}/top.sls || echo " - letsencrypt_${R}_configuration" >> ${P_DIR}/top.sls + sed -i "s/__CERT_REQUIRES__/cmd: create-initial-cert-${ROLE2NODES['balancer']}*/g; + s#__CERT_PEM__#/etc/letsencrypt/live/${ROLE2NODES['balancer']}/fullchain.pem#g; + s#__CERT_KEY__#/etc/letsencrypt/live/${ROLE2NODES['balancer']}/privkey.pem#g" \ + ${P_DIR}/nginx_${R}_configuration.sls + + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then + grep -q "aws_credentials" ${P_DIR}/top.sls || echo " - aws_credentials" >> ${P_DIR}/top.sls + fi + elif [ "${SSL_MODE}" = "bring-your-own" ]; then + grep -q "ssl_key_encrypted" ${P_DIR}/top.sls || echo " - ssl_key_encrypted" >> ${P_DIR}/top.sls + sed -i "s/__CERT_REQUIRES__/file: extra_custom_certs_file_copy_arvados-${R}.pem/g; + s#__CERT_PEM__#/etc/nginx/ssl/arvados-${R}.pem#g; + s#__CERT_KEY__#/etc/nginx/ssl/arvados-${R}.key#g" \ + ${P_DIR}/nginx_${R}_configuration.sls + grep -q "${R}" ${P_DIR}/extra_custom_certs.sls || echo " - ${R}" >> ${P_DIR}/extra_custom_certs.sls + fi + ;; + "controller") + ### States ### + grep -q "\- nginx$" ${S_DIR}/top.sls || echo " - nginx" >> ${S_DIR}/top.sls + grep -q "arvados.${R}" ${S_DIR}/top.sls || echo " - arvados.${R}" >> ${S_DIR}/top.sls + + if [ "${ENABLE_BALANCER}" == "no" ]; then + if [ "${SSL_MODE}" = "lets-encrypt" ]; then + if [ "x${USE_LETSENCRYPT_ROUTE53:-}" = "xyes" ]; then + grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls + fi + grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls + elif [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} ${R} + fi + fi + + ### Pillars ### + grep -q "nginx_passenger" ${P_DIR}/top.sls || echo " - nginx_passenger" >> ${P_DIR}/top.sls + grep -q "nginx_${R}_configuration" ${P_DIR}/top.sls || echo " - nginx_${R}_configuration" >> ${P_DIR}/top.sls + + if [ "${ENABLE_BALANCER}" == "no" ]; then + if [ "${SSL_MODE}" = "lets-encrypt" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then + grep -q "aws_credentials" ${P_DIR}/top.sls || echo " - aws_credentials" >> ${P_DIR}/top.sls + fi + + grep -q "letsencrypt" ${P_DIR}/top.sls || echo " - letsencrypt" >> ${P_DIR}/top.sls + grep -q "letsencrypt_${R}_configuration" ${P_DIR}/top.sls || echo " - letsencrypt_${R}_configuration" >> ${P_DIR}/top.sls + sed -i "s/__CERT_REQUIRES__/cmd: create-initial-cert-${R}.${DOMAIN}*/g; + s#__CERT_PEM__#/etc/letsencrypt/live/${R}.${DOMAIN}/fullchain.pem#g; + s#__CERT_KEY__#/etc/letsencrypt/live/${R}.${DOMAIN}/privkey.pem#g" \ + ${P_DIR}/nginx_${R}_configuration.sls + else + grep -q "ssl_key_encrypted" ${P_DIR}/top.sls || echo " - ssl_key_encrypted" >> ${P_DIR}/top.sls + sed -i "s/__CERT_REQUIRES__/file: extra_custom_certs_file_copy_arvados-${R}.pem/g; + s#__CERT_PEM__#/etc/nginx/ssl/arvados-${R}.pem#g; + s#__CERT_KEY__#/etc/nginx/ssl/arvados-${R}.key#g" \ + ${P_DIR}/nginx_${R}_configuration.sls + grep -q ${R} ${P_DIR}/extra_custom_certs.sls || echo " - ${R}" >> ${P_DIR}/extra_custom_certs.sls + fi + fi + # We need to tweak the Nginx's pillar depending whether we want plain nginx or nginx+passenger + sed -i "s/__NGINX_INSTALL_SOURCE__/${NGINX_INSTALL_SOURCE}/g" ${P_DIR}/nginx_passenger.sls + ;; + "websocket" | "workbench" | "workbench2" | "webshell" | "keepweb" | "keepproxy") + ### States ### if [ "${R}" = "workbench" ]; then grep -q " - logrotate" ${S_DIR}/top.sls || echo " - logrotate" >> ${S_DIR}/top.sls NGINX_INSTALL_SOURCE="install_from_phusionpassenger" @@ -838,8 +947,9 @@ else else grep -q "\- nginx$" ${S_DIR}/top.sls || echo " - nginx" >> ${S_DIR}/top.sls fi + if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "x${USE_LETSENCRYPT_ROUTE53}" = "xyes" ]; then + if [ "x${USE_LETSENCRYPT_ROUTE53:-}" = "xyes" ]; then grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls fi grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls @@ -856,11 +966,13 @@ else fi fi fi + # webshell role is just a nginx vhost, so it has no state if [ "${R}" != "webshell" ]; then grep -q "arvados.${R}" ${S_DIR}/top.sls || echo " - arvados.${R}" >> ${S_DIR}/top.sls fi - # Pillars + + ### Pillars ### if [ "${R}" = "workbench" ]; then grep -q "logrotate_wb1" ${P_DIR}/top.sls || echo " - logrotate_wb1" >> ${P_DIR}/top.sls fi @@ -957,21 +1069,21 @@ fi # Leave a copy of the Arvados CA so the user can copy it where it's required if [ "${SSL_MODE}" = "self-signed" ]; then echo "Copying the Arvados CA certificate '${DOMAIN}-arvados-snakeoil-ca.crt' to the installer dir, so you can import it" - if [ "x${VAGRANT}" = "xyes" ]; then + if [ "x${VAGRANT:-}" = "xyes" ]; then cp /etc/ssl/certs/arvados-snakeoil-ca.pem /vagrant/${DOMAIN}-arvados-snakeoil-ca.pem else cp /etc/ssl/certs/arvados-snakeoil-ca.pem ${SCRIPT_DIR}/${DOMAIN}-arvados-snakeoil-ca.crt fi fi -if [ "x${VAGRANT}" = "xyes" ]; then +if [ "x${VAGRANT:-}" = "xyes" ]; then # If running in a vagrant VM, also add default user to docker group echo "Adding the vagrant user to the docker group" usermod -a -G docker vagrant fi # Test that the installation finished correctly -if [ "x${TEST}" = "xyes" ]; then +if [ "x${TEST:-}" = "xyes" ]; then cd ${T_DIR} # If we use RVM, we need to run this with it, or most ruby commands will fail RVM_EXEC=""