fix(container): keep named multiplex gateway slots down (#65368)

This commit is contained in:
Ben Barclay 2026-07-16 14:30:05 +10:00 committed by GitHub
parent f8ddf4fd86
commit 6a35f9e667
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 1 deletions

View file

@ -125,6 +125,16 @@ def reconcile_profile_gateways(
"""
actions: list[ReconcileAction] = []
# A multiplexing root/default gateway owns inbound platform connections
# for every profile. Named slots must still be registered (so explicit
# lifecycle management remains available), but booting them from their
# persisted run intent would create additional multiplex owners.
from utils import is_truthy_value
multiplex_profiles = is_truthy_value(
os.environ.get("GATEWAY_MULTIPLEX_PROFILES"),
)
# Default profile — always register, even if nothing has ever
# populated the root profile dir. The slot exists so
# ``hermes gateway start`` (no ``-p``) has somewhere to land;
@ -173,7 +183,9 @@ def reconcile_profile_gateways(
continue
prior_state = _read_desired_state(entry)
should_start = prior_state in _AUTOSTART_STATES
should_start = (
not multiplex_profiles and prior_state in _AUTOSTART_STATES
)
if not dry_run:
_cleanup_stale_runtime_files(entry)

View file

@ -195,6 +195,39 @@ def test_desired_state_running_autostarts_even_if_runtime_failed(tmp_path: Path)
assert not (scandir / "gateway-resilient" / "down").exists()
def test_multiplex_boot_keeps_named_running_profile_registered_down(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Only the root/default s6 slot may own a multiplex gateway process."""
monkeypatch.setenv("GATEWAY_MULTIPLEX_PROFILES", "true")
scandir = tmp_path / "run-service"; scandir.mkdir()
_seed_default_root(tmp_path, state="running")
profile = _make_profile(
tmp_path,
"resilient",
state="running",
desired_state="running",
)
persisted_state = (profile / "gateway_state.json").read_text()
actions = reconcile_profile_gateways(
hermes_home=tmp_path, scandir=scandir, dry_run=False,
)
assert actions == [
ReconcileAction(
profile="default", prior_state="running", action="started",
),
ReconcileAction(
profile="resilient", prior_state="running", action="registered",
),
]
assert not (scandir / "gateway-default" / "down").exists()
assert (scandir / "gateway-resilient" / "down").exists()
assert (profile / "gateway_state.json").read_text() == persisted_state
def test_desired_state_stopped_blocks_legacy_running_runtime(tmp_path: Path) -> None:
"""Explicit stop must survive a stale legacy runtime state of running."""
scandir = tmp_path / "run-service"; scandir.mkdir()