LINUX:Pacemaker - Détail sur le script de configuration LUA

De WIKI sur Linux (ADB)
Aller à la navigation Aller à la recherche

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