igneum/tools/fleet/publish-0315.py

39 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""Publish 1 of 0.3.15 on the standing live-devnet boxes (the shipper's set, 6 October 2026, 21:4xZ): the Linux igneumd 7f0bde70
(release-0.3.15-node f1ea7a38; the first two cuts 713ef876 and 7961c5f1 failed the canary), igneum-miner e827d9db, the generator-4 workers (cuda 97e036e2, opencl ef9fbd03); the override
file stays the live thirteen-field object (digest b18ed271 on the new binary). Per box, through lib.box: the node binary to
/root/fleet/in/igneumd-<sha16> (sha-checked), the miner and workers over /opt/igneum/pkg/bin (the old ones kept as *.0314),
/root/fleet/standing.node rewritten so the supervisor restarts the node on it (data dir kept), the miner killed once so
the supervisor's loop restarts it on the new miner and worker. Then the read-back table: version line, digest, worker sha.
publish-0315.py [labels...] default: every standing box with role live
publish-0315.py --readback [labels...]
"""
import sys, os, hashlib
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); from lib import Box, Registry, standing
from concurrent.futures import ThreadPoolExecutor
SHIP = os.environ["IGNEUM_SHIP_TREE"] # the shipper's worktree with the built binaries; no default: another worktree is never assumed
NODE = (SHIP + "/vendor/igneum-node-0315/target-remote/release/igneumd", "7f0bde70cf2e72a3a9479ba6421f2b37162c3dd4391bf413717c99e6f168668d") # release-0.3.15-node f1ea7a38 (the stamp gate, the receive-side version rule, the pruned-node sync fix)
MINER = (SHIP + "/vendor/igneum-node-0315/target-remote/release/igneum-miner", "3976c1b270761218")
CUDA = (SHIP + "/infra/cross/out-workers/igneum-worker-cuda", "97e036e23f4ace66")
OCL = (SHIP + "/infra/cross/out-workers/igneum-worker-opencl", "ef9fbd03e7ce14d1")
def sha16(p): return hashlib.sha256(open(p, "rb").read()).hexdigest()[:16]
def publish(label):
b = Box.from_registry(label)
for p, s in (MINER, CUDA, OCL):
if sha16(p) != s: return label, f"local {os.path.basename(p)} sha {sha16(p)} is not {s}"
path = b.install_payload(NODE[0], NODE[1])
b.put([MINER[0], CUDA[0], OCL[0]], "/root/fleet/in/")
rc, out, err = b.run(f"""set -e; cd /opt/igneum/pkg/bin; for f in igneum-miner igneum-worker-cuda igneum-worker-opencl; do [ -e $f.0314 ] || cp $f $f.0314; cp /root/fleet/in/$f $f.new && chmod +x $f.new && mv $f.new $f; done
echo {path} > /root/fleet/standing.node
pkill -9 -f '[/](opt/igneum/pkg/bin|root/fleet/in)/igneumd(-0313|-[0-9a-f]{16})? --devnet --appdir=' 2>/dev/null; pkill -9 -f '[/]opt/igneum/pkg/bin/igneum-miner mine' 2>/dev/null; pkill -9 -f '[/]opt/igneum/pkg/bin/igneum-worker-cuda --serve' 2>/dev/null; true # the supervisor restarts the node on the new pointer within a minute, and the miner with it
echo swapped""", 120)
return label, out.strip() or err[:120]
def readback(label):
b = Box.from_registry(label)
rc, out, err = b.run(r"""P=$(pgrep -af '[/](opt/igneum/pkg/bin|root/fleet/in)/igneumd[^ ]* ' | head -1 | awk '{print $2}'); echo bin=$P sha=$(sha256sum $P 2>/dev/null | cut -c1-16) version="$($P --version 2>&1 | head -1)" vline=$(grep -oE 'igneumd/2\.1\.0-[0-9a-f]+' /root/fleet/node.log | tail -1) digest=$(grep -o 'digest: [0-9a-f]*' /root/fleet/node.log | tail -1 | awk '{print substr($2,1,16)}') miner=$(sha256sum /opt/igneum/pkg/bin/igneum-miner | cut -c1-16) cuda=$(sha256sum /opt/igneum/pkg/bin/igneum-worker-cuda | cut -c1-16) ocl=$(sha256sum /opt/igneum/pkg/bin/igneum-worker-opencl | cut -c1-16) $(/opt/igneum/pkg/bin/igneum-miner watch 1 grpc://127.0.0.1:26610 2>/dev/null | grep -oE 'blocks=[0-9]+|synced=[a-z]+' | tr '\n' ' ') miner_up=$(pgrep -fc '[/]opt/igneum/pkg/bin/igneum-miner mine') prover_up=$(pgrep -fc '[p]ython3 -u /root/fleet/in/box-prover.py') rej=$(grep -c 'PoW rejected' /root/fleet/node.log)""", 60)
return label, out.strip() or err[:120]
if __name__ == "__main__":
a = sys.argv[1:]; rb = a and a[0] == "--readback"; a = a[1:] if rb else a
labels = a or [r["label"] for r in standing.roster() if r["role"] == "live"]
with ThreadPoolExecutor(13) as ex:
for l, o in ex.map(readback if rb else publish, labels): print(l, "::", o, flush=True)