fixed rollback to wait containers status ok before restore hosts
This commit is contained in:
@@ -206,6 +206,73 @@ jobs:
|
|||||||
EOF
|
EOF
|
||||||
scp /tmp/sync-fe-hosts.sh ${DEPLOY_USER}@${HOST}:${REMOTE_PATH}/.sync-fe-hosts.sh
|
scp /tmp/sync-fe-hosts.sh ${DEPLOY_USER}@${HOST}:${REMOTE_PATH}/.sync-fe-hosts.sh
|
||||||
|
|
||||||
|
# Script di attesa "running/healthy", usato sia da "Verifica container"
|
||||||
|
# dopo un deploy riuscito sia dal rollback prima di risincronizzare
|
||||||
|
# /etc/hosts: dopo un "up -d" (nuovo deploy o rollback) i container
|
||||||
|
# impiegano tempo a diventare healthy, quindi non basta lanciare
|
||||||
|
# "up -d" e proseguire subito - va aspettato che si stabilizzino,
|
||||||
|
# altrimenti (come nel caso del rollback) si rischia di leggere
|
||||||
|
# l'IP del FE prima che sia pronto o mentre sta ancora ripartendo.
|
||||||
|
cat > /tmp/wait-healthy.sh << 'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
COMPOSE="$1"
|
||||||
|
ENV_FILE="$2"
|
||||||
|
TIMEOUT="$3"
|
||||||
|
INTERVAL=5
|
||||||
|
|
||||||
|
ENVFLAG=""
|
||||||
|
[ -n "$ENV_FILE" ] && [ -f "$ENV_FILE" ] && ENVFLAG="--env-file $ENV_FILE"
|
||||||
|
|
||||||
|
elapsed=0
|
||||||
|
while true; do
|
||||||
|
ids=$(DOCKER_CONFIG=/tmp/.docker-ci docker compose -f "$COMPOSE" $ENVFLAG ps -q)
|
||||||
|
if [ -z "$ids" ]; then
|
||||||
|
echo "ERRORE: nessun container in esecuzione."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fail=0
|
||||||
|
pending=0
|
||||||
|
for cid in $ids; do
|
||||||
|
svc=$(docker inspect -f '{{ index .Config.Labels "com.docker.compose.service" }}' "$cid" 2>/dev/null)
|
||||||
|
[ -z "$svc" ] && svc="$cid"
|
||||||
|
status=$(docker inspect -f '{{.State.Status}}' "$cid")
|
||||||
|
health=$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}n/a{{end}}' "$cid")
|
||||||
|
echo "Servizio $svc: status=$status health=$health"
|
||||||
|
if [ "$status" != "running" ]; then
|
||||||
|
echo "ERRORE: servizio $svc non e' in stato running (status=$status)."
|
||||||
|
fail=1
|
||||||
|
elif [ "$health" = "unhealthy" ]; then
|
||||||
|
echo "ERRORE: servizio $svc risulta unhealthy."
|
||||||
|
fail=1
|
||||||
|
elif [ "$health" = "starting" ]; then
|
||||||
|
pending=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$fail" -eq 1 ]; then
|
||||||
|
DOCKER_CONFIG=/tmp/.docker-ci docker compose -f "$COMPOSE" $ENVFLAG ps
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$pending" -eq 0 ]; then
|
||||||
|
echo "Tutti i servizi sono running e (se previsto) healthy."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$elapsed" -ge "$TIMEOUT" ]; then
|
||||||
|
echo "ERRORE: timeout (${TIMEOUT}s) in attesa che tutti i servizi diventino healthy."
|
||||||
|
DOCKER_CONFIG=/tmp/.docker-ci docker compose -f "$COMPOSE" $ENVFLAG ps
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "In attesa che i servizi diventino healthy... (${elapsed}s/${TIMEOUT}s)"
|
||||||
|
sleep "$INTERVAL"
|
||||||
|
elapsed=$((elapsed + INTERVAL))
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
scp /tmp/wait-healthy.sh ${DEPLOY_USER}@${HOST}:${REMOTE_PATH}/.wait-healthy.sh
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────
|
||||||
# APACHE: sostituiamo il file di config SOLO se è cambiato.
|
# APACHE: sostituiamo il file di config SOLO se è cambiato.
|
||||||
# Il backup timestamped viene creato solo in caso di differenza.
|
# Il backup timestamped viene creato solo in caso di differenza.
|
||||||
@@ -302,62 +369,9 @@ jobs:
|
|||||||
ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps"
|
ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps"
|
||||||
|
|
||||||
# Attende che tutti i container siano "running" e, se hanno un
|
# Attende che tutti i container siano "running" e, se hanno un
|
||||||
# healthcheck definito, "healthy" - non basta una fotografia subito
|
# healthcheck definito, "healthy" (vedi .wait-healthy.sh, creato
|
||||||
# dopo "up -d", che coglie quasi sempre i servizi ancora in
|
# nello step "Prepara server" e condiviso con il rollback).
|
||||||
# "starting" (specie servizi Java/Spring con avvio lento). Fallisce
|
ssh ${DEPLOY_USER}@${HOST} "cd ${REMOTE_PATH} && sh .wait-healthy.sh ${COMPOSE} ${ENV_FILE} ${TIMEOUT}"
|
||||||
# subito se un servizio è "unhealthy" o non "running" (nessuna
|
|
||||||
# attesa inutile), altrimenti continua a interrogare fino a TIMEOUT.
|
|
||||||
ssh ${DEPLOY_USER}@${HOST} "
|
|
||||||
set -e
|
|
||||||
TIMEOUT=${TIMEOUT}
|
|
||||||
INTERVAL=5
|
|
||||||
elapsed=0
|
|
||||||
while true; do
|
|
||||||
ids=\$(${CBASE} ps -q)
|
|
||||||
if [ -z \"\$ids\" ]; then
|
|
||||||
echo 'ERRORE: nessun container in esecuzione dopo il deploy.'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fail=0
|
|
||||||
pending=0
|
|
||||||
for cid in \$ids; do
|
|
||||||
svc=\$(docker inspect -f '{{ index .Config.Labels \"com.docker.compose.service\" }}' \$cid 2>/dev/null)
|
|
||||||
[ -z \"\$svc\" ] && svc=\$cid
|
|
||||||
status=\$(docker inspect -f '{{.State.Status}}' \$cid)
|
|
||||||
health=\$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}n/a{{end}}' \$cid)
|
|
||||||
if [ \"\$status\" != 'running' ]; then
|
|
||||||
echo \"ERRORE: servizio \$svc non e' in stato running (status=\$status).\"
|
|
||||||
fail=1
|
|
||||||
elif [ \"\$health\" = 'unhealthy' ]; then
|
|
||||||
echo \"ERRORE: servizio \$svc risulta unhealthy.\"
|
|
||||||
fail=1
|
|
||||||
elif [ \"\$health\" = 'starting' ]; then
|
|
||||||
pending=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ \"\$fail\" -eq 1 ]; then
|
|
||||||
echo '── Stato al momento del fallimento ──'
|
|
||||||
${CBASE} ps
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ \"\$pending\" -eq 0 ]; then
|
|
||||||
echo 'Tutti i servizi sono running e (se previsto) healthy.'
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ \"\$elapsed\" -ge \"\$TIMEOUT\" ]; then
|
|
||||||
echo \"ERRORE: timeout (\${TIMEOUT}s) in attesa che tutti i servizi diventino healthy.\"
|
|
||||||
${CBASE} ps
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo \"In attesa che i servizi diventino healthy... (\${elapsed}s/\${TIMEOUT}s)\"
|
|
||||||
sleep \$INTERVAL
|
|
||||||
elapsed=\$((elapsed + INTERVAL))
|
|
||||||
done
|
|
||||||
"
|
|
||||||
|
|
||||||
echo "── Container status (finale) ──"
|
echo "── Container status (finale) ──"
|
||||||
ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps"
|
ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps"
|
||||||
@@ -423,6 +437,7 @@ jobs:
|
|||||||
COMPOSE="docker-compose-${ENV_NAME}.yml"
|
COMPOSE="docker-compose-${ENV_NAME}.yml"
|
||||||
ENV_FILE=".env_${ENV_NAME}"
|
ENV_FILE=".env_${ENV_NAME}"
|
||||||
SITE="${{ github.event.repository.name }}.site-ssl"
|
SITE="${{ github.event.repository.name }}.site-ssl"
|
||||||
|
TIMEOUT="${{ inputs.health-timeout-seconds }}"
|
||||||
|
|
||||||
ENVFLAG=""
|
ENVFLAG=""
|
||||||
[ -f "$ENV_FILE" ] && ENVFLAG="--env-file ${ENV_FILE}"
|
[ -f "$ENV_FILE" ] && ENVFLAG="--env-file ${ENV_FILE}"
|
||||||
@@ -455,7 +470,12 @@ jobs:
|
|||||||
service apache2 reload
|
service apache2 reload
|
||||||
" || apache_ok=1
|
" || apache_ok=1
|
||||||
|
|
||||||
# 2) Rollback dei container alla versione precedente
|
# 2) Rollback dei container alla versione precedente, poi attesa che
|
||||||
|
# siano running/healthy (stesso script .wait-healthy.sh usato in
|
||||||
|
# "Verifica container"): "up -d" ritorna appena i container sono
|
||||||
|
# avviati, non quando sono pronti. Senza questa attesa, il punto 3)
|
||||||
|
# rischia di leggere l'IP del FE prima che sia stabile o mentre sta
|
||||||
|
# ancora ripartendo, risincronizzando /etc/hosts con un valore errato.
|
||||||
container_ok=0
|
container_ok=0
|
||||||
ssh ${DEPLOY_USER}@${HOST} "
|
ssh ${DEPLOY_USER}@${HOST} "
|
||||||
set -e
|
set -e
|
||||||
@@ -467,6 +487,8 @@ jobs:
|
|||||||
[ -f .rollback/pin.yml ] && PIN='-f .rollback/pin.yml'
|
[ -f .rollback/pin.yml ] && PIN='-f .rollback/pin.yml'
|
||||||
echo 'Ripristino container alla versione precedente...'
|
echo 'Ripristino container alla versione precedente...'
|
||||||
DOCKER_CONFIG=/tmp/.docker-ci docker compose -f ${COMPOSE} \$PIN ${ENVFLAG} up -d
|
DOCKER_CONFIG=/tmp/.docker-ci docker compose -f ${COMPOSE} \$PIN ${ENVFLAG} up -d
|
||||||
|
echo 'Attendo che i container ripristinati siano running/healthy...'
|
||||||
|
sh .wait-healthy.sh ${COMPOSE} ${ENV_FILE} ${TIMEOUT}
|
||||||
else
|
else
|
||||||
echo 'Nessuno snapshot disponibile: nessun rollback container (probabile primo deploy).'
|
echo 'Nessuno snapshot disponibile: nessun rollback container (probabile primo deploy).'
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user