- Add lib/state.py: in-memory state store with subsystem collectors (firewall, dnsmasq, nginx, acme, wireguard) - Refactor all handlers: read from state on GET, call refresh_state() after mutations instead of invoking subprocesses per request - daemon/server.py: add refresh_state(), /status/all, /status/refresh; populate state at startup - webui/api/certs.py: async step-by-step ACME issuance (validate, issue with request_id, poll status) replacing blocking endpoint - webui/server.py: render pages from state instead of direct lib calls - Update templates, JS for async cert issuance with polling UI - Update tests for state-based mocking; add test_state.py - Fix SIM105 lint issue (contextlib.suppress) - Add TODO.md with certificate issuance issue tracking Resolves: WebUI 30s timeout freeze during cert issuance (Problem 1)
2.1 KiB
TODO — Certificate Issuance Issues
Problem 1: Timeout Mismatch Causes WebUI Freeze → FIXED
Date Found: May 30, 2026 Date Fixed: May 30, 2026
Symptom: Clicking "Issue Certificate" in the WebUI freezes for ~30 seconds, then returns a 500 error with "Daemon request timed out". Meanwhile the daemon silently runs acme.sh in the background for up to 120s before timing out itself.
Root Cause:
daemon/client.py— WebUI client usestimeout=30for all daemon requestsdaemon/handlers/acme.py— Daemon allowsacme.shsubprocesstimeout=120- The WebUI gives up at 30s while the daemon is still legitimately processing
Fix Applied: Replaced blocking issue endpoint with async step-by-step issuance:
POST /acme/validate— Pre-flight checks (instant): acme.sh installed, email configured, webroot ready, DNS resolves, challenge configuredPOST /acme/issue— Returns immediately withrequest_id, spawns background taskGET /acme/issue/status— Client polls for step-by-step progress- UI shows pre-check results, then step progress with polling (no timeout issues)
- Blocking DNS check prevents wasted acme.sh calls when domain doesn't resolve
Files Changed: daemon/handlers/acme.py, webui/api/certs.py, webui/templates/certs.html, webui/static/app.js
Problem 2: ZeroSSL Rate Limits Block Certificate Issuance
Date Found: May 30, 2026
Symptom: acme.sh fails to issue a certificate for 218broad.vacuum.network with:
The retryafter=86400 value is too large (> 600), will not retry anymore.
Root Cause: ZeroSSL CA returns a retry-after of 86400 seconds (24 hours), likely from a prior failed challenge. acme.sh has a hard cap of 600s on retry-after values and refuses to proceed when the CA requests a longer wait.
Files: N/A (acme.sh behavior, not a project code issue)
Workarounds:
- Switch CA to Let's Encrypt:
acme.sh --set-default-ca --server letsencrypt - Wait 24 hours and retry
- Investigate and clean up prior failed challenges for the domain on ZeroSSL's side