c885b5acf4
Measured on demo-felhom (N100, 16 GB): 61 apps deployed and removed through the product, sampled every 5 s; heavy apps with one real action (Immich 200 photos, Jellyfin transcode, Paperless OCR, Nextcloud 500 MB, ...). sizing.json for the estimator (tools/build_sizing.py), SIZING.md with the proposed minimum machine, METHOD.md. Power is RAPL CPU-package only (no meter). R-993 asks the operator to approve the minimum machine; R-994 lists catalog limits/requests that are too low; R-995 records leftover unnamed volumes after removal. R-231's dated check measured: dooplex-backup.service success, journal green.
29 lines
1.3 KiB
Python
29 lines
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""run_action.py TAG APP — run actions.sh APP inside the guest; record its @ts lines as events.
|
|
|
|
The password the action needs is the app's own generated admin password (from the `up` step's
|
|
0600 scratch file) or, for apps whose first user the action creates, a fresh one. It travels inside
|
|
the piped script, never on a command line, and is never written to evidence.
|
|
"""
|
|
import json, os, re, secrets, sys
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import bench
|
|
|
|
tag, app = sys.argv[1], sys.argv[2]
|
|
gen = {}
|
|
f = os.path.join(bench.SC, f".generated-{tag}.json")
|
|
if os.path.exists(f):
|
|
gen = json.load(open(f)).get(app, {})
|
|
pw = gen.get("PAPERLESS_ADMIN_PASSWORD") or gen.get("NEXTCLOUD_ADMIN_PASSWORD") or ("Sz-" + secrets.token_hex(12))
|
|
script = f"export PW='{pw}'\n" + open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "actions.sh")).read().replace(
|
|
'APP=${1:?app}', f'APP={app}')
|
|
out = bench.guest(script, timeout=6 * 3600)
|
|
assert pw not in out, "secret in output"
|
|
d = os.path.join(bench.AUDIT, "evidence", tag); os.makedirs(d, exist_ok=True)
|
|
open(os.path.join(d, f"action-{app}.txt"), "a").write(out)
|
|
bench._load(tag)
|
|
for m in re.finditer(r"^@(\d+) (\S+)(.*)$", out, re.M):
|
|
bench.EVENTS.append(dict(ts=int(m.group(1)), kind=m.group(2), app=app, note=m.group(3).strip()))
|
|
bench._save(tag)
|
|
print(out)
|