Commit Graph
29 Commits
Author SHA1 Message Date
evangelostsak 96fa1f43aa refactor(wireguard): leave group membership to the callers 2026-10-18 13:56:06 +02:00
evangelostsak aea4373486 refactor(wireguard): create the administrator the mesh transport logs in as 2026-10-18 01:01:08 +02:00
evangelostsak 77e6588b36 refactor(wireguard): gate the core and the skip on the named compose case 2026-10-18 01:01:08 +02:00
evangelostsak 7ea924a346 feat(wireguard): skip a compose host the mesh CLI gave no mesh, visibly
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.
2026-10-16 21:26:17 +02:00
evangelostsak 3af32502af refactor: drop rationale and narration from roles/svc-net-wireguard/tasks/00_core.yml 2026-10-16 19:10:01 +02:00
evangelostsak a719eb86d9 fix(wireguard): the missing-mesh failure no longer assumes a swarm deploy 2026-10-16 03:40:16 +02:00
evangelostsak d4056891c0 fix(wireguard): name the gate after the peers it waits for, not the hub 2026-10-16 03:40:15 +02:00
evangelostsak b25dc7f667 docs(svc-net-wireguard): drop the syncconf rationale
Why the interface is reconfigured in place rather than restarted is
recorded in requirement 037; the task file only has to do it.
2026-10-05 12:43:23 +02:00
evangelostsak fa04452395 fix(svc-net-wireguard): stop the deploy when a spoke never handshakes
Tightening the retry condition was not enough. `failed_when: false` is
evaluated after the retry loop, so a task that runs out of attempts reports
`failed_when_result: false` and ends ok: the role carried on past a spoke
that never handshaked, and past a `wg show` that failed outright, whenever
the MTU probe was skipped.

The explicit failure is back, with the condition the wait now uses, so the
verdict is taken from the registered results rather than from the retry
outcome.

Measured on a three-case play, exit status of the run: a reported handshake
continues (0), '\t0' stops it (2), and a probe exiting non-zero with no
output stops it (2).
2026-10-02 01:13:23 +02:00
evangelostsak f61567fd4c fix(svc-net-wireguard): close the handshake gate on a failed probe
`wg show latest-handshakes` ran with `failed_when: false`, so a failed probe
left stdout empty. An empty string carries no '\t0' to match, the `until`
condition was satisfied on the first attempt, and the gate passed on a host
that never reported a handshake at all. The task meant to catch that could
not: Jinja's `default` replaces an undefined value, not an empty one, and
exhausted retries fail the task before a later task runs, so it was
unreachable in every case that mattered.

The wait now requires a zero exit code and a non-empty result as well as a
handshake, and the exhausted retry is the hard failure.

Verified with a local play over three cases: a reported handshake passes,
'\t0' fails, and a probe exiting non-zero with no output fails -- the last
of which passed under the previous condition.
2026-10-02 00:54:19 +02:00
evangelostsak 3bd54c1ae9 refactor(wireguard): drop the gate's explanation comments 2026-09-29 00:50:45 +02:00
evangelostsak 140c04d47f refactor(svc-net-wireguard): probe against the measured overlay MTU 2026-09-25 22:35:29 +02:00
evangelostsak 041805f1ea fix(svc-net-wireguard): reconfigure a live interface instead of restarting it
wg-quick down on the interface Ansible is connected over kills the session
carrying the play, and the up that would restore it never runs. syncconf
applies new keys and peers to the live interface, so a rotated mesh converges
without dropping the connection that is rotating it.

Latent until now only because the deploy still runs over the underlay.
2026-09-25 22:35:07 +02:00
evangelostsak 10e99b0f39 feat(svc-net-wireguard): provision the tooling and measure the MTU
The install no longer skips when wg-quick happens to exist: the node image
stopped pre-baking it, so the role is what puts it there.

