Carry an adopted node's mode and taken modules in every declaration, from one marshaller (hq ADR 0100)

This commit is contained in:
2026-09-22 17:17:54 +02:00
parent 1c32af6a22
commit a86a6c2974
6 changed files with 357 additions and 49 deletions
+36 -19
View File
@@ -1,6 +1,7 @@
package main
import (
"bytes"
"context"
"encoding/json"
"errors"
@@ -271,10 +272,10 @@ func theRestOfTheMesh(ctx context.Context, inv *inventory.Inventory,
// silently produced a declaration missing them — a difference between what `plan` showed and what
// `plan --json` handed to anything reading it.
func declarationFor(ctx context.Context, open *stores, node string,
plan catalogue.Resolution, settings catalogue.SettingsBy) ([]map[string]any, error) {
plan catalogue.Resolution, settings catalogue.SettingsBy) (sendable, error) {
gens, err := generators(ctx, open)
if err != nil {
return nil, err
return sendable{}, err
}
// **Allocating, because `plan` is the send without the sending.** It is one machine, named by
// a person, who is asking what a push would do — so the port it shows and the secret it seals
@@ -316,11 +317,11 @@ const (
func declarationWith(ctx context.Context, open *stores, node string,
plan catalogue.Resolution, settings catalogue.SettingsBy,
gens map[string]catalogue.Generator, choosing Choosing) ([]map[string]any, error) {
gens map[string]catalogue.Generator, choosing Choosing) (sendable, error) {
inv := open.inventory
grants, err := grantsFor(ctx, open, node)
if err != nil {
return nil, err
return sendable{}, err
}
// Where this machine puts what each module needs reachable (novox/hq ADR 0038).
//
@@ -333,7 +334,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
if choosing == Reading {
held, err := inv.PortsFor(ctx, node)
if err != nil {
return nil, err
return sendable{}, err
}
for _, a := range held {
if already[a.Module] == nil {
@@ -357,7 +358,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
case mayAssign && choosing == Allocating:
at, err := inv.PortFor(ctx, node, m.Module, l.Port, l.Fixed)
if err != nil {
return nil, fmt.Errorf(
return sendable{}, fmt.Errorf(
"%s needs %d reachable on %s and it could not be assigned: %w",
m.Module, l.Port, node, err)
}
@@ -398,7 +399,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
}
}
if err != nil {
return nil, err
return sendable{}, err
}
if needed[m.Module] == nil {
needed[m.Module] = map[string]string{}
@@ -416,7 +417,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
}
issued, meshCA, err := certificateFor(ctx, open, node)
if err != nil {
return nil, err
return sendable{}, err
}
certificate, authority = issued, meshCA
break
@@ -429,11 +430,11 @@ func declarationWith(ctx context.Context, open *stores, node string,
// One reading of the catalogue for the three questions below that resolve the whole mesh.
shelf, err := inv.Catalogue(ctx)
if err != nil {
return nil, err
return sendable{}, err
}
private, err := onThePrivateNetwork(ctx, inv, shelf)
if err != nil {
return nil, err
return sendable{}, err
}
// And every machine's name, so a container can reach one. The same set that writes the
@@ -441,7 +442,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
// about where another machine is.
names, err := namesInTheMesh(ctx, inv, shelf)
if err != nil {
return nil, err
return sendable{}, err
}
// And every routed name → the node that serves it (novox/hq ADR 0066). Alongside the
@@ -450,7 +451,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
// to serve and knows nothing about what they mean.
routes, err := routeNamesInTheMesh(ctx, open)
if err != nil {
return nil, err
return sendable{}, err
}
for name, at := range routes {
names[name] = at
@@ -479,15 +480,25 @@ func declarationWith(ctx context.Context, open *stores, node string,
continue
}
if kept, err = inv.OperatorExport(ctx); err != nil {
return nil, err
return sendable{}, err
}
break
}
return plan.Declaration(catalogue.Rendering{
composed, err := plan.Compose(catalogue.Rendering{
Settings: settings, Generators: gens, Grants: grants, Needed: needed, Ports: ports,
Certificate: certificate, Authority: authority, Mesh: private, Names: names,
Suffix: overlay.Suffix(), Foundation: foundation, Kept: kept})
if err != nil {
return sendable{}, err
}
// Whether this node is adopted, and what was taken on it, said in every declaration it is
// sent from this one place (novox/hq ADR 0100).
adoption, err := adoptionOf(ctx, inv, node, plan, composed)
if err != nil {
return sendable{}, err
}
return sendable{Resources: composed.Resources, Adoption: adoption}, nil
}
// routeNamesInTheMesh is every routed name and the address of the node that serves it (novox/hq
@@ -736,16 +747,21 @@ func planCommand(ctx context.Context, args []string) error {
return nil
}
if *asJSON {
resources, err := declarationFor(ctx, open, args[0], plan, settings)
declared, err := declarationFor(ctx, open, args[0], plan, settings)
if err != nil {
return err
}
body, err := json.MarshalIndent(
map[string]any{"declaration": 1, "resources": resources}, "", " ")
// The bytes a push would send, indented: one marshaller, so `plan --json` cannot show an
// envelope other than the one sent.
body, err := declared.Body()
if err != nil {
return err
}
fmt.Println(string(body))
var indented bytes.Buffer
if err := json.Indent(&indented, body, "", " "); err != nil {
return err
}
fmt.Println(indented.String())
return nil
}
@@ -769,10 +785,11 @@ func planCommand(ctx context.Context, args []string) error {
for _, n := range plan.Needs {
fmt.Printf(" needs %s from %s, for %s\n", n.Name, n.From, n.For)
}
resources, err := declarationFor(ctx, open, args[0], plan, settings)
declared, err := declarationFor(ctx, open, args[0], plan, settings)
if err != nil {
return err
}
resources := declared.Resources
for module, layers := range settings {
for _, layer := range layers {
fmt.Printf(" %-20s settings from %s\n", module, layer.From)