Commit Graph
50 Commits
Author SHA1 Message Date
kevinveenbirkenbach e1d7e32889 Release version 16.1.0 2026-10-19 16:20:32 +02:00
kevinveenbirkenbach 7075aad420 Merge pull request #1003 from evangelostsak/fix/svc-net-wireguard/split-cli-test
refactor(svc-net-wireguard): split the CLI test into files
2026-10-19 10:10:43 +02:00
kevinveenbirkenbachandClaude Opus 5.5 da690a0706 style(yaml): apply ansible-lint 26.10.1 autofix
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>
2026-10-18 21:32:04 +02:00
evangelostsak c2eb54c39c refactor(wireguard): reduce test.sh to the flow and its expectations 2026-10-18 20:36:26 +02:00
evangelostsak fab8acbe91 test(wireguard): move the assertions into lib/checks.sh 2026-10-18 20:36:25 +02:00
evangelostsak 8da00a7a26 test(wireguard): move the mesh probes into lib/probes.sh 2026-10-18 20:36:25 +02:00
evangelostsak f026439ef1 test(wireguard): move the test hosts' lifecycle into lib/hosts.sh 2026-10-18 20:36:25 +02:00
evangelostsak 70ffeeb09b test(wireguard): read mesh addresses and SSH options for the CLI test 2026-10-18 20:36:25 +02:00
evangelostsak 36d0806afc test(wireguard): write the CLI test's inventory from the layout 2026-10-18 20:36:25 +02:00
evangelostsak a21fa60512 test(wireguard): declare the CLI test's meshes and memberships as data 2026-10-18 20:36:25 +02:00
evangelostsak fc4a2da70e test(wireguard): start and remove the test hosts through compose 2026-10-18 13:56:07 +02:00
evangelostsak 5bcbc14545 test(wireguard): declare the CLI test's three hosts in a compose file 2026-10-18 13:56:07 +02:00
evangelostsak 24a07325f8 test(wireguard): run the mesh playbook from playbooks/ 2026-10-18 01:01:09 +02:00
evangelostsak fb24984ade refactor: drop rationale and narration from roles/svc-net-wireguard/files/test/test.sh 2026-10-16 19:10:00 +02:00
evangelostsak a709d237c5 test(wireguard): probe the meshes with SSH, bulk data and the cryptokey table
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.
2026-10-16 13:55:11 +02:00
evangelostsak a9e7271b9e test(wireguard): three throwaway hosts in two full meshes
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.
2026-10-16 03:40:16 +02:00
evangelostsak e7b328cd1b test(wireguard): keep the CLI test harness at the path test-e2e-cli stages 2026-10-16 03:40:16 +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 9c1cb22be4 test(svc-net-wireguard): hub-spoke server/client/NAT + MTU coverage
Reuse the proven client tunnel mechanics but restructure the e2e into 3
server/client pairs: the 3 debian nodes deploy in [server] flavor
(linuxserver generates each peer config), and each workstation joins via
that config in [client] flavor (wsdebian as [client, nat]). Verify each
client<->server tunnel, the NAT masquerade rule on the behind-NAT node,
and a sane auto-derived wg0 MTU.
2026-07-09 13:47:46 +02:00
evangelostsak dd68a6178c test(svc-net-wireguard): address mesh peers by WGNET IP
Endpoints used the outer node name (wg-e2e-<m>), which the wireguard
container cannot resolve from inside the peer node's inner dockerd, so no
handshakes formed (all 30 pairs down). Resolve each node's WGNET IP and
use it as the peer Endpoint, reached via the published relay port. Also
dump `wg show` per node before the connectivity check for debugging.
2026-07-09 13:47:46 +02:00
evangelostsak 1ede755647 test(svc-net-wireguard): deploy mesh nodes as client flavor
With the default server flavor, env.j2 sets PEERS/SERVERURL so the
linuxserver image runs in server mode and regenerates wg0.conf on
restart, wiping the rendered full-mesh peer set -> no handshakes (all 30
pairs unreachable). Deploy the mesh with WIREGUARD_FLAVOR=[client] so the
container honors the provided wg0.conf.
2026-07-09 13:47:46 +02:00
evangelostsak 0350ecbac6 fix(sys-svc-container): make in-container storage driver overridable
The DinD daemon.json hardcoded fuse-overlayfs, which fails copy-up on
images shipping an /etc/mtab symlink (e.g. linuxserver/wireguard) under
deeply-nested CI: "symlink /proc/mounts .../etc/mtab: file exists".
Expose SYS_SVC_CONTAINER_STORAGE_DRIVER (default fuse-overlayfs,
unchanged) and let the wireguard e2e deploy override it to vfs.
2026-07-09 13:47:46 +02:00
evangelostsak b5a7afcd91 test(svc-net-wireguard): install systemd in node prerequisites
make install only sets up the venv + collections; the systemd dependency
comes from the distro package (built at image-build, not run here), so
/sbin/init never existed and the systemd re-create failed. Install
systemd (+ systemd-sysv / systemd-sysvcompat for /sbin/init) as a
bootstrap prerequisite on every node.
2026-07-09 13:47:46 +02:00
evangelostsak e80d71219e test(svc-net-wireguard): re-create nodes as systemd after install
The pkgmgr bases have no systemd (no /sbin/init), so booting init failed;
systemd only arrives as an infinito package dependency during make
install. Two-phase: boot the bare base, run the per-node make install
(fresh environment), mask container-hostile first-boot units + seed a
machine-id, then commit and re-create the node with --entrypoint=/sbin/init
so systemd is PID 1 and the deploy can start docker.service like a host.
2026-07-09 13:47:46 +02:00
evangelostsak 5f59f6bda0 test(svc-net-wireguard): boot pkgmgr nodes via systemd entrypoint
The pkgmgr base image's ENTRYPOINT runs the pkgmgr CLI, so passing
/sbin/init as a command arg never made systemd PID 1 (systemd never
became ready). Override with --entrypoint=/sbin/init so systemd (already
present in the base) boots as PID 1, and dump container logs on a
readiness timeout.
2026-07-09 13:47:46 +02:00
evangelostsak 97d33ae6e0 test(svc-net-wireguard): per-node install on systemd pkgmgr bases
The role starts docker via systemd (docker.service), which raw debian/
manjaro/centos containers (PID1=sleep) cannot do. Boot the nodes from
Infinito's own fresh pkgmgr base images (systemd + pkgmgr, no infinito
baked) as systemd containers (cgroupns=host, cgroupfs rw, tmpfs /run),
so each node still runs its own make install + inventory + deploy and
the deploy can install/start docker exactly like a real host. Images are
pinned to 1.15.2 (never a moving tag); manjaro workstation -> arch base.
2026-07-09 13:47:46 +02:00
evangelostsak 435d14b952 test(svc-net-wireguard): install gnupg for docker repo setup
sys-svc-container configures the docker-ce apt repo via apt_repository,
which needs a gpg binary to handle the signing key; the minimal images
lack it (Either apt-key or gpg binary is required). Add gnupg/gnupg2 to
the per-distro prerequisites.
2026-07-09 13:47:46 +02:00
evangelostsak 991927a1a4 test(svc-net-wireguard): force DOCKER_IN_CONTAINER via extra-var
The -e container=docker env did not flip DOCKER_IN_CONTAINER: fact
gathering runs under become/sudo, which env_resets and drops `container`
before the setup module reads it. Force DOCKER_IN_CONTAINER=true as an
ansible extra-var (highest precedence) so the deploy takes the
container/DinD path and skips the host-only timezone task.
2026-07-09 13:47:46 +02:00
evangelostsak 3aca193de4 test(svc-net-wireguard): mark nodes as containers for autodetect
Infinito's DOCKER_IN_CONTAINER derives from the `container` env var,
which plain Docker (unlike systemd/podman) does not set, so the nodes
misdetected as bare metal: the constructor ran the host-only timezone
task (needs hwclock) and sys-svc-container would take the non-DinD path.
Boot nodes with -e container=docker so autodetect is correct.
2026-07-09 13:47:46 +02:00
evangelostsak 3139c63876 test(svc-net-wireguard): deploy with local connection
The deploy runs on the target node itself, but ansible defaulted to SSH
and failed UNREACHABLE (Connection refused, no sshd). Force
ansible_connection=local via extra-var so the role applies locally.
2026-07-09 13:47:46 +02:00
evangelostsak 1e95fb8033 test(svc-net-wireguard): pass vault password file to deploy
provision auto-creates a random vault password at <inv>/.password and
encrypts ansible_become_password with it. deploy dedicated does not
default to it, so rendering become_pass failed. Pass --password-file
<inv>/.password (node-local, written by provision) to the deploy.
2026-07-09 13:47:46 +02:00
evangelostsak b93bd594c9 test(svc-net-wireguard): give each node its own repo copy
The shared bind-mount let make install state (.env, venv stamps) leak
across nodes, so only the first nodes ran the real install and the rest
short-circuited with no venv (no infinito venv python). Mount the repo
read-only as -src and tar-copy it (excluding .git) into a node-local
/opt/src/infinito per node, so every node runs a full, independent
install. Aligns with the per-node-inventory design.
2026-07-09 13:47:46 +02:00
evangelostsak 43b533ff3c test(svc-net-wireguard): glob venv python path + diagnose on miss
server1 resolved /opt/venvs/infinito/bin/python but a later node did
not, so the venv lands at a different path/name there. Glob the common
venv parents (/opt/venvs/*, /root/.venvs/*, $HOME/.venvs/*) instead of
two fixed paths, and on a miss dump the existing venv dirs + .env venv
lines so the real location is visible in CI.
2026-07-09 13:47:46 +02:00
evangelostsak bdc8d5b34a test(svc-net-wireguard): resolve venv python by explicit path
load.sh's PYTHON resolver silently falls back to the system python3
(missing install deps -> ModuleNotFoundError: ruamel) when it cannot
confirm the venv, which happened on later nodes once server1 generated
the shared .env. Pin /opt/venvs/infinito/bin/python (or the HOME venv)
explicitly and fail loudly if absent, for both provision and deploy.
2026-07-09 13:47:46 +02:00
evangelostsak d4f351fcd5 test(svc-net-wireguard): invoke CLI via venv python -m cli
The `infinito` console script was not reliably on PATH across distros
(found on debian, missing on centos). Call the venv "$PYTHON" -m cli
from the repo root instead — deterministic, no console-script/PATH
dependency, and the venv python carries the install deps.
2026-07-09 13:47:46 +02:00
evangelostsak a27a06c32f test(svc-net-wireguard): run CLI via venv entrypoint, not bare python3
Bare `python3 -m cli` used the system interpreter, missing make install's
venv deps (ModuleNotFoundError: ruamel). Source scripts/meta/env/load.sh
to put /opt/venvs/infinito/bin on PATH and call the `infinito` console
script for provision + deploy.
2026-07-09 13:47:46 +02:00
evangelostsak 03d4a176c1 test(svc-net-wireguard): --allowerasing for centos prereqs
CentOS Stream 9 ships curl-minimal; installing curl conflicts with it.
dnf --allowerasing lets it swap curl-minimal for curl cleanly.
2026-07-09 13:47:46 +02:00
evangelostsak d801fa05b7 test(svc-net-wireguard): let deploy install docker engine, not bootstrap
make install ships only the docker CLI, not the engine, so the manual
`dockerd` start in 01_bootstrap failed with `dockerd: not found`. The
deploy installs + starts the engine itself via sys-svc-container
(DinD-aware), so bootstrap now just boots nodes + make install.
2026-07-09 13:47:46 +02:00
evangelostsak c1523d9044 test(svc-net-wireguard): surface dockerd startup failure + use vfs storage
make install now succeeds; the inner dockerd would not come up. Start it with --storage-driver=vfs (nested-friendly) and dump /tmp/dockerd.log on failure so the real cause is visible in CI.
2026-07-09 13:47:46 +02:00
evangelostsak ba82180033 test(svc-net-wireguard): install bootstrap prerequisites before make install
Raw debian/manjaro/centos base images have no make/git/python, so 'make install' failed with 'make: not found'. Install per-distro prerequisites first (apt/pacman/dnf).
2026-07-09 13:47:46 +02:00
evangelostsak 5eee13bb5f test(svc-net-wireguard): fail hard, never hang the e2e harness
Wrap make install / inventory provision / deploy dedicated in timeouts with stdin from /dev/null and non-interactive env, and cap the connectivity check at 180s. A stuck step now fails the harness fast instead of hanging the CI job.
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 b97d1a5fc6 fix(svc-net-wireguard): let Docker auto-assign the NAT gateway upstream IP
Pinning the gateway to 10.30.30.1 collided with the docker-reserved subnet gateway address (Address already in use). The source-based masquerade does not need a fixed IP, so let docker assign it.
2026-07-09 13:47:46 +02:00
evangelostsak f830424d19 test(svc-net-wireguard): add client-mode + NAT masquerade e2e stage
nat.sh brings up a WireGuard client (MTU 1400) behind a masquerading gateway and verifies it reaches an upstream host only via the masquerade, plus rule present/absent assertions. Wired into test.sh after mesh.sh.
2026-07-09 13:47:46 +02:00
evangelostsak f99a0f87d9 style(svc-net-wireguard): trim verbose comments from harness and vars 2026-07-09 13:47:45 +02:00
evangelostsak bb04818026 fix(svc-net-wireguard): use /tmp/wg for mesh keys/conf instead of /etc/wireguard
On the linuxserver Alpine image /etc/wireguard is a dangling symlink when the s6 init is bypassed (--entrypoint sleep), so key generation failed. Use a plain /tmp/wg workdir and 'wg-quick up /tmp/wg/wg0.conf' on every node.
2026-07-09 13:47:45 +02:00
evangelostsak b35545fc24 fix(svc-net-wireguard): install ping via apk on the Alpine server mesh nodes
linuxserver/wireguard is Alpine-based; the server-kind install used apt-get and exited 127. Use apk (iputils-ping, falling back to iputils).
2026-07-09 13:47:45 +02:00
evangelostsak a24d3a9b32 fix(svc-net-wireguard): make e2e peer handshake reliable in DinD
The server-generated peer config has AllowedIPs=0.0.0.0/0, which routes the endpoint through the tunnel and deadlocks the handshake, and WireGuard never initiates without traffic. external.sh now narrows AllowedIPs to the server tunnel subnet, adds PersistentKeepalive, and pings the server tunnel IP to trigger the handshake.
2026-07-09 13:47:45 +02:00
evangelostsak c6b20352dc refactor(svc-net-wireguard): move e2e harness to the test-e2e-cli contract
tests/ -> files/test/ (test.sh/local.sh/external.sh/mesh.sh) + templates/test.env.j2 (the test-e2e-cli discovery marker). README and requirement 026 updated to the adopted contract.
2026-07-09 13:47:45 +02:00