feat(menu): Tailscale exit-node rows show country/city
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 <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,6 @@ HARDWARE-QUEUE. Close #76 on PASS.
|
|||||||
impermanence, BIOS/legacy boot.
|
impermanence, BIOS/legacy boot.
|
||||||
- **Boot-from-snapshot**: a systemd-boot equivalent of grub-btrfs.
|
- **Boot-from-snapshot**: a systemd-boot equivalent of grub-btrfs.
|
||||||
- **MIPI/IPU software-ISP camera** support (no-UVC machines).
|
- **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
|
- **NixOS release bump → v2** `[human]`: deliberate, hand-edited, never
|
||||||
automated; the previous attempt was discarded (2026-06-22) over a
|
automated; the previous attempt was discarded (2026-06-22) over a
|
||||||
Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should
|
Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ the **T14s** (webcam case).
|
|||||||
- [ ] **VPN menu live paths** — import a real WireGuard `.conf` and an
|
- [ ] **VPN menu live paths** — import a real WireGuard `.conf` and an
|
||||||
`.ovpn` via System → VPN, toggle up/down (● / ○ state), and the
|
`.ovpn` via System → VPN, toggle up/down (● / ○ state), and the
|
||||||
Tailscale block: up/down + exit-node without sudo (operator grant).
|
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 →
|
- [ ] **Printer menu** — with `nomarchy.services.printing`, System →
|
||||||
Printers opens system-config-printer; add a printer, test page.
|
Printers opens system-config-printer; add a printer, test page.
|
||||||
- [ ] **GRUB UEFI ISO theme render** — boot the ISO on UEFI hardware:
|
- [ ] **GRUB UEFI ISO theme render** — boot the ISO on UEFI hardware:
|
||||||
|
|||||||
@@ -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)
|
## 2026-07-11 — Night-light geo mode (lat/long → wlsunset)
|
||||||
- **Task:** BACKLOG LATER "Night-light geo mode" (human-picked).
|
- **Task:** BACKLOG LATER "Night-light geo mode" (human-picked).
|
||||||
- **Did:** `nomarchy.nightlight.latitude`/`.longitude` (both set = geo mode):
|
- **Did:** `nomarchy.nightlight.latitude`/`.longitude` (both set = geo mode):
|
||||||
|
|||||||
@@ -1191,9 +1191,26 @@ ${themeRows}
|
|||||||
else ${cfg.terminal} -e sudo tailscale "$@"; fi
|
else ${cfg.terminal} -e sudo tailscale "$@"; fi
|
||||||
}
|
}
|
||||||
ts_exit_node() {
|
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
|
printf '%s\n' "$BACK"; } | rofi_menu -p "Exit node" ) || return
|
||||||
{ [ -z "$node" ] || [ "$node" = "$BACK" ]; } && return
|
{ [ -z "$node" ] || [ "$node" = "$BACK" ]; } && return
|
||||||
|
node=''${node%% *} # display row → hostname
|
||||||
[ "$node" = none ] && node=""
|
[ "$node" = none ] && node=""
|
||||||
ts_priv set --exit-node="$node"
|
ts_priv set --exit-node="$node"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user