Merge branch 'gpu-fleet' into HEAD

This commit is contained in:
igneum-labs 2026-10-06 23:28:55 +00:00
commit 6aad8d8a53
5 changed files with 6 additions and 6 deletions

View file

@ -2,7 +2,7 @@
# The fleet's deploy gate (coordinator, 6 October 2026 23:0xZ, after three comment-on-a-line faults): every script pushed to a box
# passes master's defaults-line check and a syntax check first; lib/box.py's put() calls this for any .sh/.py source under
# tools/fleet and refuses the push on red. Usage: deploy-gate.sh <file...> (exit 0 = clean)
set -u; rc=0; HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"; MASTER_CI="${IGNEUM_MASTER_CI:-/Users/joshm/Projects/igneum/tools/ci}"
set -u; rc=0; HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"; MASTER_CI="${IGNEUM_MASTER_CI:-$HERE/../ci}" # the same tree's CI checks (master's once merged)
for f in "$@"; do
case "$f" in
*.sh) bash -n "$f" 2>&1 | head -2 | sed "s|^|$f: |" ; [ "${PIPESTATUS[0]}" = 0 ] || rc=1 ;;

View file

@ -8,7 +8,7 @@ import sys, os, json, time, subprocess
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); from lib import Box, Registry
from concurrent.futures import ThreadPoolExecutor
ROOT = os.path.expanduser("~/Desktop/fleet"); OUT = os.path.join(ROOT, "disk.json"); ALERTS = os.path.join(ROOT, "disk-alerts.json")
HOOKS = "/Users/joshm/Projects/igneum/tools/community/discord-hooks.mjs"
HOOKS = os.environ.get("IGNEUM_DISCORD_HOOKS", os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "community", "discord-hooks.mjs")) # this tree's hook script
def now(): return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
def one(item):
iid, b = item

View file

@ -78,7 +78,7 @@ class Box:
return f"{F}/in/{name}"
# ---- node ----
def stop_node(self):
self.run(f"pkill -f '{NODE_PATH_PATTERN}'; sleep 3; pkill -9 -f '{NODE_PATH_PATTERN}' 2>/dev/null; true", 40)
self.run(f"pkill -f '[/]root/fleet/in/igneumd|[/]opt/igneum/pkg/bin/igneumd'; sleep 3; pkill -9 -f '[/]root/fleet/in/igneumd|[/]opt/igneum/pkg/bin/igneumd' 2>/dev/null; true", 40)
def start_node(self, binary, override_local, peers, devnet_suffix=None, verifier=None, extra=(), appdir=None, log=None, unsynced_mining=False):
"""Writes the override file, kills the old node (anchored on its path), starts the new one; returns the digest it prints."""
appdir = appdir or (f"{F}/dn2" if devnet_suffix else f"{F}/node"); log = log or (f"{F}/dn2-node.log" if devnet_suffix else f"{F}/node.log")
@ -118,7 +118,7 @@ class Box:
b = self.rpc("eth_getBlockByNumber", [hex(height), False]) or {}
return b.get("stateRoot")
def node_version(self):
return self.run(f"v=$(pgrep -fa '{NODE_PATH_PATTERN}' | head -1 | awk '{{print $2}}'); [ -n \"$v\" ] && echo \"$(sha256sum \"$v\" | cut -c1-16) $($v --version 2>&1 | head -1)\"", 30)[1].strip()
return self.run(f"v=$(pgrep -fa '[/]root/fleet/in/igneumd|[/]opt/igneum/pkg/bin/igneumd' | head -1 | awk '{{print $2}}'); [ -n \"$v\" ] && echo \"$(sha256sum \"$v\" | cut -c1-16) $($v --version 2>&1 | head -1)\"", 30)[1].strip()
def rejects_since(self, since_utc, log=None):
log = log or f"{F}/node.log"
out = self.run(f"awk -v s='{since_utc}' 'substr($0,1,19) >= s' {log} 2>/dev/null | grep -cE 'got reject message|PoW rejected|block rejected|invalid block'", 30)[1].strip()

View file

@ -54,7 +54,7 @@ def digest_alert(label, got, expected):
st = json.load(open(DIGEST_ALERTS)) if os.path.exists(DIGEST_ALERTS) else {}
if time.time() - st.get(label, 0) < 3600: return
what = f"Fleet box {label} answers handshakes with consensus digest {got[:8]}, the live object is {expected[:8]}: peers on the live object refuse it and a node whose only peer it is sits on a frozen tip"
subprocess.run(["node", "/Users/joshm/Projects/igneum/tools/community/discord-hooks.mjs", "incident", "open", "--what", what, "--affected", "nodes that peer only with that box (a home miner reads synced on a frozen tip)", "--doing", "the fleet agent restarts the box's node on the live object; the supervisor's five-minute check found it", "--id", f"digest-{label}-{int(time.time())}", "--live"], capture_output=True, text=True, timeout=60)
subprocess.run(["node", os.environ.get("IGNEUM_DISCORD_HOOKS", os.path.join(HERE, "..", "community", "discord-hooks.mjs")), "incident", "open", "--what", what, "--affected", "nodes that peer only with that box (a home miner reads synced on a frozen tip)", "--doing", "the fleet agent restarts the box's node on the live object; the supervisor's five-minute check found it", "--id", f"digest-{label}-{int(time.time())}", "--live"], capture_output=True, text=True, timeout=60)
st[label] = time.time(); json.dump(st, open(DIGEST_ALERTS, "w")); print(now(), "digest alert", label, got[:8], "expected", expected[:8], flush=True)
def check_one(r):
b = Box.from_registry(r["label"]); row = dict(r); row["t"] = now()

View file

@ -10,7 +10,7 @@ result rows (results.json: {card_key: {...}}), the night rows (night.json: [..])
"""
import time, json, os, sys, time, datetime, subprocess
ROOT = os.path.expanduser("~/Desktop/fleet"); OUT = os.path.join(ROOT, "fleet.json")
PUBLISH = "/Users/joshm/Projects/igneum/tools/fleet/publish-fleet.sh"
PUBLISH = os.environ.get("IGNEUM_FLEET_PUBLISH", os.path.join(os.path.dirname(os.path.abspath(__file__)), "publish-fleet.sh")) # this tree's publish script (master's once merged)
def now(): return datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
def jl(name, default):
p = os.path.join(ROOT, name)