Added networking scripts for waybar

This commit is contained in:
fwastring 2026-03-29 14:30:22 +02:00
parent 1a874f68d8
commit 534f8199f3
4 changed files with 510 additions and 13 deletions

View file

@ -37,6 +37,407 @@ with lib;
}; };
xdg.configFile."waybar/config.jsonc".source = config.waybar.configPath; xdg.configFile."waybar/config.jsonc".source = config.waybar.configPath;
xdg.configFile."waybar/style.css".source = config.waybar.stylePath; xdg.configFile."waybar/style.css".source = config.waybar.stylePath;
xdg.configFile."waybar/scripts/tailscale.sh" = {
text = ''
#!${pkgs.bash}/bin/bash
PATH=${
lib.makeBinPath [
pkgs.coreutils
pkgs.jq
pkgs.tailscale
]
}
STATE_FILE="/tmp/waybar_tailscale_state"
CONNECTING_DURATION=2 # seconds to show transition states
get_tailscale_status() {
local status_json
if status_json=$(tailscale status --json 2>/dev/null); then
local backend_state=$(echo "$status_json" | jq -r '.BackendState // "NoState"')
case "$backend_state" in
"Running")
echo "connected"
;;
"Stopped"|"NoState"|"NeedsLogin")
echo "stopped"
;;
*)
echo "stopped"
;;
esac
else
echo "stopped"
fi
}
get_tooltip() {
local status_json
if ! status_json=$(tailscale status --json 2>/dev/null); then
echo ""
return
fi
local backend_state=$(echo "$status_json" | jq -r '.BackendState // "NoState"')
if [[ "$backend_state" != "Running" ]]; then
echo ""
return
fi
local hostname=$(echo "$status_json" | jq -r '.Self.HostName // "Unknown"')
local tooltip="<b>Hostname: <span foreground='#87CEEB'>$hostname</span></b>\n"
tooltip+="\nPeers:\n"
local peers=$(echo "$status_json" | jq -r '.Peer // {} | to_entries[] | "\(.value.HostName):\(.value.Online)"' | sort)
if [[ -n "$peers" ]]; then
while IFS=: read -r peer_name peer_online; do
if [[ "$peer_online" == "true" ]]; then
tooltip+="\n<span foreground='#00ff00'></span> $peer_name"
else
tooltip+="\n<span foreground='#666666'></span> <span foreground='#888888'>$peer_name</span>"
fi
done <<< "$peers"
else
tooltip+="\n<i><span foreground='#888888'>No peers</span></i>"
fi
echo "$tooltip"
}
show_status() {
local status=$(get_tailscale_status)
local text=""
local alt=""
local tooltip=""
case $status in
"connected")
text=""
alt="connected"
tooltip=$(get_tooltip)
;;
"stopped")
text=""
alt="stopped"
tooltip="Tailscale is turned off"
;;
esac
if [[ -n "$tooltip" ]]; then
echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\",\"tooltip\":\"$tooltip\"}"
else
echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\"}"
fi
}
show_connecting() {
echo "{\"text\":\"\",\"class\":\"connecting\",\"alt\":\"connecting\",\"tooltip\":\"Connecting...\"}"
}
show_disconnecting() {
echo "{\"text\":\"\",\"class\":\"disconnecting\",\"alt\":\"disconnecting\",\"tooltip\":\"Disconnecting...\"}"
}
is_in_transition() {
if [[ -f "$STATE_FILE" ]]; then
local state_info=$(cat "$STATE_FILE")
local state_time=$(echo "$state_info" | cut -d: -f1)
local current_time=$(date +%s)
if (( current_time - state_time < CONNECTING_DURATION )); then
return 0
else
rm -f "$STATE_FILE"
return 1
fi
fi
return 1
}
case "$1" in
--status)
if is_in_transition; then
state_info=$(cat "$STATE_FILE")
state_action=$(echo "$state_info" | cut -d: -f2)
if [[ "$state_action" == "connecting" ]]; then
show_connecting
exit 0
elif [[ "$state_action" == "disconnecting" ]]; then
show_disconnecting
exit 0
fi
fi
show_status
;;
--toggle)
if is_in_transition; then
state_info=$(cat "$STATE_FILE")
state_action=$(echo "$state_info" | cut -d: -f2)
if [[ "$state_action" == "connecting" ]]; then
show_connecting
elif [[ "$state_action" == "disconnecting" ]]; then
show_disconnecting
fi
exit 0
fi
current_status=$(get_tailscale_status)
if [[ "$current_status" == "connected" ]]; then
tailscale down
show_status
else
echo "$(date +%s):connecting" > "$STATE_FILE"
tailscale up
show_connecting
fi
;;
*)
echo "Usage: $0 {--status|--toggle}"
exit 1
;;
esac
'';
executable = true;
};
xdg.configFile."waybar/scripts/netbird.sh" = {
text = ''
#!${pkgs.bash}/bin/bash
PATH=${
lib.makeBinPath [
pkgs.coreutils
pkgs.netbird
]
}
STATE_FILE="/tmp/waybar_netbird_state"
CONNECTING_DURATION=2 # seconds to show transition states
get_netbird_status() {
local status_output
local management_status=""
if ! status_output=$(netbird status -d 2>/dev/null); then
echo "stopped"
return
fi
while IFS= read -r line; do
case "$line" in
"Management:"*)
management_status="''${line#Management: }"
;;
esac
done <<< "$status_output"
case "$management_status" in
*Connected*)
echo "connected"
;;
*)
echo "stopped"
;;
esac
}
get_tooltip() {
local status_output
local management_status=""
local signal_status=""
local relays_available=0
local relays_total=0
local nameservers_available=0
local nameservers_total=0
local netbird_ip=""
local peers_count=""
local interface_type=""
local section=""
if ! status_output=$(netbird status -d 2>/dev/null); then
echo ""
return
fi
while IFS= read -r line; do
case "$line" in
"Management:"*)
management_status="''${line#Management: }"
section=""
;;
"Signal:"*)
signal_status="''${line#Signal: }"
section=""
;;
"Relays:"*)
section="relays"
;;
"Nameservers:"*)
section="nameservers"
;;
"NetBird IP:"*)
netbird_ip="''${line#NetBird IP: }"
section=""
;;
"Interface type:"*)
interface_type="''${line#Interface type: }"
section=""
;;
"Peers count:"*)
peers_count="''${line#Peers count: }"
section=""
;;
"Peers detail:"*)
section=""
;;
" ["*)
if [[ "$section" == "relays" ]]; then
relays_total=$((relays_total + 1))
if [[ "$line" == *"Available"* ]]; then
relays_available=$((relays_available + 1))
fi
elif [[ "$section" == "nameservers" ]]; then
nameservers_total=$((nameservers_total + 1))
if [[ "$line" == *"Available"* ]]; then
nameservers_available=$((nameservers_available + 1))
fi
fi
;;
esac
done <<< "$status_output"
if [[ -z "$management_status" ]]; then
echo ""
return
fi
local tooltip="<b>Management:</b> $management_status"
if [[ -n "$signal_status" ]]; then
tooltip+="\n<b>Signal:</b> $signal_status"
fi
if (( relays_total > 0 )); then
tooltip+="\n<b>Relays:</b> $relays_available/$relays_total Available"
fi
if (( nameservers_total > 0 )); then
tooltip+="\n<b>Nameservers:</b> $nameservers_available/$nameservers_total Available"
fi
if [[ -n "$netbird_ip" ]]; then
tooltip+="\n<b>NetBird IP:</b> $netbird_ip"
fi
if [[ -n "$interface_type" ]]; then
tooltip+="\n<b>Interface:</b> $interface_type"
fi
if [[ -n "$peers_count" ]]; then
tooltip+="\n<b>Peers:</b> $peers_count"
fi
echo "$tooltip"
}
show_status() {
local status=$(get_netbird_status)
local text=""
local alt=""
local tooltip=""
case $status in
"connected")
text=""
alt="connected"
tooltip=$(get_tooltip)
;;
"stopped")
text=""
alt="stopped"
tooltip="NetBird is turned off"
;;
esac
if [[ -n "$tooltip" ]]; then
echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\",\"tooltip\":\"$tooltip\"}"
else
echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\"}"
fi
}
show_connecting() {
echo "{\"text\":\"\",\"class\":\"connecting\",\"alt\":\"connecting\",\"tooltip\":\"Connecting...\"}"
}
show_disconnecting() {
echo "{\"text\":\"\",\"class\":\"disconnecting\",\"alt\":\"disconnecting\",\"tooltip\":\"Disconnecting...\"}"
}
is_in_transition() {
if [[ -f "$STATE_FILE" ]]; then
local state_info=$(cat "$STATE_FILE")
local state_time=$(echo "$state_info" | cut -d: -f1)
local current_time=$(date +%s)
if (( current_time - state_time < CONNECTING_DURATION )); then
return 0
else
rm -f "$STATE_FILE"
return 1
fi
fi
return 1
}
case "$1" in
--status)
if is_in_transition; then
state_info=$(cat "$STATE_FILE")
state_action=$(echo "$state_info" | cut -d: -f2)
if [[ "$state_action" == "connecting" ]]; then
show_connecting
exit 0
elif [[ "$state_action" == "disconnecting" ]]; then
show_disconnecting
exit 0
fi
fi
show_status
;;
--toggle)
if is_in_transition; then
state_info=$(cat "$STATE_FILE")
state_action=$(echo "$state_info" | cut -d: -f2)
if [[ "$state_action" == "connecting" ]]; then
show_connecting
elif [[ "$state_action" == "disconnecting" ]]; then
show_disconnecting
fi
exit 0
fi
current_status=$(get_netbird_status)
if [[ "$current_status" == "connected" ]]; then
netbird down
show_status
else
echo "$(date +%s):connecting" > "$STATE_FILE"
netbird up
show_connecting
fi
;;
*)
echo "Usage: $0 {--status|--toggle}"
exit 1
;;
esac
'';
executable = true;
};
}; };
# catppuccin.waybar = { # catppuccin.waybar = {
# enable = true; # enable = true;

