Wheelhouse docs

Companions#

Services → Companions reports whether three service subtrees exist in the router's configuration, and prints them when they do. That is the whole of what it does today, and the page's value is in what it makes visible rather than in what it changes: nothing here is editable, and the agent supervises no process.

The three panels#

GET /api/daemons reads three configuration paths and reports each as configured or not-configuredagent/main.go, handleDaemons:

PanelSubtreeWhat being configured means
UPNPservice upnpThe router has a UPnP/IGD configuration.
DNSservice dnsThe resolver, its forwarders and any authoritative zones.
DHCPservice dhcp-serverShared networks, subnets and reservations.

A configured panel prints the subtree as JSON. An unconfigured one says so in a sentence: "No service upnp node in the config tree."

The page polls every 15 s and also refetches after a commit.

A read failure is not silently turned into "not configured". If the router cannot be read the handler answers 502 naming which of the three reads failed, and the page shows an error with a retry — a router that cannot be reached and a router with nothing configured are different facts.

Why these three#

Each of these is a place where the base platform's model and a production network's needs do not quite meet, catalogued in PLAN.md §3. The page exists to make the current state of each visible in one place.

The resolver. VyOS' forwarding resolver cannot express a wildcard record — records a * fails validation — and its authoritative support is apex-oriented. Split-horizon *.internal.example.com → 192.0.2.1 is a common requirement it cannot state.

The DHCP server. Kea, as VyOS configures it, has no per-host option overrides, so one device that needs its own resolver cannot be given one from the configuration tree. PXE is single-bootfile: there is no RFC 4578 architecture-conditional matrix, so a network serving four architecture-specific loaders needs something else.

UPnP. There is no UPnP answer in the product at all.

The one hint on this page#

If dnsmasq is installed from the catalogue, a card appears above the panels titled "Closes three platform gaps". It carries no operations — it is advice — because how you hand DNS or DHCP to a container is a decision about your network, not a command anyone can pre-write.

dnsmasq is the catalogue's direct answer to three of the gaps above: wildcard and split-horizon DNS, per-host DHCP option overrides, and the architecture-conditional PXE matrix. Its catalogue card is marked "Closes a platform gap" for exactly that reason — see Apps and integration offers.

Reading the same thing from the CLI#

show configuration commands | match "service upnp"
show configuration commands | match "service dns"
show configuration commands | match "service dhcp-server"

What this page will not do#

  • It edits nothing. There is no form here. The resolver is configured on the DNS page, DHCP on the DHCP page, and anything else on the Config tree page or the CLI.
  • It does not report process state. "Configured" means a subtree exists, not that a daemon is running or healthy. For process state, the Diagnostics processes tab shows the router's process table.
  • It is not a service list. The agent has a broader GET /api/services that enumerates everything under service, but this page reads the three-way GET /api/daemons instead.

See also#

  • DNS and DHCP — the two services this page reports on, where they are actually configured.
  • Apps — where dnsmasq and the other companions come from.
  • Integration offers — how the card above the panels is built.
  • Diagnostics — processes — what is actually running.
  • Telemetry — why a 15-second poll on three configuration reads is nearly free.

Checked against ui/src/pages/Daemons.tsx, ui/src/components/nav.ts, agent/main.go, agent/opmode.go, agent/catalog.json, PLAN.md, docs/apps.md.

Updated 2026-09-02 manual companions upnp dns dhcp