The node-engine reads, records and routes artifact references through the registry clients' reference forms (registryforms), not mesh-sdk catalogue's (ADR 0634 §4, S-8; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 17:38:04 +01:00
parent b8dbee28cc
commit 4a57d8c90c
6 changed files with 42 additions and 19 deletions
+3
View File
@@ -3,6 +3,9 @@ module github.com/novox/mesh-host
go 1.26.0
require (
git.novox.be/novox/mesh-delivery/contracts/go/clients/containerimageregistryclient v0.0.0-20261105000000-000000000000
git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry v0.0.0-20261105000000-000000000000
git.novox.be/novox/mesh-delivery/contracts/go/seats/ociartifactregistry v0.0.0-20261105000000-000000000000
git.novox.be/novox/mesh-contracts/identity-and-access/go/clients/meshnodeenrollerclient v0.0.0-20261105000000-000000000000
git.novox.be/novox/mesh-contracts/identity-and-access/go/seats/meshnodeenroller v0.0.0-20261105000000-000000000000
git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate v0.0.0-20261105000000-000000000000
+5 -3
View File
@@ -4,16 +4,18 @@ import (
"encoding/json"
"errors"
"fmt"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
engcomp "github.com/novox/mesh-host/internal/compositions"
"slices"
"sort"
"strings"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
engcomp "github.com/novox/mesh-host/internal/compositions"
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/declaration"
"github.com/novox/mesh-host/internal/compose/resolution"
"github.com/novox/mesh-host/internal/registryforms"
)
// Compositions is one node's compositions (novox/hq ADR 0539 clauses 1 and 2): its declaration composed over in, as
@@ -354,7 +356,7 @@ func ToolsRunning(running []engcomp.Composed) map[string][]catalogue.Bundle {
case r.Type == "archive" && owner != "" && strings.HasPrefix(r.ID, owner+"."+resolution.BundleID("")):
name := strings.TrimPrefix(r.ID, owner+"."+resolution.BundleID(""))
if r.Path == resolution.BundlePath(owner, name) {
out[owner] = append(out[owner], catalogue.Bundle{Name: name, Source: catalogue.Recorded(r.Source), Digest: r.Digest})
out[owner] = append(out[owner], catalogue.Bundle{Name: name, Source: registryforms.Forms.Recorded(r.Source), Digest: r.Digest})
}
}
}
+9 -7
View File
@@ -35,6 +35,12 @@ import (
"encoding/json"
"errors"
"fmt"
"maps"
"net/netip"
"slices"
"sort"
"strings"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-contracts/identity-and-access/go/clients/meshvaultclient"
"git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
@@ -43,17 +49,13 @@ import (
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
engcomp "github.com/novox/mesh-host/internal/compositions"
"maps"
"net/netip"
"slices"
"sort"
"strings"
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/declaration"
"github.com/novox/mesh-host/internal/compose"
"github.com/novox/mesh-host/internal/compose/resolution"
"github.com/novox/mesh-host/internal/registryforms"
"github.com/novox/mesh-host/internal/takein"
)
@@ -83,7 +85,7 @@ type Reader interface {
// when the builder holds none. The composing node composes each of its modules from its build (issue 1126).
Build(ctx context.Context, module, fp string) (*builds.BuilderBuild, error)
// Archive is the archive at url, a kept reference routed to the artifact store as the composing node reaches it
// (catalogue.Routed), checked against digest: a moved module's templates archive, read back for its texts as the
// (registryforms.Forms.Routed), checked against digest: a moved module's templates archive, read back for its texts as the
// controller's take-in reads it (takein.Built).
Archive(ctx context.Context, url, digest string) ([]byte, error)
// Served is, of one module's config values on another node than the composing one (mesh-config's state `resolved`,
@@ -834,7 +836,7 @@ func fromBuilds(ctx context.Context, r Reader, build func(ctx context.Context, m
case address == "":
return nil, fmt.Errorf("%s reaches no artifact store (%s)", s.Node, storeSought(*in))
}
return r.Archive(ctx, catalogue.Routed(reference, address), digest)
return r.Archive(ctx, registryforms.Forms.Routed(reference, address), digest)
}
built := func(module, fp string, b *builds.BuilderBuild) (catalogue.Manifest, error) {
if b.Manifest == "" {
+7 -6
View File
@@ -5,6 +5,7 @@ import (
"strings"
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
"github.com/novox/mesh-host/internal/registryforms"
)
// artifactsInto composes the artifact store's address into a resource's `image` and `source`.
@@ -32,7 +33,7 @@ func artifactsInto(resource map[string]any, module string, with mcat.Rendering)
if !ok {
continue
}
if _, kept := mcat.InArtifactStore(written); kept {
if _, kept := registryforms.Forms.InArtifactStore(written); kept {
if with.ArtifactStore == "" {
return fmt.Errorf(
"%s's %v names %s, which is in the mesh's artifact store, and this mesh has no "+
@@ -40,18 +41,18 @@ func artifactsInto(resource map[string]any, module string, with mcat.Rendering)
"container-image-registry, or the machine holding it is not on the private network",
module, resource["id"], written)
}
resource[key] = mcat.Routed(written, with.ArtifactStore)
resource[key] = registryforms.Forms.Routed(written, with.ArtifactStore)
imageSeatInto(resource, key, written, with)
continue
}
if with.ArtifactStore == "" {
continue
}
recorded := mcat.Recorded(written)
recorded := registryforms.Forms.Recorded(written)
if recorded == written {
continue
}
path, _ := mcat.InArtifactStore(recorded)
path, _ := registryforms.Forms.InArtifactStore(recorded)
repository := path
if at := strings.IndexAny(path, "@"); at >= 0 {
repository = path[:at]
@@ -59,7 +60,7 @@ func artifactsInto(resource map[string]any, module string, with mcat.Rendering)
repository = path[:blobs]
}
if with.Built[repository] {
resource[key] = mcat.Routed(recorded, with.ArtifactStore)
resource[key] = registryforms.Forms.Routed(recorded, with.ArtifactStore)
imageSeatInto(resource, key, written, with)
}
}
@@ -80,7 +81,7 @@ func imageSeatInto(resource map[string]any, key, written string, with mcat.Rende
}
// The seat a reference of the registry form names; the older forms came through the artifact store's.
seat := artifactSeat
if named, _, ok := mcat.InRegistrySeat(written); ok {
if named, _, ok := registryforms.Forms.InRegistrySeat(written); ok {
seat = named
}
if with.SeatHolder[seat] == "" {
+13
View File
@@ -0,0 +1,13 @@
// Package registryforms is how the node-engine reads an artifact's reference: the registry clients' reference forms
// (novox/hq ADR 0605 §9, ADR 0634 §4), with the two registry seats' names from their contracts. The forms are the
// registry clients' (mesh-delivery's contracts), not mesh-sdk's; this package only gives them the seats' names.
package registryforms
import (
"git.novox.be/novox/mesh-delivery/contracts/go/clients/containerimageregistryclient/reference"
containerimageregistry "git.novox.be/novox/mesh-delivery/contracts/go/seats/containerimageregistry"
ociartifactregistry "git.novox.be/novox/mesh-delivery/contracts/go/seats/ociartifactregistry"
)
// Forms reads, records and routes a reference in the registry seat's form and the older artifact-store one.
var Forms = reference.Seats{Image: containerimageregistry.Seat, Object: ociartifactregistry.Seat}
+5 -3
View File
@@ -18,14 +18,16 @@ import (
"context"
"errors"
"fmt"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"io"
"strings"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"github.com/novox/mesh-host/internal/registryforms"
)
// Archive reads the archive a recorded reference names (catalogue.Recorded: the artifact store's address left out),
// Archive reads the archive a recorded reference names (registryforms.Forms.Recorded: the artifact store's address left out),
// checked against its digest.
type Archive func(ctx context.Context, reference, digest string) ([]byte, error)
@@ -82,7 +84,7 @@ func Built(ctx context.Context, m catalogue.Manifest, artifacts []builds.BuiltAr
if kind == "" {
kind = d.Kind
}
b := catalogue.Built{Name: a.Name, Kind: kind, Reference: catalogue.Recorded(a.Reference), Digest: a.Digest}
b := catalogue.Built{Name: a.Name, Kind: kind, Reference: registryforms.Forms.Recorded(a.Reference), Digest: a.Digest}
if launchers := catalogue.Launchers(d.Language, d.Entrypoints); len(launchers) > 0 {
b.Launchers = launchers
}