Skip to content

Extract a swappable networkProxy seam from deployOps - #5906

Merged
ChrisJBurns merged 2 commits into
mainfrom
cburns/envoy-proxy-seam
Jul 22, 2026
Merged

Extract a swappable networkProxy seam from deployOps#5906
ChrisJBurns merged 2 commits into
mainfrom
cburns/envoy-proxy-seam

Conversation

@ChrisJBurns

Copy link
Copy Markdown
Collaborator

Summary

The deployOps interface in pkg/container/docker mixes proxy-container concerns (egress/ingress) with workload-container concerns (DNS, MCP container creation), which makes it impossible to swap the proxy backend without splitting the interface. This PR extracts a networkProxy seam so the backend becomes pluggable, and re-homes the existing Squid logic behind it. Pure refactor — no user-visible behavior change, Squid stays the only backend.

Closes #5901. Part of #5900.

Medium level
  • New networkProxy interface with a single SetupProxies(ctx, proxySpec) (proxyResult, error) method, plus proxySpec/proxyResult value types.
  • Existing Squid egress/ingress logic moved off deployOps into a squidProxy implementation; deployOps no longer owns proxy methods.
  • newNetworkProxy factory reads TOOLHIVE_NETWORK_PROXY (""/squid → Squid) and fails loudly at NewClient on unknown values.
  • SetupProxies is invoked before createMcpContainer so returned proxy env vars can be injected into the workload; port extraction for non-stdio is done before the call, preserving the stdio short-circuit.
  • Also fixes two pre-existing copy-before-mutate issues in addEgressEnvVars and generatePortBindings surfaced by the refactor.
Low level
File Change
pkg/container/docker/networkproxy.go New — networkProxy interface, proxySpec/proxyResult, newNetworkProxy factory, compile-time assertion
pkg/container/docker/squid.go Add squidProxy type wrapping the existing egress/ingress funcs
pkg/container/docker/client.go Drop proxy methods from deployOps; add proxy field + newNetworkProxy wiring in NewClient; call SetupProxies before createMcpContainer; copy-before-mutate fixes
pkg/container/docker/networkproxy_test.go New — factory tests (default/squid/unknown)
pkg/container/docker/client_deploy_test.go Split fakeDeployOpsfakeNetworkProxy; add call-ordering test

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring

Test plan

  • task build passes
  • task test passes for pkg/container/docker/... with -race
  • golangci-lint clean on the changed package
  • TestNewNetworkProxy — default/squid select Squid; unknown value errors
  • TestDeployWorkload_Isolated_SetupProxiesBeforeCreateMcp — asserts SetupProxies runs before createMcpContainer
  • Existing isolation tests unchanged (TestDeployWorkload_*), including non-bridge-mode drop

Special notes for reviewers

Pure refactor foundation for the Envoy backend (#5902). The one behavioral nuance: proxy setup now happens before MCP container creation so proxy env vars can be injected — guarded by an explicit ordering test. Squid remains the default and its config generation is untouched.

Generated with Claude Code

Introduces a networkProxy interface as the single enforcement point for
proxy container setup (egress forward proxy, ingress reverse proxy).
The existing Squid logic moves behind a squidProxy backend selected via
TOOLHIVE_NETWORK_PROXY (default: squid). Fails loudly on unknown values.

SetupProxies is now invoked before createMcpContainer so the returned
env vars can be injected into the workload; port extraction for non-stdio
transports is done before the call (stdio short-circuit preserved).

Also fixes two pre-existing copy-before-mutate violations in
addEgressEnvVars and generatePortBindings.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the size/M Medium PR: 300-599 lines changed label Jul 21, 2026
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.58%. Comparing base (fbf2f6d) to head (81643d8).

Files with missing lines Patch % Lines
pkg/container/docker/squid.go 0.00% 18 Missing ⚠️
pkg/container/docker/client.go 88.63% 3 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5906      +/-   ##
==========================================
- Coverage   71.63%   71.58%   -0.05%     
==========================================
  Files         698      699       +1     
  Lines       71541    71575      +34     
==========================================
- Hits        51245    51239       -6     
- Misses      16598    16655      +57     
+ Partials     3698     3681      -17     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

JAORMX
JAORMX previously approved these changes Jul 22, 2026
The single SetupProxies call ran before createMcpContainer, which created
the Squid ingress reverse proxy before the MCP container existed. Squid
resolved the cache_peer upstream hostname on first probe, cached the
negative DNS result, and never recovered within the readiness window, so
isolated non-stdio workloads hung in "starting" and E2E timed out.

Restore the original, proven ordering by splitting the seam into
SetupEgress (before the MCP container, so proxy env vars are injected and
egress gets a head start) and SetupIngress (after it, so the reverse-proxy
upstream resolves immediately). A consolidated backend threads any reserved
state forward through egressResult, avoiding per-workload state on the
shared proxy. Verified locally: an isolated Squid workload now reaches
running with a healthy ingress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/M Medium PR: 300-599 lines changed and removed size/M Medium PR: 300-599 lines changed labels Jul 22, 2026
@ChrisJBurns
ChrisJBurns merged commit 193a7f2 into main Jul 22, 2026
78 of 79 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Medium PR: 300-599 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract a swappable networkProxy seam from deployOps

2 participants