Phase 13.5: Orphan Remediation Staging Cleanup Control-Plane Hotfix (cleanup-partial-remediation-staging)
This commit is contained in:
parent
f69774e34b
commit
3e65c36cce
1 changed files with 133 additions and 2 deletions
|
|
@ -2327,6 +2327,136 @@ verify_ready_cmd() { # $1 = role (read-only)
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# cleanup-partial-remediation-staging (Phase 13.5 · Orphan Remediation Staging Cleanup)
|
||||||
|
# Kontrollierter Cleanup eines NACHWEISLICH verwaisten Remediation-Staging-Ordners.
|
||||||
|
# KEINE freie Pfadangabe. Zielidentitaet vollstaendig aus kontrolliertem State
|
||||||
|
# (Gold-Source-Session) abgeleitet. Fail-closed bei jeder Abweichung.
|
||||||
|
# Safety-Model (Punkt 3-8): Path Hard Gates, Session Binding an feste autorisierte
|
||||||
|
# Gold-Source-Session, Orphan-Proof (kein aktiver Image State/Image/Archive/Pin/Prozess/Mount),
|
||||||
|
# Content-Verify gegen erwartetes Build-Input, Build-Support-Verify, Build-Input-SHA.
|
||||||
|
# =============================================================================
|
||||||
|
cleanup_partial_remediation_staging() {
|
||||||
|
expect_zero "$@"
|
||||||
|
echo "=== CLEANUP-PARTIAL-REMEDIATION-STAGING ($RUN_MODE) ==="
|
||||||
|
# Session Binding: feste autorisierte Gold-Source-Session aus kontrolliertem State
|
||||||
|
load_remediation_source_state
|
||||||
|
echo " SOURCE_SESSION=$REMEDIATION_SESSION_ID"
|
||||||
|
# Punkt 4: Session muss exakt die feste autorisierte Gold-Source-Session sein
|
||||||
|
[ "$REMEDIATION_SESSION_ID" = "20260830_104127" ] || die "cleanup: Session $REMEDIATION_SESSION_ID != autorisierte 20260830_104127 (FAIL CLOSED)"
|
||||||
|
local sdir base
|
||||||
|
sdir="$REMEDIATION_STAGING_ROOT"
|
||||||
|
base="$REMEDIATION_STAGING_DIR"
|
||||||
|
echo " STAGING_PATH=$base"
|
||||||
|
# --- PATH HARD GATES (Punkt 3) ---
|
||||||
|
# 1. Pfad ist absolut
|
||||||
|
case "$base" in /*) ;; *) die "cleanup: Pfad nicht absolut $base (FAIL CLOSED)";; esac
|
||||||
|
# 2. Pfad exakt aus State abgeleitet
|
||||||
|
[ "$base" = "$REMEDIATION_STAGING_ROOT/$REMEDIATION_SESSION_ID" ] || die "cleanup: Pfad nicht exakt aus State (FAIL CLOSED)"
|
||||||
|
# 3. Parent exakt Staging-Root
|
||||||
|
[ "$sdir" = "/opt/rq-historical-remediation-staging" ] || die "cleanup: Parent nicht exakt Staging-Root (FAIL CLOSED)"
|
||||||
|
# 4. Ziel ist nicht /
|
||||||
|
[ "$base" != "/" ] || die "cleanup: Ziel ist / (FAIL CLOSED)"
|
||||||
|
# 5. Ziel ist nicht Parent selbst
|
||||||
|
[ "$base" != "$sdir" ] || die "cleanup: Ziel ist Parent selbst (FAIL CLOSED)"
|
||||||
|
# 6. Ziel enthaelt keine ..
|
||||||
|
case "$base" in *..*) die "cleanup: Ziel enthaelt .. (FAIL CLOSED)";; esac
|
||||||
|
# 7. Ziel ist kein Symlink
|
||||||
|
[ ! -L "$base" ] || die "cleanup: Ziel ist Symlink (FAIL CLOSED)"
|
||||||
|
# 8. Parent ist kein Symlink
|
||||||
|
[ ! -L "$sdir" ] || die "cleanup: Parent ist Symlink (FAIL CLOSED)"
|
||||||
|
# 9. Ziel ist Directory
|
||||||
|
[ -d "$base" ] || die "cleanup: Ziel ist kein Directory (FAIL CLOSED)"
|
||||||
|
# 10. kein Mountpoint (Ziel + Parent)
|
||||||
|
if mountpoint -q "$base" 2>/dev/null; then die "cleanup: Ziel ist Mountpoint (FAIL CLOSED)"; fi
|
||||||
|
if mountpoint -q "$sdir" 2>/dev/null; then die "cleanup: Parent ist Mountpoint (FAIL CLOSED)"; fi
|
||||||
|
# 11. kein Bind Mount / Docker Volume Mount
|
||||||
|
if grep -q " $base " /proc/mounts 2>/dev/null; then die "cleanup: Ziel ist Bind/Volume Mount (FAIL CLOSED)"; fi
|
||||||
|
if grep -q " $sdir " /proc/mounts 2>/dev/null; then die "cleanup: Parent ist Bind/Volume Mount (FAIL CLOSED)"; fi
|
||||||
|
echo " PATH_GATES=PASS"
|
||||||
|
# --- ORPHAN CLASSIFICATION (Punkt 5) ---
|
||||||
|
# A) Kein aktiver Remediation Image State (stale State mit fehlendem Image = kein aktiver)
|
||||||
|
if remediation_session; then
|
||||||
|
local sid; sid="$(remediation_full_image_id)"
|
||||||
|
if docker image inspect "$sid" >/dev/null 2>&1; then
|
||||||
|
die "cleanup: aktiver Remediation Image State mit existierendem Image $sid (FAIL CLOSED)"
|
||||||
|
else
|
||||||
|
echo " A) Remediation Image State stale (Image $sid fehlt) -> kein aktiver State"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " A) Kein Remediation Image State"
|
||||||
|
fi
|
||||||
|
# B) Kein aktuelles Remediation Image aus dieser Build-Session
|
||||||
|
if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "candidate-phase13-5-runner-remediation"; then
|
||||||
|
die "cleanup: Remediation Image existiert (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
echo " B) Kein Remediation Image"
|
||||||
|
# C) Kein Remediation Archive
|
||||||
|
local arch_dir="$ARCHIVE_ROOT/candidates"
|
||||||
|
if [ -d "$arch_dir" ] && [ -n "$(ls -A "$arch_dir" 2>/dev/null)" ]; then
|
||||||
|
die "cleanup: Remediation Archive existiert (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
echo " C) Kein Remediation Archive"
|
||||||
|
# D) Kein Remediation Pin
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -q "rq-historical-pin-phase13-5-runner-remediation"; then
|
||||||
|
die "cleanup: Remediation Pin existiert (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
echo " D) Kein Remediation Pin"
|
||||||
|
# E) Kein laufender Build-/Runner-Prozess
|
||||||
|
if ps aux | grep -E "docker build|run_backfill" | grep -v grep >/dev/null 2>&1; then
|
||||||
|
die "cleanup: Build-/Runner-Prozess aktiv (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
echo " E) Kein Build-/Runner-Prozess"
|
||||||
|
# F) Kein Docker Build mit diesem Context
|
||||||
|
if docker ps --format '{{.Names}}' | grep -qE "build|remediation"; then
|
||||||
|
die "cleanup: Build-Container aktiv (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
echo " F) Kein Docker Build"
|
||||||
|
# G/H) historical-service/db nutzen Staging nicht als Mount
|
||||||
|
for c in historical-service historical-db; do
|
||||||
|
if docker inspect "$c" --format '{{range .Mounts}}{{.Source}}{{println}}{{end}}' 2>/dev/null | grep -q "$sdir"; then
|
||||||
|
die "cleanup: $c mountet Staging (FAIL CLOSED)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo " G/H) Kein Service/DB Mount"
|
||||||
|
echo " ORPHAN_STAGING=CONFIRMED"
|
||||||
|
# --- CONTENT-VALIDIERUNG (Punkt 6) ---
|
||||||
|
# Staging gegen erwartetes Build-Input (Gold-Source + Overlay)
|
||||||
|
remediation_staging_matches_expected || die "cleanup: Staging != erwartetes Build-Input (FAIL CLOSED)"
|
||||||
|
# 62+1 Klassifikation
|
||||||
|
remediation_expected_manifest_ok || die "cleanup: erwartetes Build-Input nicht exakt (FAIL CLOSED)"
|
||||||
|
echo " CONTENT_VERIFY=PASS (MATCH=$RM_MATCH AUTH=$RM_AUTH UNAUTH=$RM_UNAUTH MISSING=$RM_MISSING EXTRA=$RM_EXTRA)"
|
||||||
|
# repository.py == Gold
|
||||||
|
local repo_sha
|
||||||
|
repo_sha="$(sha256sum "$base/app/persistence/repository.py" | awk '{print $1}')"
|
||||||
|
[ "$repo_sha" = "8fff892f52a612f464b5be21c66ef7787a47f2d7d049f815ef87837553c2a228" ] || die "cleanup: repository.py != Gold (FAIL CLOSED)"
|
||||||
|
echo " repository.py=8fff892f (Gold)"
|
||||||
|
# --- BUILD SUPPORT VALIDIEREN (Punkt 7) ---
|
||||||
|
local gs="$GOLD_SOURCE_ROOT/$REMEDIATION_SESSION_ID"
|
||||||
|
for bf in Dockerfile requirements.txt docker-compose.yml .dockerignore; do
|
||||||
|
local gs_sha st_sha
|
||||||
|
gs_sha="$(sha256sum "$gs/$bf" 2>/dev/null | awk '{print $1}')"
|
||||||
|
st_sha="$(sha256sum "$base/$bf" 2>/dev/null | awk '{print $1}')"
|
||||||
|
[ -n "$gs_sha" ] && [ "$gs_sha" = "$st_sha" ] || die "cleanup: Build-Support $bf != Gold (FAIL CLOSED)"
|
||||||
|
done
|
||||||
|
echo " BUILD_SUPPORT_VERIFY=PASS"
|
||||||
|
# --- EXPECTED BUILD INPUT SHA (Punkt 8) ---
|
||||||
|
local ebi; ebi="$(remediation_expected_build_input_sha "$base")"
|
||||||
|
[ "$ebi" = "75555a411b64e0ac0ef0f8502180ee0a331bab93748515d24b5c8d8f255f2d84" ] || die "cleanup: Build-Input-SHA $ebi != erwartet (FAIL CLOSED)"
|
||||||
|
echo " REMEDIATION_BUILD_INPUT_SHA=$ebi"
|
||||||
|
# --- ACTION ---
|
||||||
|
if [ "$RUN_MODE" = "DRY_RUN" ]; then
|
||||||
|
echo " ACTION=WOULD_REMOVE_STAGING"
|
||||||
|
echo "DRY_RUN_PASS: cleanup-partial-remediation-staging wuerde $base entfernen (keine Aktion)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
mode_or_die
|
||||||
|
# MUTATION: kontrollierter Cleanup des verwaisten Staging-Ordners
|
||||||
|
rm -rf -- "$base" || die "cleanup: Entfernen fehlgeschlagen (FAIL CLOSED)"
|
||||||
|
[ ! -e "$base" ] || die "cleanup: Ziel nach Entfernen noch vorhanden (FAIL CLOSED)"
|
||||||
|
echo "CLEANUP-PARTIAL-REMEDIATION-STAGING OK: $base entfernt"
|
||||||
|
echo " Retry bereit: build-runner-remediation wird neues Staging materialisieren."
|
||||||
|
}
|
||||||
|
|
||||||
# restore-recovery-image-archive (DESIGN; realer Restore NICHT in dieser Mission ausfuehren)
|
# restore-recovery-image-archive (DESIGN; realer Restore NICHT in dieser Mission ausfuehren)
|
||||||
restore_recovery_dry() { # dry-run
|
restore_recovery_dry() { # dry-run
|
||||||
expect_zero "$@"
|
expect_zero "$@"
|
||||||
|
|
@ -2676,7 +2806,7 @@ if [ "$SUBCMD" = "dry-run" ]; then
|
||||||
SUBCMD="${1:-}"
|
SUBCMD="${1:-}"
|
||||||
shift || true
|
shift || true
|
||||||
case "$SUBCMD" in
|
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|recover-gold-build-source) ;;
|
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|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" ;;
|
*) 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
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
@ -3088,6 +3218,7 @@ case "$SUBCMD" in
|
||||||
verify-recovery-archive) verify_archive_cmd recovery "$@" ;;
|
verify-recovery-archive) verify_archive_cmd recovery "$@" ;;
|
||||||
verify-remediation-archive) verify_archive_cmd remediation "$@" ;;
|
verify-remediation-archive) verify_archive_cmd remediation "$@" ;;
|
||||||
cleanup-partial-recovery-archive) cleanup_partial_recovery_archive "$@" ;;
|
cleanup-partial-recovery-archive) cleanup_partial_recovery_archive "$@" ;;
|
||||||
|
cleanup-partial-remediation-staging) cleanup_partial_remediation_staging "$@" ;;
|
||||||
verify-recovery-pin) verify_pin_cmd recovery "$@" ;;
|
verify-recovery-pin) verify_pin_cmd recovery "$@" ;;
|
||||||
verify-remediation-pin) verify_pin_cmd remediation "$@" ;;
|
verify-remediation-pin) verify_pin_cmd remediation "$@" ;;
|
||||||
verify-recovery-ready) verify_ready_cmd recovery "$@" ;;
|
verify-recovery-ready) verify_ready_cmd recovery "$@" ;;
|
||||||
|
|
@ -3104,6 +3235,6 @@ case "$SUBCMD" in
|
||||||
verify-recovered-gold-build-source) verify_recovered_gold_build_source "$@";;
|
verify-recovered-gold-build-source) verify_recovered_gold_build_source "$@";;
|
||||||
wrapper-sha) expect_zero "$@"; sha256sum /usr/local/bin/rq-historical ;;
|
wrapper-sha) expect_zero "$@"; sha256sum /usr/local/bin/rq-historical ;;
|
||||||
|
|
||||||
*) die "Aufruf: ps|inspect|logs|run|code <K>|hashes|code-list|stage-dir|stage-check <K>|test <K>|search-writes|healthcheck|backup <K>|deploy <K>|rollback <K>|build-def|build-files|host-manifest|host-code <p>|container-manifest|container-code <p>|tree-diff|backup-sot|sot-session|recover-sot <K>|recover-sot-list|verify-sot-recovery|restore-sot|snapshot-recovery|dry-run snapshot-recovery|verify-recovery-snapshot|build-recovery-gold|dry-run build-recovery-gold|verify-recovery-gold-image|pin-current-candidate|dry-run pin-current-candidate|verify-candidate-image|recreate-candidate-safe|dry-run recreate-candidate-safe|rollback-to-recovery-gold|dry-run rollback-to-recovery-gold|promote-runner-patch|dry-run promote-runner-patch|rollback-runner-patch|dry-run rollback-runner-patch|build-runner-remediation|dry-run build-runner-remediation|verify-runner-remediation-image|recreate-runner-remediation-safe|dry-run recreate-runner-remediation-safe|verify-remediation-build-input|build-historical|dry-run build-historical|recreate-historical|dry-run recreate-historical|verify-gold-reproduction|create-build-exclusion|show-build-exclusion|archive-recovery-image|archive-remediation-image|pin-recovery-image|pin-remediation-image|verify-recovery-archive|verify-remediation-archive|cleanup-partial-recovery-archive|verify-recovery-pin|verify-remediation-pin|verify-recovery-ready|verify-remediation-ready|dry-restore-recovery-image-archive|restore-recovery-image-archive|verify-deployed-gold-source|dry-run recover-gold-build-source|recover-gold-build-source|verify-recovered-gold-build-source"
|
*) die "Aufruf: ps|inspect|logs|run|code <K>|hashes|code-list|stage-dir|stage-check <K>|test <K>|search-writes|healthcheck|backup <K>|deploy <K>|rollback <K>|build-def|build-files|host-manifest|host-code <p>|container-manifest|container-code <p>|tree-diff|backup-sot|sot-session|recover-sot <K>|recover-sot-list|verify-sot-recovery|restore-sot|snapshot-recovery|dry-run snapshot-recovery|verify-recovery-snapshot|build-recovery-gold|dry-run build-recovery-gold|verify-recovery-gold-image|pin-current-candidate|dry-run pin-current-candidate|verify-candidate-image|recreate-candidate-safe|dry-run recreate-candidate-safe|rollback-to-recovery-gold|dry-run rollback-to-recovery-gold|promote-runner-patch|dry-run promote-runner-patch|rollback-runner-patch|dry-run rollback-runner-patch|build-runner-remediation|dry-run build-runner-remediation|verify-runner-remediation-image|recreate-runner-remediation-safe|dry-run recreate-runner-remediation-safe|verify-remediation-build-input|build-historical|dry-run build-historical|recreate-historical|dry-run recreate-historical|verify-gold-reproduction|create-build-exclusion|show-build-exclusion|archive-recovery-image|archive-remediation-image|pin-recovery-image|pin-remediation-image|verify-recovery-archive|verify-remediation-archive|cleanup-partial-recovery-archive|cleanup-partial-remediation-staging|verify-recovery-pin|verify-remediation-pin|verify-recovery-ready|verify-remediation-ready|dry-restore-recovery-image-archive|restore-recovery-image-archive|verify-deployed-gold-source|dry-run recover-gold-build-source|recover-gold-build-source|verify-recovered-gold-build-source"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue