router.* schema (wan, lans, dns.forwarders) compiled to systemd-networkd, a generated nftables ruleset with NAT, Kea DHCPv4 and Unbound, plus build-time assertions against lock-out and interface conflicts. tests/basic.nix is a three-node VM test (upstream/router/client) covering WAN DHCP, LAN DHCP and DNS, NAT, WAN-deny and LAN SSH/ping. `nix run .#lab` boots the same topology in tmux with one console pane per VM and the driver REPL. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
45 lines
2.0 KiB
Nix
45 lines
2.0 KiB
Nix
# Shell script for `nix run .#lab` (see flake.nix).
|
|
{ lib, driver, nodes }:
|
|
''
|
|
sock=nixos-router-lab
|
|
log=$(mktemp -t nixos-router-lab.XXXXXX)
|
|
trap 'tmux -L $sock kill-server 2>/dev/null || true; rm -f "$log"' EXIT
|
|
tmux -L $sock kill-server 2>/dev/null || true
|
|
|
|
# Bottom pane: the test-driver REPL. `script` keeps it on a tty while
|
|
# logging everything it prints, which the per-VM panes below filter.
|
|
# When the REPL exits, take the whole session down.
|
|
repl=$(tmux -L $sock new-session -d -x 220 -y 60 -s lab -P -F '#{pane_id}' \
|
|
"script -qfc '${driver}/bin/nixos-test-driver --interactive' '$log'; tmux -L $sock kill-server")
|
|
tmux -L $sock set -g pane-border-status top
|
|
tmux -L $sock select-pane -t "$repl" -T repl
|
|
|
|
# Top row: one pane per VM, console lines only (prefixed "<name> #").
|
|
prev="$repl"
|
|
first=1
|
|
remaining=${toString (builtins.length nodes - 1)}
|
|
for node in ${lib.escapeShellArgs nodes}; do
|
|
cmd="tail -F '$log' 2>/dev/null | grep -a --line-buffered -E \"(^|\\[[0-9;]*m)$node #\""
|
|
if [ "$first" = 1 ]; then
|
|
prev=$(tmux -L $sock split-window -vb -l 65% -t "$prev" -P -F '#{pane_id}' "$cmd")
|
|
first=0
|
|
else
|
|
# Give the new pane its share of the pane being split, so the row ends up even.
|
|
prev=$(tmux -L $sock split-window -h -l "$((100 * remaining / (remaining + 1)))%" -t "$prev" -P -F '#{pane_id}' "$cmd")
|
|
remaining=$((remaining - 1))
|
|
fi
|
|
tmux -L $sock select-pane -t "$prev" -T "$node"
|
|
done
|
|
|
|
# Boot the VMs once the REPL is ready, and leave a reminder at the prompt.
|
|
for _ in $(seq 60); do
|
|
tmux -L $sock capture-pane -p -t "$repl" | grep -q CPython && break
|
|
sleep 0.5
|
|
done
|
|
tmux -L $sock send-keys -t "$repl" 'start_all()' Enter
|
|
tmux -L $sock send-keys -t "$repl" -l 'print("router.shell_interact() | client.succeed(\"ip a\") | test_script() | Ctrl-D quits, Ctrl-b d detaches")'
|
|
tmux -L $sock send-keys -t "$repl" Enter
|
|
tmux -L $sock select-pane -t "$repl"
|
|
tmux -L $sock attach -t lab
|
|
''
|