fix: the web service works in every state of the router.
Release / release (push) Successful in 11s

This commit is contained in:
slawek committed 2026-10-23 22:35:53 +02:00
1 parent cc6748a622
commit a4cffb67e4
10 files changed
+370 -139

No files matched your search

+28 -2
View File
@@ -29,7 +29,7 @@ restores the rules. The rules cover IPv4 only.
## ADR-2: A status web service of the standard library, bound to the internal address
Status: Accepted
Status: Accepted; amended by ADR-7
Context: The router has no way to see its state without a shell. A check from the protected
network, by a person or by a monitor, needs a page or an endpoint. The router is an
@@ -55,7 +55,7 @@ address is picked up at the next run of `vpn-router-setup`.
## ADR-3: /config is authenticated with a short-lived JWT signed with a shared secret
Status: Accepted
Status: Accepted; amended by ADR-7
Context: A client such as manage-ui needs the configuration and the resolved state of the
router, which `/` and `/status` must not show. The service has only the standard library, listens
@@ -148,3 +148,29 @@ Consequences: The web service still imports nothing outside the standard library
program serves the command line and the API. Each request starts a process, which is fine for
user administration. The API is protected by the token of `/config`, so whoever has the secret
can manage users.
## ADR-7: The web service starts on its own and reads its inputs at each request
Status: Accepted
Context: The web service took the address to listen on, the port, the token secret and the
features from `/run/vpn-router/web.json`, written by `vpn-router-setup`, and ended with a failure
while the file or the internal address was missing. It was ordered after `vpn-router-setup`, so a
problem in the setup kept the status page, the tool to see that problem, from running.
Decision: The service depends on nothing to start and does not end on its own. A discovery
thread works out, every 30 seconds, the internal address from `vpn-router.json` as
`general.mode` directs, with the discovery code in `vpnrouter_net.py`, which uses only the
standard library and which `vpnrouter.py` uses too, and `web.port` and `web.enabled` from the
same file. It runs the HTTP server in a thread of its own at that address and port, stops it and
starts a new one when they change, and runs none while the service is disabled, the address is
not known or it cannot be bound. Each request reads the token secret from `vpn-router.json` and
the features and resolved facts from `web.json`, which setup still writes, because they need the
configuration code; while that file is missing the router shows no features. The unit is not
ordered after `vpn-router-setup`, and setup does not restart it.
Consequences: The status page answers as soon as the internal address exists, whatever state
setup is in, and follows a changed address, port or `web.enabled` within 30 seconds without a
restart. `web.json` no longer holds the address, the port or the secret, so the secret is only in
`vpn-router.json`. A change of the secret applies to the next request. The interfaces are read
every 30 seconds, which costs a few `ip` commands.