/etc/hosts is the machine's: the distribution's localhost lines, the operator's own entries, and marked blocks other tools maintain there. Writing node-names whole replaced all of it the moment the private network was taken, and every later write by those tools was lost at the next machine joining. The node-names fact is now emitted with into: "block", so the host owns only its marked region and keeps the rest byte for byte. The region holds only the mesh's names: no header claiming the file, no localhost, no 127.0.1.1 line — the floor was never the mesh's to write. How a fact is written is a property of the fact in the closed table; node-zones stays a whole file the mesh owns. Sequencing: a host older than the block mode refuses the whole declaration on an unknown into, so every host must be upgraded before this controller is rolled out.
55 lines
2.4 KiB
Go
55 lines
2.4 KiB
Go
package overlay
|
|
|
|
import (
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Names are how one node reaches another by name rather than by address.
|
|
//
|
|
// novox/hq 08-connectivity: what the host receives is the resolver's configuration, as files,
|
|
// listing every peer's internal name and overlay address. Computed centrally for the same reason
|
|
// the peer graph is — it needs every node at once.
|
|
|
|
// SuffixVar lets a mesh choose what its internal names end in.
|
|
const SuffixVar = "MESH_INTERNAL_SUFFIX"
|
|
|
|
// DefaultSuffix is `.internal`, which IANA reserved for exactly this in 2024. A name under it can
|
|
// never collide with a public one, so an internal name that leaks into a public resolver fails
|
|
// rather than reaching a stranger's machine.
|
|
const DefaultSuffix = "internal"
|
|
|
|
// HostsPath is where the names go.
|
|
//
|
|
// This is not the `/etc/hosts` floor the design removes. That floor existed because a node had to
|
|
// reach the mesh's database before its own DNS worked — a fallback for a circularity, and the
|
|
// circularity is gone. This is the mechanism itself: the complete set of names in this mesh
|
|
// (novox/hq ADR 0011). Written as a marked region *into* the file rather than as the file: the
|
|
// rest of it — `localhost`, the machine's own name, other tools' blocks — is the machine's, and
|
|
// writing it whole replaced all of that (novox/hq issue 128).
|
|
//
|
|
// A file rather than a resolver daemon, deliberately, for now: it works on every Linux, needs no
|
|
// package, and has no failure mode of its own. A daemon becomes necessary when names are wanted
|
|
// that are not one-per-node — service names, wildcards — and that is not yet true.
|
|
const HostsPath = "/etc/hosts"
|
|
|
|
// Suffix is what internal names end in.
|
|
func Suffix() string {
|
|
if v := strings.TrimSpace(os.Getenv(SuffixVar)); v != "" {
|
|
return strings.TrimPrefix(v, ".")
|
|
}
|
|
return DefaultSuffix
|
|
}
|
|
|
|
// nodeName is what a node may be called, so that it can also be a hostname.
|
|
var nodeName = regexp.MustCompile(`^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`)
|
|
|
|
// InternalName is a node's name inside the mesh.
|
|
func InternalName(node string) string { return node + "." + Suffix() }
|
|
|
|
// **What remains of a larger file.** The rest wrote /etc/hosts — that is the `node-names` fact now
|
|
// (catalogue.FactsInto), computed where the graph lives instead of by a module that ran nothing.
|
|
// The naming stays here, because several things compose a node's internal name and one of them
|
|
// writing the suffix differently would be a name nothing answers to.
|