LINUX:Pacemaker - Détail sur le script de configuration LUA
→ retour à la Configuration des services Lsyncd
But
Pour les plus curieux, nous donnons quelques détails sur ce programme écrit en LUA. Nous allons avancer par étapes.
Script de base
La configuration la plus simple est la suivante pour le répertoire "/site/cluster5" vers la machine "sv2.home.dom":
sync{ default.rsync, source="/site/cluster5", target="sv2.home.dom::cluster5/", }
Il suffit de dupliquer trois fois en plus ces lignes en adaptant le nom de machine pour atteindre les trois autres machines.
C'est l'option "default.rsync" qui définit l'utilisation du service Rsyncd distant. Le processus "rsync" synchronisera le répertoire local "source" vers le répertoire distant "target".
Ajout de paramètres
On y ajoute quelques paramètres pour être plus précis:
settings { logfile = "/var/log/lsyncd/lsyncd5.log", statusFile = "/var/log/lsyncd/lsyncd5.status", statusInterval = 10 } sync{ default.rsync, source="/site/cluster5", target="sv2.home.dom::cluster5/", rsync = { perms=true, owner=true, group=true } }
La section "settings" définit des fichiers journal et d'état spéciaux qui ne seront mis à jour que toutes les 10s.
La section "rsync" ajoute quelques options au processus "rsync"; on tient compte des privilèges du fichier ou répertoire d'origine (droits, propriétaire et groupe) nécessaire pour que le service Httpd lancé sous la responsabilité de l'utilisateur "apache" aie l'accès à ces fichiers.
Bouclage
Au lieu de dupliquer cette configuration, on va effectuer un bouclage. On crée une matrice nommée "machines" reprenant le nom des quatre machines du cluster et on boucle sous le nom de variable "machine". Pour remplir la matrice "machines", on lit le fichier "hosts.txt".
settings { logfile = "/var/log/lsyncd/lsyncd5.log", statusFile = "/var/log/lsyncd/lsyncd5.status", statusInterval = 10 } nomfichierhost="/etc/lsyncd.d/hosts.txt" fichierhost=io.open(nomfichierhost,"r") machines = {} i=0 for ligne in fichierhost:lines() do i=i+1 machines[i] = ligne end fichierhost:close() for _, machine in ipairs( machines ) do sync{ default.rsync, source="/site/cluster5", target=machine.."::cluster5/", rsync = { perms=true, owner=true, group=true } } end
Machine locale
Il est inutile de recopier le répertoire source sur lui-même en ciblant la machine locale.
socketbase = require("socket") machinelocal = socketbase.dns.gethostname() settings { logfile = "/var/log/lsyncd/lsyncd5.log", statusFile = "/var/log/lsyncd/lsyncd5.status", statusInterval = 10 } nomfichierhost="/etc/lsyncd.d/hosts.txt" fichierhost=io.open(nomfichierhost,"r") machines = {} i=0 for ligne in fichierhost:lines() do i=i+1 machines[i] = ligne end fichierhost:close() for _, machine in ipairs( machines ) do if not (machine == machinelocal) then sync{ default.rsync, source="/site/cluster5", target=machine.."::cluster5/", rsync = { perms=true, owner=true, group=true } } end end
Il faut donc récupérer le nom de la machine locale dans la variable "machinelocal" en utilisant la fonction "socket.dns.gethostname()". Mais cette fonction a besoin qu'on charge le module "socket" ("require("socket")") et d'en créer une instance que l'on place dans la variable "socketbase". Armé de cette information, il suffit d'effectuer un test d'exclusion.
Connexions au service Rsyncd distant
Maintenant nous allons tester si le service Rsyncd distant est joignable car si la machine ou le service Rsyncd distants sont arrêtés, le transfert ne pourra pas se faire et Lsyncd entrera en état d'erreur. Il faut donc éviter ce cas.
socketbase = require("socket") sockettcp = socketbase.tcp() sockettcp:settimeout(3) port = 873 settings { logfile = "/var/log/lsyncd/lsyncd5.log", statusFile = "/var/log/lsyncd/lsyncd5.status", statusInterval = 10 } nomfichierhost="/etc/lsyncd.d/hosts.txt" fichierhost=io.open(nomfichierhost,"r") machines = {} i=0 for ligne in fichierhost:lines() do i=i+1 machines[i] = ligne end fichierhost:close() machinelocal = socketbase.dns.gethostname() for _, machine in ipairs( machines ) do if not (machine == machinelocal) then local SocketRsync, errRsync = sockettcp:connect(machine, port) if SocketRsync then sync{ default.rsync, source="/site/cluster5", target=machine.."::cluster5/", rsync = { perms=true, owner=true, group=true } } log("Normal", machine..": Connected to Rsyncd") sockettcp:close() else log("Error", machine..": Cannot connect to Rsyncd: ", errRsync) end end end
Il nous faut pour cela effectuer une connexion réseau TCP ("socket.tcp()") vers Rsyncd ("port = 873") de la machine distante (variable "machine") avec la fonction "socket:connect(machine, port)" et test le résultat. Pour que le temps d'attente en cas de non connexion ne soit pas trop important, on le limite à 3s ("socket:settimeout(3)"). On utilise encore le module "socket". La variable "sockettcp" accueille l'instance "socket-tcp".
En cas de non connexion, on émet un message d'erreur qui viendra d'ajouter au fichier "/var/log/messages" grâce à la fonction "log" dans l'autre cas, on envoie un message d'information d'état normal qui ira dans le même fichier. En cas de connexion, pour finir, on doit clôturer le canal ouvert ("socket:close()").
Fichier texte d'état
Eventuellement on peut créer un fichier texte qui reprend l'état des différents essais de connexions. Ce fichier servira plus tard à un script externe qui corrigera les changements d'état en cours d'exécution.
socketbase = require("socket") sockettcp = socketbase.tcp() sockettcp:settimeout(3) port = 873 nomfichier="/var/log/lsyncd/lsyncd5.txt" fichier=io.open(nomfichier,"w") settings { logfile = "/var/log/lsyncd/lsyncd5.log", statusFile = "/var/log/lsyncd/lsyncd5.status", statusInterval = 10 } nomfichierhost="/etc/lsyncd.d/hosts.txt" fichierhost=io.open(nomfichierhost,"r") machines = {} i=0 for ligne in fichierhost:lines() do i=i+1 machines[i] = ligne end fichierhost:close() machinelocal = socketbase.dns.gethostname() for _, machine in ipairs( machines ) do if not (machine == machinelocal) then local SocketRsync, errRsync = sockettcp:connect(machine, port) if SocketRsync then sync{ default.rsync, source="/site/cluster5", target=machine.."::cluster5/", rsync = { perms=true, owner=true, group=true } } log("Normal", machine..": Connected to Rsyncd") fichier:write("OK "..machine.."\n") sockettcp:close() else log("Error", machine..": Cannot connect to Rsyncd: ", errRsync) fichier:write("KO "..machine.."\n") end end end fichier:close()
Avec la fonction "io.open", on ouvre un fichier en écriture ("w"). On écrit dedans le nom de la machine précédé de son état ("OK" s'il y a eu connexion sinon "KO") avec la fonction "write". Au final, on ferme le fichier avec la fonction "close".
→ retour à la Configuration des services Lsyncd