Add per-node action groups with schedules, runs, and logs.

Let operators manage ordered action groups on each host, run them manually or on a schedule over SSH, and inspect disk-backed JSON run logs from a node detail UI.
This commit is contained in:
2026-07-19 20:01:11 +02:00
parent 50568127c5
commit 32af91fd30
22 changed files with 4337 additions and 32 deletions
+53
View File
@@ -0,0 +1,53 @@
package runner
import (
"testing"
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
)
func TestResolveItemLibraryAndLocal(t *testing.T) {
library := []settings.Action{
{
ID: settings.BuiltinActionUptimeID,
Name: "Uptime",
Kind: settings.ActionKindShell,
Body: "uptime",
Env: []settings.ActionEnvVar{},
},
}
resolved, err := ResolveItem(settings.NodeActionItem{
ID: "i1",
Source: settings.ActionItemSourceLibrary,
LibraryActionID: settings.BuiltinActionUptimeID,
}, library)
if err != nil {
t.Fatalf("ResolveItem library: %v", err)
}
if resolved.Name != "Uptime" || resolved.Body != "uptime" {
t.Fatalf("resolved = %#v", resolved)
}
local, err := ResolveItem(settings.NodeActionItem{
ID: "i2",
Source: settings.ActionItemSourceLocal,
Name: "Echo",
Kind: settings.ActionKindShell,
Body: "echo hi",
Env: []settings.ActionEnvVar{},
}, library)
if err != nil {
t.Fatalf("ResolveItem local: %v", err)
}
if local.Name != "Echo" {
t.Fatalf("local = %#v", local)
}
if _, err := ResolveItem(settings.NodeActionItem{
Source: settings.ActionItemSourceLibrary,
LibraryActionID: "missing",
}, library); err == nil {
t.Fatal("expected missing library action error")
}
}