allow linux/amd64 images#105
Open
erikswedberg wants to merge 2 commits into
Open
Conversation
* Add --host-port to expose host loopback services into sandboxes
Apple's container CLI puts each sandbox on a vmnet bridge with its own
IP. Services bound to 127.0.0.1 on the host (like the Figma desktop
app's MCP server at 127.0.0.1:3845) are therefore unreachable from
inside a sandbox.
This adds a repeatable --host-port flag to 'sand new' (and the
oneshot/exec creation paths). For each requested port:
* The daemon spawns an in-process TCP forwarder bound to the sandbox's
bridge gateway IP, forwarding to 127.0.0.1:<port> on the host. The
listener is scoped to the bridge interface (not 0.0.0.0).
* An iptables DNAT + MASQUERADE rule is installed inside the sandbox
so 127.0.0.1:<port> is rewritten to <gateway>:<port>, with
route_localnet=1 to allow the kernel to route the redirected
loopback packet. The agent sees the service at the same loopback
address it would use on the host -- no client reconfiguration.
Lifecycle: forwarders and rules are set up by a start hook and torn
down on StopContainer / SoftDelete / daemon Close.
* new package internal/hostport: Forwarder + Manager
* new migration 000010_host_ports + sqlc regen
* proto: CreateSandboxRequest.host_ports (field 16)
* doc/HOST_SERVICES.md
Co-authored-by: Shelley <shelley@exe.dev>
* Run host-port iptables setup as root via Exec User=0
The container hook abstraction execs as the container's default user,
which by the time post-bootstrap hooks run is usually the non-root
agent user. iptables (and route_localnet sysctl) need CAP_NET_ADMIN /
root, so the hook was failing with:
iptables: Could not fetch rule set generation id: Permission denied
(you must be root)
Switch to calling ContainerService.Exec directly with User="0" so
the script always runs as uid 0 inside the sandbox.
Co-authored-by: Shelley <shelley@exe.dev>
* Run host-port setup via doas; add host.sand fallback
Recent sand changes mean the container's default user is no longer
root, so ExecContainer.User=0 alone wasn't enough. The base image
configures 'permit nopass :wheel' for doas and adds the sandbox user
to wheel, so switch to 'doas sh -c ...' for both the iptables setup
and the /etc/hosts edit.
Also make the iptables step best-effort: Apple's container runtime
typically does not grant CAP_NET_ADMIN, so DNAT will fail anyway.
When it does, fall back to a 'host.sand' /etc/hosts entry pointing
at the bridge gateway IP. Agents can then reach the host service at
http://host.sand:<port>/ instead of http://127.0.0.1:<port>/.
Co-authored-by: Shelley <shelley@exe.dev>
* Make host-port forwarder HTTP Host-aware; clean up UX
The proxy now sniffs the first bytes of each connection; if they look
like an HTTP/1.x request and a rewrite target is configured (always
the case when started via the Manager), it parses each request,
rewrites the Host header to 127.0.0.1:<port>, and re-serializes it
upstream. Non-HTTP traffic falls back to a plain TCP pipe. WebSocket
and other Upgrade requests have their initial Host header rewritten
and then switch to raw passthrough.
This means a sandbox client can use http://host.sand:<port>/ with no
custom headers; servers like Figma's MCP that validate Host are happy.
Also: * Demote the expected iptables/CAP_NET_ADMIN failure from a warning
to an info log; print a single positive '[sand] host services
exposed at...' line on start.
* Rewrite doc/HOST_SERVICES.md to lead with host.sand:<port> as the
user-facing entry point and document the HTTP Host rewrite.
Co-authored-by: Shelley <shelley@exe.dev>
---------
Co-authored-by: Erik Swedberg <erik@swed.org>
Co-authored-by: Shelley <shelley@exe.dev>
The Apple 'container' CLI defaults to --arch arm64. Creating a sandbox from an image that only ships linux/amd64 variants (e.g. the android sandbox image built with --platform linux/amd64 on an arm64 host) failed with 'Error: platform linux/arm64'. Inspect the image manifest at create time; if no variant matches the host arch, pass --platform <os>/<arch> from the first available variant so 'container create' selects a real variant instead of the arm64 default. Co-authored-by: Shelley <shelley@exe.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
container build --platform linux/amd64 ...when you try to
sand newthis image you see the errorerror is: sand: error: failed to create container for sandbox 8effcd05-18ca-4aa9-b12d-0cb76eda4fad: exit status 1: Error: platform linux/arm64this PR detects the architecture of your image and passes it through / doesn't error. it doesn't add a
--platformswitch (or--archor--os) tosand new