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.
25 lines
2.1 KiB
JSON
25 lines
2.1 KiB
JSON
{
|
|
"module": "dnsmasq",
|
|
"version": "1",
|
|
|
|
"requires": ["resolver-data"],
|
|
"provides": ["wildcard-resolution"],
|
|
"claims": [{"name": "the-dns-port", "scope": "node"}],
|
|
|
|
"listens": [
|
|
{"port": 53, "protocol": "udp", "from": "mesh",
|
|
"why": "names under every machine in this mesh, for this machine and what it runs"}
|
|
],
|
|
|
|
"resources": [
|
|
{"id": "package", "type": "package", "package": "dnsmasq"},
|
|
|
|
{"id": "config", "type": "file", "path": "/etc/dnsmasq.conf", "mode": "0644",
|
|
"content": "# Managed by the mesh. dnsmasq's own defaults are replaced whole rather than\n# patched, because this module owns the file and a patch would leave whatever\n# was there before to be discovered later.\n\n# What the mesh computed: one wildcard per machine, its name and everything\n# under it. Rewritten whenever a machine joins or leaves, which is why the\n# service below reflects it.\nconf-file=/etc/mesh-resolver/nodes.conf\n\n# Where it answers. Both are names the mesh chose, so this file needs to know\n# nothing about this particular machine:\n#\n# mesh0 the private network, so anything on it — including a container\n# on this machine — can ask.\n# 127.0.0.54 this machine's own use. Not 127.0.0.1 and not 127.0.0.53:\n# the first is where everything else expects a resolver, and the\n# second is systemd-resolved's. Taking either would be this\n# module claiming something it did not say it claims.\n#\n# bind-dynamic rather than bind-interfaces: mesh0 does not exist until the\n# machine is on the private network, and binding an interface that is not there\n# yet fails to start rather than waiting for it.\nbind-dynamic\ninterface=mesh0\nlisten-address=127.0.0.54\n\n# It answers for the mesh and forwards nothing it was not asked about. Names\n# outside the mesh are somebody else's business, and a resolver that answered\n# them would be this module taking over more than it claims.\ndomain-needed\nbogus-priv\n"},
|
|
|
|
{"id": "service", "type": "service", "unit": "dnsmasq.service",
|
|
"state": "running", "boot": "enabled",
|
|
"restart-on": ["config", "mesh-resolver.nodes"]}
|
|
]
|
|
}
|