50 lines
3.0 KiB
Python
50 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""ADVERSARY: after the --quick FAIL run, independently verify the rollback restored the EXACT
|
|
known-good (data + healthy app), the known-good was NOT promoted, then leave idle."""
|
|
import os, subprocess, sys, hashlib
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from harness import canonical, lifecycle, warmsnap
|
|
|
|
R="custom-html"; D="warm-custom-html.ci.commoninternet.net"; HTML="/usr/share/nginx/html"
|
|
KG_STR="WC2-DATA-MARKER-7f3a9c"; BASE_SNAP_SHA="9ef62bdf11c6060c"
|
|
fails=[]
|
|
def sh(*c): return lifecycle.exec_in_app(D, list(c), service="app")
|
|
def snap_sha():
|
|
import glob
|
|
t=glob.glob(f"/var/lib/ci-warm/{R}/snapshot/volumes/*.tar")
|
|
return hashlib.sha256(open(t[0],"rb").read()).hexdigest()[:16] if t else "NONE"
|
|
def code(p):
|
|
return subprocess.run(["curl","-sk","--resolve",f"{D}:443:127.0.0.1","-o","/dev/null","-w","%{http_code}",
|
|
"--max-time","10",f"https://{D}{p}"],capture_output=True,text=True).stdout.strip()
|
|
|
|
reg=canonical.read_registry(R) or {}
|
|
ssha=snap_sha()
|
|
print(f"registry version={reg.get('version')} status={reg.get('status')} snapshot_sha={ssha} (baseline {BASE_SNAP_SHA})")
|
|
if reg.get('version')!="1.11.0+1.29.0": fails.append(f"known-good promoted/changed: {reg.get('version')}")
|
|
if reg.get('status')!="idle": fails.append(f"not idle: {reg.get('status')}")
|
|
if ssha!=BASE_SNAP_SHA: fails.append(f"snapshot changed: {ssha} != {BASE_SNAP_SHA}")
|
|
|
|
# bring canonical up, confirm restored data + healthy + non-broken image
|
|
canonical.deploy_canonical(R)
|
|
lifecycle.wait_healthy(D, ok_codes=(200,), path="/", deploy_timeout=300, http_timeout=20)
|
|
html=sh("ls",HTML).split()
|
|
kg_files=[f for f in html if f=="wc2-marker.txt"]
|
|
kg_content=sh("cat",f"{HTML}/wc2-marker.txt").strip() if kg_files else ""
|
|
img=subprocess.run(["docker","service","ls","--format","{{.Name}} {{.Image}}"],capture_output=True,text=True).stdout
|
|
serving=code("/")
|
|
print(f"AFTER deploy: html={html} kg_content={kg_content!r} serving/={serving}")
|
|
print(f"image: {[l for l in img.splitlines() if 'custom-html' in l]}")
|
|
if not kg_files: fails.append("rollback did NOT restore known-good marker file")
|
|
if KG_STR not in kg_content: fails.append(f"restored marker content wrong: {kg_content!r}")
|
|
if serving!="200": fails.append(f"rolled-back app not serving 200: {serving}")
|
|
if "99.99.99-doesnotexist" in img: fails.append("BROKEN image still deployed after rollback")
|
|
if "nginx:1.29.0" not in img: fails.append(f"canonical not on known-good image: {img!r}")
|
|
|
|
# leave idle
|
|
canonical.undeploy_keep_volume(R)
|
|
print(f"END status={(canonical.read_registry(R) or {}).get('status')} "
|
|
f"service={'custom-html' in subprocess.run(['docker','service','ls','--format','{{.Name}}'],capture_output=True,text=True).stdout}")
|
|
print("\nRESULT:", "FAIL: "+"; ".join(fails) if fails else
|
|
"PASS — --quick FAIL rolled back to EXACT known-good (marker+content restored, app healthy on nginx:1.29.0, broken image gone), known-good UNCHANGED+snapshot byte-identical (never promoted); left idle")
|
|
sys.exit(1 if fails else 0)
|