diff options
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/daemon.py | 14 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_cli_dispatch.py | 10 |
2 files changed, 23 insertions, 1 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/daemon.py b/packages/meshbay-node/src/meshbay_node/daemon.py index 8f9307c..3a024f0 100644 --- a/packages/meshbay-node/src/meshbay_node/daemon.py +++ b/packages/meshbay-node/src/meshbay_node/daemon.py @@ -1599,9 +1599,23 @@ def _systemctl_user(verb: str, unit: str, *, not_running_hint: str, signalling it, respawning it — is a second, worse implementation of what systemd is already doing, and pattern-matching a process list has already hit a real developer's real running node by accident. + + Reloads the user manager's view of unit files first. The package + installers (deb postinst, rpm %post) run as root and can only reload the + *system* manager — a different process from any signed-in user's *user* + manager, which is the one that actually owns this unit — so a package + upgrade leaves that manager still holding the old unit file and prints a + warning naming the exact fix. Doing it here runs it under the right + privilege, the user's own, right before the command that would otherwise + act on a stale definition. Best-effort and unchecked: a reload the + manager did not need must never block what the operator actually asked + for, and a genuine problem still surfaces from the verb below. """ import subprocess + subprocess.run(["systemctl", "--user", "daemon-reload"], + capture_output=True, text=True) + result = subprocess.run(["systemctl", "--user", verb, unit], capture_output=True, text=True) if result.returncode != 0: diff --git a/packages/meshbay-node/tests/test_cli_dispatch.py b/packages/meshbay-node/tests/test_cli_dispatch.py index b676546..c774dc0 100644 --- a/packages/meshbay-node/tests/test_cli_dispatch.py +++ b/packages/meshbay-node/tests/test_cli_dispatch.py @@ -150,12 +150,20 @@ def test_lifecycle_commands_delegate_to_systemctl_user( `reload` and `restart-daemon` must ask systemd to do it, not hunt a PID with pgrep and signal it directly — that pattern-matched a developer's own running node by accident once, which is why it was replaced. + + They must also reload the user manager's view of unit files first: a + package upgrade only reloads the *system* manager (it runs as root and + cannot reach a signed-in user's own), so the user manager can still be + holding a stale unit when one of these runs. """ monkeypatch.setattr(sys, "argv", ["meshbay-node", *argv]) daemon_mod.main() systemctl_calls = dict(stub_daemon)["_systemctl_calls"] - assert systemctl_calls == [["systemctl", "--user", verb, "meshbay-node"]] + assert systemctl_calls == [ + ["systemctl", "--user", "daemon-reload"], + ["systemctl", "--user", verb, "meshbay-node"], + ] assert not capsys.readouterr().err |