Files
mesh-controller/examples/modules/README.md
T
jschoubben bff893f8af Resolver modules: one that serves, and two ways of deciding what a machine asks
Three manifests and the rule that keeps them apart. Serving and asking are
genuinely different roles, and systemd-resolved can only do the second — it
cannot answer a wildcard, it routes the mesh's suffix to something that can. A
module that treated them as one role could not work, which is the mistake worth
naming rather than discovering.

So `the-dns-port` and `the-resolver-configuration` are two claims. A machine
gets one of each, and two of either is refused by the mesh rather than fought
over on the machine — which is what ADR 0009's table meant by listing resolvers
beside the seat and pid 1. That table names the resource `/etc/resolv.conf`,
which is what it is; a claim is a name in the catalogue's own form, and the
catalogue refuses the path as one.

Neither module knows anything about the machine it is on, which is what lets
them be static manifests: they name `mesh0` and `127.0.0.54`, both chosen by
the mesh, rather than an address only that machine has. Not 127.0.0.1 and not
127.0.0.53 — taking either would be a module claiming something it did not say
it claims.

A service can now reflect a file another module put on the machine, written
`<module>.<id>`. The resolver has to restart when the mesh rewrites the names;
without it, it would serve the names it started with for ever, with every
machine that joined afterwards unreachable and every check passing.
2026-08-31 12:21:58 +02:00

43 lines
2.1 KiB
Markdown

# Example modules
Manifests, not programs. They are here because the contract is easier to read as something that
works than as a description of something that would.
**Third-party software runs *on* the mesh, not *of* it** (novox/hq ADR 0001). dnsmasq is not the
mesh's, and neither is systemd-resolved — what is the mesh's is the fact only it can know, which
is which machines exist and where they are. So the mesh writes that to a file and these read it.
## Resolving a service named under a machine
`postgres.novox.internal`, `plex.ace.internal`. The first label is the service and the rest is the
node, so **anything under a node's name must resolve to that node** and a proxy there routes by
the name it was asked for. That routing is a separate concern and stays separate.
Two roles, and they are genuinely different things:
| | claims | |
|---|---|---|
| **serving** | `the-dns-port` | answers the wildcards — `dnsmasq.json` |
| **asking** | `the-resolver-configuration` | decides what the machine asks — `resolved-split-dns.json`, `resolv-conf.json` |
**systemd-resolved cannot serve a wildcard**, so it is only ever an *asking* module: it routes the
mesh's suffix to something that can. Treating the two roles as one would produce a module that
cannot work, which is the mistake worth naming.
Assign one of each. Two of either is refused by the mesh rather than fought over on the machine:
> `resolved-split-dns and resolv-conf both claim "the-resolver-configuration", and only one thing
> may hold it per node`
ADR 0009's table names that resource `/etc/resolv.conf`, which is what it *is*, the way it writes
*the seat*. A claim is a name in the catalogue's own form, so it is written as one.
## Why neither needs to know the machine's address
Both would ordinarily need it — a resolver must bind somewhere, and a stub must be pointed
somewhere — and a static manifest cannot know it.
Neither does, because both name things **the mesh itself named**: the private network's interface
is `mesh0` on every machine, and the address a resolver listens on for the machine's own use is
`127.0.0.54` on every machine. A name the mesh chose is a name a manifest can use.