X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6b77f5f193b9c7e931d2e0b0712c1b27cd547fc8..bdcf09e34f8eec88e1e326094ac60b5d484844e1:/tools/salt-install/installer.sh diff --git a/tools/salt-install/installer.sh b/tools/salt-install/installer.sh new file mode 100755 index 0000000000..e5ff7be4e7 --- /dev/null +++ b/tools/salt-install/installer.sh @@ -0,0 +1,257 @@ +#!/bin/bash + +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: CC-BY-SA-3.0 + +# +# installer.sh +# +# Helps manage the configuration in a git repository, and then deploy +# nodes by pushing a copy of the git repository to each node and +# running the provision script to do the actual installation and +# configuration. +# + +set -eu + +# The parameter file +declare CONFIG_FILE=local.params + +# The salt template directory +declare CONFIG_DIR=local_config_dir + +# The 5-character Arvados cluster id +# This will be populated by loadconfig() +declare CLUSTER + +# The parent domain (not including the cluster id) +# This will be populated by loadconfig() +declare DOMAIN + +# A bash associative array listing each node and mapping to the roles +# that should be provisioned on those nodes. +# This will be populated by loadconfig() +declare -A NODES + +# The ssh user we'll use +# This will be populated by loadconfig() +declare DEPLOY_USER + +# The git repository that we'll push to on all the nodes +# This will be populated by loadconfig() +declare GITTARGET + +sync() { + local NODE=$1 + local BRANCH=$2 + + # Synchronizes the configuration by creating a git repository on + # each node, pushing our branch, and updating the checkout. + + if [[ "$NODE" != localhost ]] ; then + if ! ssh $NODE test -d ${GITTARGET}.git ; then + + # Initialize the git repository (1st time case). We're + # actually going to make two repositories here because git + # will complain if you try to push to a repository with a + # checkout. So we're going to create a "bare" repository + # and then clone a regular repository (with a checkout) + # from that. + + ssh $NODE git init --bare ${GITTARGET}.git + if ! git remote add $NODE $DEPLOY_USER@$NODE:${GITTARGET}.git ; then + git remote set-url $NODE $DEPLOY_USER@$NODE:${GITTARGET}.git + fi + git push $NODE $BRANCH + ssh $NODE git clone ${GITTARGET}.git ${GITTARGET} + fi + + # The update case. + # + # Push to the bare repository on the remote node, then in the + # remote node repository with the checkout, pull the branch + # from the bare repository. + + git push $NODE $BRANCH + ssh $NODE "git -C ${GITTARGET} checkout ${BRANCH} && git -C ${GITTARGET} pull" + fi +} + +deploynode() { + local NODE=$1 + local ROLES=$2 + + # Deploy a node. This runs the provision script on the node, with + # the appropriate roles. + + if [[ -z "$ROLES" ]] ; then + echo "No roles declared for '$NODE' in ${CONFIG_FILE}" + exit 1 + fi + + if [[ "$NODE" = localhost ]] ; then + sudo ./provision.sh --config ${CONFIG_FILE} --roles ${ROLES} + else + ssh $DEPLOY_USER@$NODE "cd ${GITTARGET} && sudo ./provision.sh --config ${CONFIG_FILE} --roles ${ROLES}" + fi +} + +loadconfig() { + if [[ ! -s $CONFIG_FILE ]] ; then + echo "Must be run from initialized setup dir, maybe you need to 'initialize' first?" + fi + source ${CONFIG_FILE} + GITTARGET=arvados-deploy-config-${CLUSTER} +} + +subcmd="$1" +if [[ -n "$subcmd" ]] ; then + shift +fi +case "$subcmd" in + initialize) + if [[ ! -f provision.sh ]] ; then + echo "Must be run from arvados/tools/salt-install" + exit + fi + + set +u + SETUPDIR=$1 + PARAMS=$2 + SLS=$3 + set -u + + err= + if [[ -z "$PARAMS" || ! -f local.params.example.$PARAMS ]] ; then + echo "Not found: local.params.example.$PARAMS" + echo "Expected one of multiple_hosts, single_host_multiple_hostnames, single_host_single_hostname" + err=1 + fi + + if [[ -z "$SLS" || ! -d config_examples/$SLS ]] ; then + echo "Not found: config_examples/$SLS" + echo "Expected one of multi_host/aws, single_host/multiple_hostnames, single_host/single_hostname" + err=1 + fi + + if [[ -z "$SETUPDIR" || -z "$PARAMS" || -z "$SLS" ]]; then + echo "installer.sh " + err=1 + fi + + if [[ -n "$err" ]] ; then + exit 1 + fi + + echo "Initializing $SETUPDIR" + git init $SETUPDIR + cp -r *.sh tests $SETUPDIR + + cp local.params.example.$PARAMS $SETUPDIR/${CONFIG_FILE} + cp -r config_examples/$SLS $SETUPDIR/${CONFIG_DIR} + + cd $SETUPDIR + git add *.sh ${CONFIG_FILE} ${CONFIG_DIR} tests + git commit -m"initial commit" + + echo "setup directory initialized, now go to $SETUPDIR, edit '${CONFIG_FILE}' and '${CONFIG_DIR}' as needed, then run 'installer.sh deploy'" + ;; + deploy) + set +u + NODE=$1 + set -u + + loadconfig + + if grep -rni 'fixme' ${CONFIG_FILE} ${CONFIG_DIR} ; then + echo + echo "Some parameters still need to be updated. Please fix them and then re-run deploy." + exit 1 + fi + + BRANCH=$(git branch --show-current) + + set -x + + git add -A + if ! git diff --cached --exit-code ; then + git commit -m"prepare for deploy" + fi + + if [[ -z "$NODE" ]]; then + for NODE in "${!NODES[@]}" + do + # First, push the git repo to each node. This also + # confirms that we have git and can log into each + # node. + sync $NODE $BRANCH + done + + for NODE in "${!NODES[@]}" + do + # Do 'database' role first, + if [[ "${NODES[$NODE]}" =~ database ]] ; then + deploynode $NODE ${NODES[$NODE]} + unset NODES[$NODE] + fi + done + + for NODE in "${!NODES[@]}" + do + # then 'api' or 'controller' roles + if [[ "${NODES[$NODE]}" =~ (api|controller) ]] ; then + deploynode $NODE ${NODES[$NODE]} + unset NODES[$NODE] + fi + done + + for NODE in "${!NODES[@]}" + do + # Everything else (we removed the nodes that we + # already deployed from the list) + deploynode $NODE ${NODES[$NODE]} + done + else + # Just deploy the node that was supplied on the command line. + sync $NODE $BRANCH + deploynode $NODE + fi + + echo + echo "Completed deploy, run 'installer.sh diagnostics' to verify the install" + + ;; + diagnostics) + loadconfig + + set +u + declare LOCATION=$1 + set -u + + if ! which arvados-client ; then + echo "arvados-client not found, install 'arvados-client' package with 'apt-get' or 'yum'" + exit 1 + fi + + if [[ -z "$LOCATION" ]] ; then + echo "Need to provide '-internal-client' or '-external-client'" + echo + echo "-internal-client You are running this on the same private network as the Arvados cluster (e.g. on one of the Arvados nodes)" + echo "-external-client You are running this outside the private network of the Arvados cluster (e.g. your workstation)" + exit 1 + fi + + export ARVADOS_API_HOST="${CLUSTER}.${DOMAIN}" + export ARVADOS_API_TOKEN="$SYSTEM_ROOT_TOKEN" + + arvados-client diagnostics $LOCATION + ;; + *) + echo "Arvados installer" + echo "" + echo "initialize initialize the setup directory for configuration" + echo "deploy deploy the configuration from the setup directory" + echo "diagnostics check your install using diagnostics" + ;; +esac