diff --git a/proxmox/ups/config/upssched.conf b/proxmox/ups/config/upssched.conf index 9a8b315..94d4734 100644 --- a/proxmox/ups/config/upssched.conf +++ b/proxmox/ups/config/upssched.conf @@ -1,13 +1,14 @@ # Configurare upssched pentru shutdown orchestrat cluster Proxmox # # Acest fișier definește acțiuni temporale pentru evenimente UPS +# Actualizat: 2026-01-14 - Adaugat notificari periodice status baterie CMDSCRIPT /usr/local/bin/upssched-cmd PIPEFN /run/nut/upssched.pipe LOCKFN /run/nut/upssched.lock # Când UPS trece pe baterie (ONBATT): -# 1. Trimite notificare imediată +# 1. Trimite notificare imediată + pornește monitorizare periodică # 2. Așteaptă 180 secunde (3 minute) înainte de shutdown AT ONBATT * EXECUTE onbatt_start AT ONBATT * START-TIMER onbatt 180 @@ -15,9 +16,15 @@ AT ONBATT * START-TIMER onbatt 180 # Când UPS raportează baterie scăzută (LOWBATT), shutdown imediat AT LOWBATT * EXECUTE lowbatt -# Când curentul revine (ONLINE), anulează timer-ele și trimite notificare +# Când curentul revine (ONLINE): +# 1. Anulează timer-ul de shutdown +# 2. Trimite notificare + pornește monitorizare încărcare +# 3. Notificări la 5, 10, 30 minute pentru a vedea încărcarea AT ONLINE * CANCEL-TIMER onbatt AT ONLINE * EXECUTE online +AT ONLINE * START-TIMER charge_5min 300 +AT ONLINE * START-TIMER charge_10min 600 +AT ONLINE * START-TIMER charge_30min 1800 # Când comunicația cu UPS se pierde (COMMBAD), așteaptă 30 secunde AT COMMBAD * START-TIMER commbad 30 diff --git a/proxmox/ups/docs/INSTALARE-NUT.md b/proxmox/ups/docs/INSTALARE-NUT.md index 5a7c96e..d91e5da 100644 --- a/proxmox/ups/docs/INSTALARE-NUT.md +++ b/proxmox/ups/docs/INSTALARE-NUT.md @@ -241,14 +241,39 @@ EOF ### 5.2. Creare handler script -Copiază scriptul `upssched-cmd` din directorul `scripts/` în `/usr/local/bin/`: +Copiaza scriptul `upssched-cmd` din directorul `scripts/` in `/usr/local/bin/`: ```bash cp scripts/upssched-cmd /usr/local/bin/ chmod +x /usr/local/bin/upssched-cmd ``` -### 5.3. Creare director runtime +### 5.3. Configurare sudo pentru user nut + +Scripturile ruleaza ca user `nut` si au nevoie de sudo pentru a accesa PVE::Notify: + +```bash +# Instaleaza sudo daca nu exista +apt-get install -y sudo + +# Configureaza permisiuni sudo pentru user nut +cat > /etc/sudoers.d/nut << 'EOF' +nut ALL=(root) NOPASSWD: /usr/bin/perl +EOF +chmod 440 /etc/sudoers.d/nut +``` + +### 5.4. Configurare permisiuni fisiere log + +Fisierele de log trebuie sa fie writable de user-ul `nut`: + +```bash +touch /var/log/ups-events.log /var/log/ups-shutdown.log +chown nut:nut /var/log/ups-events.log /var/log/ups-shutdown.log +chmod 664 /var/log/ups-events.log /var/log/ups-shutdown.log +``` + +### 5.5. Creare director runtime ```bash mkdir -p /run/nut diff --git a/proxmox/ups/scripts/ups-shutdown-cluster.sh b/proxmox/ups/scripts/ups-shutdown-cluster.sh index 5672a18..5b857a0 100644 --- a/proxmox/ups/scripts/ups-shutdown-cluster.sh +++ b/proxmox/ups/scripts/ups-shutdown-cluster.sh @@ -4,7 +4,7 @@ # Trimite notificari email via PVE::Notify pentru fiecare pas # # Creat: 2025-10-06 -# Actualizat: 2026-01-13 - Adaugat notificari email si UPS shutdown +# Actualizat: 2026-01-14 - Fix permisiuni log file, adaugat sudo pentru PVE::Notify LOGFILE=/var/log/ups-shutdown.log NODES=("10.0.20.200" "10.0.20.202") # pve1, pveelite (pvemini va fi ultimul) @@ -16,8 +16,22 @@ TEMPLATE_DIR="/etc/pve/notification-templates/default" HOSTNAME=$(hostname) FQDN=$(hostname -f 2>/dev/null || hostname) +# Asigura ca fisierul de log exista si are permisiunile corecte +# Scriptul poate rula ca user 'nut', deci fisierul trebuie sa fie writable +ensure_logfile() { + if [ ! -f "$LOGFILE" ]; then + touch "$LOGFILE" 2>/dev/null || sudo touch "$LOGFILE" + fi + if [ ! -w "$LOGFILE" ]; then + sudo chown nut:nut "$LOGFILE" 2>/dev/null + sudo chmod 664 "$LOGFILE" 2>/dev/null + fi +} + +ensure_logfile + log_message() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOGFILE + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOGFILE 2>/dev/null logger -t ups-shutdown "$1" } @@ -42,7 +56,7 @@ send_notification() { log_message "Sending notification: $EVENT_TITLE" - perl -I/usr/share/perl5 << EOFPERL 2>&1 | tee -a $LOGFILE + /usr/bin/sudo /usr/bin/perl -I/usr/share/perl5 << EOFPERL 2>&1 | tee -a $LOGFILE use strict; use warnings; use PVE::Notify; diff --git a/proxmox/ups/scripts/upssched-cmd b/proxmox/ups/scripts/upssched-cmd index 1099746..b54cebf 100644 --- a/proxmox/ups/scripts/upssched-cmd +++ b/proxmox/ups/scripts/upssched-cmd @@ -4,16 +4,32 @@ # Trimite notificari email via PVE::Notify # # Creat: 2025-10-06 -# Actualizat: 2026-01-13 - Adaugat notificari email +# Actualizat: 2026-01-14 - Adaugat notificari periodice status baterie LOGFILE=/var/log/ups-events.log UPS_NAME="nutdev1" TEMPLATE_DIR="/etc/pve/notification-templates/default" HOSTNAME=$(hostname) FQDN=$(hostname -f 2>/dev/null || hostname) +BATTERY_MONITOR_PID="/run/nut/battery-monitor.pid" + +# Asigura ca fisierul de log exista si are permisiunile corecte +# Scriptul ruleaza ca user 'nut', deci fisierul trebuie sa fie writable +ensure_logfile() { + if [ ! -f "$LOGFILE" ]; then + touch "$LOGFILE" 2>/dev/null || sudo touch "$LOGFILE" + fi + if [ ! -w "$LOGFILE" ]; then + sudo chown nut:nut "$LOGFILE" 2>/dev/null + sudo chmod 664 "$LOGFILE" 2>/dev/null + fi +} + +ensure_logfile log_event() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOGFILE + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOGFILE 2>/dev/null || \ + logger -t upssched-cmd "LOG_FALLBACK: $1" } # Obtine status UPS @@ -38,6 +54,14 @@ get_battery_runtime() { fi } +get_battery_voltage() { + upsc $UPS_NAME battery.voltage 2>/dev/null || echo "0" +} + +get_ups_load() { + upsc $UPS_NAME ups.load 2>/dev/null || echo "0" +} + # Creeaza template-uri daca nu exista create_templates() { mkdir -p $TEMPLATE_DIR @@ -92,6 +116,7 @@ EOFTEMPLATE .status-online { color: #27ae60; border-color: #27ae60; } .status-lowbatt { color: #c0392b; border-color: #c0392b; } .status-shutdown { color: #8e44ad; border-color: #8e44ad; } + .status-charging { color: #3498db; border-color: #3498db; } .alert-box { padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid; } .alert-warning { background: #fef9e7; border-color: #f39c12; } .alert-danger { background: #fdedec; border-color: #e74c3c; } @@ -170,7 +195,7 @@ send_notification() { log_event "Sending $SEVERITY notification: $EVENT_TITLE" - perl -I/usr/share/perl5 << EOFPERL 2>&1 | tee -a $LOGFILE + /usr/bin/sudo /usr/bin/perl -I/usr/share/perl5 << EOFPERL 2>&1 | tee -a $LOGFILE use strict; use warnings; use PVE::Notify; @@ -206,6 +231,88 @@ if (\$@) { EOFPERL } +# Porneste monitorizarea periodica a bateriei (la fiecare minut) +start_battery_monitor() { + # Opreste monitorul existent daca exista + stop_battery_monitor + + log_event "Starting battery discharge monitor (every 60 seconds)" + + # Porneste procesul de monitorizare in background + ( + MINUTE=1 + while true; do + sleep 60 + + # Verifica daca UPS-ul e inca pe baterie + STATUS=$(upsc $UPS_NAME ups.status 2>/dev/null) + if [[ ! "$STATUS" =~ "OB" ]]; then + log_event "Battery monitor: UPS no longer on battery, stopping monitor" + break + fi + + CHARGE=$(get_battery_charge) + VOLTAGE=$(get_battery_voltage) + RUNTIME=$(get_battery_runtime) + LOAD=$(get_ups_load) + + log_event "Battery monitor: Minute $MINUTE - Charge: ${CHARGE}%, Voltage: ${VOLTAGE}V, Load: ${LOAD}%" + + send_notification \ + "BATTERY_STATUS" \ + "Status baterie - ${CHARGE}% (min $MINUTE)" \ + "UPS pe baterie de $MINUTE minute. Baterie: ${CHARGE}%, Voltaj: ${VOLTAGE}V, Load: ${LOAD}%${RUNTIME:+, Runtime: ${RUNTIME} min}" \ + "onbatt" \ + "warning" \ + "warning" \ + "Monitorizare descarcare" \ + "Se trimite status la fiecare minut" + + MINUTE=$((MINUTE + 1)) + done + rm -f $BATTERY_MONITOR_PID + ) & + + echo $! > $BATTERY_MONITOR_PID + log_event "Battery monitor started with PID $(cat $BATTERY_MONITOR_PID)" +} + +# Opreste monitorizarea periodica a bateriei +stop_battery_monitor() { + if [ -f "$BATTERY_MONITOR_PID" ]; then + PID=$(cat $BATTERY_MONITOR_PID) + if [ -n "$PID" ] && kill -0 $PID 2>/dev/null; then + log_event "Stopping battery monitor (PID $PID)" + kill $PID 2>/dev/null + # Asteapta putin si forteaza daca nu s-a oprit + sleep 1 + kill -9 $PID 2>/dev/null + fi + rm -f $BATTERY_MONITOR_PID + fi +} + +# Trimite status incarcare baterie +send_charge_status() { + local MINUTES="$1" + local CHARGE=$(get_battery_charge) + local VOLTAGE=$(get_battery_voltage) + local INPUT=$(get_input_voltage) + local LOAD=$(get_ups_load) + + log_event "Charge status at $MINUTES min: ${CHARGE}%, Voltage: ${VOLTAGE}V, Input: ${INPUT}V" + + send_notification \ + "CHARGING_STATUS" \ + "Incarcare baterie - ${CHARGE}% (+${MINUTES} min)" \ + "Status incarcare la $MINUTES minute dupa revenirea curentului. Baterie: ${CHARGE}%, Voltaj baterie: ${VOLTAGE}V, Tensiune intrare: ${INPUT}V, Load: ${LOAD}%" \ + "charging" \ + "info" \ + "info" \ + "Monitorizare incarcare" \ + "Bateria se incarca" +} + # Handler principal case $1 in onbatt_start) @@ -222,6 +329,9 @@ case $1 in "warning" \ "Timer 3 minute pornit" \ "Asteptare revenire curent sau shutdown automat" + + # Porneste monitorizarea periodica a bateriei + start_battery_monitor ;; onbatt) @@ -229,6 +339,9 @@ case $1 in log_event "UPS EVENT: Pe baterie de 3 minute - Incepe shutdown orchestrat" logger -t upssched-cmd "UPS on battery for 3 minutes - starting orchestrated shutdown" + # Opreste monitorizarea - urmeaza shutdown + stop_battery_monitor + send_notification \ "ONBATT_TIMEOUT" \ "Pe baterie 3 min - SHUTDOWN" \ @@ -247,15 +360,36 @@ case $1 in log_event "UPS EVENT: Curent revenit - UPS online" logger -t upssched-cmd "Power restored - UPS back online" + # Opreste monitorizarea descarcarii + stop_battery_monitor + send_notification \ "ONLINE" \ "Curent revenit - OK" \ - "Curentul electric a revenit. UPS functioneaza normal pe linia AC." \ + "Curentul electric a revenit. UPS functioneaza normal pe linia AC. Se vor trimite statusuri de incarcare la 5, 10 si 30 de minute." \ "online" \ "success" \ "info" \ "Sistem stabil" \ - "Nicio actiune necesara" + "Monitorizare incarcare activa" + ;; + + charge_5min) + log_event "==========================================" + log_event "UPS EVENT: Status incarcare la 5 minute" + send_charge_status "5" + ;; + + charge_10min) + log_event "==========================================" + log_event "UPS EVENT: Status incarcare la 10 minute" + send_charge_status "10" + ;; + + charge_30min) + log_event "==========================================" + log_event "UPS EVENT: Status incarcare la 30 minute" + send_charge_status "30" ;; lowbatt) @@ -263,6 +397,9 @@ case $1 in log_event "UPS EVENT: BATERIE SCAZUTA - Shutdown IMEDIAT" logger -t upssched-cmd "UPS LOW BATTERY - immediate shutdown" + # Opreste monitorizarea + stop_battery_monitor + send_notification \ "LOWBATT" \ "BATERIE CRITICA - SHUTDOWN IMEDIAT" \