Fix UPS notifications and add periodic battery status emails
- Fix permission denied on log files (chown nut:nut) - Fix upssched.conf permissions (root:nut) - Add sudo for perl to allow PVE::Notify from user nut - Add periodic battery status emails every minute when on battery - Add charging status emails at 5, 10, 30 min after power restore - Remove diacritics from all notification messages - Update documentation with sudo and permissions setup Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
# Configurare upssched pentru shutdown orchestrat cluster Proxmox
|
# Configurare upssched pentru shutdown orchestrat cluster Proxmox
|
||||||
#
|
#
|
||||||
# Acest fișier definește acțiuni temporale pentru evenimente UPS
|
# 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
|
CMDSCRIPT /usr/local/bin/upssched-cmd
|
||||||
PIPEFN /run/nut/upssched.pipe
|
PIPEFN /run/nut/upssched.pipe
|
||||||
LOCKFN /run/nut/upssched.lock
|
LOCKFN /run/nut/upssched.lock
|
||||||
|
|
||||||
# Când UPS trece pe baterie (ONBATT):
|
# 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
|
# 2. Așteaptă 180 secunde (3 minute) înainte de shutdown
|
||||||
AT ONBATT * EXECUTE onbatt_start
|
AT ONBATT * EXECUTE onbatt_start
|
||||||
AT ONBATT * START-TIMER onbatt 180
|
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
|
# Când UPS raportează baterie scăzută (LOWBATT), shutdown imediat
|
||||||
AT LOWBATT * EXECUTE lowbatt
|
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 * CANCEL-TIMER onbatt
|
||||||
AT ONLINE * EXECUTE online
|
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
|
# Când comunicația cu UPS se pierde (COMMBAD), așteaptă 30 secunde
|
||||||
AT COMMBAD * START-TIMER commbad 30
|
AT COMMBAD * START-TIMER commbad 30
|
||||||
|
|||||||
@@ -241,14 +241,39 @@ EOF
|
|||||||
|
|
||||||
### 5.2. Creare handler script
|
### 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
|
```bash
|
||||||
cp scripts/upssched-cmd /usr/local/bin/
|
cp scripts/upssched-cmd /usr/local/bin/
|
||||||
chmod +x /usr/local/bin/upssched-cmd
|
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
|
```bash
|
||||||
mkdir -p /run/nut
|
mkdir -p /run/nut
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# Trimite notificari email via PVE::Notify pentru fiecare pas
|
# Trimite notificari email via PVE::Notify pentru fiecare pas
|
||||||
#
|
#
|
||||||
# Creat: 2025-10-06
|
# 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
|
LOGFILE=/var/log/ups-shutdown.log
|
||||||
NODES=("10.0.20.200" "10.0.20.202") # pve1, pveelite (pvemini va fi ultimul)
|
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)
|
HOSTNAME=$(hostname)
|
||||||
FQDN=$(hostname -f 2>/dev/null || 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() {
|
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"
|
logger -t ups-shutdown "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +56,7 @@ send_notification() {
|
|||||||
|
|
||||||
log_message "Sending notification: $EVENT_TITLE"
|
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 strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use PVE::Notify;
|
use PVE::Notify;
|
||||||
|
|||||||
@@ -4,16 +4,32 @@
|
|||||||
# Trimite notificari email via PVE::Notify
|
# Trimite notificari email via PVE::Notify
|
||||||
#
|
#
|
||||||
# Creat: 2025-10-06
|
# 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
|
LOGFILE=/var/log/ups-events.log
|
||||||
UPS_NAME="nutdev1"
|
UPS_NAME="nutdev1"
|
||||||
TEMPLATE_DIR="/etc/pve/notification-templates/default"
|
TEMPLATE_DIR="/etc/pve/notification-templates/default"
|
||||||
HOSTNAME=$(hostname)
|
HOSTNAME=$(hostname)
|
||||||
FQDN=$(hostname -f 2>/dev/null || 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() {
|
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
|
# Obtine status UPS
|
||||||
@@ -38,6 +54,14 @@ get_battery_runtime() {
|
|||||||
fi
|
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
|
# Creeaza template-uri daca nu exista
|
||||||
create_templates() {
|
create_templates() {
|
||||||
mkdir -p $TEMPLATE_DIR
|
mkdir -p $TEMPLATE_DIR
|
||||||
@@ -92,6 +116,7 @@ EOFTEMPLATE
|
|||||||
.status-online { color: #27ae60; border-color: #27ae60; }
|
.status-online { color: #27ae60; border-color: #27ae60; }
|
||||||
.status-lowbatt { color: #c0392b; border-color: #c0392b; }
|
.status-lowbatt { color: #c0392b; border-color: #c0392b; }
|
||||||
.status-shutdown { color: #8e44ad; border-color: #8e44ad; }
|
.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-box { padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid; }
|
||||||
.alert-warning { background: #fef9e7; border-color: #f39c12; }
|
.alert-warning { background: #fef9e7; border-color: #f39c12; }
|
||||||
.alert-danger { background: #fdedec; border-color: #e74c3c; }
|
.alert-danger { background: #fdedec; border-color: #e74c3c; }
|
||||||
@@ -170,7 +195,7 @@ send_notification() {
|
|||||||
|
|
||||||
log_event "Sending $SEVERITY notification: $EVENT_TITLE"
|
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 strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use PVE::Notify;
|
use PVE::Notify;
|
||||||
@@ -206,6 +231,88 @@ if (\$@) {
|
|||||||
EOFPERL
|
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
|
# Handler principal
|
||||||
case $1 in
|
case $1 in
|
||||||
onbatt_start)
|
onbatt_start)
|
||||||
@@ -222,6 +329,9 @@ case $1 in
|
|||||||
"warning" \
|
"warning" \
|
||||||
"Timer 3 minute pornit" \
|
"Timer 3 minute pornit" \
|
||||||
"Asteptare revenire curent sau shutdown automat"
|
"Asteptare revenire curent sau shutdown automat"
|
||||||
|
|
||||||
|
# Porneste monitorizarea periodica a bateriei
|
||||||
|
start_battery_monitor
|
||||||
;;
|
;;
|
||||||
|
|
||||||
onbatt)
|
onbatt)
|
||||||
@@ -229,6 +339,9 @@ case $1 in
|
|||||||
log_event "UPS EVENT: Pe baterie de 3 minute - Incepe shutdown orchestrat"
|
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"
|
logger -t upssched-cmd "UPS on battery for 3 minutes - starting orchestrated shutdown"
|
||||||
|
|
||||||
|
# Opreste monitorizarea - urmeaza shutdown
|
||||||
|
stop_battery_monitor
|
||||||
|
|
||||||
send_notification \
|
send_notification \
|
||||||
"ONBATT_TIMEOUT" \
|
"ONBATT_TIMEOUT" \
|
||||||
"Pe baterie 3 min - SHUTDOWN" \
|
"Pe baterie 3 min - SHUTDOWN" \
|
||||||
@@ -247,15 +360,36 @@ case $1 in
|
|||||||
log_event "UPS EVENT: Curent revenit - UPS online"
|
log_event "UPS EVENT: Curent revenit - UPS online"
|
||||||
logger -t upssched-cmd "Power restored - UPS back online"
|
logger -t upssched-cmd "Power restored - UPS back online"
|
||||||
|
|
||||||
|
# Opreste monitorizarea descarcarii
|
||||||
|
stop_battery_monitor
|
||||||
|
|
||||||
send_notification \
|
send_notification \
|
||||||
"ONLINE" \
|
"ONLINE" \
|
||||||
"Curent revenit - OK" \
|
"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" \
|
"online" \
|
||||||
"success" \
|
"success" \
|
||||||
"info" \
|
"info" \
|
||||||
"Sistem stabil" \
|
"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)
|
lowbatt)
|
||||||
@@ -263,6 +397,9 @@ case $1 in
|
|||||||
log_event "UPS EVENT: BATERIE SCAZUTA - Shutdown IMEDIAT"
|
log_event "UPS EVENT: BATERIE SCAZUTA - Shutdown IMEDIAT"
|
||||||
logger -t upssched-cmd "UPS LOW BATTERY - immediate shutdown"
|
logger -t upssched-cmd "UPS LOW BATTERY - immediate shutdown"
|
||||||
|
|
||||||
|
# Opreste monitorizarea
|
||||||
|
stop_battery_monitor
|
||||||
|
|
||||||
send_notification \
|
send_notification \
|
||||||
"LOWBATT" \
|
"LOWBATT" \
|
||||||
"BATERIE CRITICA - SHUTDOWN IMEDIAT" \
|
"BATERIE CRITICA - SHUTDOWN IMEDIAT" \
|
||||||
|
|||||||
Reference in New Issue
Block a user