aboutsummaryrefslogtreecommitdiffstats
path: root/bin/vms_dots.sh
blob: bf9507051a6da24c8439e619f681b3df70f25e2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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}'