Files
fips/testing/iface-binding/docker-compose.yml
T
Johnathan Corgan 1eb0e8a34e Move the TUN and DNS child start and stop bodies into ipv6tun
Bringing the TUN device and the .fips DNS responder up and taking them
down is host-side work, but the bodies sat inline in the node's
supervisor arms, and their handles were eight loose fields on the
supervisor. Move the bodies to ipv6tun::lifecycle and gather the
handles into one Handles struct there, held by the supervisor. The
supervisor arms, their order and the child-exit reporting are
unchanged; each arm now calls into ipv6tun.

The TUN start is two calls so the node can refresh its MSS ceiling
between them, exactly where it did before: open_tun creates and logs
the device, then spawn_tun creates the macOS/FreeBSD shutdown pipe and
starts the writer and reader threads. A failure to create the device
still continues without a TUN, and a pipe or writer failure still fails
the node's start. stop_tun and stop_dns carry the teardown unchanged,
including the shutdown-pipe write that wakes the reader on macOS and
FreeBSD.

The TUN device name moves into Handles as well, so the teardown up-set
can ask ipv6tun whether each child is up. A TUN counts as up when it
has a device name, not when it has a sender, so an app-owned TUN still
produces no TUN teardown; DNS counts as up while its task handle
exists. Node::tun_name, tun_tx, dns_local_addr and
enable_app_owned_tun keep their behaviour and now read or write the
handles. Node::mesh_ifindex had no caller left outside a test and is
replaced by the same method on Handles. Tests install a TUN sender
through a test-only Node::install_tun.

The moved log lines now log under fips::ipv6tun::lifecycle instead of
fips::node::lifecycle. Add that target to the NAT harness and its trace
overlay, and to the harnesses that relied on fips::node=debug, and note
the rename in the changelog.
2026-09-24 14:45:51 +00:00

81 lines
3.4 KiB
YAML

networks:
# Management bridge only. The FIPS transport under test is raw Ethernet on a
# veth pair the harness creates *after* the daemons are already running —
# that is the whole point of the suite — so no FIPS traffic crosses this
# network. No subnet is requested, so two concurrent runs cannot collide on
# one address range.
#
# The compose project name is still fixed, so two runs that do not set
# COMPOSE_PROJECT_NAME share a project and the second `up` recreates the
# first's containers. The local CI runner scopes it externally
# (run_iface_binding in ci-local.sh); a bare hand run does not.
ifb-net:
driver: bridge
labels:
- "com.corganlabs.fips-ci=1"
x-fips-common: &fips-common
build:
# The harness scopes its build context per run and passes it here; the
# shared directory is the hand-run default. Compose resolves a relative
# value against THIS file's directory, so the harness must export an
# absolute path.
context: ${FIPS_BUILD_CONTEXT:-../docker}
image: ${FIPS_TEST_IMAGE:-fips-test:latest}
entrypoint: ["/usr/local/bin/entrypoint.sh"]
cap_add:
- NET_ADMIN
- NET_RAW
restart: "no"
environment:
# `default`, deliberately — NOT `chaos`. The chaos entrypoint waits up to
# 30 s for every configured Ethernet interface to appear before it starts
# the daemon, which is precisely the workaround this mechanism retires. The
# daemon must do its own waiting here or the suite proves nothing.
- FIPS_TEST_MODE=default
- RUST_LOG=info,fips::transport::ethernet=debug,fips::node=debug,fips::ipv6tun::icmp=debug,fips::ipv6tun::lifecycle=debug
networks:
- ifb-net
services:
node-a:
<<: *fips-common
container_name: fips-ifb-node-a${FIPS_CI_NAME_SUFFIX:-}
hostname: host-a
volumes:
- ../docker/resolv.conf:/etc/resolv.conf:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-a/fips.yaml:/etc/fips/fips.yaml:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-a/fips.key:/etc/fips/fips.key:ro
node-b:
<<: *fips-common
container_name: fips-ifb-node-b${FIPS_CI_NAME_SUFFIX:-}
hostname: host-b
volumes:
- ../docker/resolv.conf:/etc/resolv.conf:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-b/fips.yaml:/etc/fips/fips.yaml:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-b/fips.key:/etc/fips/fips.key:ro
# The clean-start case. Its interface exists before its daemon does, which is
# the ordinary state of a booted router and the one ordering node-a and
# node-b cannot produce: their interface is created after they are already
# running, so they can only ever bind through the binder loop.
#
# The gate is what buys that ordering. The harness needs a running container
# to have a netns to move a veth into, but the daemon must not start until
# after the move — so the container comes up, parks on this file, and the
# harness releases it once the interface is in place.
node-c:
<<: *fips-common
container_name: fips-ifb-node-c${FIPS_CI_NAME_SUFFIX:-}
hostname: host-c
entrypoint: ["/bin/sh", "-c"]
command:
- |
while [ ! -e /tmp/fips-go ]; do sleep 0.2; done
exec /usr/local/bin/entrypoint.sh
volumes:
- ../docker/resolv.conf:/etc/resolv.conf:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-c/fips.yaml:/etc/fips/fips.yaml:ro
- ./generated-configs${FIPS_CI_NAME_SUFFIX:-}/node-c/fips.key:/etc/fips/fips.key:ro