fix(ups): shutdown-ul orchestrat la pana de curent nu functiona deloc
upsmon face fork in doua procese, iar NOTIFYCMD ruleaza in cel neprivilegiat, ca user `nut`: shell nologin, home /var/lib/nut, NICIO cheie SSH. Verificat pe pvemini — pentru `nut`, `qm list`, `pct list` si `ssh root@pve1` esueaza toate. Deci ups-shutdown-cluster.sh nu putea opri niciun guest si nu putea ajunge la niciun nod. Singurul lucru care mergea erau emailurile, pentru care exista deja `nut ALL=(root) NOPASSWD: /usr/bin/perl`. De asta /var/log/ups-shutdown.log nu continea nicio oprire reusita din 2025-10-06 incoace: la fiecare pana de curent se trimiteau emailuri si nu se oprea nimic, iar pve1/pveelite mergeau pana se termina bateria. Reparat: - /etc/sudoers.d/nut-shutdown da userului nut dreptul sa ruleze scriptul ca root - upssched-cmd il invoca prin sudo (liniile 355 si 413) - scriptul refuza sa porneasca daca nu e root, cu mesaj explicit Rescris scriptul: - seteaza shutdown_policy=freeze INAINTE de orice. Fara asta, politica implicita `conditional` transforma fiecare poweroff de nod in failover catre un nod care se stinge si el imediat — exact incidentul 2026-01-11, cu VM 201 migrat in timpul unei pene - guest-urile HA se opresc cu `ha-manager set --state stopped`, nu cu pct/qm shutdown, care din CLI nu actualizeaza state-ul HA - Oracle primeste `shutdown immediate` inainte de oprirea containerului - consumatorii se opresc in paralel, Oracle ultimul - detecteaza lipsa quorumului si cade pe oprire directa, in loc sa blocheze - flock: ONBATT si LOWBATT pot declansa amandoua scriptul - sare peste nodurile care nu raspund la ping in loc sa astepte timeout SSH - timeout pe notificarile email: nu consumam baterie pe SMTP - --dry-run si --force; credentialele UPS pot veni din /etc/nut/ups-shutdown.conf in loc sa fie in script ups-shutdown-test.sh nu mai duplica logica: invoca scriptul real cu --dry-run. Un test cu cod propriu testeaza altceva decat ce ruleaza in realitate. Testat pe pvemini prin lantul complet: sudo -u nut sudo /usr/local/bin/ups-shutdown-cluster.sh --dry-run --force Descopera corect toate cele 11 guest-uri, inclusiv cele de pe pve1 (deci SSH-ul merge), si gaseste shutdown.stayoff pe UPS. RAMANE DE VERIFICAT FIZIC: ups.load e 8%, putin pentru trei servere. Daca pve1 si pveelite nu sunt alimentate din UPS, mor instant la pana si toata orchestrarea e decorativa. Nu se poate verifica din software. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RRyaDj39hPQ89SZS6URRpS
This commit is contained in:
@@ -52,12 +52,56 @@ Restart servicii
|
||||
### Cluster Proxmox
|
||||
- **pvemini (10.0.20.201)** - Nod PRIMARY
|
||||
- Are UPS-ul conectat fizic
|
||||
- Rulează NUT server și driver
|
||||
- Rulează NUT server și driver (`MODE=standalone`)
|
||||
- Orchestrează oprirea celorlalte noduri prin SSH
|
||||
- Ultimul nod care se oprește
|
||||
- **pve1 (10.0.20.200)** - Nod SECONDARY
|
||||
- Se oprește primul în caz de baterie critică
|
||||
- **pve2 (10.0.20.202)** - Nod SECONDARY
|
||||
- Se oprește primul în caz de baterie critică
|
||||
- **NU rulează NUT deloc** — e oprit prin SSH de pe pvemini
|
||||
- **pveelite (10.0.20.202)** - Nod SECONDARY
|
||||
- **NU rulează NUT deloc** — e oprit prin SSH de pe pvemini
|
||||
|
||||
### Cum ajung secundarele să se oprească
|
||||
|
||||
NUT nu e instalat pe pve1 și pveelite. Nu sunt clienți `netclient` ai lui pvemini.
|
||||
Singurul mecanism care le oprește e scriptul `ups-shutdown-cluster.sh`, care
|
||||
rulează pe pvemini și face SSH în ele.
|
||||
|
||||
**Consecință:** dacă scriptul nu rulează sau eșuează, secundarele NU se opresc —
|
||||
merg până se termină bateria și apoi sunt tăiate hard. NUT-ul de pe pvemini își
|
||||
oprește curat doar propriul nod, prin `SHUTDOWNCMD`.
|
||||
|
||||
> ### ⚠️ De verificat fizic: sunt toate trei nodurile în UPS?
|
||||
>
|
||||
> `ups.load` era **8%** la ultima verificare, ceea ce e puțin pentru trei
|
||||
> servere. Dacă pve1 și pveelite nu sunt alimentate din UPS, ele mor instantaneu
|
||||
> la pană, SSH-ul din script eșuează, iar toată orchestrarea e decorativă.
|
||||
> **Niciun script nu poate verifica asta — trebuie urmărite cablurile.**
|
||||
|
||||
### Lanțul de permisiuni (esențial)
|
||||
|
||||
`upsmon` face fork în două procese: unul root și unul neprivilegiat, ca user
|
||||
`nut`. **`NOTIFYCMD` (deci `upssched`, deci scriptul de shutdown) rulează ca
|
||||
`nut`**, care are shell `nologin`, home `/var/lib/nut` și **nicio cheie SSH**.
|
||||
|
||||
De aceea `upssched-cmd` invocă scriptul prin `sudo`, iar
|
||||
`/etc/sudoers.d/nut-shutdown` îi dă userului `nut` dreptul de a-l rula ca root.
|
||||
|
||||
Fără asta, scriptul nu poate face nimic util: `pct`, `qm`, `ha-manager` și
|
||||
`ssh` eșuează toate. **Exact asta s-a întâmplat între 2025-10-06 și 2026-08-27** —
|
||||
scriptul trimitea emailuri (singurul lucru pentru care `nut` avea sudo) și atât.
|
||||
`/var/log/ups-shutdown.log` nu conținea nicio oprire reușită.
|
||||
|
||||
### Testare
|
||||
|
||||
```bash
|
||||
# rulare în gol a procedurii reale, ca root
|
||||
ssh root@10.0.20.201 /usr/local/bin/ups-shutdown-test.sh
|
||||
|
||||
# testarea lanțului complet de permisiuni, exact ca la o pană reală
|
||||
ssh root@10.0.20.201 "sudo -u nut sudo /usr/local/bin/ups-shutdown-cluster.sh --dry-run --force"
|
||||
```
|
||||
|
||||
A doua comandă e cea care contează: dacă ea merge, merge și la o pană adevărată.
|
||||
|
||||
### Monitorizare
|
||||
- **VM 201 (Windows 11)** - Monitorizare vizuală via WinNUT
|
||||
|
||||
Reference in New Issue
Block a user