#!/usr/bin/env bash # service-nodes-shutdown.sh - Apagado de la(s) raspi(s) de servicio por SSH de # forma segura. Se ejecuta en la raspi principal. Ordena el poweroff y espera # a que deje de hacer ping antes de continuar. Despues corta la alimentacion # fisica a traves del relé correspondiente. # REQUISITOS: # - Claves SSH sin passphrase en /root/.ssh/id_shutdown autorizada en cada nodo # - Regla sudoers NOPASSWD para /usr/sbin/poweroff en cada nodo set -uo pipefail # CONFIGURACION --------------------------------------------------------------- NODES=( "pi@192.168.1.219|sudo /usr/sbin/poweroff" # Raspi Dinamica "root@192.168.1.50|/sbin/poweroff" # NVR ) SSH_KEY="/root/.ssh/id_shutdown" POWEROFF_CMD="sudo /usr/sbin/poweroff" TIMEOUT_HALT=60 # Timeout para el apagado LOG="/var/log/safe-shutdown.log" SSH_OPTS="-i $SSH_KEY -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new" # ----------------------------------------------------------------------------- log() { echo "$(date -Is) [service-nodes-shutdown] $*" | tee -a "$LOG"; } log "inicio (${#NODES[@]} nodo/s)" for entry in "${NODES[@]}"; do host_user="${entry%%|*}" host="${host_user#*@}" # extrae la IP/host del NODE cmd="${entry#*|}" log "apagando $host_user ..." # Ordenar poweroff por ssh if ssh $SSH_OPTS "$host_user" "$cmd"; then log "$entry: orden de poweroff enviada" else # Si falla avisamos y seguimos (puede no ser un error real) log "$entry: AVISO, el SSH devolvio error" fi # Esperamos la NO respuesta de ping halted=0 for ((i=1; i/dev/null; then log "$host: apagado confirmado (dejo de responder tras ${i}s)" halted=1 break fi sleep 1 done if [[ "$halted" -eq 0 ]]; then log "$host: AVISO, sigue respondiendo tras ${TIMEOUT_HALT}s (apagado no confirmado)" fi done log "fin"