The network carries the registry trust (ADR 0082, issues 042/048)
Being on the private network is what grants a machine the right to pull from the mesh's artifact store, so the module that puts a machine on the network writes the runtime's trust — a merged /etc/docker/daemon.json naming the store's internal name under insecure-registries, and a docker.service restart when that fact first lands. The registry speaks plain HTTP because every path to it is already inside the overlay's encryption; the provider is found, not configured — whichever module serves artifact-store, on whichever machine holds it — and with no store on the network nothing is written, which is genesis. https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -83,8 +83,17 @@ type Generator struct {
|
||||
// keyPath is where each node keeps the private half it generated. Named rather than carried:
|
||||
// the mesh has never seen it and never will.
|
||||
keyPath string
|
||||
// registry is the mesh's artifact store as the network reaches it (host:port), or empty when
|
||||
// the mesh has none. Being on the network is what grants a machine the right to pull from it
|
||||
// (novox/hq ADR 0082), so the module that puts a machine on the network is what writes the
|
||||
// runtime's trust — the same reasoning that has it write /etc/hosts.
|
||||
registry string
|
||||
}
|
||||
|
||||
// TrustRegistry names the artifact store this network's machines pull from in the clear —
|
||||
// the overlay is the transport security (ADR 0082).
|
||||
func (g *Generator) TrustRegistry(hostPort string) { g.registry = hostPort }
|
||||
|
||||
// From builds a generator over the machines that are part of the network.
|
||||
//
|
||||
// The nodes given are the ones assigned the module — not every node the mesh knows. A machine
|
||||
@@ -123,7 +132,29 @@ func (g *Generator) Resources(node string) ([]map[string]any, bool, error) {
|
||||
if err := json.Unmarshal(raw, &parsed); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return parsed.Resources, true, nil
|
||||
resources := parsed.Resources
|
||||
if g.registry != "" {
|
||||
trust, err := json.Marshal(map[string]any{"insecure-registries": []string{g.registry}})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
resources = append(resources,
|
||||
map[string]any{
|
||||
// Merged, not owned: the runtime's daemon file is the machine's, and this states
|
||||
// one fact into it. The registry speaks plain HTTP because every path to it is
|
||||
// already inside the overlay's encryption (ADR 0082) — this line is the runtime
|
||||
// being told what the mesh already means.
|
||||
"id": "registry-trust", "type": "file", "path": "/etc/docker/daemon.json",
|
||||
"content": string(trust) + "\n", "mode": "0644", "merge": "json",
|
||||
},
|
||||
map[string]any{
|
||||
// The runtime reloads nothing for this setting, so it is restarted when the fact
|
||||
// changes — once, at joining, before the machine runs anything that would mind.
|
||||
"id": "registry-trust-reload", "type": "service", "unit": "docker.service",
|
||||
"state": "running", "restart-on": []string{"registry-trust"},
|
||||
})
|
||||
}
|
||||
return resources, true, nil
|
||||
}
|
||||
|
||||
// Nodes are the machines this generator was built over, so a caller can say who is on the network.
|
||||
|
||||
Reference in New Issue
Block a user