Files
felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/birth/BIRTH/birth.py
T

39 lines
2.8 KiB
Python

"""birth.py — checklist 5.1 / 4.3 (bench half) for sparkyfitness at the PIN, from birth, swap 0.
Renders the catalog template exactly as upgrade-test.py does (its own render/build_env/settle), starts the
from-birth sampler BEFORE `up -d`, times up -d -> every container healthy, then keeps sampling idle for HOLD s.
Images are pre-pulled, so the time is start time, not download time. Prints no secret."""
import importlib.util, json, os, subprocess, sys, time
sys.path.insert(0, "/opt/upg"); os.chdir("/opt/upg")
spec = importlib.util.spec_from_file_location("ut", "/opt/upg/upgrade-test.py"); ut = importlib.util.module_from_spec(spec)
sys.argv = ["upgrade-test.py"]; spec.loader.exec_module(ut)
from pathlib import Path
HOLD = int(os.environ.get("HOLD", "300"))
app, project = "sparkyfitness", "birth"
wd = Path("/opt/upg/work/BIRTH"); ev = Path("/opt/upg/evidence/BIRTH"); ev.mkdir(parents=True, exist_ok=True)
tdir = ut.TEMPLATES / app
env = ut.cvp.build_env(app, (tdir / ".felhom.yml").read_text(), (tdir / "docker-compose.yml").read_text())
ut.render(app, {}, wd, env)
log = open(ev / "birth.log", "w", buffering=1)
def say(m):
l = time.strftime("[%H:%M:%S] ", time.gmtime()) + m; print(l, flush=True); log.write(l + "\n")
say("images: " + json.dumps(ut.template_images(app, ut.TEMPLATES)))
say("swap on the bench: " + (subprocess.run(["swapon", "--show"], capture_output=True, text=True).stdout.strip() or "none"))
subprocess.run("rm -f /root/mem-birth.csv.stop; (NAMES='sparkyfitness-db sparkyfitness-server sparkyfitness' OUT=/root/mem-birth.csv DUR=1200 nohup bash /opt/upg/sampler.sh >/dev/null 2>&1 &)", shell=True)
time.sleep(1)
t0 = time.time()
up = ut.compose(wd, project, "up", "-d")
say(f"up -d rc={up.returncode} in {time.time()-t0:.1f}s")
ok, secs, states = ut.settle(project, wd, wait=600)
say(f"settled={ok} in {time.time()-t0:.1f}s after up -d (settle loop {secs}s) :: {json.dumps(states)}")
for c in ("sparkyfitness-db", "sparkyfitness-server", "sparkyfitness"):
r = subprocess.run(["docker", "inspect", "-f", "{{.State.StartedAt}} {{.State.Health.Status}} rc={{.RestartCount}} mem={{.HostConfig.Memory}}", c], capture_output=True, text=True)
say(f" {c}: {r.stdout.strip()}")
say(f"holding {HOLD}s idle for the from-birth sampler")
time.sleep(HOLD)
for c in ("sparkyfitness-db", "sparkyfitness-server", "sparkyfitness"):
r = subprocess.run(["docker", "inspect", "-f", "{{.State.Status}} {{.State.Health.Status}} rc={{.RestartCount}} OOMKilled(not-used)={{.State.OOMKilled}}", c], capture_output=True, text=True)
say(f" end {c}: {r.stdout.strip()}")
r = subprocess.run(f"docker logs sparkyfitness-server 2>&1 | grep -i -E 'migrat|error|listening|started' | head -40", shell=True, capture_output=True, text=True)
(ev / "server-startlines.txt").write_text(r.stdout)
say("server start lines saved (migrat|error|listening|started), %d lines" % len(r.stdout.splitlines()))