The README merged with #323 lists svc-swarm-node as a 1:1 dependent, but
no role on main references svc-net-wireguard. make docs regenerates the
Cosmos block from the actual dependency graph and drops the edge.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A freshly built dev container installs ansible-lint unpinned (26.10.1,
yamllint 1.38.0), and its --fix pass in make autoformat now drops the
trailing blank line of meta/packages.yml and
roles/sys-svc-container/meta/packages.yml and adds the missing document
start to roles/svc-net-wireguard/files/test/compose.yml (from #323).
Parsed YAML is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A row that deploys only svc-net-wireguard installs no engine, and the test
builds its three hosts as inner containers. Verified on a freshly created dev
container with no engine: the role skipped the mesh-less host, the
prerequisite installed the engine, and all 20 checks passed.
Swarm still fails hard on a host without a mesh. A compose host in the group
without one, such as the role's own CI row, prints why and changes nothing.
A ping proved the tunnels answer, not that a session lands on the right host
or that full-size TCP segments cross them. Each pair sharing a mesh now also
opens an SSH session to the peer's mesh address and must land on that peer,
then pulls 8 MiB through it and compares the checksum with the one taken at
the source. Each pair that shares no mesh must fail the SSH connection itself,
never on authentication, since every host trusts every other host's key.
WireGuard must refuse a packet forced into a mesh that holds no peer for it
(Required key not available), so the isolation is shown to come from the
cryptokey table rather than from a missing route. The two hosts must still
reach each other on the underlay, so the isolation is the mesh's doing.
The SSH options are the platform's own, mesh_ssh_args over the repository's
ssh_args, the ones the swarm transport switches Ansible onto; the addresses
come from mesh_address. Every probe runs through one check helper, so a probe
is a predicate rather than another copy of the pass and fail bookkeeping.
Verified in the dev stack: all 20 checks passed, and a mutant that inverted
every expectation (unreachable pairs, a wrong identity, a different file, a
denied key, the peer's own address forced through the cryptokey check) failed
all 9 of its checks.
It builds three hosts from the repository the deploy runs from, which only
the controller holds. A swarm node, and the lab's backup host deployed in
its own compose play, no longer run it.
The image is the same pinned debian:13.7-slim svc-net-tor and svc-db-openldap
build from. The interpreter is the controller's, which carries the mesh CLI's
dependencies; the managed /usr/local/bin/python3 does not.
Starts three bare Debian hosts from one inventory, puts host II into both
meshes through a role's networks.meshes, writes the mesh with the CLI, deploys
playbook-mesh.yml onto them, which installs WireGuard there, and asserts that
I and II reach each other, that II and III reach each other, and that I and
III do not.
Verified in a local compose deploy of svc-db-redis with svc-net-wireguard:
all six reachability assertions passed and every throwaway host ended with
failed=0.
The handshake gate already waits on every peer a non-hub interface holds.
The MTU probe and the path MTU targets now follow the dialled peers too, which
for a spoke is still its hub and in a full mesh is every peer.
networks.meshes is where a deployment declares its meshes and
networks.interfaces where the mesh CLI records each host's own. Both ship
empty: the platform declares no mesh.
The overview and features named the swarm and data meshes as if the role
shipped them, and the administration command lacked the required
--group-vars-file.