diff --git a/tests/tools/test_process_registry.py b/tests/tools/test_process_registry.py index 62dd2f9496..3f8527aaf1 100644 --- a/tests/tools/test_process_registry.py +++ b/tests/tools/test_process_registry.py @@ -2424,6 +2424,34 @@ class TestSystemdCgroupIsolation: assert "XDG_RUNTIME_DIR" not in os.environ assert "DBUS_SESSION_BUS_ADDRESS" not in os.environ + def test_probe_uses_portable_payload_not_hardcoded_bin_true( + self, registry, monkeypatch + ): + """The probe payload must not hardcode ``/bin/true``: NixOS has no FHS + ``/bin`` (only ``sh``), so an absolute ``/bin/true`` probe fails there for + a reason unrelated to scope availability and disables restart-safe cron + dispatch on every scheduled fire (#105365). The payload is + ``/bin/sh -c 'exit 0'``, which exists on every Linux.""" + import tools.process_registry as pr + + monkeypatch.setattr(pr, "_SYSTEMD_SCOPE_AVAILABLE", None) + monkeypatch.setattr(pr, "_SYSTEMD_SCOPE_PROBED_AT", 0.0, raising=False) + probe_calls = [] + + def fake_run(*args, **kwargs): + probe_calls.append(args) + return subprocess.CompletedProcess(args=args[0], returncode=0) + + monkeypatch.setattr("shutil.which", lambda name: "/usr/bin/systemd-run") + monkeypatch.setattr("subprocess.run", fake_run) + + assert pr._systemd_run_user_scope_available() is True + probe_argv = probe_calls[0][0] + sep_idx = probe_argv.index("--") + payload = probe_argv[sep_idx + 1 :] + assert "/bin/true" not in payload, probe_argv + assert payload[:3] == ["/bin/sh", "-c", "exit 0"], probe_argv + def test_systemd_scope_first_probe_is_serialized(self, monkeypatch): """Concurrent first-use callers must wait for one definitive probe. diff --git a/tools/process_registry.py b/tools/process_registry.py index f35027d8f2..5c1b1a2cb7 100644 --- a/tools/process_registry.py +++ b/tools/process_registry.py @@ -207,7 +207,12 @@ def _systemd_run_user_scope_available() -> bool: """True if ``systemd-run --user --scope`` can create a cgroup. ``shutil.which`` alone is insufficient: system services and containers may lack the user D-Bus bus even with the binary on PATH (every spawn would fail with - ``Failed to connect to user bus``), so a cheap ``/bin/true`` probe is run and cached.""" + ``Failed to connect to user bus``), so a cheap probe is run and cached. + + The probe payload is ``/bin/sh -c 'exit 0'`` rather than ``/bin/true``: NixOS has + no FHS ``/bin`` (only ``sh``), so an absolute ``/bin/true`` probe fails there for a + reason unrelated to scope availability and disables restart-safe cron dispatch on + every scheduled fire (#105365).``""" global _SYSTEMD_SCOPE_AVAILABLE, _SYSTEMD_SCOPE_PROBED_AT verdict = _systemd_scope_cached() if verdict is not None: @@ -228,7 +233,7 @@ def _systemd_run_user_scope_available() -> bool: # Unique unit avoids collisions; the timeout bounds D-Bus. probe_unit = f"hermes-probe-scope-{os.getpid()}-{uuid.uuid4().hex[:8]}" result = subprocess.run( - _systemd_scope_argv(binary, probe_unit, "/bin/true"), + _systemd_scope_argv(binary, probe_unit, "/bin/sh", "-c", "exit 0"), capture_output=True, timeout=3, env=systemd_user_bus_env(),