Skip to content

Instantly share code, notes, and snippets.

@LuisPalacios
Created July 25, 2025 15:43
Show Gist options
  • Save LuisPalacios/1e8d6c1348d8c99a3f13f8704094b30e to your computer and use it in GitHub Desktop.
Save LuisPalacios/1e8d6c1348d8c99a3f13f8704094b30e to your computer and use it in GitHub Desktop.
Script de apagado ordenado por UPS usando NUT (Network UPS Tools)
#!/bin/bash
set -euo pipefail
# =============================================================================
# Script de apagado ordenado por UPS usando NUT (Network UPS Tools)
# =============================================================================
# Este script se ejecuta automáticamente desde el contenedor LXC `nut`, que actúa
# como servidor maestro (upsmon master). El contenedor está directamente
# conectado a la UPS por USB y monitoriza su estado en tiempo real.
#
# VM's "críticas" -> sumidero y muro, al apagarlas pierdo DNS, DHCP e Internet
# VM's "appliances" -> hass y wlc, así que no puedo darle órdenes remotas.
#
# ┌────────┐
# │ UPS │
# └──┬─────┘
# │ USB
# ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
# │ router │ │ pihole │ │ wlc │ │ hass │ │ nut │
# └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘
# \ | | | /
# \___________|_______________|_______________|______________/
# Host Proxmox: proxmox
# ┌──────────────────────────────┐
# │ Proxmox VE (proxmox) │
# │ Virtualization Host Server │
# └──────────────────────────────┘
#
# Propósitos del diseño:
# - Que Home Assistant vea el estado de la UPS (solo monitorización)
# - Que nut pueda orquestar el apagado ordenado de TODO cuando detecte
# corte prolongado de energía.
#
# Estrategia de apagado:
# 1. nut (el maestro) detecta evento de fallo eléctrico y ejecuta este script.
# 2. Se apagan en orden:
# a) pihole: contenedor con Pi-hole, DHCP y DNS (infraestructura base).
# b) router: firewall principal.
# c) VMs críticas del host Proxmox (hass, wlc...)
# d) El propio host Proxmox (hipervisor).
# e) Finalmente, el contenedor nut se apaga a sí mismo.
#
# Notas:
#
# - nut usa direcciones IP directas, sin depender de DNS.
# - a pesar de perder DNS, DHCP e Internet, el proceso continúa sin problemas
# porque nut usa direcciones IP directas.
# - hass y wlc se apagan desde el host Proxmox mediante `qm shutdown`
# porque son appliances cerradas y no permiten login SSH directo.
#
# =============================================================================
# === CONFIGURACIÓN ===
LOCKFILE="/run/nut-shutdown.lock"
LOGFILE="/var/log/nut-shutdown.log"
SSH_KEY="/root/.ssh/nut_shutdown_key"
SSH_OPTS="-i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10"
# IPs públicas ficticias para documentación
PIHOLE_IP="192.168.1.2"
ROUTER_IP="192.168.1.1"
PROXMOX_IP="192.168.1.254"
log() {
echo "[nut-shutdown-master] $(date '+%F %T') $1" | tee -a "$LOGFILE"
}
# Evitar ejecución concurrente
if [ -e "$LOCKFILE" ]; then
log "Lockfile detectado. Abortando ejecución duplicada."
exit 1
fi
touch "$LOCKFILE"
log "==== INICIO DE SECUENCIA DE APAGADO POR UPS ===="
# 1. Apagar PIHOLE
log "Apagando PIHOLE ($PIHOLE_IP)..."
ssh $SSH_OPTS root@$PIHOLE_IP "shutdown -h +0" && log "✅ PIHOLE: apagado ordenado iniciado." || log "⚠️ PIHOLE: error al ejecutar shutdown."
# 2. Apagar ROUTER
log "Apagando ROUTER ($ROUTER_IP)..."
ssh $SSH_OPTS root@$ROUTER_IP "shutdown -h +0" && log "✅ ROUTER: apagado ordenado iniciado." || log "⚠️ ROUTER: error al ejecutar shutdown."
# 3. Apagar VMs desde el host Proxmox
log "Apagando VM WLC (ID 102) desde Proxmox..."
ssh $SSH_OPTS root@$PROXMOX_IP "qm shutdown 102" && log "✅ VM WLC: apagado enviado." || log "⚠️ VM WLC: error al ejecutar qm shutdown."
log "Apagando VM HASS (ID 103) desde Proxmox..."
ssh $SSH_OPTS root@$PROXMOX_IP "qm shutdown 103" && log "✅ VM HASS: apagado enviado." || log "⚠️ VM HASS: error al ejecutar qm shutdown."
# 4. Esperar para asegurar apagado de VMs
log "Esperando 60s para que las VMs se apaguen correctamente..."
sleep 60
# 5. Apagar host Proxmox
log "Enviando shutdown a HOST PROXMOX ($PROXMOX_IP)..."
ssh $SSH_OPTS root@$PROXMOX_IP "shutdown -h now" && log "✅ HOST PROXMOX: apagado ejecutado." || log "⚠️ HOST PROXMOX: error al ejecutar shutdown."
# 6. Apagar contenedor actual (nut)
log "Apagando el contenedor LXC actual (nut)..."
rm -f "$LOCKFILE"
log "==== EJECUTANDO POWEROFF ===="
poweroff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment