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.
26 lines
1.4 KiB
Python
26 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
||
"""render_table.py — put the per-app table from evidence/apps-table.json into SIZING.md (__APPS_TABLE__ or between markers)."""
|
||
import json, os, re
|
||
A = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
t = json.load(open(os.path.join(A, "evidence", "apps-table.json")))
|
||
rows = ["<!-- apps-table: generated by tools/render_table.py -->",
|
||
"| App | Typical MB | Peak MB | Catalog request / limit | CPU class | CPU rest % | Busiest minute % | Source |",
|
||
"|---|---|---|---|---|---|---|---|"]
|
||
for a in sorted(t, key=lambda a: -(a["mem_peak_mb"] or 0)):
|
||
f = lambda v: "–" if v is None else (f"{v:,}" if isinstance(v, int) else str(v))
|
||
src = a["source"] + (" !" if a["sources_disagree"] else "")
|
||
if a.get("lifecycle"):
|
||
src += f" — {a['lifecycle']}"
|
||
rows.append(f"| {a['display_name']} (`{a['slug']}`) | {f(a['mem_typical_mb'])} | {f(a['mem_peak_mb'])} | "
|
||
f"{f(a['catalog_request_mb'])} / {f(a['catalog_limit_mb'])} | {a['cpu_class'] or '—'} | "
|
||
f"{f(a['cpu_rest_pct'])} | {f(a['cpu_peak_1m_pct'])} | {src} |")
|
||
rows.append("<!-- /apps-table -->")
|
||
p = os.path.join(A, "SIZING.md"); s = open(p, encoding="utf-8").read()
|
||
block = "\n".join(rows)
|
||
if "__APPS_TABLE__" in s:
|
||
s = s.replace("__APPS_TABLE__", block)
|
||
else:
|
||
s = re.sub(r"<!-- apps-table:.*?<!-- /apps-table -->", block, s, flags=re.S)
|
||
open(p, "w", encoding="utf-8").write(s)
|
||
print(len(t), "rows")
|