#!/bin/bash # Detect unexpected VM/container shutdowns set -euo pipefail SEND_NTFY="/usr/local/bin/send-ntfy.sh" STATE_FILE="/var/run/vm-states.txt" CURRENT_STATE="/tmp/vm-current-state.txt" # Get current VM/CT states qm list | awk 'NR>1 {print "VM:"$1":"$3}' > "$CURRENT_STATE" pct list | awk 'NR>1 {print "CT:"$1":"$2}' >> "$CURRENT_STATE" # If state file exists, compare if [ -f "$STATE_FILE" ]; then while IFS=':' read -r TYPE ID STATE; do PREV_STATE=$(grep "^$TYPE:$ID:" "$STATE_FILE" 2>/dev/null | cut -d':' -f3 || echo "") # If was running but now stopped, alert if [ "$PREV_STATE" = "running" ] && [ "$STATE" = "stopped" ]; then if [ "$TYPE" = "VM" ]; then NAME=$(qm config $ID 2>/dev/null | grep "^name:" | awk '{print $2}' || echo "VM$ID") $SEND_NTFY critical "VM Stopped Unexpectedly" "🔴 CRITICAL: VM $NAME (VMID $ID) stopped unexpectedly!" "skull,error,computer" else NAME=$(pct config $ID 2>/dev/null | grep "^hostname:" | awk '{print $2}' || echo "CT$ID") $SEND_NTFY critical "Container Stopped Unexpectedly" "🔴 CRITICAL: Container $NAME (CT $ID) stopped unexpectedly!" "skull,error,package" fi fi done < "$CURRENT_STATE" fi # Save current state cp "$CURRENT_STATE" "$STATE_FILE" logger -t vm-shutdown-monitor "VM/CT state check completed"