aboutsummaryrefslogtreecommitdiffstats
path: root/bin/vms_dots.sh
diff options
context:
space:
mode:
Diffstat (limited to 'bin/vms_dots.sh')
-rwxr-xr-xbin/vms_dots.sh89
1 files changed, 89 insertions, 0 deletions
diff --git a/bin/vms_dots.sh b/bin/vms_dots.sh
new file mode 100755
index 0000000..bf95070
--- /dev/null
+++ b/bin/vms_dots.sh
@@ -0,0 +1,89 @@
+#! /bin/bash
+# One dot per defined VM, coloured by state.
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+# Licensed under the GNU General Public License v2 only.
+#
+# dependencies: libvirt (virsh), jq
+#
+# The colours come from the palette, not from here: install.sh writes
+# ~/.config/waybar-udt/dots.colors from the selected udt scheme, and this
+# sources it. The defaults below are only what a missing file falls back to,
+# so the bar still draws if the theme has not been installed yet.
+set -euo pipefail
+
+JQ_BIN="${JQ:-jq}"
+
+# Palette. Sourced, with fallbacks, so this script works standalone.
+DOT_SUCCESS="#a6da95"
+DOT_WARNING="#eed49f"
+DOT_CRITICAL="#ed8796"
+DOT_INFO="#8bd5ca"
+DOT_ACCENT="#b7bdf8"
+DOT_FAINT="#6e738d"
+colors="$HOME/.config/waybar-udt/dots.colors"
+# shellcheck source=/dev/null
+[[ -r "$colors" ]] && . "$colors"
+
+# Require virsh
+if ! command -v virsh >/dev/null 2>&1; then
+ $JQ_BIN -cn '{text: "", tooltip: "virsh not found", class: "vmdot"}'
+ exit 0
+fi
+
+# Collect all defined VMs and their states.
+# virsh list --all columns: Id Name State (state may be multi-word, e.g. "shut off")
+declare -A vm_states
+while IFS= read -r line; do
+ # Skip header lines and separator lines
+ [[ "$line" =~ ^[[:space:]]*Id[[:space:]] ]] && continue
+ [[ "$line" =~ ^[-[:space:]]+$ ]] && continue
+ [[ -z "${line// }" ]] && continue
+
+ # Fields: id (may be "-"), name, state (rest of line)
+ read -r _id name state_rest <<< "$line"
+ vm_states["$name"]="$state_rest"
+done < <(virsh list --all 2>/dev/null)
+
+if [[ ${#vm_states[@]} -eq 0 ]]; then
+ $JQ_BIN -cn '{text: "", tooltip: "No VMs defined", class: "vmdot"}'
+ exit 0
+fi
+
+# libvirt state → palette role.
+declare -A state_color=(
+ ["running"]="$DOT_SUCCESS"
+ ["idle"]="$DOT_WARNING" # running but idle
+ ["paused"]="$DOT_WARNING"
+ ["pmsuspended"]="$DOT_ACCENT" # PM sleep / ACPI S3
+ ["saved"]="$DOT_INFO" # managed save
+ ["crashed"]="$DOT_CRITICAL"
+ ["shut off"]="$DOT_FAINT"
+)
+fallback_color="$DOT_FAINT" # any unknown future state
+
+dots=()
+tooltip_parts=()
+classes="vmdot"
+
+# Sort VM names for stable ordering
+mapfile -t sorted_names < <(printf '%s\n' "${!vm_states[@]}" | sort)
+
+for name in "${sorted_names[@]}"; do
+ state="${vm_states[$name]}"
+ color="${state_color[$state]:-$fallback_color}"
+ # Derive a CSS-safe class token (spaces → hyphens)
+ state_class="${state// /-}"
+
+ dots+=("<span foreground=\"${color}\">●</span>")
+ classes="$classes vm-${state_class}"
+ tooltip_parts+=("${name}: ${state}")
+done
+
+text="${dots[*]}"
+tooltip="$(IFS=' | '; echo "${tooltip_parts[*]}")"
+
+$JQ_BIN -cn \
+ --arg text "$text" \
+ --arg tooltip "$tooltip" \
+ --arg class "$classes" \
+ '{text: $text, tooltip: $tooltip, class: $class}'