View file

@ -13,6 +13,8 @@
"bluetooth", "bluetooth",
"pulseaudio", "pulseaudio",
"upower", "upower",
"custom/tailscale",
"custom/netbird",
"network", "network",
"clock" "clock"
], ],
@ -44,7 +46,7 @@
"on-click": "pgrep .blueman-manage && pkill .blueman-manage || blueman-manager &" "on-click": "pgrep .blueman-manage && pkill .blueman-manage || blueman-manager &"
}, },
"network": { "network": {
"interface": "wlp1s0", "interface": "wlp0s20f3",
"format": "{ifname}", "format": "{ifname}",
"format-wifi": " {essid} ({signalStrength}%)", "format-wifi": " {essid} ({signalStrength}%)",
"format-ethernet": "{ifname} ", "format-ethernet": "{ifname} ",
@ -86,5 +88,35 @@
"tooltip": true, "tooltip": true,
"tooltip-format": "{:%A, %d %B %Y}\n %H:%M:%S", "tooltip-format": "{:%A, %d %B %Y}\n %H:%M:%S",
"interval": 1 "interval": 1
},
"custom/tailscale": {
"exec": "/home/fw/.config/waybar/scripts/tailscale.sh --status",
"on-click": "/home/fw/.config/waybar/scripts/tailscale.sh --toggle",
"exec-on-event": true,
"format": "{icon} {text}",
"format-icons": {
"connected": "",
"stopped": "",
"connecting": "",
"disconnecting": ""
},
"tooltip": true,
"return-type": "json",
"interval": 5
},
"custom/netbird": {
"exec": "/home/fw/.config/waybar/scripts/netbird.sh --status",
"on-click": "/home/fw/.config/waybar/scripts/netbird.sh --toggle",
"exec-on-event": true,
"format": "{icon} {text}",
"format-icons": {
"connected": "",
"stopped": "",
"connecting": "",
"disconnecting": ""
},
"tooltip": true,
"return-type": "json",
"interval": 5
} }
} }

