Collector was spawned with stdout=PIPE but nobody read from the pipe.
After days of accumulated log output the OS buffer filled, blocking
the collector and freezing all metrics updates.
Configure python-semantic-release for automated changelog and
versioning: rc releases on dev branch, stable releases on main.
Remove the custom bash version-bump and changelog scripts from
both CI pipelines.
rebuild_all_rules now discovers existing user_ chains and removes any
that are no longer in the DB. Reconcile always runs the firewall
rebuild even with 0 devices, so stale forward rules and orphan chains
are cleaned up when all devices are deleted.
Revert to the exact per-test create/drop conftest that worked at
25cff5e4. The session-scoped and module-level patching approaches
both broke e2e tests in CI.
Remove module-level engine/session replacement that affected all tests
including e2e. The test engine is now only used via the session fixture,
so e2e tests keep using the real DB the app writes to.
Chromium cannot resolve Docker service hostnames (mock-saml) in CI.
Skip the two tests that require browser navigation to the IdP; the
other SAML tests (button visibility, SP metadata) still run.
SAML e2e tests were timing out in CI waiting for the IdP redirect.
Increase Playwright wait_for_url timeout from 10s to 30s and add a
health check on the mock-saml service container so it's ready before
tests start.
Remove 7 test files fully covered by e2e tests (admin, account, models,
API routes, integration MFA/OIDC, notifications). Trim 5 more files to
keep only edge cases not reachable via e2e.
Fix conftest to replace wiregui.db engine/session at import time so all
code uses the test database. Use session-scoped tables with per-test
savepoint isolation to prevent data leaking between tests.
- Add ECharts live traffic rate chart on device detail page (RX/s + TX/s
area lines, 60-point rolling window, human-readable byte axis)
- Add traffic rate display (B/s) next to RX/TX totals
- Add connection status column (green/yellow/red dot) to user and admin
device tables based on handshake age
- Add status badge to device detail page
- Reduce all UI refresh timers from 30s to 5s
- Add row click navigation on admin devices table
- Allow admins to view any device detail (not just their own)
- Fix rowClick event args (list not dict) on both device tables
- Add connection_status() helper in utils/time.py
Metrics collector (wiregui/collector.py):
- Standalone process spawned by web app when WG_METRICS_ENABLED=true
- Polls wg show dump every WG_METRICS_POLL_INTERVAL seconds (default 5)
- Updates device stats in PostgreSQL
- Pushes Prometheus-format metrics to VictoriaMetrics (if configured)
- Graceful shutdown on SIGTERM
Integration test stack (compose.yml):
- Unified compose file for dev, test, and integration modes
- VictoriaMetrics single-node TSDB for metrics storage
- 3 mock WireGuard client containers generating ping traffic
- Automated setup script seeds server keypair, admin user, client devices
- make test-stack-up: one command to start everything
- make test-stack-verify: validates metrics flowing end-to-end
Infrastructure:
- Makefile with targets for dev, test, integration, and production
- Integration tests verify VictoriaMetrics has data for all 3 clients
- Fix Dockerfile to include img/ directory
- Separate TESTS.md for test tracking, clean TODO.md for features only
- Put logo and title on same row in login page
- Use ui.code with syntax highlighting for nftables ruleset dialog
- Widen nftables dialog to 900px
- Limit WAN connectivity checks to last 10 entries
- Add transparent SVG logo to img/
- Serve img/ as static files, set SVG favicon
- Show logo on login page and header bar
- Theme Quasar CSS variables using logo palette:
light: primary #3598C3, secondary #5AA6B9, header navy gradient
dark: primary #5AA6B9, secondary #3598C3, darker header gradient
- Add valkey and mock-oidc services to both release and dev workflows
- Install Playwright with Chromium deps for headless e2e tests
- Set WG_REDIS_URL and MOCK_OIDC_HOST env vars for CI
- Make mock OIDC discovery URL configurable via MOCK_OIDC_HOST env var
- Add full test job (unit + e2e) to dev pipeline before Docker build
- Fix OIDC callback to extract email from ID token claims as fallback
- Add /auth/complete bridge page to transfer auth to NiceGUI storage
- Use window.location.href for OIDC login (full navigation for OAuth)
- Hide password change card for OIDC-only users
- Widen config dialog, use ui.code with syntax highlighting
- Switch QR codes to PNG base64 images
- Rename logging.py to log_config.py to avoid stdlib shadow
- Add mock-oauth2-server to compose.yml for dev/testing
Add WG_IDP_CONFIG_FILE env var to seed OIDC/SAML identity providers
from a YAML file at startup, enabling GitOps and IaC workflows.
Providers are upserted by id (merge strategy preserves manual additions).
Convert all e2e tests from NiceGUI User fixture to Playwright async API
with --headed and --slowmo flags for visual debugging. Add full OIDC
login flow test against the mock-oidc service.
Override fields now display the actual configured defaults (from
DB Settings or env vars) instead of empty placeholders. Fields
are still disabled when the "use default" toggle is on, but users
can see what values their device will get.
build_client_config was reading defaults (allowed IPs, DNS, endpoint,
MTU, keepalive) from env vars only, ignoring the values set in the
admin Settings page. Now reads from the Configuration DB table first,
falling back to env vars when no DB config exists.
- Add peer-to-peer and LAN-to-peers switches on the rules page
- Both settings persisted in configurations table and applied
as nftables chains on toggle
- Add "View nftables Rules" button to dump the live ruleset
for troubleshooting
- Rules page redesigned with card-based layout matching other
admin pages
- Rule create/edit/delete events fire as background tasks
allocate_ipv4/ipv6 was calling list(network.hosts()) which
materializes 4+ million IP objects for a /10 network, blocking
the event loop for 6+ seconds. Now uses random sampling with
O(1) per attempt — allocates in <1ms on any network size.
This was the root cause of WebSocket disconnects during device
creation in production.
Builds and pushes docker images on every push to dev branch.
Tags based on latest main release: e.g. v1.2.3.dev0, v1.2.3.dev5.
No tests — fast feedback loop for testing.
In production (WG_WG_ENABLED=true), on_device_created() runs multiple
WG and nftables subprocess calls that take seconds. The UI handler
was awaiting all of them before showing the config dialog, causing
WebSocket timeouts and page reloads.
Now the dialog/QR/download appears right after DB commit, and WG peer
+ firewall configuration runs as a background task via asyncio.create_task.
Replace subprocess calls to wg genkey/pubkey with cryptography
library's X25519PrivateKey. This eliminates the wg CLI dependency
for key generation, fixes device creation on machines without
wireguard-tools, and removes the event loop blocking that caused
WebSocket disconnects during device creation.
Also fix E2E test teardown to use a fresh engine for cleanup,
avoiding cross-event-loop issues with asyncpg connection pools.