Feature 57 (config and provisioning): release mesh-controller, the reviewed release branch merged with main, on top of main

This commit is contained in:
2026-10-16 08:28:38 +00:00
parent d70bb1f388
commit d984816844
259 changed files with 34899 additions and 353 deletions
+48 -5
View File
@@ -550,8 +550,17 @@ func shelfWithChange(base map[string]catalogue.Manifest, sources map[string]inve
out[k] = m
}
var failures []string
// The list of predefined keys at the tree's root (novox/hq ADR 0348 §7): what the build of this tree judges each
// manifest against and registration publishes, so what the gate judges each against too. A list that is
// wrong is refused by name, and every manifest is then judged against none.
predefined, err := catalogue.ReadPredefined(tree)
if err != nil {
failures = append(failures, fmt.Sprintf("%s: the controller judging this (%s) refuses it — %s",
catalogue.PredefinedFile, version, oneLine(err.Error())))
predefined = nil
}
found := map[string]string{} // module → its directory in the tree
err := filepath.WalkDir(tree, func(path string, d fs.DirEntry, err error) error {
err = filepath.WalkDir(tree, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
@@ -575,7 +584,19 @@ func shelfWithChange(base map[string]catalogue.Manifest, sources map[string]inve
if err != nil {
return err
}
m, err := catalogue.ParseManifest(raw)
m, err := catalogue.ParseManifestWith(raw, predefined)
// The manifest as written, still naming its templates: what the stand-in build resolves, as a real build
// does, so a moved module is handed its templates (issue 876).
written := m
var texts map[string]string
if err == nil {
// Each template's text from the tree beside the manifest, as the build reads it back from the archive it
// packs (novox/hq ADR 0349 §2): so a change to a template alone is a change to its module.
m, err = catalogue.WithTemplatesFrom(m, filepath.Dir(path))
}
if err == nil && written.Templated() {
texts, err = catalogue.ReadTemplates(written, filepath.Dir(path))
}
if err != nil {
if inScope(dir) {
failures = append(failures, fmt.Sprintf("%s: the controller judging this (%s) refuses it — %s",
@@ -600,12 +621,12 @@ func shelfWithChange(base map[string]catalogue.Manifest, sources map[string]inve
"of one module name (issue 239)", orRoot(dir), m.Module, s.Repository))
return nil
}
resolved, err := standInBuild(m)
resolved, err := standInBuild(written, texts)
if err == nil {
// As registration reads a built manifest: strictly, again (takeIn).
var raw []byte
if raw, err = json.Marshal(resolved); err == nil {
resolved, err = catalogue.ParseManifest(raw)
resolved, err = catalogue.ParseManifestWith(raw, predefined)
}
}
if err == nil {
@@ -723,15 +744,24 @@ func builtAlike(m catalogue.Manifest) string {
// standInBuild resolves a manifest as a build would, with artifacts nobody built: a digest made from the
// module's and the artifact's names, in the store's own vocabulary. Composition and validation read the
// shape of a reference, never its bytes.
func standInBuild(m catalogue.Manifest) (catalogue.Manifest, error) {
func standInBuild(m catalogue.Manifest, texts map[string]string) (catalogue.Manifest, error) {
if m.Build == nil {
return m.Resolve(nil)
}
// The templates archive carries each template's text by its path inside the archive, as a build reads it back.
archive, inside := catalogue.TemplatesArtifact(m), m.TemplatesDir()+"/"
read := map[string]string{}
for template, text := range texts {
read[strings.TrimPrefix(template, inside)] = text
}
var built []catalogue.Built
for _, a := range m.Build.Artifacts {
sum := sha256.Sum256([]byte("gate\x00" + m.Module + "\x00" + a.Name))
digest := fmt.Sprintf("sha256:%x", sum)
b := catalogue.Built{Name: a.Name, Kind: a.Kind, Digest: digest}
if a.Name == archive && archive != "" {
b.Texts = read
}
switch a.Kind {
case catalogue.ArtifactImage, catalogue.ArtifactUpstream:
b.Reference = catalogue.ArtifactStoreScheme + m.Module + "/" + a.Name + "@" + digest
@@ -1083,6 +1113,19 @@ func raiseFromFacts(ctx context.Context, open *stores, f snapshot.Facts, shelf m
continue
}
}
// And the provisioner client's account, the same way (novox/hq ADR 0349 clause 11, design 57 P3).
if a.Provider == "" && a.Name == broker.ProvisionerSecret {
if pm, held := shelf[a.Module]; !held || !runsTheProvisionerClient(pm) {
continue
}
if _, err := inv.MintBusPassword(ctx, inventory.BusUser{Kind: inventory.BusProvisioner, Node: m.Name,
Module: a.Module, Username: broker.Principal{Kind: broker.KindProvisioner, Node: m.Name,
Module: a.Module}.Username()}); err != nil {
notes = append(notes, fmt.Sprintf("%s's provisioner client account for %s is not kept: %s",
m.Described(), a.Module, oneLine(err.Error())))
continue
}
}
var err error
if a.Provider == "" {
err = inv.AcceptSecretForModule(ctx, m.Name, a.Module, a.Name, standIn)