Add a dashboard and backup download to the web UI

Metric history (5s to 1h tiers, persisted), uplink status, ping targets,
DHCP leases, and a tar.gz backup of the state directory.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
2026-10-29 13:34:21 +01:00
co-authored by Claude Sonnet 5.5
parent e684ddb06c
commit 2a111d012b
13 changed files with 1835 additions and 37 deletions
+20
View File
@@ -196,5 +196,25 @@ pkgs.testers.runNixOSTest {
target.wait_until_succeeds("test $(systemctl show -p ActiveState --value router-confirm.service) = inactive")
assert target.succeed("readlink -f /nix/var/nix/profiles/system").strip() == current()
assert "match the confirmed system" in curl(f"{ui}/")
with subtest("the dashboard shows the uplink, the LAN and pings from the router"):
curl(f"-d csrf={csrf('/advanced')} --data-urlencode 'pingTargets=gateway, 192.168.10.50' {ui}/prefs")
# The UI pings from its sandbox (raw socket); the client answers.
# (Into a file: grep -q would end curl with SIGPIPE, failing the pipe.)
client.wait_until_succeeds(
f"curl -sk -b /tmp/jar -o /tmp/dash '{ui}/dashboard?range=1h' && grep -q 'Ping 192.168.10.50</dt><dd>[0-9.]* ms' /tmp/dash",
timeout=60)
page = curl(f"{ui}/")
# No DHCP server on the uplink in this test.
for text in ["Not connected", "LAN main (eth2)", "Internet (eth1)", "Latency", "CPU and memory", "/static/dashboard.js"]:
assert text in page, f"{text!r} missing:\n{page}"
assert "<html" not in curl(f"'{ui}/dashboard?range=7d'")
client.succeed("curl -sfk -o /dev/null https://192.168.10.1/static/dashboard.js")
with subtest("the web UI hands out a backup of the router's state"):
curl(f"-sf -d csrf={csrf('/advanced')} -o /tmp/backup.tar.gz {ui}/backup")
files = client.succeed("tar -tzf /tmp/backup.tar.gz")
for f in ["router/config/settings.json", "router/webui-password", "router/webui/cert.pem", "router/webui/dashboard.json"]:
assert f in files.split(), files
'';
}