feat(peer-cli): run harness containers on a macvlan network
The previous `peer-cli-run` recipe attached containers with `--network host`.
That makes every peer share the host network namespace, which means two
harness containers on the same machine cannot independently advertise mDNS
or look like distinct LAN devices: they all reuse the host's interface, the
mDNS daemon is single-instance per namespace, and any port the peer binds
is a host-wide port. That defeats the whole point of running multiple
peers side-by-side for end-to-end testing.
Switch the recipe to a Docker macvlan network. Each container gets its own
MAC and IP carved out of the real LAN subnet, sends and receives multicast
on the parent NIC, and appears to the rest of the home network as a fresh
device. mDNS discovery then works between peers exactly as it would for
two laptops on the same LAN, with no relay, reflector, or special routing.
Add a `peer-cli-net` recipe that creates the network idempotently (the
`docker network inspect` short-circuits when it already exists), make
`peer-cli-run` depend on it, and parameterise the parent interface,
subnet, and gateway as justfile variables so they can be overridden from
the command line for machines whose LAN does not match the defaults:
just LANSPREAD_PARENT_IFACE=enp4s0 \
LANSPREAD_SUBNET=10.0.0.0/24 \
LANSPREAD_GATEWAY=10.0.0.1 \
peer-cli-run alpha
The well-known macvlan limitation that the host cannot reach its own
macvlan children over the network is intentionally not worked around:
agents drive each peer through `docker run -i` stdin/stdout, which is the
docker control socket, not the LAN. Host-to-peer connectivity is not part
of the mental model and is not needed for any current test scenario.
Test Plan:
- `just peer-cli-image`
- `docker network create -d macvlan ... lanspread` succeeds on a host with
the default `eth0` interface (or with overridden variables on others).
- `just peer-cli-run alpha` and `just peer-cli-run beta` in two terminals;
both containers come up on the LAN with distinct IPs and discover each
other via mDNS without any `connect` command.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,9 +31,25 @@ peer-cli-build:
|
||||
peer-cli-image:
|
||||
docker build -f crates/lanspread-peer-cli/Dockerfile -t lanspread-peer-cli:dev .
|
||||
|
||||
peer-cli-run NAME:
|
||||
# macvlan: each peer container gets its own MAC/IP on the real LAN.
|
||||
# Override on the command line if your LAN differs, e.g.
|
||||
# just LANSPREAD_PARENT_IFACE=enp4s0 LANSPREAD_SUBNET=10.0.0.0/24 LANSPREAD_GATEWAY=10.0.0.1 peer-cli-net
|
||||
LANSPREAD_NET := "lanspread"
|
||||
LANSPREAD_PARENT_IFACE := "eth0"
|
||||
LANSPREAD_SUBNET := "192.168.1.0/24"
|
||||
LANSPREAD_GATEWAY := "192.168.1.1"
|
||||
|
||||
peer-cli-net:
|
||||
docker network inspect {{LANSPREAD_NET}} >/dev/null 2>&1 || \
|
||||
docker network create -d macvlan \
|
||||
--subnet={{LANSPREAD_SUBNET}} \
|
||||
--gateway={{LANSPREAD_GATEWAY}} \
|
||||
-o parent={{LANSPREAD_PARENT_IFACE}} \
|
||||
{{LANSPREAD_NET}}
|
||||
|
||||
peer-cli-run NAME: peer-cli-net
|
||||
mkdir -p "target/peer-cli/{{NAME}}/state" "target/peer-cli/{{NAME}}/games"
|
||||
docker run --rm --init --network host --name "lanspread-peer-cli-{{NAME}}" -i \
|
||||
docker run --rm --init --network {{LANSPREAD_NET}} --name "lanspread-peer-cli-{{NAME}}" -i \
|
||||
-v "$PWD/target/peer-cli/{{NAME}}/state:/state" \
|
||||
-v "$PWD/target/peer-cli/{{NAME}}/games:/games" \
|
||||
lanspread-peer-cli:dev \
|
||||
|
||||
Reference in New Issue
Block a user