Windows combined package 0.2.0 (proto-cuda/windows-app): v4 exes from target-integration, peers = seed then Mac, fresh appdir devnet-v4, one miner and one worker per card with --identities 8, --evm-address (PAYOUT_EVM or derived per vendor from the PC name), voting on (VOTE=0 opts out), --prepare-packs for the hot swap with --exit-on-seed-change as the fallback, --yes on the node, STATUS regex tolerant of the v4 now= segment, version in the dashboard header. Mac app 0.2.0 (packaging/mac): v4 binaries, Metal worker rebuilt for macOS 11, data folder devnet-v4, EVM payout, identities in one process, synced= flag honoured. Seed (infra/seed-nodes): stage-v4.sh builds v4 on the VM as a niced, memory-capped transient service and installs a disabled igneumd-v4 unit with a fresh data dir; switch-v4.sh swaps the units (--back reverses); health.sh reports active-v4. Runbook: docs/plans/cutover-2026-10-04.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
34 lines
2.8 KiB
Bash
Executable file
34 lines
2.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Cut a seed over to devnet v4, or back. 4 October 2026. Run only after ./stage-v4.sh has installed igneumd-v4.
|
|
# ./switch-v4.sh [seed-name] stop and disable the v3 unit (igneumd), enable and start igneumd-v4 (fresh
|
|
# data dir /var/lib/igneum-v4), then print its sync state for up to 3 minutes
|
|
# ./switch-v4.sh [seed-name] --back the reverse: stop igneumd-v4, start the v3 unit on its untouched v3 database
|
|
# Both units bind the same ports (26610, 26611, 28610), so the stop comes first. The v3 database in /var/lib/igneum is
|
|
# never deleted by this script.
|
|
. "$(dirname "$0")/lib.sh"
|
|
name="${1:-$SEED_NAME}"; back=0
|
|
case "$name" in --back) back=1; name="$SEED_NAME" ;; esac
|
|
[ "${2:-}" = --back ] && back=1
|
|
ip=$(seed_ip "$name"); [ -n "$ip" ] || die "$name not in seeds.tsv"
|
|
|
|
if [ $back -eq 0 ]; then from=igneumd; to=igneumd-v4; label="devnet v4"; else from=igneumd-v4; to=igneumd; label="devnet v3 (rollback)"; fi
|
|
sssh "$ip" "test -f /etc/systemd/system/igneumd-v4.service && test -x /opt/igneum/v4/bin/igneumd" || die "igneumd-v4 is not staged on $name (./stage-v4.sh $name first)"
|
|
|
|
log "$name: switching to $label: stop+disable $from, enable+start $to"
|
|
sssh "$ip" "
|
|
set -e
|
|
systemctl disable --now $from >/dev/null 2>&1 || true
|
|
for i in 1 2 3 4 5 6 7 8 9 10; do systemctl is-active $from >/dev/null 2>&1 || break; sleep 1; done
|
|
systemctl enable --now $to
|
|
sleep 4
|
|
echo \"$from: \$(systemctl is-enabled $from 2>/dev/null || true)/\$(systemctl is-active $from 2>/dev/null || true) $to: \$(systemctl is-enabled $to 2>/dev/null)/\$(systemctl is-active $to 2>/dev/null)\"
|
|
journalctl -u $to --no-pager -n 6 -o cat
|
|
"
|
|
log "sync state of $to (one line every 10 s, up to 3 minutes; Ctrl+C any time):"
|
|
for i in $(seq 1 18); do
|
|
line=$(sssh "$ip" "python3 /opt/igneum/bin/wrpc.py call getInfo 2>/dev/null | python3 -c 'import json,sys; j=json.load(sys.stdin); print(\"synced=%s version=%s\" % (j.get(\"isSynced\"), j.get(\"serverVersion\")))' 2>/dev/null; python3 /opt/igneum/bin/wrpc.py call getBlockDagInfo 2>/dev/null | python3 -c 'import json,sys; j=json.load(sys.stdin); print(\"blocks=%s headers=%s daa=%s sink=%s\" % (j.get(\"blockCount\"), j.get(\"headerCount\"), j.get(\"virtualDaaScore\"), str(j.get(\"sink\",\"\"))[:12]))' 2>/dev/null; python3 /opt/igneum/bin/wrpc.py call getConnectedPeerInfo 2>/dev/null | python3 -c 'import json,sys; print(\"peers=%d\" % len(json.load(sys.stdin).get(\"peerInfo\",[])))' 2>/dev/null; systemctl is-active $to" 2>/dev/null | tr '\n' ' ')
|
|
log " $line"
|
|
case "$line" in *"synced=True"*"peers="[1-9]*) log "$to is synced with peers"; break ;; esac
|
|
sleep 10
|
|
done
|
|
log "done. Back with: ./switch-v4.sh $name $(if [ $back -eq 0 ]; then echo --back; else echo '(forward: no flag)'; fi). Health: ./health.sh $name"
|