{ "module": "dnsmasq", "version": "1", "upgrade": { "policy": "record", "why": "the mesh's resolver: a build that breaks it can stop a machine resolving the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236, issue 260)" }, "provides": [ { "name": "wildcard-resolution", "scope": "mesh", "identity": false } ], "requires": [ "mesh-addressing" ], "emits": [ "name.added", "name.removed", "restarted", "restart-judged" ], "own-secrets": { "broker": "${dir:mesh-state}/broker" }, "claims": [ { "name": "mesh-dns-resolver", "scope": "mesh" } ], "tools": [ "dnsmasq_health", "dnsmasq_names", "dnsmasq_resolve" ], "listens": [ { "name": "dns-udp", "port": 53, "protocol": "udp", "from": "mesh", "why": "one of the mesh's resolvers (ADR 0194, 0223): every node's and every container's resolver, beside any other holder of the seat — the mesh's own names answered here, a module's zone forwarded to it, the rest forwarded upstream", "fixed": true }, { "name": "dns-tcp", "port": 53, "protocol": "tcp", "from": "mesh", "why": "the same names over tcp, which a resolver answers on as well and is asked for whenever an answer will not fit in a datagram. Declared because the daemon serves it: a declaration that covers one of the two protocols its own service listens on leaves the other closed while everything reports success", "fixed": true } ], "resources": [ { "id": "mesh-state", "type": "directory", "mode": "0700", "place": "mesh" }, { "id": "package", "type": "package", "package": "dnsmasq" }, { "id": "config", "type": "file", "path": "/etc/dnsmasq.conf", "mode": "0644", "template": "files/dnsmasq.conf" }, { "id": "drop-ins", "type": "directory", "path": "/etc/systemd/system/dnsmasq.service.d", "mode": "0755" }, { "id": "wait-for-address", "type": "file", "path": "/etc/systemd/system/dnsmasq.service.d/mesh.conf", "mode": "0644", "template": "files/mesh.conf" }, { "id": "service", "type": "service", "unit": "dnsmasq.service", "state": "running", "boot": "enabled", "restart-on": [ "config", "wait-for-address", "dnsmasq.fact-node-zones", "dnsmasq.fact-zones" ], "health": { "kind": "unit" } }, { "id": "watch-dir", "type": "directory", "path": "/var/lib/dnsmasq-watch", "mode": "0755" }, { "id": "watch", "type": "process", "name": "dnsmasq-watch", "artifact": "tools", "run": [ "./dnsmasq-tools", "watch" ], "health": { "kind": "tool", "tool": "dnsmasq_health", "interval": "20s", "timeout": "10s", "looks": 2, "grace": "60s" } } ], "facts": { "node-zones": { "path": "/etc/mesh-resolver/nodes.conf", "template": "# Generated by the mesh. Do not edit — this file is replaced whenever a machine\n# joins or leaves, and an edit would survive until then and vanish.\n\nlocal=/{{.Suffix}}/\n# A machine's own name is a host record as well as a wildcard: asked for an IPv6 address, the\n# resolver then says the name exists and has none, where the wildcard alone said there is no such\n# name — and a resolver that reads that as final (musl, so every Alpine container) failed to find\n# the machine at all (novox/hq issue 262).\n{{range .Machines}}address=/{{.FQDN}}/{{.Address}}\nhost-record={{.FQDN}},{{.Address}}\n{{end}}" }, "zones": { "path": "/etc/mesh-resolver/zones.conf", "template": "# Generated by the mesh. Do not edit — this file is replaced whenever a module declares a zone or\n# its machine moves (novox/hq ADR 0199). One forwarding line per zone, to the module answering it.\n\n{{range .Zones}}server=/{{.Zone}}/{{.Address}}#{{.Port}}\n{{end}}" } }, "build": { "artifacts": [ { "name": "tools", "kind": "bundle", "language": "go", "system": "arch", "from": "cmd/dnsmasq-tools", "binary": "dnsmasq-tools", "loads": [ "dnsmasq-tools" ] }, { "name": "files", "kind": "archive", "from": "files" } ] } }