1. Considérations générales sur les UPS

1.1. Définition et rôles

UPS signifie Uninterruptable Power System. Comme son nom l'indique, son rôle principal consiste à fournir une alimentation électrique continue quoiqu'il arrive. Plus précisément un UPS a 2 rôles :

  • batterie de secours en cas de panne de courant : attention les batteries ne permettent que quelques dizaines de minutes d'autonomie (dépend de la charge à fournir). Un UPS a donc pour principal but de pouvoir éteindre proprement les machines qui lui sont connectées dès qu'une panne de courant survient, et d'éviter ainsi toute perte de données dûe à un crash disque provoqué par une interruption brutale d'alimentation.
  • régulateur de tension : un bon UPS fournit un signal parfaitement sinusoïdal (stabilité de l'alimentation) et protège contre tous types de parasites, variations de tension et surcharges dûes à la foudre, par exemple.

Outre son rôle purement électrique, l'UPS doit aussi communiquer avec l'ordinateur pour lui signaler son état et lui dire qu'il doit s'arrêter. Cette communication passe par un câble série RS-232, USB (de plus en plus fréquent), ou même par SNMP pour le haut de gamme. C'est cet aspect-là qu'il faut configurer et qui fait l'objet de cet article.

1.2. Types d'UPS

(souvent référencé sous le terme "topologie d'UPS")
Il en existe 3 :

  • UPS offline : l'entrée de gamme, n'offre quasiment aucune régulation de tension, a pour seul but d'offrir une batterie de secours. Transmet intégralement toute perturbation électrique aux machines... A éviter autant que faire se peut, surtout pour des serveurs !
  • UPS "line interactive" : milieu de gamme, offre une relative protection contre les surcharges avec un certain nombres de filtres électroniques. Si la foudre frappe violemment, la protection risque de ne pas être suffisante. Cependant dans la majeure partie des cas ce type d'UPS est satisfaisant.
  • UPS online : le sommet de la technologie :) Regénère entièrement le signal (transformation alternatif --> continu --> alternatif), protection totale contre les surtensions. En cas de foudre c'est l'UPS qui encaissera (au point qu'il peut se détruire lui-même), mais les machines n'auront rien : la protection aura donc parfaitement rempli son devoir.

1.3. Comment choisir un UPS ?

Pour chacun des 3 types d'appareils, il existe plusieurs modèles, selon la puissance fournie, en VA (volt-ampère). Il est assez difficile d'estimer la puissance appropriée, mais il faut savoir qu'il ne faut pas additionner la puissance brute des alimentations de PC (en simplifiant W = VA).

Par exemple un onduleur de 800 VA peut parfaitement protéger 3 PC normaux (sans raccorder les 3 écrans cependant) pendant 25 minutes (testé avec succès sur un UPS APC Back-UPS RS800). En effet un PC ne consomme jamais toute la puissance que son alimentation est capable de fournir. Naturellement, moins vous avez d'appareils connectés (graveur, lecteurs cd/dvd, disques etc.), moins de puissance vous consommerez.

Pour plus de détails, reportez-vous au site suivant qui reprend pas mal de conseils : www.onduleurs.fr
Calcul de puissance

2. Application pratique

Notre cas de figure est une architecture de 3 serveurs : 2 linux Debian et 1 Windows 2000, tous 3 reliés à un switch Ethernet. L'UPS ne pouvant communiquer qu'avec une seule machine, on choisit un des serveurs linux comme étant le "maître", les 2 autres serveurs devenant les "esclaves". Les 3 serveurs devant échanger des données surtout lors d'une panne de courant, il est impératif que leurs alimentations soient toutes 3 branchées sur l'UPS, de même que le switch réseau, sinon toute communication sera impossible !

Dans notre cas, je dispose d'un UPS APC Back-UPS RS de 800 VA, topologie Line Interactive.
L'UPS ayant des entrées tripôles type "PC", il est impossible d'y raccorder une fiche électrique européenne normale. Dès lors, pour y connecter le switch le mieux est de se servir d'un multi-prise spécial tel que le MGE Pulsar CL5 qui présente l'avantage d'avoir un connecteur d'alimentation tripôle sous la forme "PC" standard. Il suffit dès lors de le relier à l'UPS par un câble d'alimentation mâle-femelle qu'on trouve dans tous les magasins d'informatique.
Voici le schéma de l'installation :

Image non disponible

But à atteindre : quand une coupure de courant survient (éventuellement après un certain délai si la panne n'est qu'une micro-coupure de quelques secondes), la machine maître doit envoyer un signal aux autres serveurs via le réseau pour leur commander une extinction automatique, puis le serveur principal doit s'éteindre à son tour.

3. Installation sous linux

3.1. Préparation du système

Il faut savoir que le périphérique USB à gérer est de type "HID" (je l'ai découvert en voyant que le nom du driver à employer est "hidups"). Il faut donc impérativement que le noyau supporte ce type de matériel. Ayant une Debian installée encore avec le noyau par défaut 2.4.18-bf24, j'en ai profité pour passer au dernier kernel stable : 2.6.8.1 au moment où j'ai réalisé l'opération. J'ai intégré la gestion de l'USB en dur dans le noyau, et les périphériques USB de type "HID" en module. Il faudra alors ajouter le module "usbhid" au fichier /etc/modules pour qu'il soit chargé automatiquement au prochain démarrage (sinon taper "modprobe usbhid" pour le charger au moment voulu)

Au démarrage de l'ordinateur vous devriez voir un message montrant que votre UPS est détecté :

 
Sélectionnez
usbcore: registered new driver hiddev
hiddev96: USB HID v1.10 Device [American Power Conversion Back-UPS BR  800 FW:9.o2 .I USB FW:o2] on usb-0000:00:10.0-1
usbcore: registered new driver usbhid
drivers/usb/input/hid-core.c: v2.0:USB HID core driver

Ok, l'UPS est détecté correctement, mais maintenant il faut encore créer son pseudo-fichier dans /dev ! Eh non cela n'est pas fait automatiquement... Heureusement, l'aide dans le menu de configuration du noyau sur le module usbhid mentione un fichier /usr/src/linux/Documentation/usb/hiddev.txt dans lequel est indiquée la commande magique à taper :

 
Sélectionnez
mknod /dev/usb/hiddev0 c 180 96	

Cela crée un périphérique en mode caractère ; en effet les données échangées entre l'ups et l'ordinateur sont des codes alphanumériques lisibles par tous.

3.2. Installation de NUT

J'ai choisi d'utiliser le driver libre NUT (pour Network UPS Tools), dont voici le site vitrine : http://www.networkupstools.org.
C'est un logiciel libre largement soutenu par le célèbre fabricant d'UPS français Merlin-Gerin (MGE) qui y contribue beaucoup, dont les 2 atouts principaux sont :

  • universalité : fonctionne avec la plupart des UPS du marché (liste ici), quelque soit leur connectique (liaison série, USB... ).
  • client/serveur : un serveur tourne sur la machine à laquelle est branché l'UPS, ce qui permet à tout le réseau de connaître à tout moment l'état du système, et éventuellement d'envisager les actions nécessaires le cas échéant (batterie faible >> extinction propre).

De plus il existe des packages intégrés dans la plupart des distributions classiques (formats RPM et Debian), ainsi qu'un client Windows. Ce logiciel dispose donc de tout ce qu'il faut pour plaire !

Sous Debian l'installation est extrêmement aisée, comme d'habitude. Nous aurons besoin, en plus du package de base, du package spécial pour l'usb (nut-usb) :

 
Sélectionnez
apt-get install nut nut-usb

Attention : il est indispensable d'utiliser des sources "testing" (ou "unstable") dans votre fichier sources.list pour avoir des versions récentes (ceux de la version "stable" sont obsolètes comme d'habitude), et d'autre part le package nut-usb est relativement récent et donc non encore intégré dans la branche "stable" officielle de la distribution.
L'installation se déroule sans problème, mais l'aspect configuration est plus délicat : aucun fichier de configuration dans /etc/nut, aucun assistant ou même message d'information : il est impératif de lire la documentation dans /usr/share/doc/nut, ou de chercher sur le net... Heureusement ce tutoriel est là pour vous simplifier la tâche ;-)

NB : si vous possédez une autre distribution que Debian, vous aurez probablement un package spécifique pour celle-ci (en RPM par exemple), sinon vous pouvez installer NUT en compilant ses sources. Il y aura sans doute quelques différences au niveau de la localisation des fichiers de configuration.

3.3. Configuration de NUT sur le serveur maître

NUT est composé de 2 démons : upsd et upsmon. Le premier (upsd) est le démon qui surveille l'UPS et fournit les informations à upsmon. Le second (upsmon) est le programme réseau qui se connecte au serveur (soit lui-même si on est sur la machine maître, soit distant si on est sur une machine esclave) pour connaître l'état de l'UPS et lancer les actions adéquates sur le système.

Lors du démarrage de NUT par le script Init-V /etc/init.d/nut start il faut lui préciser quel(s) démon(s) démarrer, ce qui se fait via le fichier /etc/default/nut :

 
Sélectionnez
# start upsd
START_UPSD=yes

# start upsmon
START_UPSMON=yes

Dans le cas du master, on démarre les 2.

Remarque : les fichiers de configuration que nous allons voir maintenant ont tous été créés par moi-même après l'installation, les commentaires en anglais sont les miens.

Il faut ensuite spécifier comment communiquer avec l'UPS, donc choisir le driver et le port adéquats, ce qui fait dans le fichier /etc/nut/ups.conf (à créer) :

 
Sélectionnez
# define the ups driver and the port where it's connected
[myups]
driver=hidups
port=/dev/usb/hiddev0

Entre crochets on définit le nom qu'on veut donner à notre UPS, ici j'ai choisi tout simplement "myups". Ceci permettra de l'identifier plus tard, car NUT peut gérer plusieurs UPS.
On précise ensuite le pilote qui est "hidups" pour les UPS USB (n'importe quel modèle et marque supportés) et le périphérique auquel il est connecté : /dev/usb/hiddev0 créé précédemment.
A noter que si on veut utiliser un UPS série, il suffit de changer le port /dev/ttyS0 par exemple) et choisir le driver correspondant au modèle de l'onduleur (voir man ups.conf et man nutupsdrv).

On va maintenant configurer le démon réseau au niveau des accès via le fichier /etc/nut/upsd.conf (à créer) :

 
Sélectionnez
# access-lists:
ACL all 0.0.0.0/0
ACL localhost 127.0.0.1/32
ACL lan 192.168.1.0/24

# rights:
ACCEPT localhost lan
REJECT all

Attention la syntaxe présentée est celle introduite à partir de la version 2.0.x. Si vous avez une version plus ancienne (1.4.x) vous devrez utiliser la syntaxe suivante pour les droits d'accès :

 
Sélectionnez
# rights:
ACCESS grant monitor localhost
ACCESS grant monitor lan
ACCESS deny all all

Ce fichier définit les access lists (ACL) et les droits de chacune. Ici on autorise les accès depuis le poste local et le réseau local.

Nous définissons alors les utilisateurs et leur mot de passe pour pouvoir se connecter au démon par le fichier /etc/nut/upsd.users (à créer) :

 
Sélectionnez
# define the user rights according to the ACL in upsd.conf
[user]
password = mypassword
allowfrom = localhost lan
upsmon master

Ici on définit les utilisateurs et mot de passe et leurs droits. Inutile de se compliquer la vie, un seul utilisateur est créé ici ayant tous les pouvoirs. "upsmon master" dit que cet utilisateur a le droit de se connecter sur le serveur maître pour contrôler l'UPS.

Reste maintenant à paramétrer la surveillance de l'UPS et les actions à exécuter dans /etc/nut/upsmon.conf (à créer) :

 
Sélectionnez
# define the ups to monitor and the permissions
MONITOR myups@localhost 1 user mypassword master

# define the shutdown comand
SHUTDOWNCMD "/sbin/shutdown -h now"

On définit l'UPS à surveiller avec les login/password et on spécifie qu'on est ici en mode "master". Il est obligatoire de renseigner la commande exacte à exécuter pour éteindre proprement l'ordinateur, dans le paramètre "SHUTDOWNCMD".

Dernière chose à faire : lancer NUT par /etc/init.d/nut start
Et voilà ! L'UPS est ainsi configuré et fonctionnel. Pour s'en assurer, un coup d'oeil dans /var/log/daemon.log (car le programme n'est pas fort bavard à l'écran) :

 
Sélectionnez
Sep 23 18:47:52 srvtest hidups[712]: Startup successful
Sep 23 18:47:52 srvtest upsd[713]: Connected to UPS [myups]: hidups-hiddev0
Sep 23 18:47:52 srvtest upsd[714]: Startup successful
Sep 23 18:47:52 srvtest upsmon[716]: Startup successful
Sep 23 18:47:52 srvtest upsd[714]: Connection from 127.0.0.1
Sep 23 18:47:52 srvtest upsd[714]: Client user@127.0.0.1 logged into UPS [myups]

On voit ici en première ligne que le driver est correctement chargé, ce qu'on peut vérifier avec la commande suivante :

 
Sélectionnez
dmesg | grep hid

qui va afficher les messages de boot du noyau concernant le pilote "hid", ce qui nous donne comme résultat :

 
Sélectionnez
usbcore: registered new driver hiddev
hiddev96: USB HID v1.10 Device [American Power Conversion Back-UPS BR  800 FW:9.o2 .I USB FW:o2] on usb-0000:00:10.0-1
usbcore: registered new driver usbhid
drivers/usb/input/hid-core.c: v2.0:USB HID core driver

Notre UPS est bel et bien détecté :-)

