chore(mirror): sync desde templates/web-backend-python (ADR-095)
All checks were successful
__APP_NAME__ — build & deploy / ¿Credenciales de build listas? (push) Successful in 0s
__APP_NAME__ — build & deploy / Calidad + build + push (push) Has been skipped
__APP_NAME__ — build & deploy / ¿Cluster del tenant listo? (push) Has been skipped
__APP_NAME__ — build & deploy / Helm upgrade --install (push) Has been skipped
All checks were successful
__APP_NAME__ — build & deploy / ¿Credenciales de build listas? (push) Successful in 0s
__APP_NAME__ — build & deploy / Calidad + build + push (push) Has been skipped
__APP_NAME__ — build & deploy / ¿Cluster del tenant listo? (push) Has been skipped
__APP_NAME__ — build & deploy / Helm upgrade --install (push) Has been skipped
This commit is contained in:
@@ -205,139 +205,20 @@ jobs:
|
||||
echo "$KUBECONFIG_B64" | base64 -d > "${HOME}/.kube/config"
|
||||
chmod 600 "${HOME}/.kube/config"
|
||||
|
||||
# ── ADR-066: AddonClaim vive FUERA del chart Helm ───────────────────
|
||||
# El claim lo gestiona addon-provisioner via finalizer cleanup-logical;
|
||||
# no debe acoplarse al lifecycle del release Helm para no rotar
|
||||
# credenciales en cada upgrade.
|
||||
|
||||
- name: De-adoptar AddonClaim legacy (migracion chart 1.0.0 -> 1.1.0)
|
||||
# Idempotente: skip silencioso si AddonClaim no existe (primera
|
||||
# instalacion) o si ya esta de-adoptado (segundo run post-migracion).
|
||||
# Si tiene annotations Helm de un release v1.0.0, las quita para que
|
||||
# el siguiente helm upgrade no intente borrarlo (no esta en el chart).
|
||||
# Sunset del step tras una rotacion completa (~2 semanas).
|
||||
run: |
|
||||
RELEASE_NAME=__APP_NAME__ bash scripts/pre-helm-detach.sh
|
||||
|
||||
- name: Aplicar AddonClaim
|
||||
# Sustitucion de placeholders con sed (evita dependencia de envsubst,
|
||||
# que no esta garantizado en la imagen del runner). kubectl apply es
|
||||
# idempotente: primer push lo crea, push subsiguientes son no-op si
|
||||
# el spec no cambia. helm upgrade --install nunca lo trackea ni lo borra.
|
||||
env:
|
||||
RELEASE_NAME: __APP_NAME__
|
||||
run: |
|
||||
# databaseName = release name con guiones a underscores + sufijo _db.
|
||||
# Coincide con el default del chart 1.0.0 (.Release.Name | replace
|
||||
# "-" "_" | printf "%s_db").
|
||||
DATABASE_NAME="$(echo "${RELEASE_NAME}" | tr '-' '_')_db"
|
||||
sed -e "s|\${RELEASE_NAME}|${RELEASE_NAME}|g" \
|
||||
-e "s|\${DATABASE_NAME}|${DATABASE_NAME}|g" \
|
||||
manifests/addonclaim.yaml | kubectl apply -f -
|
||||
|
||||
- name: Esperar rancher-webhook ready (RANCHER-WEBHOOK-RACE-RECOVERY)
|
||||
# Race condition durante el bootstrap del cluster tenant: el
|
||||
# `rancher-webhook` Deployment en cattle-system aún no tiene endpoints
|
||||
# cuando el primer `helm upgrade --install` intenta crear el namespace
|
||||
# `apps`, lo que dispara el webhook
|
||||
# `rancher.cattle.io.namespaces.create-non-kubesystem` y aborta el
|
||||
# release con `no endpoints available for service rancher-webhook`.
|
||||
# El re-dispatch ~5-10min después recupera natural, pero degrada el smoke
|
||||
# E2E. Espera explícita evita el flake.
|
||||
run: |
|
||||
# `kubectl wait` falla con NotFound si el Deployment aún no existe:
|
||||
# durante el bootstrap del cluster tenant, `rancher-webhook` puede no
|
||||
# haberse creado todavía cuando corre este step. Primero esperamos a
|
||||
# que el objeto APAREZCA (poll), luego a que esté Available.
|
||||
until kubectl get deployment rancher-webhook -n cattle-system >/dev/null 2>&1; do
|
||||
echo "Esperando a que el Deployment rancher-webhook exista en cattle-system..."
|
||||
sleep 5
|
||||
done
|
||||
kubectl wait deployment rancher-webhook \
|
||||
-n cattle-system \
|
||||
--for=condition=Available \
|
||||
--timeout=600s
|
||||
|
||||
- name: Recuperar release Helm atascado (TENANT-BUILD-NO-CONCURRENCY-GUARD)
|
||||
# Red de seguridad ADEMÁS del guard `concurrency`: si un run previo quedó a
|
||||
# mitad de una operación Helm (cancelado, runner reiniciado, o carrera
|
||||
# histórica anterior a este fix), el release queda en un estado `pending-*`
|
||||
# y el siguiente `helm upgrade --install` aborta. Lo detectamos y recuperamos
|
||||
# antes de desplegar.
|
||||
# Fail-safe: SOLO actúa sobre estados `pending-*`/`uninstalling`; un release
|
||||
# `deployed`, `failed` o inexistente NO se toca. Si el parseo no encuentra
|
||||
# STATUS (formato inesperado) cae al branch no-op → comportamiento idéntico
|
||||
# al actual, nunca peor.
|
||||
run: |
|
||||
# `helm status` de un release inexistente (first-deploy frío) sale con
|
||||
# exit≠0; bajo el shell del runner (`bash -e -o pipefail`) eso abortaría
|
||||
# el step ANTES del case. `|| true` lo neutraliza → STATUS="" → branch no-op.
|
||||
STATUS="$(helm status __APP_NAME__ -n apps 2>/dev/null | sed -n 's/^STATUS: //p')" || true
|
||||
echo "Estado actual del release __APP_NAME__: ${STATUS:-<no existe>}"
|
||||
case "$STATUS" in
|
||||
pending-install|uninstalling)
|
||||
# Nunca hubo una revisión desplegada con éxito → no se puede rollback.
|
||||
# `helm uninstall` limpia el secret del release trabado (equivale al
|
||||
# destrabado manual del 2026-06-10) sin riesgo de datos: el primer deploy
|
||||
# aún no levantó la app.
|
||||
echo "Release en '${STATUS}' (sin revisión estable) → helm uninstall para limpiar."
|
||||
helm uninstall __APP_NAME__ -n apps --wait --timeout 2m || true
|
||||
;;
|
||||
pending-upgrade|pending-rollback)
|
||||
# Hubo una revisión estable previa → rollback a la última desplegada
|
||||
# (preserva la app viva; el upgrade siguiente reintenta la nueva imagen).
|
||||
echo "Release en '${STATUS}' → helm rollback a la última revisión estable."
|
||||
helm rollback __APP_NAME__ 0 -n apps --wait --timeout 2m || true
|
||||
;;
|
||||
*)
|
||||
echo "Release en estado estable o inexistente → sin recuperación necesaria."
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Helm upgrade --install
|
||||
# ── Deploy del tenant — lógica factorizada a script reusable (ADR-095 §B2-D2) ─
|
||||
# La secuencia completa del deploy (de-adopt → AddonClaim → wait-webhook →
|
||||
# recovery-release → helm upgrade --install → rollout → smoke) vive en
|
||||
# scripts/tenant-first-deploy.sh. CS-7: el gate efímero B2 invoca ese MISMO
|
||||
# shell byte-idéntico (con GATE_MODE=1) → prueba en runtime el shell donde
|
||||
# estuvo el bug canónico de la enfermedad B (el `helm status` bajo `set -e`).
|
||||
# El AddonClaim (ADR-066) lo aplica el script solo si existe
|
||||
# manifests/addonclaim.yaml (este template lo tiene). helm y el kubeconfig ya
|
||||
# quedaron listos en los steps previos (setup de entorno, no lógica de deploy).
|
||||
- name: Deploy del tenant (tenant-first-deploy.sh)
|
||||
env:
|
||||
APP_NAME: __APP_NAME__
|
||||
IMAGE_TAG: ${{ needs.build.outputs.image_tag }}
|
||||
TENANT_ID: ${{ vars.TENANT_ID }}
|
||||
TENANT_ID_NODASHES: ${{ vars.TENANT_ID_NODASHES }}
|
||||
TENANT_TIER: ${{ vars.TENANT_TIER }}
|
||||
IMAGE_TAG: ${{ needs.build.outputs.image_tag }}
|
||||
# ADR-054: en cluster tenant los namespaces son funcionales (apps/addons),
|
||||
# sin tenant-id en el nombre — el cluster ya es el sandbox del tenant.
|
||||
run: |
|
||||
helm upgrade --install __APP_NAME__ ./helm/__APP_NAME__ \
|
||||
--namespace apps \
|
||||
--create-namespace \
|
||||
--set image.tag=${IMAGE_TAG} \
|
||||
--set tenantId=${TENANT_ID} \
|
||||
--set tenantIdNodashes=${TENANT_ID_NODASHES} \
|
||||
--set tier=${TENANT_TIER} \
|
||||
--wait --timeout 10m
|
||||
# 10m absorbe el peor caso del reconcile de addon-provisioner
|
||||
# (RECONCILE_INTERVAL 60s + initial_delay 60s + 3 ticks ≈ 240s) +
|
||||
# StatefulSet MariaDB ready (~60s) + Job DDL (~10s) +
|
||||
# InitContainer wait-for-secret 360s + Alembic. Lección 2026-05-28:
|
||||
# con RECONCILE_INTERVAL=300s y wait 240s el init container moria
|
||||
# antes (delay observado 577s, ticket
|
||||
# ADDON-PROVISIONER-DB-SECRET-NOT-PUBLISHED). AddonClaim ya fue
|
||||
# aplicado en el step previo (ADR-066).
|
||||
|
||||
- name: Verificar rollout
|
||||
run: |
|
||||
kubectl -n apps rollout status deploy/__APP_NAME__ --timeout=3m
|
||||
|
||||
- name: Smoke check post-deploy
|
||||
# FQDN en formato subdominio (ADR-067 / ADR-082): <app>.<tenant-uuid>.apps...
|
||||
# Coincide con el host del Ingress del cluster tenant (helm/APP_NAME/values.yaml)
|
||||
# y con el wildcard A record *.{tenant-uuid}.apps.coralware.cloud que crea tenant-manager.
|
||||
env:
|
||||
INGRESS_HOST: __APP_NAME__.${{ vars.TENANT_ID }}.apps.coralware.cloud
|
||||
run: |
|
||||
for i in $(seq 1 12); do
|
||||
if wget -q -O - --timeout=10 "https://${INGRESS_HOST}/health" | grep -q '"status":"ok"'; then
|
||||
echo "Smoke OK: /health responde 200 con db:up"
|
||||
exit 0
|
||||
fi
|
||||
echo "Intento ${i}/12 — /health aún no responde, esperando 5s…"
|
||||
sleep 5
|
||||
done
|
||||
echo "ERROR: /health no respondió 200 dentro del timeout"
|
||||
exit 1
|
||||
run: bash scripts/tenant-first-deploy.sh
|
||||
|
||||
Reference in New Issue
Block a user