v0.2.1
Patch release: closes a single bug class the v0.2.0 verification on
rv.vpn surfaced — DEFAULT_SUBNET (and DEFAULT_WG_PORT) set in
.env.prod were silently ignored by the production stack. The v0.2.0
prod overlay never propagated those ${VAR}s into the containers
that needed them; operators set the override, watched nothing
change, and saw the default tenant come up with the code-default
10.9.0.0/24 regardless.
Fixed
-
DEFAULT_SUBNET+DEFAULT_WG_PORTnow flow from.env.prod
through the prod overlay (PR #50 + PR #51). The two PRs together
cover the full data path: request-time + migration-time.- PR #50 — pass the two env vars through to
api+worker.
Without this,Settings.default_subneton the running api falls
back to the code default (config.py:60=10.9.0.0/24) on
everyPOST /serverspayload that omits thesubnetfield. The
dashboard's "New server" form pre-fills from this value too, so
an operator who set the override in.env.prodwould see the
pre-fill ignore them. - PR #51 — same passthrough for
bootstrap-app. Alembic
migration0016_add_tenant_subnet_pool.py:68reads
live_settings.default_subnetAT MIGRATION TIME to backfill the
default tenant'ssubnet_pool. The migration runs inside
bootstrap-app(the container that doesalembic upgrade head),
NOT inside api/worker. So even after PR #50 fixed the request-
time path, the default tenant'ssubnet_poolstill came up at
10.9.0.0/24on every fresh-volume boot becausebootstrap-app
was missing the env. PR #51 closes the loop.
Verified end-to-end on rv.vpn after both PRs landed: with
DEFAULT_SUBNET=10.8.0.0/24in.env.prod,make prod-down -v+
make prod-upbrings the default tenant up with
subnet_pool='10.8.0.0/24'(confirmed via both
SELECT * FROM tenantdirectly against MySQL and
GET /v1/tenantsthrough the mTLS API).Operator remediation on a stack already bootstrapped with the
buggy v0.2.0 default:- A.
make prod-down -v+make prod-upon v0.2.1 — re-runs
migration 0016 against the env-correctedbootstrap-app. Wipes
state. - B. Manual SQL —
UPDATE tenant SET subnet_pool='<your-cidr>' WHERE id=1. Preserves state.
.env.prod.examplegrew a documentedDEFAULT_SUBNET+
DEFAULT_WG_PORTblock explaining when an operator overrides
(overlapping VPN address space with another stack, conflicting
host routes). Tests grew two parametrised cases pinning the
passthrough on api + bootstrap-app so the bug class can't
re-emerge silently. - PR #50 — pass the two env vars through to
Published images
ghcr.io/jfudally/wg_manager:v0.2.1— API + workerghcr.io/jfudally/wg_manager-web:v0.2.1— dashboard
Pull either with a granularity-appropriate tag (vX.Y.Z, vX.Y, vX, or latest).
Supply-chain attestation
Both images are signed via cosign keyless OIDC and carry an
in-toto CycloneDX SBOM attestation. Verify with:
cosign verify \
--certificate-identity-regexp \
'https://github.com/jfudally/wg_manager/.github/workflows/release.yml@.*' \
--certificate-oidc-issuer \
'https://token.actions.githubusercontent.com' \
ghcr.io/jfudally/wg_manager:v0.2.1The SBOMs are also attached as release assets:
sbom-api.cdx.json— CycloneDX SBOM of the API + worker image's Python depssbom-web.cdx.json— CycloneDX SBOM of the dashboard image's Node deps