Wait for a done key whose artifact names no reference, as the controller's take-in does, and hold the fold guard with a row (issue 1126, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-sdk@d48365aed010
mesh/delivery-group group fix/1126-node-creds merged: every member is merged
mesh/check checking 7a8e9f970648 on d48365aed010 | novox/mesh-sdk#109 in group fix/1126-node-creds

This commit is contained in:
2026-10-27 21:12:13 +01:00
parent d7a758894a
commit 7a8e9f9706
2 changed files with 37 additions and 1 deletions
+22
View File
@@ -43,9 +43,11 @@ type bus struct {
fetched []string
served map[string]map[string]any
servedRead []string
buildsRead []string
}
func (b *bus) Build(_ context.Context, module, fp string) (*delivery.BuilderBuild, error) {
b.buildsRead = append(b.buildsRead, module)
return b.builds[module+" "+fp], nil
}
@@ -587,6 +589,26 @@ func TestInput(t *testing.T) {
if c := fromBuild[resticKey]; len(c.Filled) != 4 { // its three templated files and its own secret
t.Errorf("restic is not handed to the provisioner: its filled files are %v", c.Filled)
}
// A done key an artifact of which names no reference is waited for, in the controller's words (ADR 0498 §8).
unreferenced := movedMesh(true)
unreferenced.builds["restic "+movedFps["restic"]].Artifacts = []delivery.BuiltArtifact{{Name: "tools", Kind: "bundle", Digest: digestOf("6")}, resticArtifacts[1]}
if _, _, err := Compose(ctx, unreferenced, Mesh{}, Scope{Node: "n1"}, movedFps); err == nil || !strings.Contains(err.Error(), "the build of restic is done and waits for the reference of tools") {
t.Errorf("a done key with an unreferenced artifact: %v", err)
}
// A module the node runs inside its own composition (the fold) composes from the indexer's manifest though a done
// build of it is at the trunk's FP2: its build is not read.
folding := movedMesh(true)
foldIn, err := Input(ctx, folding, Mesh{}, Scope{Node: "n1", InOwn: []string{"mesh-provisioner-client"}})
if err != nil {
t.Fatal(err)
}
clientParsed, err := catalogue.ParseManifestForInputs(clientRaw)
if err != nil {
t.Fatal(err)
}
if slices.Contains(folding.buildsRead, "mesh-provisioner-client") || !reflect.DeepEqual(foldIn.Catalogue["mesh-provisioner-client"], clientParsed) {
t.Errorf("a folded module was taken from its build: builds read %v", folding.buildsRead)
}
// The controller's: its take-in resolves each manifest with the key's artifacts and the archive's texts, and composes
// from those over the same input.
storeIn, err := Input(ctx, movedMesh(false), Mesh{}, Scope{Node: "n1"})
+15 -1
View File
@@ -29,13 +29,27 @@ import (
// checked against its digest.
type Archive func(ctx context.Context, reference, digest string) ([]byte, error)
// Manifest is m, as its manifest at b's fingerprint reads, resolved with what b made: the built manifest. b must be done.
// Manifest is m, as its manifest at b's fingerprint reads, resolved with what b made: the built manifest. b must be done
// and every artifact must name its reference.
// A templated module's templates archive is read through archive; a module without templates reads none, and archive
// may then be nil.
func Manifest(ctx context.Context, m catalogue.Manifest, b delivery.BuilderBuild, archive Archive) (catalogue.Manifest, error) {
if b.State != delivery.BuildDone {
return catalogue.Manifest{}, fmt.Errorf("takein: the build of %s is %s, not done: nothing to resolve it with", m.Module, b.State)
}
// **A done key whose artifact names no reference is waited for, never composed from** (novox/hq ADR 0498 §8), in the
// controller's words (mesh-controller internal/builderkeys Key.Says): a key done before R4e, or a candidate's image or
// package not yet built again for the trunk.
var missing []string
for _, a := range b.Artifacts {
if strings.TrimSpace(a.Reference) == "" {
missing = append(missing, a.Name)
}
}
if len(missing) > 0 {
return catalogue.Manifest{}, fmt.Errorf("takein: the build of %s is done and waits for the reference of %s",
m.Module, strings.Join(missing, ", "))
}
built, err := Built(ctx, m, b.Artifacts, archive)
if err != nil {
return catalogue.Manifest{}, err