The node-engine finds the tool runner by what its manifest says (tool-runner), never by its name, pinned at mesh-sdk a973bfa (issue 774, the operator 2026-11-03)
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.20261103103643-4f141ff08892
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103105230-a973bfaf42b2
|
||||
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
|
||||
|
||||
@@ -2,6 +2,8 @@ git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAu
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103103643-4f141ff08892 h1:XWorhIHDVECRCYzGbkaexEpJ7v03B9LrZ8IVy7vkUKs=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103103643-4f141ff08892/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103105230-a973bfaf42b2 h1:CMNEBKlWI36rQEG5lhFRKoICquvYP4hBD7h/jCVFIcc=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103105230-a973bfaf42b2/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=
|
||||
|
||||
@@ -316,7 +316,6 @@ func RunsAnyOf(runs *delivery.Composed, module string) bool {
|
||||
// nothing of has no Loads: the runtime dropped it, and the composition reads its loads again from the module's build
|
||||
// (issue 1126, review: shanks had already applied the drop of systemd-resolved). Nil when running holds no runtime process.
|
||||
func ToolsRunning(running []delivery.Composed) map[string][]catalogue.Bundle {
|
||||
runtimeID := catalogue.RuntimeModule + "." + resolution.RuntimeProcessID()
|
||||
type resource struct {
|
||||
ID string `json:"id"`
|
||||
Module string `json:"module"`
|
||||
@@ -339,7 +338,8 @@ func ToolsRunning(running []delivery.Composed) map[string][]catalogue.Bundle {
|
||||
owner, _ = declaration.ModuleGuess(r.ID)
|
||||
}
|
||||
switch {
|
||||
case r.Type == "process" && r.ID == runtimeID && owner == catalogue.RuntimeModule:
|
||||
case r.Type == "process" && owner != "" && r.ID == owner+"."+resolution.RuntimeProcessID():
|
||||
// The tool runner's process, by its id alone: `<its module>.runtime` (resolutionRuntimeProcess).
|
||||
env = r.Env
|
||||
case r.Type == "archive" && owner != "" && strings.HasPrefix(r.ID, owner+"."+resolution.BundleID("")):
|
||||
name := strings.TrimPrefix(r.ID, owner+"."+resolution.BundleID(""))
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestCompositionsAreTheDeclarationSplitByModule(t *testing.T) {
|
||||
// indexer's commit has no bundles (shanks's runtime lost the folded systemd-resolved, novox's the folded nats), and a
|
||||
// held module's new build's bundles are not delivered.
|
||||
dg := func(c byte) string { return "sha256:" + strings.Repeat(string(c), 64) }
|
||||
runtime := catalogue.Manifest{Module: catalogue.RuntimeModule, Version: "1",
|
||||
runtime := catalogue.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/mesh/node-tools/broker"}},
|
||||
Bundles: []catalogue.Bundle{{Name: "runtime", Source: catalogue.ArtifactStoreScheme + "node-tools/runtime/blobs/" + dg('a'),
|
||||
Digest: dg('a'), Language: "go", Binary: "node-tools"}}}
|
||||
@@ -125,7 +125,7 @@ func TestCompositionsAreTheDeclarationSplitByModule(t *testing.T) {
|
||||
if dropped {
|
||||
env = `"MESH_TOOL_MODULES":""` // the drop already applied (shanks, 2026-10-29)
|
||||
}
|
||||
return delivery.Composed{Node: "anchor", Module: catalogue.RuntimeModule, Resources: []json.RawMessage{json.RawMessage(
|
||||
return delivery.Composed{Node: "anchor", Module: "node-tools", Resources: []json.RawMessage{json.RawMessage(
|
||||
`{"id":"node-tools.runtime","module":"node-tools","type":"process","name":"node-tools","env":{` + env + `}}`)}}
|
||||
}
|
||||
lampRuns := `{"id":"lamp.bundle-tools","type":"archive","source":"` + catalogue.ArtifactStoreScheme + `lamp/tools/blobs/` + dg('b') +
|
||||
@@ -155,13 +155,13 @@ func TestCompositionsAreTheDeclarationSplitByModule(t *testing.T) {
|
||||
}, map[string]string{"lamp": fpFor('1')}, false},
|
||||
} {
|
||||
tools := aMesh(t)
|
||||
tools.Catalogue[catalogue.RuntimeModule], tools.Catalogue["artifacts"], tools.Catalogue["lamp"] = runtime, store, lamp
|
||||
tools.Catalogue["node-tools"], tools.Catalogue["artifacts"], tools.Catalogue["lamp"] = runtime, store, lamp
|
||||
anchor := nodeOf(t, &tools, "anchor")
|
||||
anchor.Assigned = append(anchor.Assigned, "artifacts", catalogue.RuntimeModule, "lamp")
|
||||
tools.BusMinted = []string{"anchor." + catalogue.RuntimeModule}
|
||||
anchor.Assigned = append(anchor.Assigned, "artifacts", "node-tools", "lamp")
|
||||
tools.BusMinted = []string{"anchor." + "node-tools"}
|
||||
anchor.SealingKey = keyOf(t, "anchor")
|
||||
anchor.RunsTools = ToolsRunning([]delivery.Composed{runtimeRuns(row.dropped), row.set(anchor)})
|
||||
row.fps[overlay.Name], row.fps["artifacts"], row.fps[catalogue.RuntimeModule] = fpFor('a'), fpFor('5'), fpFor('e')
|
||||
row.fps[overlay.Name], row.fps["artifacts"], row.fps["node-tools"] = fpFor('a'), fpFor('5'), fpFor('e')
|
||||
out, _, _, err := CompositionsIn(tools, "anchor", row.fps, Foreseeing)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", row.name, err)
|
||||
|
||||
@@ -404,11 +404,11 @@ func firstReason(err error, failed map[string]string) error {
|
||||
return fmt.Errorf("%s; its stand-in is then refused: %w", strings.Join(named, "; "), err)
|
||||
}
|
||||
|
||||
// blames says the composition with m's stub (again) makes m the culprit of err: it composes, or fails otherwise. The
|
||||
// blames says the composition with m's stub (again) makes m the culprit of err, m the tool runner (runner) or not: it composes, or fails otherwise. The
|
||||
// runtime's stub is never a runtime (no build is taken in, so it carries no bundle) and always fails otherwise: it is
|
||||
// the culprit only where its stub composes (issue 774, 2026-10-30 19:30: node-tools held for any error naming it).
|
||||
func blames(m string, again, err error) bool {
|
||||
if m == catalogue.RuntimeModule {
|
||||
func blames(runner bool, again, err error) bool {
|
||||
if runner {
|
||||
// Or where its stub fails only for the modules of their own account it would run (issue 774): they are held
|
||||
// after it, each for its own words, and the node composes the rest.
|
||||
var none *resolution.NoRuntimeToRunError
|
||||
@@ -470,7 +470,8 @@ func culprit(in compose.Input, node string, fps map[string]string, mode compose.
|
||||
}
|
||||
changes := func(m, leave string) bool {
|
||||
_, _, _, again := compose.CompositionsIn(stubbed(in, node, m, leave), node, fps, mode)
|
||||
return blames(m, again, err)
|
||||
man, known := manifestOn(in, node, m)
|
||||
return blames(known && catalogue.IsToolRunner(man), again, err)
|
||||
}
|
||||
for _, m := range order {
|
||||
if _, done := failed[m]; done {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"github.com/novox/mesh-host/internal/compose"
|
||||
"github.com/novox/mesh-host/internal/compose/resolution"
|
||||
@@ -100,12 +99,12 @@ func theRuntimeIsBlamedOnlyWhereItsStubComposes(t *testing.T) {
|
||||
{"lamp", nil, true},
|
||||
{"lamp", errors.New("other"), true},
|
||||
{"lamp", errors.New("lamp refuses"), false},
|
||||
{catalogue.RuntimeModule, nil, true},
|
||||
{catalogue.RuntimeModule, errors.New("node-tools is assigned to n1 and its build produced 0 bundle(s)"), false},
|
||||
{catalogue.RuntimeModule, fmt.Errorf("compose: %w", &resolution.NoRuntimeToRunError{Held: true}), true},
|
||||
{catalogue.RuntimeModule, &resolution.NoRuntimeToRunError{}, false},
|
||||
{"node-tools", nil, true},
|
||||
{"node-tools", errors.New("node-tools is assigned to n1 and its build produced 0 bundle(s)"), false},
|
||||
{"node-tools", fmt.Errorf("compose: %w", &resolution.NoRuntimeToRunError{Held: true}), true},
|
||||
{"node-tools", &resolution.NoRuntimeToRunError{}, false},
|
||||
} {
|
||||
if got := blames(row.module, row.again, err); got != row.blamed {
|
||||
if got := blames(row.module == "node-tools", row.again, err); got != row.blamed {
|
||||
t.Errorf("%s with %v: blamed %v, want %v", row.module, row.again, got, row.blamed)
|
||||
}
|
||||
}
|
||||
@@ -117,13 +116,13 @@ func theRuntimeIsBlamedOnlyWhereItsStubComposes(t *testing.T) {
|
||||
// another build than the trunk's is composed from the build its want names.
|
||||
func aRunningModuleWaitsForItsBuild(t *testing.T) {
|
||||
dg := func(c string) string { return "sha256:" + strings.Repeat(c, 64) }
|
||||
tools := `{"module":"node-tools","version":"1","own-secrets":{"broker":"/var/lib/mesh/node-tools/broker"},` +
|
||||
tools := `{"module":"node-tools","version":"1","tool-runner":true,"own-secrets":{"broker":"/var/lib/mesh/node-tools/broker"},` +
|
||||
`"build":{"artifacts":[{"name":"runtime","kind":"bundle","language":"go","system":"arch","from":"cmd/node-tools"}]}}`
|
||||
lamp := `{"module":"lamp","version":"1","resources":[{"id":"service","type":"service","unit":"lamp.service","state":"running","boot":"enabled"}]}`
|
||||
store := `{"module":"artifacts","version":"1","provides":[{"name":"artifact-store","scope":"mesh"}],"serves":{"artifact-store":{"port":5100}},` +
|
||||
`"receives":{"artifact-store":"/var/lib/artifacts/received.json"}}`
|
||||
old, next := "src2:"+strings.Repeat("a", 64), "src2:"+strings.Repeat("b", 64)
|
||||
running := []delivery.Composed{{Node: "n1", Module: catalogue.RuntimeModule, FP: old, Resources: []json.RawMessage{
|
||||
running := []delivery.Composed{{Node: "n1", Module: "node-tools", FP: old, Resources: []json.RawMessage{
|
||||
json.RawMessage(`{"id":"node-tools.runtime","module":"node-tools","type":"process","name":"node-tools","env":{"MESH_TOOL_MODULES":""}}`),
|
||||
json.RawMessage(`{"id":"node-tools.bundle-runtime","module":"node-tools","type":"archive","source":"artifact-store://node-tools/runtime/blobs/` +
|
||||
dg("1") + `","digest":"` + dg("1") + `","path":"` + resolution.BundlePath("node-tools", "runtime") + `"}`)}}}
|
||||
@@ -207,7 +206,7 @@ func aHeldModulesFirstReasonLeads(t *testing.T) {
|
||||
// secrets: the node composes every other module, and the held one keeps the words it was first held for.
|
||||
func aHeldModuleOfItsOwnAccountNeverRefusesTheNode(t *testing.T) {
|
||||
dg := "sha256:" + strings.Repeat("1", 64)
|
||||
tools := `{"module":"node-tools","version":"1","own-secrets":{"broker":"/var/lib/mesh/node-tools/broker"},` +
|
||||
tools := `{"module":"node-tools","version":"1","tool-runner":true,"own-secrets":{"broker":"/var/lib/mesh/node-tools/broker"},` +
|
||||
`"build":{"artifacts":[{"name":"runtime","kind":"bundle","language":"go","system":"arch","from":"cmd/node-tools"}]}}`
|
||||
own := func(name string) string {
|
||||
return `{"module":"` + name + `","version":"1","runs-as":"` + name + `","secrets-owner":"` + name + `","tools":["status"],` +
|
||||
|
||||
@@ -1046,7 +1046,7 @@ func resolutionCompose(r mcat.Resolution, with mcat.Rendering, owner map[string]
|
||||
return nil, err
|
||||
}
|
||||
if process != nil { // none for a held runtime's stand-in: what runs of it is carried
|
||||
owner[fmt.Sprint(process["id"])] = mcat.RuntimeModule
|
||||
owner[fmt.Sprint(process["id"])] = fmt.Sprint(process["name"]) // the tool runner's module (resolutionRuntimeProcess)
|
||||
out = append(out, process)
|
||||
}
|
||||
// And a runtime of its own for each module of its own account, after it (novox/hq ADR 0259 §8).
|
||||
@@ -1308,7 +1308,7 @@ func resolutionOwnSecretOwner(r mcat.Resolution, m mcat.Manifest, name string) s
|
||||
if o := m.OwnSecrets[name].Owner; o != "" {
|
||||
return o
|
||||
}
|
||||
if r.Account != "" && (m.Module == mcat.RuntimeModule || ToolsBusSecret(m, name)) {
|
||||
if r.Account != "" && (mcat.IsToolRunner(m) || ToolsBusSecret(m, name)) {
|
||||
return r.Account
|
||||
}
|
||||
return m.SecretsOwner
|
||||
|
||||
@@ -113,7 +113,7 @@ func TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt(t *testing.T) {
|
||||
// The number this node was given for the forge — the one the machine it is about to run on
|
||||
// already publishes.
|
||||
out, err := Declaration(r, mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-broker"}},
|
||||
Given: map[string]map[int]int{"gitea": {3000: 2999}},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -129,7 +129,7 @@ func TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt(t *testing.T) {
|
||||
t.Fatalf("the forge is not published on the port this node gave it: %v", server["ports"])
|
||||
}
|
||||
// The forge's own code runs in the node's runtime (novox/hq ADR 0198), given its words there.
|
||||
runtime := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
runtime := fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
if runtime == nil {
|
||||
t.Fatalf("the node's runtime is not in the declaration: %v", ids(out))
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func declaredGiteaSsh(t *testing.T, given map[int]int) map[string]any {
|
||||
givenPorts[k] = v
|
||||
}
|
||||
out, err := Declaration(r, mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-broker"}},
|
||||
Ports: map[string]map[int]int{"gitea": givenPorts},
|
||||
Given: map[string]map[int]int{"gitea": given},
|
||||
})
|
||||
|
||||
@@ -46,9 +46,9 @@ func twoMergeableFiles(app, sidecar []any) mcat.Manifest {
|
||||
// The indexer's judge's proofs, items 1 to 13 of its list.
|
||||
func TestTheJudgesProofsOfAComposition(t *testing.T) {
|
||||
runtimeWith := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}, "dash": {"token": "sealed-token"}}}
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}, "dash": {"token": "sealed-token"}}}
|
||||
processOf := func(out []map[string]any) map[string]any {
|
||||
return fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
return fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
}
|
||||
|
||||
t.Run("1 a bundle's words resolve per machine into the runtime's tool env", func(t *testing.T) {
|
||||
|
||||
@@ -13,13 +13,13 @@ import (
|
||||
// place the operator-sealed secrets are kept — and no other module is told.
|
||||
func TestTheHolderOfNodeReadsIsToldWhereItsNodeKeepsASecret(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}, "reads": {"broker": "own"}, "desk": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}, "reads": {"broker": "own"}, "desk": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ func TestTheHolderOfNodeReadsIsToldWhereItsNodeKeepsASecret(t *testing.T) {
|
||||
t.Fatalf("the holder is not told its node's secret places: %v (%v)", err, given)
|
||||
}
|
||||
want := []string{"/etc/app/db.secret", "/home/ops/.config/app", "/var/lib/desk", "/var/lib/mesh-reads",
|
||||
"/var/lib/mesh-vault", "/var/lib/mesh/" + mcat.RuntimeModule}
|
||||
"/var/lib/mesh-vault", "/var/lib/mesh/" + "node-tools"}
|
||||
if strings.Join(places, " ") != strings.Join(want, " ") {
|
||||
t.Errorf("secret places:\n got %v\nwant %v", places, want)
|
||||
}
|
||||
|
||||
@@ -21,12 +21,8 @@ func BundlePath(module, bundle string) string { return mcat.BundleRoot + "/" + m
|
||||
// a node is sent exactly what it was sent before, bundles included, because a bundle nothing loads
|
||||
// is bytes nobody reads.
|
||||
func resolutionRuntimeHere(r mcat.Resolution) bool {
|
||||
for _, m := range r.Modules {
|
||||
if m.Module == mcat.RuntimeModule {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
_, here := mcat.ToolRunnerOf(r.Modules)
|
||||
return here
|
||||
}
|
||||
|
||||
// bundleArchives is one archive per tools bundle of a module — a bundle the runtime LOADS something
|
||||
@@ -59,13 +55,13 @@ func RuntimeProcessID() string { return "runtime" }
|
||||
// interpreterFor is how a bundle in a language is run: the program the host's unit starts, with the
|
||||
// bundle's entrypoint after it. The one thing the composer takes from a language, and said here
|
||||
// rather than in a manifest because the runtime's process is the mesh's to compose (to-be 38 WP3).
|
||||
func interpreterFor(language string) (string, error) {
|
||||
func interpreterFor(module, language string) (string, error) {
|
||||
switch language {
|
||||
case "typescript":
|
||||
return "node", nil
|
||||
}
|
||||
return "", fmt.Errorf(
|
||||
"%s is written in %q, and the mesh knows no interpreter to run a %q bundle with", mcat.RuntimeModule, language, language)
|
||||
"%s is written in %q, and the mesh knows no interpreter to run a %q bundle with", module, language, language)
|
||||
}
|
||||
|
||||
// runtimeProcess is the one process a machine runs the node's tool runtime as (novox/hq ADR 0175,
|
||||
@@ -80,7 +76,7 @@ func interpreterFor(language string) (string, error) {
|
||||
func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[string]any, error) {
|
||||
var runtime *mcat.Manifest
|
||||
for i := range r.Modules {
|
||||
if r.Modules[i].Module == mcat.RuntimeModule {
|
||||
if mcat.IsToolRunner(r.Modules[i]) {
|
||||
runtime = &r.Modules[i]
|
||||
}
|
||||
}
|
||||
@@ -93,7 +89,7 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
if len(runtime.Bundles) != 1 {
|
||||
return nil, fmt.Errorf(
|
||||
"%s is assigned to %s and its build produced %d bundle(s); the runtime is one bundle "+
|
||||
"the mesh runs, so the module declares exactly one (novox/hq to-be 38)", mcat.RuntimeModule, r.Node, len(runtime.Bundles))
|
||||
"the mesh runs, so the module declares exactly one (novox/hq to-be 38)", runtime.Module, r.Node, len(runtime.Bundles))
|
||||
}
|
||||
bundle := runtime.Bundles[0]
|
||||
// What runs it (novox/hq ADR 0193): a runtime compiled to a binary runs itself, from its own
|
||||
@@ -105,9 +101,9 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
if len(bundle.Entrypoints) != 1 {
|
||||
return nil, fmt.Errorf(
|
||||
"%s's bundle %q names %d entrypoint(s); the runtime is run from one, so the module "+
|
||||
"declares exactly one (novox/hq to-be 38)", mcat.RuntimeModule, bundle.Name, len(bundle.Entrypoints))
|
||||
"declares exactly one (novox/hq to-be 38)", runtime.Module, bundle.Name, len(bundle.Entrypoints))
|
||||
}
|
||||
interpreter, err := interpreterFor(bundle.Language)
|
||||
interpreter, err := interpreterFor(runtime.Module, bundle.Language)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -117,7 +113,7 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
if !declared {
|
||||
return nil, fmt.Errorf(
|
||||
"%s declares no own secret named broker, and the node's credential is delivered there: "+
|
||||
"a module that speaks on the bus declares \"own-secrets\": {\"broker\": <path>}", mcat.RuntimeModule,
|
||||
"a module that speaks on the bus declares \"own-secrets\": {\"broker\": <path>}", runtime.Module,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -163,7 +159,7 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
}
|
||||
}
|
||||
sort.Strings(served)
|
||||
restartOn = append(restartOn, mcat.RuntimeModule+"."+mcat.NeedID("broker"))
|
||||
restartOn = append(restartOn, runtime.Module+"."+mcat.NeedID("broker"))
|
||||
sort.Strings(restartOn)
|
||||
|
||||
env := map[string]string{mcat.RuntimeToolModules: strings.Join(served, ","), mcat.RuntimeBrokerFile: credential.Path}
|
||||
@@ -176,7 +172,7 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
env[mcat.RuntimeToolEnv] = string(body)
|
||||
}
|
||||
process := map[string]any{
|
||||
"id": mcat.RuntimeModule + "." + RuntimeProcessID(), "type": "process", "name": mcat.RuntimeModule,
|
||||
"id": runtime.Module + "." + RuntimeProcessID(), "type": "process", "name": runtime.Module,
|
||||
"source": bundle.Source, "digest": bundle.Digest,
|
||||
"run": run,
|
||||
"env": env,
|
||||
@@ -193,7 +189,7 @@ func resolutionRuntimeProcess(r mcat.Resolution, with mcat.Rendering) (map[strin
|
||||
}
|
||||
// Routed through the artifact store as this network reaches it now, like everything the mesh
|
||||
// built; refused with the same words when there is no store to route through.
|
||||
if err := artifactsInto(process, mcat.RuntimeModule, with); err != nil {
|
||||
if err := artifactsInto(process, runtime.Module, with); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return process, nil
|
||||
@@ -229,14 +225,14 @@ func resolutionOwnRuntimes(r mcat.Resolution, with mcat.Rendering) ([]map[string
|
||||
}
|
||||
var runtime *mcat.Manifest
|
||||
for i := range r.Modules {
|
||||
if r.Modules[i].Module == mcat.RuntimeModule {
|
||||
if mcat.IsToolRunner(r.Modules[i]) {
|
||||
runtime = &r.Modules[i]
|
||||
}
|
||||
}
|
||||
if runtime == nil || len(runtime.Bundles) != 1 || runtime.Bundles[0].Binary == "" {
|
||||
return nil, &NoRuntimeToRunError{Held: runtime != nil && runtime.Stubbed, said: fmt.Sprintf("%s runs as its own "+
|
||||
"account in a runtime of its own, and %s is not here to run it from: assign %s to %s first (novox/hq ADR 0259)",
|
||||
own[0].Module, mcat.RuntimeModule, mcat.RuntimeModule, r.Node)}
|
||||
"account in a runtime of its own, and the tool runner is not here to run it from: assign the tool runner to %s first "+
|
||||
"(novox/hq ADR 0259)", own[0].Module, r.Node)}
|
||||
}
|
||||
program := runtime.Bundles[0]
|
||||
var out []map[string]any
|
||||
@@ -314,7 +310,7 @@ func resolutionOwnRuntimes(r mcat.Resolution, with mcat.Rendering) ([]map[string
|
||||
if yielding != nil {
|
||||
process["yields"] = yielding
|
||||
}
|
||||
if err := artifactsInto(process, mcat.RuntimeModule, with); err != nil {
|
||||
if err := artifactsInto(process, runtime.Module, with); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, process)
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
// The runtime-health is composed onto <module>.own-runtime, in the words the node-engine takes; to an engine
|
||||
// that does not read health it is not sent, as for every resource.
|
||||
func TestARuntimeHealthIsComposedOntoTheModulesOwnRuntime(t *testing.T) {
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func TestARuntimeHealthIsComposedOntoTheModulesOwnRuntime(t *testing.T) {
|
||||
"looks": 2.0}
|
||||
for _, reads := range []bool{true, false} {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101", ReadsHealth: reads,
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed"}, "keeper": {"broker": "own"}}}
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed"}, "keeper": {"broker": "own"}}}
|
||||
out, err := Declaration(mcat.Resolution{Node: "anchor", Account: "ops", Modules: []mcat.Manifest{keeper, goRuntime}}, with)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -46,7 +46,7 @@ func TestARuntimeHealthIsComposedOntoTheModulesOwnRuntime(t *testing.T) {
|
||||
h["timeout"] != "10s" || h["looks"] != 2 || h["grace"] != "1m0s" {
|
||||
t.Errorf("its own runtime's health: %v", own[mcat.HealthField])
|
||||
}
|
||||
if machine := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID()); machine[mcat.HealthField] != nil {
|
||||
if machine := fileNamed(out, "node-tools"+"."+RuntimeProcessID()); machine[mcat.HealthField] != nil {
|
||||
t.Errorf("the machine's runtime was given the module's health: %v", machine[mcat.HealthField])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,12 @@ func aToolsModule(t *testing.T, name string, entrypoints ...string) mcat.Manifes
|
||||
// loaded, and its broker secret to receive the node's credential in.
|
||||
func theRuntime(t *testing.T) mcat.Manifest {
|
||||
t.Helper()
|
||||
m := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
m := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "typescript",
|
||||
Entrypoints: []string{"src/main.js"}}}}}
|
||||
resolved, err := m.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func theRuntime(t *testing.T) mcat.Manifest {
|
||||
|
||||
func TestEveryToolsBundleIsDeliveredWhereTheRuntimeRuns(t *testing.T) {
|
||||
store := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}}}
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}}}
|
||||
nftables := aToolsModule(t, "nftables", "tools/index.js")
|
||||
zsh := aToolsModule(t, "zsh", "tools/index.js", "tools/more.js")
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestEveryToolsBundleIsDeliveredWhereTheRuntimeRuns(t *testing.T) {
|
||||
t.Errorf("zsh's tools bundle was not delivered: %v", ids(out))
|
||||
}
|
||||
// The runtime's own bundle is run, not loaded: its process delivers it, not an archive.
|
||||
if fileNamed(out, mcat.RuntimeModule+"."+BundleID("runtime")) != nil {
|
||||
if fileNamed(out, "node-tools"+"."+BundleID("runtime")) != nil {
|
||||
t.Error("the runtime's own bundle was delivered as an archive beside its process")
|
||||
}
|
||||
})
|
||||
@@ -86,6 +86,18 @@ func TestEveryToolsBundleIsDeliveredWhereTheRuntimeRuns(t *testing.T) {
|
||||
t.Errorf("%s was delivered to a machine running no runtime to load it", id)
|
||||
}
|
||||
}
|
||||
// The tool runner is what says it is one, never a name (issue 774): node-tools saying nothing is no runner.
|
||||
silent := theRuntime(t)
|
||||
silent.ToolRunner = false
|
||||
out, err = Declaration(mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{nftables, zsh, silent}}, store)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, id := range ids(out) {
|
||||
if strings.Contains(id, BundleID("")) || strings.HasSuffix(id, "."+RuntimeProcessID()) {
|
||||
t.Errorf("%s was composed for a module that does not say it is the tool runner", id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -101,7 +113,7 @@ func ids(out []map[string]any) []string {
|
||||
// where its credential is, and who the operator is — restarted when any of that changes.
|
||||
func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}}}
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}}}
|
||||
nftables := aToolsModule(t, "nftables", "tools/index.js")
|
||||
// A bundle carrying a daemon beside its tools says which files the runtime loads.
|
||||
showcase := mcat.Manifest{Module: "showcase", Version: "1", Tools: []string{"greet"},
|
||||
@@ -118,12 +130,12 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
process := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
process := fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
if process == nil {
|
||||
t.Fatalf("no runtime process was composed: %v", ids(out))
|
||||
}
|
||||
if process["type"] != "process" || process["name"] != mcat.RuntimeModule || process["digest"] != bundleDigest ||
|
||||
process["source"] != "http://anchor.internal:5101/v2/"+mcat.RuntimeModule+"/runtime/blobs/"+bundleDigest {
|
||||
if process["type"] != "process" || process["name"] != "node-tools" || process["digest"] != bundleDigest ||
|
||||
process["source"] != "http://anchor.internal:5101/v2/"+"node-tools"+"/runtime/blobs/"+bundleDigest {
|
||||
t.Errorf("the runtime's process is %v", process)
|
||||
}
|
||||
if fmt.Sprint(process["run"]) != "[node src/main.js]" {
|
||||
@@ -134,7 +146,7 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
"showcase="+mcat.BundleRoot+"/showcase/code/tools/index.js" {
|
||||
t.Errorf("the runtime is told to serve %q: every loaded file, by module, and nothing a bundle runs", env[mcat.RuntimeToolModules])
|
||||
}
|
||||
if env[mcat.RuntimeBrokerFile] != "/var/lib/mesh/"+mcat.RuntimeModule+"/broker" {
|
||||
if env[mcat.RuntimeBrokerFile] != "/var/lib/mesh/"+"node-tools"+"/broker" {
|
||||
t.Errorf("the runtime reads its credential at %q, not where the module's own secret is placed", env[mcat.RuntimeBrokerFile])
|
||||
}
|
||||
if env[mcat.RuntimeOperatorAccount] != "ops" || env[mcat.RuntimeOperatorHome] != "/home/ops" || process["user"] != "ops" {
|
||||
@@ -142,18 +154,18 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
}
|
||||
// The credential the process reads belongs to the account it runs as, or it could not read it
|
||||
// (to-be 38 WP3); other modules' secrets are left as their manifests say.
|
||||
if credential := fileNamed(out, mcat.RuntimeModule+"."+mcat.NeedID("broker")); credential == nil || credential["owner"] != "ops" {
|
||||
if credential := fileNamed(out, "node-tools"+"."+mcat.NeedID("broker")); credential == nil || credential["owner"] != "ops" {
|
||||
t.Errorf("the runtime's credential is not the account's to read: %v", credential)
|
||||
}
|
||||
restarts := fmt.Sprint(process["restart-on"])
|
||||
for _, want := range []string{"nftables." + BundleID("tools"), "showcase." + BundleID("code"), mcat.RuntimeModule + "." + mcat.NeedID("broker")} {
|
||||
for _, want := range []string{"nftables." + BundleID("tools"), "showcase." + BundleID("code"), "node-tools" + "." + mcat.NeedID("broker")} {
|
||||
if !strings.Contains(restarts, want) {
|
||||
t.Errorf("the runtime is not restarted when %s changes: %s", want, restarts)
|
||||
}
|
||||
}
|
||||
// After every bundle and the credential, so both exist before it starts.
|
||||
names := ids(out)
|
||||
if names[len(names)-1] != mcat.RuntimeModule+"."+RuntimeProcessID() {
|
||||
if names[len(names)-1] != "node-tools"+"."+RuntimeProcessID() {
|
||||
t.Errorf("the runtime's process is not last: %v", names)
|
||||
}
|
||||
|
||||
@@ -162,7 +174,7 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
process := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
process := fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
env := process["env"].(map[string]string)
|
||||
if _, set := env[mcat.RuntimeOperatorAccount]; set {
|
||||
t.Error("an operator account was named on a machine that has none")
|
||||
@@ -170,13 +182,13 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
if _, set := process["user"]; set {
|
||||
t.Error("a user was set on a machine with no account")
|
||||
}
|
||||
if credential := fileNamed(out, mcat.RuntimeModule+"."+mcat.NeedID("broker")); credential == nil || credential["owner"] != nil {
|
||||
if credential := fileNamed(out, "node-tools"+"."+mcat.NeedID("broker")); credential == nil || credential["owner"] != nil {
|
||||
t.Errorf("the runtime's credential was given an owner on a machine with no account: %v", credential)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("a runtime module built wrong is refused by name", func(t *testing.T) {
|
||||
two := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1", OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/b"}},
|
||||
two := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true, OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/b"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "typescript",
|
||||
Entrypoints: []string{"a.js", "b.js"}}}}}
|
||||
resolved, err := two.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
@@ -195,7 +207,7 @@ func TestTheMachineRunsOneRuntimeLoadingEveryDeliveredBundle(t *testing.T) {
|
||||
// build from before launchers — so the move needs no flag day.
|
||||
func TestTheRuntimeStartsTheLauncherWhereTheBuildWroteOne(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}}}
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}}}
|
||||
launched := mcat.Manifest{Module: "dash", Version: "1", Tools: []string{"status"},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "tools", Kind: mcat.ArtifactBundle, Language: "typescript",
|
||||
Entrypoints: []string{"tools/index.js"}}}}}
|
||||
@@ -210,7 +222,7 @@ func TestTheRuntimeStartsTheLauncherWhereTheBuildWroteOne(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
env := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())["env"].(map[string]string)
|
||||
env := fileNamed(out, "node-tools"+"."+RuntimeProcessID())["env"].(map[string]string)
|
||||
want := "dash=" + mcat.BundleRoot + "/dash/tools/tools/index.serve.mjs,nftables=" + mcat.BundleRoot + "/nftables/tools/tools/index.js"
|
||||
if env[mcat.RuntimeToolModules] != want {
|
||||
t.Errorf("the runtime is told %q, want %q", env[mcat.RuntimeToolModules], want)
|
||||
@@ -220,13 +232,13 @@ func TestTheRuntimeStartsTheLauncherWhereTheBuildWroteOne(t *testing.T) {
|
||||
// novox/hq ADR 0193: a runtime compiled to a binary runs itself from its own unpacked bundle.
|
||||
func TestARuntimeCompiledToABinaryRunsItself(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}}}
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}}}
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -234,7 +246,7 @@ func TestARuntimeCompiledToABinaryRunsItself(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
process := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
process := fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
if fmt.Sprint(process["run"]) != "[./node-tools]" {
|
||||
t.Errorf("a Go runtime is run as %v, want its own binary", process["run"])
|
||||
}
|
||||
@@ -249,13 +261,13 @@ func TestARuntimeCompiledToABinaryRunsItself(t *testing.T) {
|
||||
// which runs as the operator's account and is given none of its words.
|
||||
func TestAModuleOfItsOwnAccountIsServedByARuntimeOfItsOwn(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}, "telegram": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}, "telegram": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -267,7 +279,7 @@ func TestAModuleOfItsOwnAccountIsServedByARuntimeOfItsOwn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
machine := fileNamed(out, mcat.RuntimeModule+"."+RuntimeProcessID())
|
||||
machine := fileNamed(out, "node-tools"+"."+RuntimeProcessID())
|
||||
if served := machine["env"].(map[string]string)[mcat.RuntimeToolModules]; strings.Contains(served, "telegram") || !strings.Contains(served, "nftables") {
|
||||
t.Errorf("the machine's runtime serves %q", served)
|
||||
}
|
||||
@@ -342,13 +354,13 @@ func TestAModuleOfItsOwnAccountIsServedByARuntimeOfItsOwn(t *testing.T) {
|
||||
// as the account agents run as there — either would hand what it holds back to the accounts it is kept from.
|
||||
func TestAModuleOfItsOwnAccountIsRefusedTheOperatorsAndTheAgentsAccount(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}, "telegram": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}, "telegram": {"broker": "own"}}}
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -368,16 +380,16 @@ func TestAModuleOfItsOwnAccountIsRefusedTheOperatorsAndTheAgentsAccount(t *testi
|
||||
// files it holds for its consumers, and what its words name — belongs to that account, never the operator's.
|
||||
func TestWhatAModuleOfItsOwnAccountReadsIsItsAccounts(t *testing.T) {
|
||||
with := mcat.Rendering{ArtifactStore: "anchor.internal:5101",
|
||||
Needed: map[string]map[string]string{mcat.RuntimeModule: {"broker": "sealed-credential"}, "vault": {"broker": "own"}},
|
||||
Needed: map[string]map[string]string{"node-tools": {"broker": "sealed-credential"}, "vault": {"broker": "own"}},
|
||||
Kept: &mcat.KeptExport{Export: 1, OperatorKey: "k"},
|
||||
Grants: []mcat.Grant{{Provision: "secret", Consumer: "anchor", From: "telegram", Sealed: "sealed-to-anchor",
|
||||
Values: map[string]any{"name": "telegram"}}}}
|
||||
goRuntime := mcat.Manifest{Module: mcat.RuntimeModule, Version: "1",
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + mcat.RuntimeModule + "/broker"}},
|
||||
goRuntime := mcat.Manifest{Module: "node-tools", Version: "1", ToolRunner: true,
|
||||
OwnSecrets: mcat.OwnSecrets{"broker": {Path: "/var/lib/mesh/" + "node-tools" + "/broker"}},
|
||||
Build: &mcat.Build{Artifacts: []mcat.Artifact{{Name: "runtime", Kind: mcat.ArtifactBundle, Language: "go",
|
||||
System: "arch", From: "cmd/node-tools"}}}}
|
||||
goRuntime, err := goRuntime.Resolve([]mcat.Built{{Name: "runtime", Kind: mcat.ArtifactBundle,
|
||||
Reference: mcat.ArtifactStoreScheme + mcat.RuntimeModule + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
Reference: mcat.ArtifactStoreScheme + "node-tools" + "/runtime/blobs/" + bundleDigest, Digest: bundleDigest}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user