fix(sidecars): apply_routes_change targets the bundle + SIGHUP forwarding
test / unit (pull_request) Successful in 20s
test / integration (pull_request) Successful in 42s

Two bugs surfaced when applying an egress route change:

1. egress_apply.py still targeted claude-bottle-egress-<slug> —
   the legacy per-sidecar container that no longer exists (it's
   a docker-network alias on the bundle now). Switched it to
   sidecar_bundle_container_name(slug), matching the chunk-5
   fix already made to pipelock_apply.py.

2. `docker kill --signal HUP <bundle>` lands SIGHUP on the
   supervisor (PID 1 in the bundle), which previously had no
   SIGHUP handler — the signal was ignored. Added
   `_Supervisor.forward_signal(sig, daemon_name)` and a SIGHUP
   handler in main() that forwards to the egress daemon so
   mitmdump's addon reload still works under the bundle.

Tests:
- New _Supervisor.forward_signal cases: forwards to the named
  child (Python subprocess as the SIGHUP target — bash trap +
  stdout=PIPE deferral interferes with the production-style
  test); unknown-daemon name is a no-op.

Stale-reference cleanup (separate issue surfaced while looking
at this):
- claude_bottle/{egress,git_gate,egress_addon,
  egress_addon_core,supervise_server}.py: Dockerfile.egress /
  Dockerfile.git-gate / Dockerfile.supervise references updated
  to Dockerfile.sidecars (the old per-sidecar Dockerfiles were
  deleted in PRD 0024 chunk 5).
- tests/README.md: dropped the entry for
  test_pipelock_sidecar_smoke (deleted in chunk 3) and added
  the new bundle integration tests.
- git_gate.py: stale `DockerGitGate.start via docker cp`
  reference (the method was deleted in chunk 3) rewritten to
  the bind-mount path the renderer uses now.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 01:56:38 -04:00
parent 853d28bc89
commit 0848344438
9 changed files with 113 additions and 28 deletions
+3 -3
View File
@@ -31,7 +31,7 @@ from ...egress import EGRESS_ROUTES_IN_CONTAINER
from ...egress_addon_core import load_routes
from ...yaml_subset import YamlSubsetError, parse_yaml_subset
from .bottle_state import egress_state_dir
from .egress import egress_container_name
from .sidecar_bundle import sidecar_bundle_container_name
from .pipelock_apply import (
PipelockApplyError,
apply_allowlist_change,
@@ -81,7 +81,7 @@ def fetch_current_routes(slug: str) -> str:
for `slug`. Returns the file content as a string. Raises
EgressApplyError if the sidecar isn't reachable or the read
fails."""
container = egress_container_name(slug)
container = sidecar_bundle_container_name(slug)
r = subprocess.run(
["docker", "exec", container, "cat", EGRESS_ROUTES_IN_CONTAINER],
capture_output=True, text=True, check=False,
@@ -185,7 +185,7 @@ def apply_routes_change(slug: str, new_content: str) -> tuple[str, str]:
Returns (before, after) where `after` == `new_content`. Raises
EgressApplyError on any step."""
container = egress_container_name(slug)
container = sidecar_bundle_container_name(slug)
before = fetch_current_routes(slug)
validate_routes_content(new_content)