fix(sidecars): apply_routes_change targets the bundle + SIGHUP forwarding #60

Merged
didericis merged 1 commits from fix-egress-apply-bundle-target into main 2026-05-27 02:02:54 -04:00
Owner

Summary

Fixes the apply failed: could not read routes.yaml from claude-bottle-egress-<slug> error when applying an egress route change. Two bugs were stacked:

  1. egress_apply.py still targeted the legacy container name. After PRD 0024 chunk 5, claude-bottle-egress-<slug> is a docker-network alias on the bundle, not a real container. docker exec against an alias fails. Switched the apply path to sidecar_bundle_container_name(slug) (the same fix already made for pipelock_apply.py in chunk 5 — egress_apply was missed).

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

Tests

  • New _Supervisor.forward_signal cases: forwards to the named child, unknown-daemon name is a no-op. The test uses a Python subprocess as the SIGHUP target — bash trap + stdout=PIPE defers signal handlers on macOS, which produces flaky shell-trap fixtures; the production code path doesn't have a shell between (egress_entrypoint.sh execs mitmdump).

Bonus: stale-reference cleanup

Surfaced while looking at the SIGHUP fix. Files in claude_bottle/ (outside the docker backend) referenced Dockerfile.{egress,git-gate,supervise} — all deleted in PRD 0024 chunk 5. Updated to Dockerfile.sidecars. Also dropped the tests/README.md entry for test_pipelock_sidecar_smoke (deleted in chunk 3) and updated the DockerGitGate.start via docker cp comment in git_gate.py (the method was deleted in chunk 3; the renderer uses bind mounts now).

A separate pass to clean up Docker-isms in the platform-neutral ABCs (egress.py, git_gate.py, pipelock.py) should wait for PRD 0023 smolmachines work — the right phrasing depends on what concepts that backend introduces.

Test status

500 unit + integration smoke locally green.

## Summary Fixes the `apply failed: could not read routes.yaml from claude-bottle-egress-<slug>` error when applying an egress route change. Two bugs were stacked: 1. **`egress_apply.py` still targeted the legacy container name.** After PRD 0024 chunk 5, `claude-bottle-egress-<slug>` is a docker-network alias on the bundle, not a real container. `docker exec` against an alias fails. Switched the apply path to `sidecar_bundle_container_name(slug)` (the same fix already made for `pipelock_apply.py` in chunk 5 — egress_apply was missed). 2. **SIGHUP was being silently dropped.** `docker kill --signal HUP <bundle>` lands SIGHUP on the supervisor (PID 1 in the bundle), which previously had no SIGHUP handler. Added `_Supervisor.forward_signal(sig, daemon_name)` plus a SIGHUP handler in `main()` that forwards to the egress daemon, so mitmdump's addon reload still works. ## Tests - New `_Supervisor.forward_signal` cases: forwards to the named child, unknown-daemon name is a no-op. The test uses a Python subprocess as the SIGHUP target — bash trap + `stdout=PIPE` defers signal handlers on macOS, which produces flaky shell-trap fixtures; the production code path doesn't have a shell between (`egress_entrypoint.sh` `exec`s mitmdump). ## Bonus: stale-reference cleanup Surfaced while looking at the SIGHUP fix. Files in `claude_bottle/` (outside the docker backend) referenced `Dockerfile.{egress,git-gate,supervise}` — all deleted in PRD 0024 chunk 5. Updated to `Dockerfile.sidecars`. Also dropped the `tests/README.md` entry for `test_pipelock_sidecar_smoke` (deleted in chunk 3) and updated the `DockerGitGate.start via docker cp` comment in `git_gate.py` (the method was deleted in chunk 3; the renderer uses bind mounts now). A separate pass to clean up Docker-isms in the platform-neutral ABCs (`egress.py`, `git_gate.py`, `pipelock.py`) should wait for PRD 0023 smolmachines work — the right phrasing depends on what concepts that backend introduces. ## Test status 500 unit + integration smoke locally green.
didericis added 1 commit 2026-05-27 01:56:55 -04:00
fix(sidecars): apply_routes_change targets the bundle + SIGHUP forwarding
test / unit (pull_request) Successful in 20s
test / integration (pull_request) Successful in 42s
0848344438
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>
didericis merged commit c48f791d7d into main 2026-05-27 02:02:54 -04:00
Sign in to join this conversation.