The tunnel and overlay MTUs are now measured with automtu against the hub's
underlay endpoint rather than hardcoded. Fixed values contradict the MTU
automtu already derives for the docker daemon, and the mesh addresses cannot
be probed because the interface those MTUs configure is not up yet.
2026-09-25 22:35:01 +02:00
evangelostsak 6e1c72bb42 fix(wireguard): act only on the meshes this host belongs to
Declaring meta/meshes.yml made the validator accept the generated block, and
handed every host both meshes whether or not it is a member. The role then
rendered an interface for a mesh with no address and died in the template:
'object of type list has no attribute 1', from splitting an empty subnet.

The failure pattern named the cause exactly -- the NFS server failed on the
swarm mesh, the workers on the data mesh, and the manager, which belongs to
both, passed.

An entry the writer filled in carries an address; a declared-but-unassigned one
does not. That is what now separates a real membership from the shape the
contract declares.
2026-09-19 08:21:29 +02:00
evangelostsak c30ef534b1 fix(wireguard): prove the tunnel with the handshake, not with ping
The gate pinged its hub, and the NFS node ships no ping. The tunnel there was
healthy the whole time -- handshake 46 seconds old, 7.37 KiB in and 27.10 KiB
out -- and the deploy still failed, so the gate was reporting on its own
tooling rather than on the mesh.

wg reports the handshake directly: it needs nothing the host might not carry,
and it stays true where ICMP is filtered, which a tunnel gate must survive.
A peer that never completed one reports a literal 0.

The MTU probe still needs ping, because only a sized DF packet can show the
VXLAN-inside-WireGuard trap, so it is skipped rather than failed when ping is
absent. The handshake above already proves the tunnel; this proves the frame
size, and losing the second check is not worth failing a working deploy.
2026-09-18 23:22:49 +02:00
evangelostsak 7e45a85cbb fix(wireguard): gate on the direction the host can actually initiate
The gate had every host ping every peer it was configured for, which a hub can
never satisfy. Only the spoke carries an Endpoint; the hub learns a spoke's
address when that spoke dials in, so a hub probing its spokes is racing them.
The backup host settles it: deployed in a later play, its interface cannot
exist while the cluster play runs, so the manager's data mesh was unprovable by
construction.

Observed in a drill where both meshes were demonstrably healthy -- the workers
had handshakes and traffic on the swarm mesh, the NFS server on the data mesh
-- and the gate still failed on the manager and the NFS server.

A spoke now probes the hub and nothing else. That is the failure worth
catching: a spoke that cannot reach the hub has no mesh, while the hub's own
view converges as spokes arrive. The retry window widens because hosts
configure in parallel and a spoke can probe before the hub's interface
exists.
2026-09-18 19:01:12 +02:00
evangelostsak 85d05e2407 fix(wireguard): probe the tooling by path, not by a shell builtin
The guard used ansible.builtin.command with 'command -v wg-quick'. The command
module execs without a shell and 'command' is a shell builtin, so there is no
binary to exec, the probe reported a non-zero return code on every host, and
the install ran everywhere the guard existed to prevent it.

Verifying the probe through swarm-exec hid the bug, because that path does go
through a shell. stat has no such gap: it needs no shell and answers the
question directly.
2026-09-18 17:38:40 +02:00
evangelostsak 424017291c fix(wireguard): skip the package install when the tooling is present
The swarm node images already ship wireguard-tools, and they also carry a
half-installed linux-image-rt-amd64. apt therefore refuses the install with
'unmet dependencies' even though it reports wireguard-tools is already the
newest version, so the role failed on all three nodes with nothing actually
missing.

Checking for wg-quick first keeps the role from doing work that is already
done, and stops an unrelated broken package state on the image from failing a
deploy the layer would otherwise complete.
2026-09-18 17:06:37 +02:00
evangelostsak cebb1935b9 feat(wireguard): fail the deploy at the gate rather than later
The layer is binary: either every swarm deploy proceeds over the mesh or none
does. The gate runs before swarm initialises and names the unreachable peer, so
a partition is reported where it happened instead of surfacing as an unrelated
role failing to reach a service.

