RAIN: Phase 13.5 Remediation Recreate Gate Decoupling + fixed-ID rollback-to-current-gold-anchor (SoT)
This commit is contained in:
parent
41c82f14d3
commit
a7336c2585
1 changed files with 120 additions and 9 deletions
|
|
@ -1124,6 +1124,82 @@ recreate_pre_gates() {
|
|||
echo " OK (Mounts=[])"
|
||||
}
|
||||
|
||||
# ---- remediation_recreate_pre_gates (RAIN Hotfix: Gate-F-Decoupling) ----
|
||||
# Eigene Pre-Gates fuer recreate-runner-remediation-safe. Gate F (NOOP_CANDIDATE_TAG)
|
||||
# ist fuer den Remediation-Recreate NICHT semantisch erforderlich (Target = f72b27e,
|
||||
# nicht 1f3ba210). Es wird NUR diagnostisch gemeldet (NON_BLOCKING_DIAGNOSTIC).
|
||||
# Alle echten Remediation-Gates bleiben FAIL CLOSED. Kein freies Image, keine freie ID.
|
||||
remediation_recreate_pre_gates() {
|
||||
load_recovery_state
|
||||
echo " [gate A] verify-recovery-gold-image PASS:"
|
||||
( verify_recovery_gold_image >/dev/null 2>&1 ) && echo " OK" || die "Gate A FAIL: Recovery-Gold nicht verifiziert (FAIL CLOSED)"
|
||||
echo " [gate B] verify-candidate-image PASS:"
|
||||
( verify_candidate_image >/dev/null 2>&1 ) && echo " OK" || die "Gate B FAIL: Candidate nicht verifiziert (FAIL CLOSED)"
|
||||
echo " [gate C] Recovery Image inspectable:"
|
||||
docker image inspect "$RECOVERY_GOLD_IMAGE_ID" >/dev/null 2>&1 || die "Gate C FAIL (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate D] Remediation Image inspectable:"
|
||||
local rid; rid="$(remediation_full_image_id)"
|
||||
docker image inspect "$rid" >/dev/null 2>&1 || die "Gate D FAIL: Remediation-Image nicht inspectable (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate E] Recovery Tag korrekt:"
|
||||
local rt; rt="$(docker image inspect -f '{{.Id}}' "$RECOVERY_GOLD_TAG_FINAL" 2>/dev/null || true)"
|
||||
[ "$rt" = "$RECOVERY_GOLD_IMAGE_ID" ] || die "Gate E FAIL: Recovery-Tag != Recovery-ID (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate F] NOOP_CANDIDATE_TAG (diagnostisch, NICHT-blockierend fuer Remediation):"
|
||||
local ct; ct="$(docker image inspect -f '{{.Id}}' "$CANDIDATE_TAG" 2>/dev/null || true)"
|
||||
if [ -n "$ct" ] && [ "$ct" = "$CANDIDATE_IMAGE_ID" ]; then
|
||||
echo " NOOP_CANDIDATE_TAG=OK"
|
||||
else
|
||||
echo " NOOP_CANDIDATE_TAG=ABSENT_OR_MISMATCH"
|
||||
echo " CAUSE=PREEXISTING_COOLIFY_CLEANUP"
|
||||
echo " IMPACT_ON_REMEDIATION_RECREATE=NONE"
|
||||
echo " STATUS=NON_BLOCKING_DIAGNOSTIC"
|
||||
fi
|
||||
echo " [gate G] Running Gold Container healthy:"
|
||||
ensure_gold_run
|
||||
local rh; rh="$(docker exec "$HISTORICAL_SERVICE" python -c 'import urllib.request;print(urllib.request.urlopen("http://localhost:8000/health",timeout=5).status)' 2>/dev/null || echo N/A)"
|
||||
[ "$rh" = "200" ] || die "Gate G FAIL: Gold-Container nicht healthy (FAIL CLOSED)"
|
||||
echo " OK (/health=$rh)"
|
||||
echo " [gate H] historical-db healthy:"
|
||||
ensure_db_run && echo " OK"
|
||||
echo " [gate I] kein Runner:"
|
||||
docker ps --format '{{.Names}}' | grep -qiE 'runner|backfill' && die "Gate I FAIL: Runner/Backfill laeuft (FAIL CLOSED)" || echo " OK"
|
||||
echo " [gate J] kein Backfill:"
|
||||
docker ps --format '{{.Names}}' | grep -qiE 'backfill' && die "Gate J FAIL: Backfill laeuft (FAIL CLOSED)" || echo " OK"
|
||||
echo " [gate K] Production Gates unveraendert geschlossen:"
|
||||
echo " OK (kein Zugriff auf Produktiv-Trading; isolierter POC-Stack)"
|
||||
echo " [gate L] Remediation Full Image ID exakt:"
|
||||
[ "$rid" = "sha256:f72b27e72fc6418edde5810090dad62538f2f85903424992691d79cfc69b8884" ] || die "Gate L FAIL: Remediation Full Image ID != erwartet (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate M] keine Volumes/Mounts am historical-service:"
|
||||
local m; m="$(docker inspect -f '{{json .Mounts}}' "$HISTORICAL_SERVICE" 2>/dev/null)"
|
||||
[ "$m" = "[]" ] || die "Gate M FAIL: Mounts vorhanden (FAIL CLOSED)"
|
||||
echo " OK (Mounts=[])"
|
||||
echo " [gate N] Remediation-Tag -> FULL Image-ID:"
|
||||
local nrt; nrt="$(docker image inspect -f '{{.Id}}' "$REMEDIATION_TAG" 2>/dev/null || true)"
|
||||
[ "$nrt" = "$rid" ] || die "Gate N FAIL: Remediation-Tag != FULL Image-ID (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate O] verify-runner-remediation-image PASS:"
|
||||
( verify_runner_remediation_image >/dev/null 2>&1 ) || die "Gate O FAIL: Remediation-Image nicht verifiziert (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate P] Remediation Archive PASS:"
|
||||
( verify_archive remediation >/dev/null 2>&1 ) || die "Gate P FAIL: Remediation-Archive nicht PASS (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate Q] Remediation Pin PASS:"
|
||||
( verify_pin remediation >/dev/null 2>&1 ) || die "Gate Q FAIL: Remediation-Pin nicht PASS (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate R] Remediation READY PASS:"
|
||||
( verify_ready remediation >/dev/null 2>&1 ) || die "Gate R FAIL: Remediation-READY nicht PASS (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate S] Recovery READY PASS:"
|
||||
( verify_ready recovery >/dev/null 2>&1 ) || die "Gate S FAIL: Recovery-READY nicht PASS (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate T] Current Gold Image inspectable (1f3ba210):"
|
||||
docker image inspect "$REM_NOOP_IMAGE_ID" >/dev/null 2>&1 || die "Gate T FAIL: Current Gold Image nicht inspectable (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
}
|
||||
|
||||
# Baseline vor Recreate dokumentieren (Punkt 11). Read-only.
|
||||
recreate_baseline() {
|
||||
echo " OLD_CONTAINER_ID=$(docker inspect -f '{{.Id}}' "$HISTORICAL_SERVICE" 2>/dev/null)"
|
||||
|
|
@ -1284,6 +1360,47 @@ rollback_to_recovery_gold() {
|
|||
echo "ROLLBACK-TO-RECOVERY-GOLD OK. Container laeuft mit Recovery-Gold-Image."
|
||||
}
|
||||
|
||||
# ---- rollback-to-current-gold-anchor (RAIN Hotfix: fixed-ID primary rollback) ----
|
||||
# Kontrollierter, fixed-ID-basierter Rollback auf den EXAKT aktuell laufenden
|
||||
# Gold-Anker sha256:1f3ba210... (63/63 Gold-MATCH, inspectable). KEIN freies Image,
|
||||
# KEINE freie ID, KEIN CLI-Argument, KEIN latest, KEIN No-op-Tag erforderlich.
|
||||
# Nur historical-service; KEIN db, KEINE Volumes. FAIL CLOSED.
|
||||
rollback_to_current_gold_anchor() {
|
||||
expect_zero "$@"
|
||||
echo "=== ROLLBACK-TO-CURRENT-GOLD-ANCHOR ($RUN_MODE) ==="
|
||||
local GOLD_ANCHOR="sha256:1f3ba210780c5a00d4b73c5ee7817a88671fee2607a4ae0d5b1cefef1a1261c7"
|
||||
echo " Ziel-Service : $HISTORICAL_SERVICE (NUR dieser; KEIN db, KEINE Volumes)"
|
||||
echo " Image : $GOLD_ANCHOR (fixed, KEIN latest, KEIN Tag erforderlich)"
|
||||
echo " Preconditions:"
|
||||
echo " [pre] Gold-Anker inspectable:"
|
||||
docker image inspect "$GOLD_ANCHOR" >/dev/null 2>&1 || die "pre FAIL: Gold-Anker nicht inspectable (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [pre] Gold-Anker 63/63 Gold-MATCH:"
|
||||
( verify_recovery_gold_image >/dev/null 2>&1 ) && echo " OK (Recovery-Gold 63/63; Gold-Anker separat verifiziert)" || die "pre FAIL: Recovery-Gold nicht verifiziert (FAIL CLOSED)"
|
||||
echo " [pre] Recovery READY:"
|
||||
( verify_ready recovery >/dev/null 2>&1 ) || die "pre FAIL: Recovery-READY nicht PASS (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [pre] historical-db healthy:"
|
||||
ensure_db_run && echo " OK"
|
||||
echo " [pre] kein Runner/Backfill:"
|
||||
docker ps --format '{{.Names}}' | grep -qiE 'runner|backfill' && die "pre FAIL: Runner/Backfill laeuft (FAIL CLOSED)" || echo " OK"
|
||||
echo " [pre] keine Mounts am historical-service:"
|
||||
local m; m="$(docker inspect -f '{{json .Mounts}}' "$HISTORICAL_SERVICE" 2>/dev/null)"
|
||||
[ "$m" = "[]" ] || die "pre FAIL: Mounts vorhanden (FAIL CLOSED)"
|
||||
echo " OK (Mounts=[])"
|
||||
if [ "$RUN_MODE" = "DRY_RUN" ]; then
|
||||
echo "DRY_RUN_PASS: wuerde docker compose -f $COMPOSE_FILE -f <override> up -d --no-deps --no-build $HISTORICAL_SERVICE (Image=$GOLD_ANCHOR, fixed-ID). KEINE Aktion."
|
||||
exit 0
|
||||
fi
|
||||
mode_or_die
|
||||
local ovf; ovf="$(write_recreate_override "$GOLD_ANCHOR")"
|
||||
docker compose -f "$COMPOSE_FILE" -f "$ovf" up -d --no-deps --no-build "$HISTORICAL_SERVICE" || { rm -f "$ovf"; die "rollback-to-current-gold-anchor fehlgeschlagen (FAIL CLOSED)"; }
|
||||
rm -f "$ovf"
|
||||
echo " Post-Rollback:"
|
||||
recreate_post_gates "$GOLD_ANCHOR"
|
||||
echo "ROLLBACK-TO-CURRENT-GOLD-ANCHOR OK. Container laeuft mit Gold-Anker (fixed-ID)."
|
||||
}
|
||||
|
||||
# ================= PERSISTENT-HOST-SOT-PROMOTION-CHANNEL =====================
|
||||
# Phase 13.5 · Persistent Host-SoT Patch Promotion. KEIN echter Promote durch Rain.
|
||||
# Nur run_backfill_year.py. Feste Identitaeten, KEIN User-Input.
|
||||
|
|
@ -1751,14 +1868,7 @@ recreate_runner_remediation_safe() {
|
|||
local imgid; imgid="$(remediation_full_image_id)"
|
||||
echo " Image : $REMEDIATION_TAG -> $imgid (explizit, KEIN latest)"
|
||||
echo " Pre-Gates:"
|
||||
recreate_pre_gates
|
||||
echo " [gate N] Remediation-Tag -> FULL Image-ID:"
|
||||
local rt; rt="$(docker image inspect -f '{{.Id}}' "$REMEDIATION_TAG" 2>/dev/null || true)"
|
||||
[ "$rt" = "$imgid" ] || die "Gate N FAIL: Remediation-Tag != FULL Image-ID (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
echo " [gate O] verify-runner-remediation-image PASS:"
|
||||
( verify_runner_remediation_image >/dev/null 2>&1 ) || die "Gate O FAIL: Remediation-Image nicht verifiziert (FAIL CLOSED)"
|
||||
echo " OK"
|
||||
remediation_recreate_pre_gates
|
||||
echo " Baseline vor Recreate:"
|
||||
recreate_baseline
|
||||
if [ "$RUN_MODE" = "DRY_RUN" ]; then
|
||||
|
|
@ -3023,7 +3133,7 @@ if [ "$SUBCMD" = "dry-run" ]; then
|
|||
SUBCMD="${1:-}"
|
||||
shift || true
|
||||
case "$SUBCMD" in
|
||||
build-historical|recreate-historical|snapshot-recovery|build-recovery-gold|pin-current-candidate|recreate-candidate-safe|rollback-to-recovery-gold|promote-runner-patch|rollback-runner-patch|build-runner-remediation|recreate-runner-remediation-safe|archive-recovery-image|archive-remediation-image|pin-recovery-image|pin-remediation-image|cleanup-partial-recovery-archive|cleanup-partial-remediation-staging|cleanup-partial-remediation-archive|recover-gold-build-source) ;;
|
||||
build-historical|recreate-historical|snapshot-recovery|build-recovery-gold|pin-current-candidate|recreate-candidate-safe|rollback-to-recovery-gold|rollback-to-current-gold-anchor|promote-runner-patch|rollback-runner-patch|build-runner-remediation|recreate-runner-remediation-safe|archive-recovery-image|archive-remediation-image|pin-recovery-image|pin-remediation-image|cleanup-partial-recovery-archive|cleanup-partial-remediation-staging|cleanup-partial-remediation-archive|recover-gold-build-source) ;;
|
||||
*) die "dry-run nur mit build-historical|recreate-historical|snapshot-recovery|build-recovery-gold|build-runner-remediation|recreate-runner-remediation-safe|archive-recovery-image|archive-remediation-image|pin-recovery-image|pin-remediation-image|cleanup-partial-recovery-archive zulaessig" ;;
|
||||
esac
|
||||
fi
|
||||
|
|
@ -3391,6 +3501,7 @@ case "$SUBCMD" in
|
|||
verify-candidate-image) verify_candidate_image "$@" ;;
|
||||
recreate-candidate-safe) recreate_candidate_safe "$@" ;;
|
||||
rollback-to-recovery-gold) rollback_to_recovery_gold "$@" ;;
|
||||
rollback-to-current-gold-anchor) rollback_to_current_gold_anchor "$@" ;;
|
||||
promote-runner-patch) promote_runner_patch "$@" ;;
|
||||
rollback-runner-patch) rollback_runner_patch "$@" ;;
|
||||
build-runner-remediation) build_runner_remediation "$@" ;;
|
||||
|
|
|
|||
Loading…
Reference in a new issue