From 4d7581b23b560a2a6803cae2df91f90368c01b21 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 3 Sep 2026 15:31:48 +0200 Subject: fix(node): reload the user manager before reload/restart-daemon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported live: after installing the .deb, systemd printed "Warning: The unit file, source configuration file or drop-ins of meshbay-node.service changed on disk. Run 'systemctl --user daemon-reload' to reload units." Both postinst scripts (deb and rpm) already run a daemon-reload, but only for the system manager — they run as root, and the unit that changed is the *user* unit (packaging/systemd/meshbay-node-user.service), owned by each signed-in person's own user manager, a different process root cannot reach. Iterating over logged-in users from postinst was considered and rejected: fragile (depends on machined and each user's session bus), and root has no business doing a user's job. `_systemctl_user` — the one place `reload` and `restart-daemon` already shell out to systemd — now reloads the user manager first, under the correct privilege, right before the verb that would otherwise act on a stale unit. Best-effort and unchecked, like the postinst's own daemon-reload: a reload the manager did not need must never block what the operator asked for, and systemd still reports a genuine failure from the verb itself. Does not touch the postinst scripts. On a package upgrade the warning can still appear once, before the next reload/restart-daemon (or a login, which starts a fresh user manager that reads the current file); this closes it from the CLI's own lifecycle commands rather than reaching into every session from root. test_lifecycle_commands_delegate_to_systemctl_user now expects the daemon-reload call ahead of the verb — checked failing against the previous code. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01AbwJDbNTkiRUh7HTWEoyss --- packages/meshbay-node/tests/test_cli_dispatch.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'packages/meshbay-node/tests/test_cli_dispatch.py') 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 -- cgit v1.2.3