Skip to content

network: inject host.vz.internal alias; clean up dormant gvproxy code#1

Merged
lightsofapollo merged 1 commit into
mainfrom
host-vz-internal-and-gvproxy-cleanup
May 18, 2026
Merged

network: inject host.vz.internal alias; clean up dormant gvproxy code#1
lightsofapollo merged 1 commit into
mainfrom
host-vz-internal-and-gvproxy-cleanup

Conversation

@lightsofapollo
Copy link
Copy Markdown
Contributor

Summary

Two related network changes:

  • vz-ufk — Every vz stack-managed container now resolves host.vz.internal192.168.64.1 (Apple's NAT gateway) via /etc/hosts, giving sandboxed workloads a stable name for the macOS host (the Docker Desktop equivalent of host.docker.internal). Constants live in vz-runtime-contract so portable consumers don't pull in the macOS-only vz crate.
  • vz-832 — Delete the dormant GvproxyBackend / GvproxyConfig / locate_gvproxy / NetworkBackend trait / NetworkHandle from crates/vz-stack/src/network.rs. The gvproxy binary was never spawned; the actual networking model is Apple NAT (outbound) + per-container /etc/hosts (sibling DNS) + a vsock-relay TCP listener in vz-oci-macos/src/runtime/networking.rs (inbound forwarding). The new top-of-file doc describes that model accurately.

Known limitation (tracked, not in this PR)

Data-plane reachability from a stack-managed netns container to 192.168.64.1 is not working today — the guest agent's setup_stack_network doesn't program MASQUERADE / ip_forward, and the initramfs ships no iptables / nft. The kernel has CONFIG_NF_NAT / CONFIG_NF_TABLES compiled in, so this is purely a userspace gap. Tracked as vz-0ml. The companion host_vz_internal_reaches_host_service_via_nat_gateway E2E is #[ignore]'d on that bead. The DNS-injection side of this PR is fully proven (see test plan below).

Also filed: vz-662network: revive gvproxy as the production network backend (would solve host.vz.internal reachability properly + LAN-bind for inbound + UDP forwarding). Reframed by the discovery during this work that port forwarding does work today via the vsock-relay TCP listener (TCP, loopback-only) — so the gvproxy revival argument is narrower than it first looked.

Test plan

  • cargo build --workspace clean
  • cargo clippy -p vz -p vz-runtime-contract -p vz-stack -p vz-oci-macos --lib clean
  • cargo nextest run -p vz-stack — 691/692 pass (the 1 failure is environment_secret_source_is_staged_and_mounted, pre-existing on main; $HOME is a directory in the sandbox)
  • New unit test host_vz_internal_injected_into_every_service proves solo-service stacks get the alias
  • Updated three_service_ip_allocation + default_network_backward_compat to acknowledge the extra /etc/hosts entry
  • Real Linux VM E2E: host_vz_internal_etc_hosts_entry_present_in_container boots a real shared VM, creates a netns-isolated container through the full stack pipeline, execs grep host.vz.internal /etc/hosts, and confirms the row points at 192.168.64.1. Run via ./scripts/run-sandbox-vm-e2e.sh --suite runtime -- --ignored --nocapture --test-threads=1 --exact host_vz_internal_etc_hosts_entry_present_in_container
  • Regression check: existing shared_vm_inter_service_connectivity E2E still passes — Task 2 cleanup didn't break the bridge / netns / extra_hosts pipeline

Files

File Why
crates/vz-runtime-contract/src/types/workload.rs, src/lib.rs New HOST_INTERNAL_ALIAS and HOST_INTERNAL_GATEWAY_IPV4 constants (lives here, not in vz, so vz-stack doesn't take a macOS-only dep)
crates/vz/src/protocol.rs Pointer comment to the canonical home
crates/vz-stack/src/executor/create.rs Inject the alias into every service's extra_hosts before the sibling-service loop
crates/vz-stack/src/executor/tests.rs New + updated unit tests
crates/vz-stack/src/network.rs Delete dormant gvproxy code; new top-of-file doc describing the real networking model
crates/vz-stack/src/lib.rs Trim re-exports
crates/vz-oci-macos/tests/runtime_e2e.rs Two E2E tests (one passing, one gated on vz-0ml)
README.md Document host.vz.internal + 0.0.0.0-vs-127.0.0.1 caveat + netns-reachability limitation
planning/host-internal-alias/README.md Design doc

🤖 Generated with Claude Code

…y code

vz-ufk: every stack-managed container now resolves `host.vz.internal` →
`192.168.64.1` (Apple's NAT gateway) via `/etc/hosts`, giving sandboxed
workloads a stable name for the macOS host. Constants live in
`vz-runtime-contract` so portable consumers don't pull in the macOS-only
`vz` crate. Reachability over the gateway from per-service netns
containers is gated on a separate MASQUERADE follow-up (vz-0ml); the
DNS-injection side is proven end-to-end on a real VM via the new
`host_vz_internal_etc_hosts_entry_present_in_container` E2E.

vz-832: delete the dormant `GvproxyBackend` / `GvproxyConfig` /
`locate_gvproxy` / `NetworkBackend` trait / `NetworkHandle`. The gvproxy
binary was never spawned; the real network is Apple NAT + per-container
`/etc/hosts` + a vsock-relay TCP listener for inbound forwarding. The new
top-of-file doc in `crates/vz-stack/src/network.rs` describes that
model accurately.

Follow-ups filed: vz-0ml (stack-network MASQUERADE), vz-662 (gvproxy
revival as the production network backend).
@lightsofapollo lightsofapollo merged commit 5ff4071 into main May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant