From 01f9a992fdd02833db3baa317b7f4e714e3170cd Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 11 Jun 2026 16:41:21 +0100 Subject: [PATCH] Route Nightwing Muninn lifecycle through Idunn --- docs/muninn.md | 11 +++++--- scripts/health-nightwing-muninn.cmd | 2 ++ scripts/health-nightwing-muninn.ps1 | 28 ++++++++++++++++++++ scripts/restart-nightwing-muninn.cmd | 2 ++ scripts/restart-nightwing-muninn.ps1 | 39 ++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 scripts/health-nightwing-muninn.cmd create mode 100644 scripts/health-nightwing-muninn.ps1 create mode 100644 scripts/restart-nightwing-muninn.cmd create mode 100644 scripts/restart-nightwing-muninn.ps1 diff --git a/docs/muninn.md b/docs/muninn.md index 0b13568..0a88272 100644 --- a/docs/muninn.md +++ b/docs/muninn.md @@ -116,7 +116,12 @@ recreates the `GameCult-Muninn` scheduled task and writes `-WindowStyle Hidden` and redirects logs under `C:\Meta\Odin\logs\muninn`. The `.cmd` file must not be the long-lived foreground process. -Nightwing runs Muninn as the user service `gamecult-muninn.service`. The binary -is installed at `/home/metacrat/.local/bin/muninn`, the store lives at +Nightwing Muninn is kept alive by the single Idunn supervisor through the +`nightwing-muninn` daemon target. Idunn learns that target through Odin's typed +daemon surface and invokes `scripts/health-nightwing-muninn.ps1` and +`scripts/restart-nightwing-muninn.ps1`; those scripts are health/restart +actuators only, not lifecycle owners. The binary is installed at +`/home/metacrat/.local/bin/muninn`, the store lives at `/home/metacrat/.local/state/gamecult/muninn/muninn.telemetry.cc`, and the -service command uses `--host nightwing --interval-seconds 15`. +restart actuator launches `serve --host nightwing --interval-seconds 15` with +PID and logs under `/home/metacrat/.local/state/gamecult/muninn`. diff --git a/scripts/health-nightwing-muninn.cmd b/scripts/health-nightwing-muninn.cmd new file mode 100644 index 0000000..cdd79c9 --- /dev/null +++ b/scripts/health-nightwing-muninn.cmd @@ -0,0 +1,2 @@ +@echo off +powershell.exe -NoProfile -ExecutionPolicy Bypass -File E:\Projects\Odin\scripts\health-nightwing-muninn.ps1 diff --git a/scripts/health-nightwing-muninn.ps1 b/scripts/health-nightwing-muninn.ps1 new file mode 100644 index 0000000..8e9d65d --- /dev/null +++ b/scripts/health-nightwing-muninn.ps1 @@ -0,0 +1,28 @@ +param( + [string] $SshTarget = "nightwing", + [string] $MuninnExe = "/home/metacrat/.local/bin/muninn", + [string] $StorePath = "/home/metacrat/.local/state/gamecult/muninn/muninn.telemetry.cc", + [string] $PidPath = "/home/metacrat/.local/state/gamecult/muninn/muninn.pid" +) + +$ErrorActionPreference = "Stop" + +$remoteScript = @" +set -eu +if [ ! -x '$MuninnExe' ]; then + echo 'Muninn executable not found at $MuninnExe' >&2 + exit 1 +fi +if [ -f '$PidPath' ] && kill -0 "`$(cat '$PidPath')" 2>/dev/null; then + : +elif pgrep -f '[m]uninn serve .*--host nightwing' >/dev/null 2>&1; then + : +else + echo 'Muninn serve process is not running on Nightwing' >&2 + exit 1 +fi +'$MuninnExe' --health --store '$StorePath' +"@ + +ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget $remoteScript +exit $LASTEXITCODE diff --git a/scripts/restart-nightwing-muninn.cmd b/scripts/restart-nightwing-muninn.cmd new file mode 100644 index 0000000..1b6a169 --- /dev/null +++ b/scripts/restart-nightwing-muninn.cmd @@ -0,0 +1,2 @@ +@echo off +powershell.exe -NoProfile -ExecutionPolicy Bypass -File E:\Projects\Odin\scripts\restart-nightwing-muninn.ps1 diff --git a/scripts/restart-nightwing-muninn.ps1 b/scripts/restart-nightwing-muninn.ps1 new file mode 100644 index 0000000..36bb2e2 --- /dev/null +++ b/scripts/restart-nightwing-muninn.ps1 @@ -0,0 +1,39 @@ +param( + [string] $SshTarget = "nightwing", + [string] $MuninnExe = "/home/metacrat/.local/bin/muninn", + [string] $StorePath = "/home/metacrat/.local/state/gamecult/muninn/muninn.telemetry.cc", + [string] $LogRoot = "/home/metacrat/.local/state/gamecult/muninn", + [int] $IntervalSeconds = 15 +) + +$ErrorActionPreference = "Stop" + +$remoteScript = @" +set -eu +mkdir -p '$LogRoot' +if [ ! -x '$MuninnExe' ]; then + echo 'Muninn executable not found at $MuninnExe' >&2 + exit 1 +fi +if [ -f '$LogRoot/muninn.pid' ] && kill -0 "`$(cat '$LogRoot/muninn.pid')" 2>/dev/null; then + kill "`$(cat '$LogRoot/muninn.pid')" 2>/dev/null || true + sleep 1 +fi +for pid in `$(pgrep -f '[m]uninn serve .*--host nightwing' 2>/dev/null || true); do + kill "`$pid" 2>/dev/null || true +done +nohup '$MuninnExe' serve \ + --store '$StorePath' \ + --log-root '$LogRoot' \ + --host nightwing \ + --interval-seconds '$IntervalSeconds' \ + > '$LogRoot/muninn-serve.out.log' \ + 2> '$LogRoot/muninn-serve.err.log' \ + < /dev/null & +echo `$! > '$LogRoot/muninn.pid' +sleep 1 +kill -0 "`$(cat '$LogRoot/muninn.pid')" 2>/dev/null +"@ + +ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget $remoteScript +exit $LASTEXITCODE