Three separate checks, because they fail differently. An interface with no peer
means the inventory is incomplete. An unreachable peer means the mesh is
partitioned. A full-size payload that does not arrive means the MTU is wrong
for VXLAN inside WireGuard, which otherwise drops only large packets and reads
as flaky CI.
2026-09-18 10:35:35 +02:00
evangelostsak c6f2b9fc27 feat(wireguard): restart each interface rather than only starting it
wg-quick up on an already-up interface is a no-op, which would leave the old
keys live in the kernel after a rotation rewrote the config. Taking the
interface down first is what makes a rotated deploy actually take effect; the
down half is tolerated because it exits non-zero when nothing was up.
2026-09-18 10:35:25 +02:00
evangelostsak f595853d66 feat(wireguard): install, render and bring up the host's interfaces
Fails immediately when a swarm host carries no mesh, rather than installing
tooling and producing nothing: an absent mesh means the cross-host writer never
ran, and every later symptom would point somewhere else.

Forwarding is enabled only on the hub, the one member with peers in both
planes, and therefore the only host that has to route between them.

The template call keeps ansible.builtin.template deliberately: this is per-host
system config, and gating it on the stack host would leave every spoke without
an interface.
2026-09-18 10:35:00 +02:00
evangelostsak 533b18b02d feat(wireguard): load the role core behind the run-once and swarm guards 2026-09-18 10:34:49 +02:00
evangelostsak c40d7aa6da chore(wireguard): remove the role and its references to start fresh
The consolidated svc-net-wireguard role, its requirement document and the three
references that only existed to support it go away together: the lint ignore for
a load failure inside its tasks, the requirements index entry, and the tunnel
subnet variable nothing else consumed.

Left in place deliberately: the WireGuard mention in the svc-net category
description, which is upstream prose about networking roles in general rather
than anything this role owned.
2026-09-18 00:30:39 +02:00
evangelostsak 6524afc62a chore(svc-net-wireguard): trim comments, drop dead harness vars
Tighten verbose comments to one line each (no-long-comments) and remove
leftovers from the old mesh design: unused NODE_OCTET / WG_PORT and the
dead WIREGUARD_IMAGE/VERSION env asserts.
2026-07-09 13:47:46 +02:00
evangelostsak 4d2694afa2 feat(svc-net-wireguard): auto-derive client MTU via automtu
Replace the hardcoded 1400 client MTU with a pkgmgr automtu probe (path
MTU minus WireGuard overhead), falling back to the configured value when
probing is unavailable. Runs before the compose env is rendered so WG_MTU
reflects the derived value (decision 11).
2026-07-09 13:47:46 +02:00
evangelostsak 2f4ea68d14 test(svc-net-wireguard): rewrite e2e as deploy-driven full mesh
Replaces the linuxserver-image harness with a deploy-driven one: 01_bootstrap (6 empty containers + make install + DinD), 02_registration (per-host dedicated inventory via 'inventory provision' + full-mesh wg0.conf), 03_handshake ('deploy dedicated --id svc-net-wireguard' per host + all-pairs check). Adds the role's inventory-driven config path (mounts a per-host wg0.conf). NAT-flavor coverage follows once the mesh is green.
2026-07-09 13:47:46 +02:00
evangelostsak e242a28876 feat(svc-net-wireguard): flavor model, central subnet, NAT-on-host, beta lifecycle
Replaces mode+nat with a flavor list [server|client|nat]; declares the WireGuard internal subnet in group_vars/all/08_networks.yml; makes the masquerade task idempotent and applied on the deployed host (drops the DOCKER_IN_CONTAINER gate); bumps svc-net-wireguard and test-e2e-cli to lifecycle beta. (Revision 2 of req 026, PR #323 review.)
2026-07-09 13:47:46 +02:00
evangelostsak 5679326bb4 feat(svc-net-wireguard): add mode dispatch tasks and compose templates 2026-07-09 13:47:45 +02:00