From 656ebc9735825782b01cfdd90fb7306a731eb165 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 11 Jul 2026 09:41:34 +0100 Subject: [PATCH] feat(menu): Tailscale exit-node rows show country/city MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Exit node picker listed bare hostnames; Mullvad-style nodes are meaningless without their location. Rows are now "hostname — Country City", sliced from `tailscale exit-node list` by the header's fixed-width column offsets (COUNTRY/CITY can be multi-word, so field splitting is wrong by construction); nodes without a location stay a bare hostname, and the pick strips back to the hostname at the first space before `tailscale set --exit-node`. Closes BACKLOG LATER "VPN exit-node richer display"; the VPN HARDWARE-QUEUE entry now covers the location rows. Verification: V1 — the awk was proven against a fabricated fixture (one-word city, multi-word "United States / New York, NY", bare self-hosted node), flake check exit 0, downstream-template-home builds (writeShellScriptBin syntax-gates the script). Real `tailscale exit-node list` output stays V3 (existing VPN menu live-paths entry). Co-Authored-By: Claude Fable 5 --- agent/BACKLOG.md | 1 - agent/HARDWARE-QUEUE.md | 4 ++++ agent/JOURNAL.md | 15 +++++++++++++++ modules/home/rofi.nix | 19 ++++++++++++++++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 6ced128..fe53fe9 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -65,7 +65,6 @@ HARDWARE-QUEUE. Close #76 on PASS. impermanence, BIOS/legacy boot. - **Boot-from-snapshot**: a systemd-boot equivalent of grub-btrfs. - **MIPI/IPU software-ISP camera** support (no-UVC machines). -- **VPN exit-node richer display** (country/city) (optional). - **NixOS release bump → v2** `[human]`: deliberate, hand-edited, never automated; the previous attempt was discarded (2026-06-22) over a Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should diff --git a/agent/HARDWARE-QUEUE.md b/agent/HARDWARE-QUEUE.md index 164f309..bef66b4 100644 --- a/agent/HARDWARE-QUEUE.md +++ b/agent/HARDWARE-QUEUE.md @@ -99,6 +99,10 @@ the **T14s** (webcam case). - [ ] **VPN menu live paths** — import a real WireGuard `.conf` and an `.ovpn` via System → VPN, toggle up/down (● / ○ state), and the Tailscale block: up/down + exit-node without sudo (operator grant). + Exit-node rows now show "hostname — Country City" (2026-07-11, + header-offset parsing): confirm Mullvad-style nodes carry their + location, a locationless self-hosted node stays a bare hostname, + and picking either still sets the node (`tailscale status` shows it). - [ ] **Printer menu** — with `nomarchy.services.printing`, System → Printers opens system-config-printer; add a printer, test page. - [ ] **GRUB UEFI ISO theme render** — boot the ISO on UEFI hardware: diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index 587c147..64ccbb1 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -19,6 +19,21 @@ Template: --- +## 2026-07-11 — Quick wins: exit-node locations + geo tooltip +- **Task:** BACKLOG LATER "VPN exit-node richer display" + a geo-mode + tooltip nit from the previous iteration (human asked for quick wins). +- **Did:** Tailscale Exit node picker rows now "hostname — Country City", + sliced by the header's fixed-width column offsets (COUNTRY/CITY are + multi-word; never field-split), locationless nodes stay bare, pick strips + back to hostname at the first space. Nightlight Waybar tooltip says + "follows your location" in geo mode. Queue's VPN entry updated. +- **Verified:** V1 — awk proven against a fabricated 3-case fixture + (Mullvad 1-word + multi-word city + bare node); flake check exit 0; + downstream-template-home builds (writeShellScriptBin syntax-gates both + scripts). Real tailscale output is V3 (existing VPN queue entry). +- **Pending:** V3 VPN menu live paths (extended, not new). +- **Next suggestion:** wallpapers artifact split (LATER, decided). + ## 2026-07-11 — Night-light geo mode (lat/long → wlsunset) - **Task:** BACKLOG LATER "Night-light geo mode" (human-picked). - **Did:** `nomarchy.nightlight.latitude`/`.longitude` (both set = geo mode): diff --git a/modules/home/rofi.nix b/modules/home/rofi.nix index 4470424..5cd8f11 100644 --- a/modules/home/rofi.nix +++ b/modules/home/rofi.nix @@ -1191,9 +1191,26 @@ ${themeRows} else ${cfg.terminal} -e sudo tailscale "$@"; fi } ts_exit_node() { - node=$( { printf 'none\n'; tailscale exit-node list 2>/dev/null | awk 'NR>1 && $2 {print $2}'; \ + # Rows show "hostname — Country City" (Mullvad-style nodes carry a + # location). The COUNTRY/CITY columns are fixed-width and multi-word, + # so they're sliced by the header's column offsets, never by field + # splitting; hostnames have no spaces, so the pick strips back to the + # hostname at the first space. Locationless nodes stay a bare hostname. + node=$( { printf 'none\n'; tailscale exit-node list 2>/dev/null | awk ' + NR==1 { c=index($0,"COUNTRY"); s=index($0,"STATUS"); next } + $2 { + loc="" + if (c > 0) { + end = (s > c) ? s : length($0) + 1 + loc = substr($0, c, end - c) + gsub(/ +/, " ", loc); sub(/^ /, "", loc); sub(/ +$/, "", loc) + } + if (loc != "" && loc !~ /^[- ]+$/) print $2 " — " loc + else print $2 + }'; \ printf '%s\n' "$BACK"; } | rofi_menu -p "Exit node" ) || return { [ -z "$node" ] || [ "$node" = "$BACK" ]; } && return + node=''${node%% *} # display row → hostname [ "$node" = none ] && node="" ts_priv set --exit-node="$node" }