86c4b9a0d8
gates / gates (push) Successful in 27s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
72 lines
4.1 KiB
Python
72 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Part D live — the ladder on controller v0.268.0. romm installed at 5.3.0 / mariadb 11.4 (the ladder's
|
|
step-1 definition, steps/7f9c6a74b5891f8e.yml, served as the drill template for the install only); the
|
|
drill template then back to the head (5.3.1 / 11.8). Two presses: press 1 must apply ONLY the app step
|
|
(5.3.1 / 11.4, from steps/90dd9d68258286ef.yml), press 2 the engine step (11.4 -> 11.8, the template).
|
|
Seeded data read back after each press; the page's steps-left line read in both languages each time."""
|
|
import html as H, json, re, sys, time
|
|
sys.path.insert(0, ".")
|
|
import walk as w
|
|
import fixtures as fx
|
|
|
|
F, SUB, APP = fx.Romm(), "arcade-ld", "romm"
|
|
CAT = f"{w.DRILL}/templates/{APP}"
|
|
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
|
|
w.login()
|
|
|
|
|
|
def drill(body, msg):
|
|
import fcntl
|
|
with open(f"{w.SC}/drill.lock", "w") as lk:
|
|
fcntl.flock(lk, fcntl.LOCK_EX)
|
|
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
|
|
open(f"{CAT}/docker-compose.yml", "w").write(body)
|
|
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "LIVE-D " + msg])
|
|
r = w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
|
|
h = w.sh(["git", "-C", w.DRILL, "rev-parse", "--short=12", "HEAD"]).stdout.strip()
|
|
w.say(f"drill {h}: {msg} push rc={r.returncode}")
|
|
return h
|
|
|
|
|
|
def steps_line():
|
|
r = {}
|
|
for lang, q in (("hu", ""), ("en", "?lang=en")):
|
|
r[lang] = re.findall(r'data-ladder-steps="(\d+)">([^<]*)<', H.unescape(w.page(f"/apps/{APP}{q}")))
|
|
return r
|
|
|
|
|
|
def box_files():
|
|
return w.guest(f"grep -nE 'image:|memory:' /opt/docker/stacks/{APP}/docker-compose.yml; echo ---; cmp -s /opt/docker/stacks/{APP}/applied-compose.yml /var/lib/docker/volumes/felhom-controller-data/_data/data/catalog-cache/templates/{APP}/steps/90dd9d68258286ef.yml && echo 'applied == steps/90dd9d68258286ef.yml' || echo 'applied != steps/90dd…'; cmp -s /opt/docker/stacks/{APP}/applied-compose.yml /var/lib/docker/volumes/felhom-controller-data/_data/data/catalog-cache/templates/{APP}/docker-compose.yml && echo 'applied == template' || echo 'applied != template'")
|
|
|
|
|
|
HEAD = open(f"{CAT}/docker-compose.yml").read()
|
|
STEP1 = open(f"{CAT}/steps/7f9c6a74b5891f8e.yml").read()
|
|
out["drill_install"] = drill(STEP1, "romm template = step 1's own definition (5.3.0 / mariadb 11.4) for the install")
|
|
w.sync_rescan()
|
|
out["deployed"] = w.deploy(APP, SUB)
|
|
A = F.seed(w, SUB, w.say)
|
|
out["seed_A"] = bool(A)
|
|
out["drill_head"] = drill(HEAD, "romm back to the head (5.3.1 / mariadb 11.8)")
|
|
out["badge_wait"] = w.sync_rescan(APP, "mariadb:11.8", tries=60)
|
|
out["before"] = {"obs": w.observables(APP), "steps_line": steps_line(), "badges": w.badges(APP)}
|
|
w.say("before: steps line " + json.dumps(out["before"]["steps_line"], ensure_ascii=False) + " badges " + json.dumps(out["before"]["badges"], ensure_ascii=False)[:300])
|
|
|
|
for n in (1, 2):
|
|
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
|
|
p = w.press_update(APP)
|
|
obs = w.observables(APP)
|
|
w.wait_app(SUB, "/api/heartbeat", want=("200",), tries=60, delay=5)
|
|
rb = bool(F.verify(w, SUB, A, w.say))
|
|
log = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -E 'update romm' | grep -E 'ladder|pin advanced|DONE|UNDO|healthy after' | tail -8")
|
|
dblog = w.guest(f"docker logs --since {t0} romm-db 2>&1 | grep -iE 'upgrade|mariadb-upgrade|Version:' | tail -6")
|
|
B = F.seed(w, SUB, w.say) if n == 1 else None
|
|
out[f"press{n}"] = {"press": p, "obs": obs, "readback_A": rb, "log": log, "db_log": dblog,
|
|
"files": box_files(), "steps_line": steps_line(), "badges": w.badges(APP)}
|
|
if B:
|
|
out["seed_B"] = B
|
|
w.say(f"PRESS {n}: phase={p.get('final_phase')} pinned={obs.get('pinned_images')} readback A={rb}\n{log}\nDB: {dblog}\nfiles: {out[f'press{n}']['files']}\nsteps line: {out[f'press{n}']['steps_line']}")
|
|
if out.get("seed_B"):
|
|
out["readback_B_after_press2"] = bool(F.verify(w, SUB, out["seed_B"], w.say))
|
|
json.dump(out, open("../partD/10-romm-two-steps.json", "w"), indent=2, ensure_ascii=False, default=str)
|
|
open("../partD/10-romm-two-steps.log", "w").write("\n".join(w.LOG) + "\n")
|