Les lignes suivantes de daemon.log indiquent que les lancements du démon upsd et du monitoring réseau upsmon ont réussi également.

Une commande utile : upsc myups@localhost indique l'état courant de l'UPS spécifié :

 
Sélectionnez
battery.charge: 100
battery.chemistry: PbAc
battery.runtime: 1290
battery.voltage: 27.8
driver.name: hidups
driver.parameter.port: /dev/usb/hiddev0
driver.version: 2.0.1
ups.delay.shutdown: -1
ups.delay.start: 0
ups.load: 380
ups.mfr: American Power Conversion
ups.model: Back-UPS BR  800 FW:9.o2 .I USB FW:o2
ups.serial: QB0406247589
ups.status: OL

Le premier flag "battery.charge" indique la charge de la batterie, ici 100%. Le dernier flag "ups.status" indique ici "OL" ce qui signifie "on line", donc situation normale, tout est alimenté via le secteur. En cas de panne de courant l'alimentation se fait via la batterie de secours, il serait indiqué "OB" ("On Battery"). "ups.load" indique quant à lui la charge totale connectée à l'UPS, en VA (ici 380 VA).

Maintenant comment va réagir le système en cas de coupure de courant ? Le test peut être fait très facilement en débranchant la prise d'alimentation de l'UPS. Dans un premier temps il ne se passe strictement rien, l'UPS se contente de fournir du courant via la batterie de réserve, le PC continue à tourner. Par défaut, dans la configuration standard qu'on a faite, NUT attend que la batterie soit presque vide (ce qu'il détecte via l'état de l'UPS) pour déclencher l'extinction du système, ce qui survient immanquablement au bout d'un certain laps de temps. Le système exécute alors automatiquement un shutdown -h now et on voit tous les process s'éteindre les uns après les autres jusqu'à l'arrêt complet de la machine. L'UPS a rempli son rôle :)
Il se peut que la machine mette 5 secondes maximum avant de s'éteindre, ceci est dû à l'intervalle avec lequel le démon surveille l'état de l'UPS, qui est fixé à 5 secondes par défaut.

Pour éviter d'avoir à attendre et vider la batterie pour les tests, il existe une commande à taper sur le serveur :

 
Sélectionnez
upsmon -c fsd

Cette commande envoit directement le signal "force shutdown" qui sera propagé à tous les esclaves et provoquera l'extinction de toutes les machines concernées, master y compris.

3.4. Configuration de NUT sur le serveur esclave

La configuration côté slave est beaucoup moins fastidieuse. Déjà, il ne faut installer que le package nut, nut-usb n'est pas nécessaire ici, puisque nous serons informé de l'état de l'UPS par le réseau.
Dans /etc/default/nut :

 
Sélectionnez
# start upsd
START_UPSD=no

# start upsmon
START_UPSMON=yes

On ne démarre que le démon upsmon ici, upsd n'est nécessaire que sur la machine branchée physiquement au câble USB de l'UPS (c'est-à-dire le master).

Un seul fichier de configuration est nécessaire : /etc/nut/upsmon.conf (à créer)

 
Sélectionnez
# define the ups to monitor and the permissions
MONITOR myups@192.168.1.5 1 user mypassword slave

# define the shutdown comand
SHUTDOWNCMD "/sbin/shutdown -h now"

On indique ici l'adresse IP du serveur et le mot "slave" à la place de "master". Le reste est identique au fichier de configuration vu précédemment dans le cas du master.

Il suffit de démarrer NUT par /etc/init.d/nut start et taper upsc 192.168.1.5 (ip du serveur) pour tester et on obtient à l'écran l'état de l'UPS !
Et si on simule une panne de courant les 2 ordinateurs s'éteindront maintenant automatiquement, le serveur ayant donné le signal à tous les esclaves qui lui sont connectés.

4. Installation sous Windows

Bien que tous les UPS soient fournis avec un logiciel de gestion pour Windows, nous devons ici bien entendu impérativement utiliser le portage de NUT pour Windows pour pouvoir communiquer avec le serveur NUT maître sous linux. La version de NUT pour Windows ne reprend pas 100% de l'application, mais uniquement la partie cliente, c'est-à-dire le monitoring réseau. Une machine Windows ne pourra donc jamais être master avec NUT, ce qui dans notre cas n'est pas un problème puisque nous avons un serveur linux jouant déjà ce rôle.
Nous installons donc WinNUT, ce qui ne pose aucun problème.

Après quoi, démarrons le programme de configuration dans le menu Démarrer --> Programmes --> WinNUT --> WinNUT Configuration Tool :

Image non disponible

Quelques options à régler :

  • cocher "install as service"
  • cocher "automatic setup", ces 2 options assurant que WinNUT sera exécuté automatiquement à chaque démarrage de Windows, en tant que service système
  • vérifier que "use timed shutdown" est décoché
  • shutdown method : forced

Il ne nous reste plus qu'à paramétrer le fichier de configuration upsmon.conf, comme sous linux. Ici vous pouvez cliquer sur le lien "edit" en face du nom du fichier, et choisir un éditeur texte pour l'ouvrir (bloc-notes fera très bien l'affaire).
Le fichier est très complet, toutes les options sont déjà réglées à leur valeur par défaut et le fichier est bien commenté ! Ici seule l'option "MONITOR" devra être réglée :

 
Sélectionnez
MONITOR myups@192.168.1.5 1 user mypassword slave

Enregistrez le fichier et quittez l'éditeur. De retour dans l'outil de configuration de WinNUT, cliquez sur le bouton "Apply and start WinNUT".

C'est tout ! Votre machine Windows est opérationnelle et surveille l'état de l'UPS grâce au démon linux. Pour vous en assurer, faites un test de shutdown programmé en simulant une panne de courant sur le serveur linux :

 
Sélectionnez
upsmon -c fsd

5 secondes plus tard maximum, la machine windows commence à se fermer proprement, et le serveur linux fait de même.

5. Configuration avancée

5.1. Evénements et actions personnalisées

NUT nous laisse la possibilité de paramétrer des actions personnalisées en fonction de certains états de l'UPS. Ceci est utile par exemple pour délencher un shutdown propre immédiatement, sans attendre que la batterie soit presque vide, mais aussi pour envoyer un mail d'avertissement à l'administrateur.
Pour cela, nous devons reprendre le fichier /etc/nut/upsmon.conf et le compléter par quelques options :

 
Sélectionnez
# define the ups to monitor and the permissions
MONITOR myups@localhost 1 user mypassword master

# define the shutdown comand
SHUTDOWNCMD "/sbin/shutdown -h now"

# specify the script to execute on event
NOTIFYCMD /root/upsalert
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC

Le paramètre "NOTIFYCMD" spécifie un fichier exécutable que l'utilisateur doit créer lui-même (ici un script shell : /root/upsalert) qui sera lancé lorsqu'un événement se produira, tandis que le paramètre "NOTIFYFLAG" définit quel(s) état(s) de l'UPS déclencheront une action personnalisée. Ici il s'agit de l'état "ONBATT" qui correspond au moment où l'UPS se met sur batterie. Les commandes suivantes indiquent les actions à exécuter : SYSLOG écrit une trace de l'événement dans les logs système, WALL envoit un message d'alerte à tous les utilisateurs connectés, et EXEC lance l'exécution du programme spécifié plus haut.

Le code que nous désirons voir exécuter est le suivant (/root/upsalert) :

 
Sélectionnez
#!/bin/sh

# send mail to admin
echo "Power is lost, UPS is shutting down servers." | mail -s "UPS ALERT" admin@myserver.com

# write to a specific log file
date=$(date +"%F %T")
echo "$date >> UPS ALERT, shutting down in a few seconds..." >> /var/log/ups.log

# actually send the shutdown signal to master (will broadcast to all slaves)
/sbin/upsmon -c fsd

N'oubliez pas de donner la permission exécutable au script (chmod 755).
A noter que si on veut gérer plusieurs événements, un seul script est autorisé, et il faudra donc un moyen pour détecter le type d'événement à traiter. Pour cela NUT définit un paramètre qui est envoyé au script ($*). Pour plus de détails, je vous renvoie à la documentation officielle, n'ayant pas jugé utile d'employer cette option dans mon cas de figure.

Pour tester notre script, nous ne pouvons évidemment plus simuler une panne par la commande upsmon -c fsd, puisque celle-ci ne change pas l'état de l'UPS, nous n'avons donc d'autre choix que de déconnecter la fiche électrique. Il s'en suit évidemment un shutdown immédiat qui correspond à la dernière instruction du script, et au redémarrage de la machine nous pourrons constater qu'effectivement le mail a bien été envoyé, et qu'il y a une trace dans /var/log/ups.log.

5.2. Actions différées

C'est bien de pouvoir éteindre le serveur avant la décharge de la batterie... mais le faire immédiatement c'est un peu trop tôt ! Idéalement il faudrait réagir seulement si la panne se prolonge pendant un certain laps de temps, par exemple 20 minutes... Heureusement, NUT autorise cette possibilité.
Nous devons encore une fois reprendre le fichier de configuration /etc/nut/upsmon.conf :

 
Sélectionnez
# define the ups to monitor and the permissions
MONITOR myups@localhost 1 user mypassword master

# define the shutdown comand
SHUTDOWNCMD "/sbin/shutdown -h now"

# launch the upssched program to execute script with delay
NOTIFYCMD /sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC

Cette fois, au lieu d'indiquer notre script à exécuter, on met le programme "upssched". C'est un utilitaire qui a été ajouté au package de NUT pour gérer l'exécution de scripts en différé. Attention aux flags NOTIFY ! Il est impératif d'ajouter l'événement ONLINE, pour annuler le compte à rebours dès que le courant revient et prévenir le déclenchement du script qui aurait provoqué une extinction des machines alors que ce n'est plus nécessaire (expérience vécue... ).
Pour paramétrer le timing, il faut ajouter un fichier de configuration spécifique /etc/nut/upssched.conf :

 
Sélectionnez
# the script to be executed
CMDSCRIPT /root/upsalert

# mandatory fields that must be set before AT commands
PIPEFN /var/run/upssched/upssched.pipe
LOCKFN /var/run/upssched/upssched.lock

# the timers, here 30 sec after the ONBATT (ups on battery) event
AT ONBATT * START-TIMER onbatt 30

# cancel the countdown is power is back
AT ONLINE * CANCEL-TIMER onbatt

CMDSCRIPT indique le script à exécuter, le même que tout à l'heure.
Les 2 paramètres suivants sont extrêmement importants, sans quoi ça ne marchera jamais. Durant son exécution, upssched a absolument besoin d'écrire temporairement quelques données sur fichier, mais il faut lui spécifier où il peut le faire et régler les permissions appropriées. Suivant les conseils de la documentation, on va lui créer un répertoire dédié /var/run/upssched qu'on devra léguer au groupe "nut" (chown nut.nut pour l'utilisateur et le groupe, pour être sûr) et lui donner l'accès en écriture (chmod 775). Lors de l'installation de NUT, Debian a créé un utilisateur "nut" membre du groupe "nut" : c'est sous cette idendité que sera exécuté upssched.
On indique ensuite le timing sur l'événement ONBATT, * désigne tous les UPS géré par NUT, START-TIMER pour dire que le compte à rebours commence, "onbatt" désigne ici le nom du timer (car il peut y avoir plusieurs événéments à des timings différents, donc il faut un nom pour les différencier), et enfin le chiffre 30 est le timeout en secondes, c'est-à-dire le délai au bout duquel le script sera exécuté.
Mais une exécution différée amène un autre problème : que faire s'il y a un changement d'état pendant le délai ? C'est l'objet de la dernière ligne de configuration qui dit d'annuler le compte à rebours (CANCEL-TIMER onbatt) si l'événement ONLINE survient, c'est-à-dire si le courant est revenu entretemps.

Testons cela ! A nouveau pas moyen de faire autrement que de débrancher l'UPS, mais dès que vous l'avez fait scrutez votre montre : dans 30 secondes environ (suivant l'intervalle de monitoring du démon) l'ordinateur va s'éteindre.
Preuve dans les logs système qui nous indique clairement et à la seconde près le suivi des opérations :

 
Sélectionnez
Sep 23 18:20:28 srvtest upsmon[1270]: UPS myups@localhost on battery
Sep 23 18:20:28 srvtest upssched[1276]: Timer daemon started
Sep 23 18:20:29 srvtest upssched[1276]: New timer: onbatt (30 seconds)
Sep 23 18:20:59 srvtest upssched[1276]: Event: onbatt
Sep 23 18:20:59 srvtest upsmon[1270]: Signal 10: User requested FSD
Sep 23 18:20:59 srvtest upsd[1267]: Setting FSD on UPS [myups]
Sep 23 18:21:08 srvtest upsd[1267]: Host 192.168.1.4 disconnected (read failure)
Sep 23 18:21:08 srvtest upsmon[1270]: Executing automatic power-fail shutdown
Sep 23 18:21:08 srvtest upsmon[1270]: Auto logout and shutdown proceeding
Sep 23 18:21:14 srvtest upssched[1276]: Timer queue empty, exiting
Sep 23 18:21:14 srvtest upsd[1267]: Host 127.0.0.1 disconnected (read failure)
Sep 23 18:21:20 srvtest upsd[1267]: Signal 15: exiting
Sep 23 18:21:20 srvtest hidups[1265]: Signal 15: exiting

A 18:20:29 le compte à rebours commence, et à 18:20:59 précisément le timer déclenche l'action prévue. :) Evidemment en utilisation réelle vous pouvez augmenter ce délai ! 15 à 20 minutes sont très bien.

5.3. Hacking

Ce tutoriel aurait pu s'arrêter là... Mais je voulais vous faire part de l'expérience que j'ai faite avant de découvrir toutes les possibilités de NUT. En fait je cherchais à déclencher un shutdown différé sans attendre que les batteries de l'UPS soient vides. Je pensais que cette option devait se régler dans les paramètres de driver, puis j'ai abandonné et j'ai décidé d'étudier le protocole réseau d'upsmon, qui est décrit dans la documentation. On y voit que les communications se font sur le port TCP 3493 et on trouve notamment la commande suivante : FSD upsname où il faut donc remplacer "upsname" par le nom de l'UPS tel qu'il a été configuré dans upsmon.conf. Grâce au fabuleux programme netcat qui permet d'envoyer n'importe quelles données sur n'importe quel port réseau sur une adresse IP au choix, j'envois cette commande sur l'adresse IP de mon serveur master. Malheureusement ça ne marche pas du premier coup : je reçois un message d'erreur comme quoi je dois d'abord définir le nom d'utilisateur. En gros il ne me reconnaît pas car je ne suis pas loggé. Une lecture plus attentive de la doc me révèle les commandes à utiliser, que j'inscris dans un fichier texte (que je choisis d'appeler ups.cmd) :

 
Sélectionnez
USERNAME myuser
PASSWORD mypassword
FSD myups
LOGOUT

J'envois ensuite ces instructions au démon upsmon du serveur par la commande suivante tapée en console (shell) :

 
Sélectionnez
cat ups.cmd | nc 192.168.1.5 3493

Et je suis très heureux de constater que ça marche : NUT déclenche un shutdown immédiatement et éteint toutes mes machines ! En fait je viens d'exécuter la commande upsmon -c fsd sans la connaître ! :)

Il est également possible de recevoir la liste des variables d'état de l'UPS, de la même manière que ce que produit la commande upsc myups@localhost, ce qui montre de manière très simple comment réaliser un client NUT. Pour cela, mettez les commandes suivantes dans ups.cmd :

 
Sélectionnez
USERNAME myuser
PASSWORD mypassword
LIST VAR myups
LOGOUT

On obtient le résultat suivant :

 
Sélectionnez
ovh@server:~$ cat ups.cmd | nc localhost 3493
OK
OK
BEGIN LIST VAR myups
VAR myups battery.charge "100"
VAR myups battery.chemistry "PbAc"
VAR myups battery.runtime "1290"
VAR myups battery.voltage "27.8"
VAR myups driver.name "hidups"
VAR myups driver.parameter.port "/dev/usb/hiddev0"
VAR myups driver.version "2.0.1"
VAR myups ups.delay.shutdown "-1"
VAR myups ups.delay.start "0"
VAR myups ups.load "380"
VAR myups ups.mfr "American Power Conversion"
VAR myups ups.model "Back-UPS BR  800 FW:9.o2 .I USB FW:o2 "
VAR myups ups.serial "QB0406247589  "
VAR myups ups.status "OL"
END LIST VAR myups
OK Goodbye

Ceci démontre la puissance des logiciels open source, qui peuvent être modifiés et adaptés à volonté.

6. Affichage de l'état de l'UPS sur un site web en PHP

En utilisant la sortie du programme upsc, il est très simple d'afficher l'état de l'UPS en PHP en utilisant les fonctions system() et exec() comme le montre l'extrait de code suivant :

 
Sélectionnez
<b>Charge UPS:</b> <? system('upsc myups@192.168.1.2 | grep "ups.load" | cut -d" " -f2'); ?>VA - 
<b>Batterie UPS</b>: <? system('upsc myups@192.168.1.2 | grep "battery.charge" | cut -d" " -f2'); ?>% - 
<b>Etat UPS</b>: 
<? 
	$ups = exec('upsc myups@192.168.1.2 | grep "ups.status" | cut -d" " -f2'); 
	switch ($ups) {
		case "OL": echo '<span style="color: green">en ligne</span>'; break;
		case "OB": echo '<span style="color: red">sur batterie !</span>'; break;
		default: echo 'indéterminé';
	}
?>

7. Clients NUT

Différents clients et plugins existent pour différents systèmes; ils ont pour but de surveiller périodiquement l'état d'UPS gérés par un démon NUT afin d'en faire un affichage graphique, des logs, ou de générer des alertes. Voir une liste non exhaustive sur le site officiel.

8. Conclusion

J'espère que cet article vous sera utile lors de vos installations d'UPS. Je pense avoir couvert tous les points utiles, en tout cas l'application d'exemple que je vous ai montrée est tout à fait opérationnelle et fonctionne impeccablement. Ce tutoriel est facilement adaptable à d'autres configurations, tant software (distributions différentes, OS différent car NUT tourne aussi sur les BSD) que hardware (plusieurs UPS, réseau plus complexe... ).
N'hésitez pas à m'envoyer un commentaire constructif.

9. Remerciements

Un grand merci à Arnaud Quette, chef de développement du projet NUT, pour sa relecture attentive, ses corrections, sa gentillesse.