View file

@ -19,6 +19,22 @@
font-size: 15px; font-size: 15px;
} }
.connecting {
animation: pulse 0.8s ease-in-out infinite;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
window#waybar { window#waybar {
/* background: @base; */ /* background: @base; */
background: transparent; background: transparent;
@ -32,7 +48,7 @@ window#waybar.termite { background: @base; }
window#waybar.chromium { background: @base; border: none; } window#waybar.chromium { background: @base; border: none; }
/* -------- Module “pill” look -------- */ /* -------- Module “pill” look -------- */
#workspaces, #clock, #mpris, #pulseaudio, #bluetooth, #upower, #network { #workspaces, #clock, #mpris, #pulseaudio, #bluetooth, #upower, #network, #custom-tailscale, #custom-netbird {
background: @base; background: @base;
border: none; border: none;
border-radius: 5px; border-radius: 5px;
@ -139,6 +155,22 @@ button:active {
letter-spacing: 0.2px; letter-spacing: 0.2px;
} }
/* -------- Upower -------- */
#custom-tailscale {
background: @peach;
color: @base;
font-weight: 600;
letter-spacing: 0.2px;
}
/* -------- Netbird -------- */
#custom-netbird {
background: @peach;
color: @base;
font-weight: 600;
letter-spacing: 0.2px;
}
/* -------- Network -------- */ /* -------- Network -------- */
#network { #network {
background: @peach; background: @peach;

View file

@ -12,6 +12,8 @@
"mpris", "mpris",
"pulseaudio", "pulseaudio",
"bluetooth", "bluetooth",
"custom/tailscale",
"custom/netbird",
"network", "network",
"clock" "clock"
], ],
@ -80,5 +82,35 @@
"tooltip": true, "tooltip": true,
"tooltip-format": "{:%A, %d %B %Y}\n %H:%M:%S", "tooltip-format": "{:%A, %d %B %Y}\n %H:%M:%S",
"interval": 1 "interval": 1
},
"custom/tailscale": {
"exec": "/home/fw/.config/waybar/scripts/tailscale.sh --status",
"on-click": "/home/fw/.config/waybar/scripts/tailscale.sh --toggle",
"exec-on-event": true,
"format": "{icon} {text}",
"format-icons": {
"connected": "",
"stopped": "",
"connecting": "",
"disconnecting": ""
},
"tooltip": true,
"return-type": "json",
"interval": 5
},
"custom/netbird": {
"exec": "/home/fw/.config/waybar/scripts/netbird.sh --status",
"on-click": "/home/fw/.config/waybar/scripts/netbird.sh --toggle",
"exec-on-event": true,
"format": "{icon} {text}",
"format-icons": {
"connected": "",
"stopped": "",
"connecting": "",
"disconnecting": ""
},
"tooltip": true,
"return-type": "json",
"interval": 5
} }
} }