Server statistics, multi-view record commands, and rc.3 fixes

Added:
- Server statistics: named's memory and CPU (from /proc), cache size,
  sockets and client counts against their limits (statistics channel,
  rndc status), host memory and load, and free disk space. Memory and
  CPU are kept over time as gauges (sum and sample count, averaged in
  timelines). Statistics page Server section, jarl stats server,
  GET /stats/server.
- jarl record add|set|delete|disable|enable --view a,b | all: the same
  change in each view, applied as one changeset.
- Blocking can be paused until resumed (jarl block pause indefinitely,
  "Until I resume", {"indefinitely": true}).

Changed:
- List options (allow-transfer, forwarders, ...) get their braces added
  when given without them.
- The dashboard lists named-checkconf's warnings about the running
  configuration; the CLI prints them after an apply.
- Stats page: tile and card rows fill their width, and the queries and
  failed answers charts share margins so their time axes line up.
- Dashboard: options have their own tile.
- 24-hour times in the web UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adamandClaude Opus 5.5 committed 2026-10-11 18:03:05 +01:00
1 parent b097e10bef
commit 7be0762f48
48 files changed
+1346 -128

No files matched your search

+30
View File
@@ -139,6 +139,7 @@ expect_dig() { # DESC WANT DIG-ARGS...
if [ "$got" = "$want" ]; then ok "dig $desc = '$want'"; else bad "dig $desc: got '$got' want '$want'"; fi
}
contains() { if echo "$OUT" | grep -q -- "$1"; then ok "output has '$1'"; else bad "output lacks '$1'"; echo "$OUT" | sed 's/^/ /'; fi; }
not_contains() { if echo "$OUT" | grep -q -- "$1"; then bad "output has '$1'"; echo "$OUT" | sed 's/^/ /'; else ok "output lacks '$1'"; fi; }
# With nothing configured, the CLI uses jarld's local socket, where
# jarld's own user (this script's) is an administrator without a token.
@@ -296,10 +297,34 @@ contains "token.revoke"
run "view create (adopts zones)" 0 $J view create internal --match-clients homelab --adopt-zones
run "view create external" 0 $J view create external --match-clients any
run "zone create in external" 0 $J zone create adbraun.test --view external --ns ns1.adbraun.test. --record "ns1 A 203.0.113.1"
# named-checkconf's own warnings stay on the dashboard after the apply.
run "option set recursion no (external)" 0 $J option set recursion no --view external
run "allow-recursion without its braces" 0 $J option set allow-recursion 192.0.2.1 --view external
contains "named-checkconf"
run "status keeps named's warning" 0 $J status
contains "named-checkconf: .*recursion"
run "option list: braces added" 0 $J option list --view external
contains "{ 192.0.2.1; }"
run "unset allow-recursion" 0 $J option unset allow-recursion --view external
run "unset recursion" 0 $J option unset recursion --view external
run "status: the warning is gone" 0 $J status
not_contains "named-checkconf"
run "zone list shows both views" 0 $J zone list
contains "external"
expect_dig "internal view nas" "192.168.1.20" nas.adbraun.test A
run "record add needs a view now" 6 $J record add adbraun.test x A 192.168.1.90
run "record add --view all" 0 $J record add adbraun.test both A 192.0.2.77 --view all
contains "applied"
expect_dig "both views: internal has it" "192.0.2.77" both.adbraun.test A
run "record list external has it too" 0 $J record list adbraun.test --view external
contains "192.0.2.77"
run "several views are all-or-nothing (exit 4)" 4 $J record add adbraun.test half A 192.0.2.78 --view internal,nosuch
contains "nothing was changed in any view"
expect_dig "so internal didn't get it" "" half.adbraun.test A
run "record delete --view internal,external" 0 $J record delete adbraun.test both A --view internal,external -y
expect_dig "deleted in both" "" both.adbraun.test A
run "and gone from external" 0 $J record list adbraun.test --view external
not_contains "192.0.2.77"
run "acme set goes into both views" 0 $J acme set adbraun.test both-views
expect_dig "acme TXT (internal, from 127.0.0.1)" '"both-views"' _acme-challenge.adbraun.test TXT
run "acme set --view external only" 0 $J acme unset adbraun.test --view internal
@@ -466,6 +491,11 @@ expect_rpz "paused: so is a blocked rule's name" blocked.adbraun.test none
run "block list says it's paused" 0 $J block list
contains "Blocking is paused until"
run "block resume" 0 $J block resume
run "block pause indefinitely" 0 $J block pause indefinitely
expect_rpz "paused until resumed: a listed name is answered" x.tracker.adbraun.test none
run "block list says until resumed" 0 $J block list
contains "paused until you resume it"
run "block resume after an indefinite pause" 0 $J block resume
expect_rpz "resumed: the list blocks again" x.tracker.adbraun.test test.blocklist.jarl.invalid.
expect_rpz "resumed: the rule blocks again" blocked.adbraun.test rules.jarl.invalid.
# The test server dates the file to the second, and the download above