The mesh's knowledge is a fact a module asks for, not three modules
mesh-names, mesh-resolver and the names half of the overlay generators are gone.
They ran no software and could not be swapped for anything, which is the test of
whether something is a module at all — they existed because computed output
needed somewhere to live, and the control plane's only shape for output was a
module.
Now a module says where it wants what the mesh knows:
facts: { node-zones: /etc/mesh-resolver/nodes.conf }
and is given a file, under its own name, applied and removed like anything else
it declares. Two facts exist: node-names (a hosts file — exact names) and
node-zones (every machine as a wildcard, *.homer.internal is homer). Asking for
a fact the mesh does not compute is refused naming what would have worked,
because a daemon that starts and reads a file nobody wrote is a worse way to
find out.
The names ride with the network now: wireguard's manifest asks for node-names
into /etc/hosts, because being on the private network is what gives a machine a
name. networking no longer requires name-resolution — names are not a provision,
and the module that answered it ran nothing.
One behaviour inverted, deliberately: choosing another VPN used to drag
WireGuard in anyway, because only WireGuard provided the addressing the names
module required — the node-scope claim existed to at least make that loud. With
names as a fact there is nothing to drag in: tailscale assigned means tailscale,
alone. The claim still catches two VPNs assigned explicitly.
And a machine the mesh cannot place is left out of both files rather than named
at nothing: a name resolving to nothing hangs a connection, where an unknown
name fails at once and says so. In practice that is only ever a token issued and
not yet used — a machine that has announced itself has an address.
Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -36,8 +36,12 @@ import (
|
||||
func providedModules() []catalogue.Manifest {
|
||||
var out []catalogue.Manifest
|
||||
for _, raw := range []map[string]any{
|
||||
overlay.Manifest(), overlay.NamesManifest(), overlay.ResolverManifest(),
|
||||
overlay.DomainManifest(),
|
||||
// **Two used to be here and are gone**: one wrote the mesh's names into a hosts file, the
|
||||
// other wrote the same machines as wildcards for a resolver to read. Neither ran software
|
||||
// and neither could be swapped for anything, which is the test of whether a thing is a
|
||||
// module at all (novox/hq ADR 0040). They existed because computed output needed somewhere
|
||||
// to live, and now a module says where it wants it — `facts` in its own manifest.
|
||||
overlay.Manifest(), overlay.DomainManifest(),
|
||||
} {
|
||||
var m catalogue.Manifest
|
||||
b, _ := json.Marshal(raw)
|
||||
|
||||
@@ -231,12 +231,13 @@ func generators(ctx context.Context, open *stores) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Both generators see the same machines: the ones on the private network. Names for a machine
|
||||
// that is not on it would resolve to addresses it cannot reach, which is worse than no names.
|
||||
// **One generator now.** Two more used to sit beside it — the names and a resolver's zone
|
||||
// file — as modules that ran nothing. Both are facts a module asks for in its manifest
|
||||
// (`facts:` — catalogue.FactsInto), computed from the same machines this sees: the ones on the
|
||||
// private network, because a name for a machine not on it would resolve to an address nothing
|
||||
// can reach.
|
||||
return map[string]catalogue.Generator{
|
||||
overlay.Name: net,
|
||||
overlay.Names: overlay.NamesFor(net.Nodes()),
|
||||
overlay.Resolver: overlay.ResolverFor(net.Nodes()),
|
||||
overlay.Name: net,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user