From 88c2e68d47532509a13da1a3fc5f26c37348be23 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 6 May 2026 22:25:40 +0000 Subject: [PATCH] fix(quic-interop): make smoke target work on Docker Desktop for Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two coupled fixes that surface together when running the smoke target outside the runner's privileged sim environment: 1. run_endpoint.sh now tolerates /setup.sh failures. The base image's /setup.sh manipulates routes for the runner's ns-3 sim. Outside the runner (e.g., make smoke without --privileged), it fails with "netlink error: Operation not permitted" — and our set -euo pipefail bailed before launching the JVM. The setup is genuinely not needed for smoke; tolerate the failure and continue. 2. make smoke uses a private Docker bridge instead of --network host. --network host on Docker Desktop for Mac is *not* the Mac host's network — it's the LinuxKit VM's, and 127.0.0.1 isn't routed back to other Docker containers. A dedicated bridge with DNS-by-name works identically on Mac and Linux. Bonus: smoke-down target reliably tears down the env. Inside the runner these changes are no-ops: the runner provides the privileges /setup.sh needs, and uses its own compose network not --network host. https://claude.ai/code/session_01HcvfQq1ttPV9PkRoJb4nyT --- quic/interop/Makefile | 31 ++++++++++++++++++++++++------- quic/interop/run_endpoint.sh | 15 ++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/quic/interop/Makefile b/quic/interop/Makefile index 87bd6c269..1eb26eec8 100644 --- a/quic/interop/Makefile +++ b/quic/interop/Makefile @@ -2,6 +2,7 @@ # # make build # compile JVM dist + build Docker image # make smoke # quick handshake test against a local picoquic +# make smoke-down # tear down the smoke environment # make image-name # print the image tag (for use in implementations_quic.json) # # These targets are deliberately thin wrappers — the real harness is the @@ -10,9 +11,11 @@ IMAGE ?= amethyst-quic-interop:latest REPO_ROOT := $(shell git rev-parse --show-toplevel) DIST_DIR := build/install/quic-interop -PICOQUIC_PORT ?= 4433 +SMOKE_NET := amethyst-quic-interop-smoke-net +SMOKE_PICOQUIC := amethyst-quic-interop-smoke-picoquic +SMOKE_CLIENT := amethyst-quic-interop-smoke-client -.PHONY: build dist docker smoke image-name clean +.PHONY: build dist docker smoke smoke-down image-name clean build: docker @@ -22,14 +25,28 @@ dist: docker: dist cd $(REPO_ROOT) && docker build -t $(IMAGE) -f quic/interop/Dockerfile . -smoke: docker - @docker rm -f amethyst-quic-interop-smoke >/dev/null 2>&1 || true - docker run --rm --name amethyst-quic-interop-smoke \ - --network host \ +# Stand up picoquic + our endpoint on a private Docker bridge network. This +# avoids `--network host`, which on Docker Desktop for Mac is misleadingly +# *not* the Mac host's network — it's the LinuxKit VM's, and port forwarding +# trickery makes 127.0.0.1 unreliable. A dedicated bridge with name-based +# DNS works the same on Mac and Linux. +smoke: docker smoke-down + docker network create $(SMOKE_NET) >/dev/null 2>&1 || true + docker run -d --name $(SMOKE_PICOQUIC) \ + --network $(SMOKE_NET) \ + privateoctopus/picoquic:latest picoquicdemo -p 4433 >/dev/null + @echo "picoquic up on $(SMOKE_PICOQUIC):4433 (in $(SMOKE_NET))" + docker run --rm --name $(SMOKE_CLIENT) \ + --network $(SMOKE_NET) \ -e ROLE=client \ -e TESTCASE=handshake \ - -e REQUESTS="https://127.0.0.1:$(PICOQUIC_PORT)/" \ + -e REQUESTS="https://$(SMOKE_PICOQUIC):4433/" \ $(IMAGE) + @$(MAKE) smoke-down + +smoke-down: + @docker rm -f $(SMOKE_PICOQUIC) $(SMOKE_CLIENT) >/dev/null 2>&1 || true + @docker network rm $(SMOKE_NET) >/dev/null 2>&1 || true image-name: @echo $(IMAGE) diff --git a/quic/interop/run_endpoint.sh b/quic/interop/run_endpoint.sh index fdbcf2146..4fc33b9c1 100755 --- a/quic/interop/run_endpoint.sh +++ b/quic/interop/run_endpoint.sh @@ -1,13 +1,18 @@ #!/usr/bin/env bash # quic-interop-runner endpoint entry point. # -# The base image (martenseemann/quic-network-simulator-endpoint) sets up -# routing in /setup.sh; we source it then dispatch to our JVM client based -# on the ROLE env var pushed in by the runner. -set -euo pipefail +# The base image (martenseemann/quic-network-simulator-endpoint) provides +# /setup.sh, which configures routing for the runner's ns-3 sim. We try +# to source it but tolerate failure so smoke tests outside the runner +# (without --privileged / the sim's network) still launch the JVM client. +# Inside the runner, /setup.sh succeeds because the runner provides the +# necessary capabilities. +set -uo pipefail # shellcheck disable=SC1091 -source /setup.sh +source /setup.sh 2>/dev/null || echo "(setup.sh skipped — running outside the runner sim)" >&2 + +set -e case "${ROLE:-client}" in client)