Skip to content

v0.78.0 — the bridge survives a reboot

Choose a tag to compare

@ralyodio ralyodio released this 30 Aug 13:06
fc72b68

The half of dns enable that a reboot takes away

moshcode dns enable sets up two things with very different lifetimes. The systemd-resolved drop-in is a file, and comes back on its own. The bridge process does not. After a restart the routing still points at 5354 with nothing behind it, and every Moshpit name stops resolving with no obvious cause — the machine looks configured, because it is.

This is the whole reason Moshpit DNS has held on servers and quietly fallen over on desktops. Servers got a unit installed by hand at some point. Desktops never did.

dns service is the missing half:

moshcode dns service            # print the unit, change nothing
moshcode dns service --write    # install and start it, as you, no root needed
moshcode dns service --system   # a system unit instead
moshcode dns service --remove   # stop it and take it away

The verb has been listed in the CLI's own verb table since that table was written, so it has been showing up in dns help and in shell completion this whole time. It had no handler behind it. Typing it printed unknown: dns service and the usage block — advertised, completable, and not there.

Why the unit is generated rather than shipped

A unit file did exist, in examples/templates/*/deploy/moshcode-dns.service, and it could not start on an ordinary install:

ExecStart=/usr/bin/env moshcode dns start --port 5354
DynamicUser=yes
ProtectHome=yes

Three independent reasons, each fatal by itself. moshcode is not on systemd's PATH — it installs to ~/.local/bin. The node its wrapper execs is not on it either, because on any mise, nvm or asdf machine that is a second shim under $HOME. And ProtectHome=yes hides the install from the service even if both had somehow been found, while DynamicUser=yes hands it a home directory with no moshcode in it.

What that unit needs in order to work is moshcode and node installed system-wide — which is the server case, the one that was already fine. The file that existed to fix desktops was the one thing structurally incapable of it. It fails at 203/EXEC, which systemd reports with nothing else to say.

So no static unit is written any more, because no static unit can be right. dns service builds one from the running process: process.execPath is an interpreter demonstrably able to run this code, on the evidence that it is running it, and the entry is the script the command was invoked from. Nothing is guessed and nothing depends on PATH. Regenerate it after moving or reinstalling either program, rather than editing it.

The user scope is the default, because it is the one that matches how moshcode is installed. It runs as you, so $HOME and the shims are reachable exactly as they are in a shell, and systemd sets XDG_RUNTIME_DIR, which puts the pidfile precisely where an unprivileged dns status goes looking for it. Under a system unit those are two different paths, and the mismatch is its own class of confusion. A user service does stop at logout unless you allow it to linger:

loginctl enable-linger "$USER"

Installing a service stays its own verb rather than something enable does quietly. Nothing here starts a service that was not asked for, and --remove takes away the service only — the routing is still dns disable.

Two smaller corrections, both in the path of the above

docs/hosting-a-moshpit-name.md and the dns examples in the CLI's help both told people to type sudo moshcode dns enable. The CLI escalates the one step that needs root by itself, and prefixing the whole thing takes every path from the wrong $HOME — the failure mode that put a pidfile in /root/.moshcode and made a running bridge invisible for the rest of its life. The docs no longer suggest it.

The three template units have been rewritten to say what they are: a fallback for the system-wide case, with the working instruction being to generate one instead.