Last active
December 5, 2019 20:10
-
-
Save ddtmachado/40ecf2792b12c0d490ff64e7228de88b to your computer and use it in GitHub Desktop.
TraefikEE install helper for swarm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -o pipefail | |
set -o errexit | |
readonly TEE_STACK_NAME=${TEE_STACK_NAME:-traefikee} | |
readonly TEE_CTL_BIN=${TEE_CTL_BIN:-teectl} | |
readonly TEMP_DIR=${TEMP_DIR:-/tmp} | |
readonly SWARM_RESOLVE_IMAGE=${SWARM_RESOLVE_IMAGE:-never} | |
readonly SWARM_SERVICE_RETRY_COUNT=${SWARM_SERVICE_RETRY_COUNT:-3} | |
readonly SWARM_SERVICE_WAIT_LOOP=${SWARM_SERVICE_WAIT_LOOP:-5} | |
main() { | |
check_tool docker | |
check_tool "$TEE_CTL_BIN" | |
ensure_is_swarm | |
local tee_setup_flags="$*" | |
local controller_stack="${TEMP_DIR}/controllers.yaml" | |
local proxy_stack="${TEMP_DIR}/proxies.yaml" | |
local generateControllers="$TEE_CTL_BIN setup --assetpath ${TEMP_DIR} --platform swarm --license ${TRAEFIKEE_LICENSE_KEY} $tee_setup_flags" | |
echo "[INFO] Generating controller stack at $controller_stack" | |
$generateControllers 2> "${TEMP_DIR}/tee_error" > "$controller_stack" || { | |
echo "[ERROR] $(<"${TEMP_DIR}/tee_error")" | |
exit 1 | |
} | |
echo "[INFO] Deploying controller stack" | |
deploy_stack "$controller_stack" | |
controllers=$(grep -o "controller-[0-9]" < "$controller_stack" | sort | uniq) | |
for controller in $controllers; do | |
wait_service_readiness "$controller" | |
done | |
$TEE_CTL_BIN setup --continue 2> "${TEMP_DIR}/tee_error" > "$proxy_stack" || { | |
echo "[ERROR] $(<"${TEMP_DIR}/tee_error")" | |
exit 1 | |
} | |
deploy_stack "$proxy_stack" | |
} | |
deploy_stack() { | |
local stack_name=$1 | |
docker stack deploy \ | |
--compose-file "${stack_name}" \ | |
--resolve-image "$SWARM_RESOLVE_IMAGE" \ | |
"$TEE_STACK_NAME" 2> "${TEMP_DIR}/tee_error" | sed "s/^/[INFO] /" || { | |
echo "[ERROR] $(<"${TEMP_DIR}/tee_error")" | |
exit 1 | |
} | |
} | |
check_tool() { | |
local cmd_name=$1 | |
command -v "$cmd_name" > /dev/null 2>&1 || { | |
echo "[ERROR] $cmd_name is not installed, aborting." | |
exit 1 | |
} | |
} | |
ensure_is_swarm() { | |
[[ "$(docker info -f '{{ .Swarm.LocalNodeState }}')" == "active" ]] || { | |
echo "[ERROR] Docker must be running as a swarm manager." | |
exit 1 | |
} | |
} | |
wait_service_readiness() { | |
local service=$1 | |
update_state=$(service_update_state "$service") | |
echo "[INFO] Waiting for service $service to become ready." | |
case $update_state in | |
updating) | |
wait_service_update_with_retries "${TEE_STACK_NAME}_${service}" | |
;; | |
*) | |
wait_match_of_number_of_replicas "$TEE_STACK_NAME" "$service" | |
;; | |
esac | |
} | |
service_update_state() { | |
local service=$1 | |
state=$(docker service inspect \ | |
"$service" \ | |
--format '{{ .UpdateStatus.State }}' \ | |
2>/dev/null) | |
echo "$state" | |
} | |
wait_service_update_with_retries() { | |
local service=$1 | |
local status="" | |
for try in $(seq 1 "$SWARM_SERVICE_RETRY_COUNT"); do | |
status=$(docker service inspect \ | |
"$service" \ | |
--format '{{ .UpdateStatus.State }}') | |
case $status in | |
completed | rollback_completed) | |
echo "[INFO] Finished updating service $service. Status: ${status}." | |
break | |
;; | |
updating | rollback_started) | |
echo "[INFO] Still updating service $service. Status: ${status}." | |
;; | |
*) | |
echo "[ERROR] Couldn't properly update service. Status: ${status}." | |
exit 1 | |
;; | |
esac | |
if [[ "$try" == "$SWARM_SERVICE_RETRY_COUNT" ]]; then | |
echo "[ERROR] Service $service couldn't reach desireable state." | |
exit 1 | |
fi | |
sleep "$SWARM_SERVICE_WAIT_LOOP" | |
done | |
} | |
wait_match_of_number_of_replicas() { | |
local stack=$1 | |
local service=$2 | |
local actual_replicas=0 | |
expected_replicas=$(docker service inspect \ | |
"${stack}_${service}" \ | |
--format '{{ json .Spec.Mode.Replicated.Replicas }}') | |
if [[ -z "$expected_replicas" ]]; then | |
echo "[ERROR] Couldn't retrieve expected number of replicas for $service." | |
exit 1 | |
fi | |
for try in $(seq 1 "$SWARM_SERVICE_RETRY_COUNT"); do | |
echo "[INFO] $service ($actual_replicas/$expected_replicas)" | |
actual_replicas=$(docker service ps \ | |
--format '{{ json . }}' \ | |
"${stack}_${service}" | | |
jq --slurp \ | |
'[.[] | select(.CurrentState | startswith("Running")).CurrentState] | length') | |
if [[ "$actual_replicas" == "$expected_replicas" ]]; then | |
break | |
fi | |
if [[ "$try" == "$SWARM_SERVICE_RETRY_COUNT" ]]; then | |
echo "[ERROR] $service couldn't reach desired number of replicas." | |
exit 1 | |
fi | |
sleep "$SWARM_SERVICE_WAIT_LOOP" | |
done | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment