Files
vacuum-wall/TODO.md
T
mteehan dc96e15643 feat: pre-computed state store and async ACME issuance (fixes timeout mismatch)
- 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)
2026-05-30 05:46:09 +00:00

48 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 uses `timeout=30` for all daemon requests
- `daemon/handlers/acme.py` — Daemon allows `acme.sh` subprocess `timeout=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 configured
- `POST /acme/issue` — Returns immediately with `request_id`, spawns background task
- `GET /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
## Status
- **Problem 1:** ✅ FIXED (2026-05-30) — Refactored to async step-by-step issuance with polling. State store collectors replace blocking subprocess calls on every request.
- **Problem 2:** ️ N/A — ZeroSSL rate limit is external to the project. Workarounds: switch CA to Let's Encrypt, wait 24h, or clean up failed challenges on ZeroSSL's side.