Follow-up to the cherry-picked #111584 (@chelsealong): - website/docs/user-guide/docker.md: new warning block next to the existing "do not override the entrypoint" note explaining WHY (with `/init` gone the hermes process is PID 1 and nothing reaps orphaned browser/MCP/shell children), the Compose `init: true` / `docker run --init` remedy, and that supervision is still lost on that path; plus a Troubleshooting entry for `<defunct>` processes under PID 1. - hermes_cli/main.py: `_warn_if_unsupervised_pid1` keeps the `os.getpid() == 1` check and drops the `platform.system()` gate and the blanket `try/except Exception: pass` — a user process is never PID 1 on any host OS (PID 1 is init/launchd; Windows PIDs are multiples of 4), and nothing in the check can raise. - tests trimmed to two invariants (warns at pid 1 / silent otherwise). Not done, on purpose: a `prctl(PR_SET_CHILD_SUBREAPER)` + SIGCHLD reaper in main-wrapper/hermes. As PID 1 hermes already receives the orphans; what is missing is a `waitpid(-1)` loop, and a process-wide one races `subprocess.Popen` for exit statuses. The maintainer decides whether that runtime change is wanted; docs + the startup warning cover the reported deployment.
17 lines
573 B
Python
17 lines
573 B
Python
"""The PID-1-with-no-init startup warning (#111577): a Compose ``entrypoint:`` override
|
|
makes hermes PID 1 with no reaper above it, so orphaned children pile up as zombies."""
|
|
|
|
from hermes_cli.main import _warn_if_unsupervised_pid1
|
|
|
|
|
|
def test_warns_when_process_is_pid_1(capsys):
|
|
_warn_if_unsupervised_pid1(pid=1)
|
|
err = capsys.readouterr().err
|
|
assert "PID 1" in err and "init: true" in err
|
|
|
|
|
|
def test_silent_when_not_pid_1(capsys):
|
|
_warn_if_unsupervised_pid1(pid=4242)
|
|
captured = capsys.readouterr()
|
|
assert captured.err == "" and captured.out == ""
|