Pin mesh-sdk 754edfae, so a manifest the mesh refuses holds that module alone and the node composes the rest (issue 774)
At 19:13 on 2026-10-30 power's bar item (mesh-catalog ca8d6f33) made frombus.Compose refuse the whole node, and the composer marked every module not composed (32 of 81 failed on shanks). The composer already holds what Compose names held (NotComposedEach, issue 1126); the SDK now names a refused manifest's module held instead of refusing the node. Quick fix: none in mesh-host; thorough fix is the SDK's input (one rule for Compose, Answer and PlansHeld). The test replays the captured power manifest and fails on the old pin with the live words.
This commit is contained in:
@@ -3,7 +3,7 @@ module github.com/novox/mesh-host
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030182415-754edfae6924
|
||||
github.com/nats-io/nats-server/v2 v2.11.17
|
||||
github.com/nats-io/nats.go v1.54.0
|
||||
golang.org/x/crypto v0.57.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0 h1:lKU3HjNXGiVbLW2hUgFjU/TMTUYMlNnnmZxG5T7biQA=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030182415-754edfae6924 h1:aIiKj066gYFEDokUOq0i2n4vsygu5g0XMKJRRaMI4fM=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030182415-754edfae6924/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||
|
||||
@@ -366,6 +366,36 @@ func TestTheNodeComposesItsWantsFromTheBus(t *testing.T) {
|
||||
strings.Contains((*told)[0], "held lemurs") {
|
||||
t.Errorf("the agent was told %q, want de-spiegel held alone, in its config form's words, without its routes", *told)
|
||||
}
|
||||
// Issue 774, 2026-10-30 19:13: a manifest the mesh refuses (power's bar item at mesh-catalog ca8d6f33, captured, with
|
||||
// attributes its bar places by none of) refused every node's composition and failed all its modules. Now power is
|
||||
// held alone, naming why, and lemurs is handed.
|
||||
power, err := os.ReadFile("testdata/power-ca8d6f33.module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c4, told4 := fresh(env.Get)
|
||||
powerDig := delivery.ManifestDigest(power)
|
||||
powerEnc, _ := delivery.EncodeManifest(delivery.Manifest{Module: "power", JSON: string(power)})
|
||||
powerKey, _ := delivery.ManifestsKey(powerDig)
|
||||
b.mu.Lock()
|
||||
b.kv[delivery.ManifestsBucket+"/"+powerKey] = powerEnc
|
||||
b.mu.Unlock()
|
||||
powerFP := delivery.SourcePrefix2 + strings.Repeat("c", 64)
|
||||
c4.modules["power"] = delivery.Module{FP2: powerFP, Manifest: powerDig, Repository: "novox/mesh-catalog", Commit: "ca8d6f33"}
|
||||
c4.wants["power"] = delivery.Want{FP: powerFP, Self: true}
|
||||
p4 := c4.placements["n1"]
|
||||
p4.Modules = append(append([]delivery.PlacedModule{}, p4.Modules...), delivery.PlacedModule{Module: "power"})
|
||||
c4.placements["n1"] = p4
|
||||
handed4 := map[string]agent.Update{}
|
||||
for _, u := range c4.compose(ctx) {
|
||||
handed4[u.Key] = u
|
||||
}
|
||||
if u, ok := handed4[lemursKey3]; !ok || u.Deleted {
|
||||
t.Errorf("lemurs is not handed beside power's refused manifest: %v (told %q)", handed4, *told4)
|
||||
}
|
||||
if len(*told4) != 1 || !strings.HasPrefix((*told4)[0], "held power: ") || !strings.Contains((*told4)[0], `"shows" is none of them`) {
|
||||
t.Errorf("the agent was told %q, want power held alone, naming its item", *told4)
|
||||
}
|
||||
|
||||
// A read the bus did not answer, timed out or not, is tried again later; the run's own end and a refusal are not.
|
||||
if !BusFailed(fmt.Errorf("the revisions of it2.mailer.domain: %w", context.DeadlineExceeded)) || !BusFailed(fmt.Errorf("x: %w", nats.ErrNoResponders)) ||
|
||||
|
||||
@@ -0,0 +1,452 @@
|
||||
{
|
||||
"module": "power",
|
||||
"version": "1",
|
||||
"moved": true,
|
||||
"templates": "templates",
|
||||
"capabilities": [
|
||||
"package-manager",
|
||||
"service-manager"
|
||||
],
|
||||
"claims": [
|
||||
{
|
||||
"name": "node-power",
|
||||
"scope": "node"
|
||||
}
|
||||
],
|
||||
"emits": [
|
||||
"booted",
|
||||
"sleeping",
|
||||
"woke",
|
||||
"shutting-down",
|
||||
"on-mains",
|
||||
"on-battery",
|
||||
"battery-low"
|
||||
],
|
||||
"state": [
|
||||
{
|
||||
"name": "draw",
|
||||
"ttl-seconds": 30,
|
||||
"per-machine": true
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
"power_state",
|
||||
"power_hooks",
|
||||
"power_history",
|
||||
"power_run",
|
||||
"power_check"
|
||||
],
|
||||
"config": {
|
||||
"handle-power-key": {
|
||||
"type": "string",
|
||||
"description": "What logind does when the power key is pressed: one of logind's actions, such as suspend, ignore or poweroff (logind.conf(5)); the operator's choice for this machine, with no default.",
|
||||
"enum": [
|
||||
"ignore",
|
||||
"poweroff",
|
||||
"reboot",
|
||||
"halt",
|
||||
"kexec",
|
||||
"suspend",
|
||||
"hibernate",
|
||||
"hybrid-sleep",
|
||||
"suspend-then-hibernate",
|
||||
"lock",
|
||||
"factory-reset",
|
||||
"sleep"
|
||||
],
|
||||
"trusted": true,
|
||||
"required": true
|
||||
},
|
||||
"handle-lid-switch": {
|
||||
"type": "string",
|
||||
"description": "What logind does when the lid is closed on battery: one of logind's actions, such as suspend, ignore or poweroff (logind.conf(5)); the operator's choice for this machine, with no default.",
|
||||
"enum": [
|
||||
"ignore",
|
||||
"poweroff",
|
||||
"reboot",
|
||||
"halt",
|
||||
"kexec",
|
||||
"suspend",
|
||||
"hibernate",
|
||||
"hybrid-sleep",
|
||||
"suspend-then-hibernate",
|
||||
"lock",
|
||||
"factory-reset",
|
||||
"sleep"
|
||||
],
|
||||
"trusted": true,
|
||||
"required": true
|
||||
},
|
||||
"handle-lid-switch-external-power": {
|
||||
"type": "string",
|
||||
"description": "What logind does when the lid is closed on external power: one of logind's actions, such as suspend, ignore or poweroff (logind.conf(5)); the operator's choice for this machine, with no default.",
|
||||
"enum": [
|
||||
"ignore",
|
||||
"poweroff",
|
||||
"reboot",
|
||||
"halt",
|
||||
"kexec",
|
||||
"suspend",
|
||||
"hibernate",
|
||||
"hybrid-sleep",
|
||||
"suspend-then-hibernate",
|
||||
"lock",
|
||||
"factory-reset",
|
||||
"sleep"
|
||||
],
|
||||
"trusted": true,
|
||||
"required": true
|
||||
},
|
||||
"handle-lid-switch-docked": {
|
||||
"type": "string",
|
||||
"description": "What logind does when the lid is closed while docked or with another screen attached: one of logind's actions, such as suspend, ignore or poweroff (logind.conf(5)); the operator's choice for this machine, with no default.",
|
||||
"enum": [
|
||||
"ignore",
|
||||
"poweroff",
|
||||
"reboot",
|
||||
"halt",
|
||||
"kexec",
|
||||
"suspend",
|
||||
"hibernate",
|
||||
"hybrid-sleep",
|
||||
"suspend-then-hibernate",
|
||||
"lock",
|
||||
"factory-reset",
|
||||
"sleep"
|
||||
],
|
||||
"trusted": true,
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"id": "polkit",
|
||||
"type": "package",
|
||||
"package": "polkit"
|
||||
},
|
||||
{
|
||||
"id": "scripts",
|
||||
"type": "archive",
|
||||
"path": "/usr/local/lib/mesh-power",
|
||||
"artifact": "scripts",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "config-dir",
|
||||
"type": "directory",
|
||||
"path": "/etc/mesh-power",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "moments-dir",
|
||||
"type": "directory",
|
||||
"path": "/etc/mesh-power/moments",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "moment-after-boot",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/after-boot",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/after-boot"
|
||||
},
|
||||
{
|
||||
"id": "moment-before-sleep",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/before-sleep",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/before-sleep"
|
||||
},
|
||||
{
|
||||
"id": "moment-after-wake",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/after-wake",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/after-wake"
|
||||
},
|
||||
{
|
||||
"id": "moment-before-shutdown",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/before-shutdown",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/before-shutdown"
|
||||
},
|
||||
{
|
||||
"id": "moment-on-mains",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/on-mains",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/on-mains"
|
||||
},
|
||||
{
|
||||
"id": "moment-on-battery",
|
||||
"type": "file",
|
||||
"path": "/etc/mesh-power/moments/on-battery",
|
||||
"mode": "0644",
|
||||
"template": "templates/mesh-power/moments/on-battery"
|
||||
},
|
||||
{
|
||||
"id": "logind-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/logind.conf.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "logind-power",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/logind.conf.d/power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/logind.conf.d/power.conf"
|
||||
},
|
||||
{
|
||||
"id": "logind",
|
||||
"type": "service",
|
||||
"unit": "systemd-logind.service",
|
||||
"reload-on": [
|
||||
"logind-power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "after-boot-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-after-boot.service",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/mesh-power-after-boot.service"
|
||||
},
|
||||
{
|
||||
"id": "before-shutdown-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-before-shutdown.service",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/mesh-power-before-shutdown.service"
|
||||
},
|
||||
{
|
||||
"id": "before-sleep-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-before-sleep.service",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/mesh-power-before-sleep.service"
|
||||
},
|
||||
{
|
||||
"id": "after-wake-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-after-wake.service",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/mesh-power-after-wake.service"
|
||||
},
|
||||
{
|
||||
"id": "supply-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-supply.service",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/mesh-power-supply.service"
|
||||
},
|
||||
{
|
||||
"id": "sleep-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/sleep.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "sleep-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/sleep.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/sleep.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "suspend-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/suspend.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "suspend-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/suspend.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/suspend.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "hibernate-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/hibernate.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "hibernate-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/hibernate.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/hibernate.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "hybrid-sleep-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/hybrid-sleep.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "hybrid-sleep-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/hybrid-sleep.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/hybrid-sleep.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "suspend-then-hibernate-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/suspend-then-hibernate.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "suspend-then-hibernate-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/suspend-then-hibernate.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/suspend-then-hibernate.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "reboot-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/reboot.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "reboot-bound",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/reboot.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/reboot.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "poweroff-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/poweroff.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "poweroff-bound",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/poweroff.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/poweroff.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "halt-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/halt.target.d",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "halt-bound",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/halt.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"template": "templates/systemd/system/halt.target.d/mesh-power.conf"
|
||||
},
|
||||
{
|
||||
"id": "udev-rule",
|
||||
"type": "file",
|
||||
"path": "/etc/udev/rules.d/90-mesh-power.rules",
|
||||
"mode": "0644",
|
||||
"template": "templates/udev/rules.d/90-mesh-power.rules"
|
||||
},
|
||||
{
|
||||
"id": "after-boot",
|
||||
"type": "service",
|
||||
"unit": "mesh-power-after-boot.service",
|
||||
"state": "running",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "before-shutdown",
|
||||
"type": "service",
|
||||
"unit": "mesh-power-before-shutdown.service",
|
||||
"state": "running",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "draw-dir",
|
||||
"type": "directory",
|
||||
"path": "/run/mesh-power",
|
||||
"mode": "0755",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "draw",
|
||||
"type": "process",
|
||||
"name": "mesh-power-draw",
|
||||
"artifact": "tools-go",
|
||||
"run": [
|
||||
"./power",
|
||||
"draw"
|
||||
],
|
||||
"health": {
|
||||
"kind": "unit"
|
||||
}
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "tools-go",
|
||||
"kind": "bundle",
|
||||
"language": "go",
|
||||
"system": "arch",
|
||||
"from": "cmd/power",
|
||||
"binary": "power",
|
||||
"loads": [
|
||||
"power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scripts",
|
||||
"kind": "archive",
|
||||
"from": "files"
|
||||
},
|
||||
{
|
||||
"name": "templates",
|
||||
"kind": "archive",
|
||||
"from": "templates"
|
||||
}
|
||||
]
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"collection": "contribution:node-bar:block",
|
||||
"name": "battery",
|
||||
"if-capability": "battery",
|
||||
"attributes": {
|
||||
"bar": "bottom",
|
||||
"place": "status",
|
||||
"order": "40"
|
||||
},
|
||||
"template": "templates/bar-battery"
|
||||
},
|
||||
{
|
||||
"collection": "contribution:node-bar:block",
|
||||
"name": "power-draw",
|
||||
"if-capability": "power-meter",
|
||||
"attributes": {
|
||||
"bar": "bottom",
|
||||
"place": "status",
|
||||
"order": "45",
|
||||
"shows": "state",
|
||||
"state": "power.draw"
|
||||
},
|
||||
"template": "templates/bar-power-draw"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user