jeudi 2 avril 2015

Tester ses connaissance en informatique : Quexeo

Où apprendre l'informatique sinon sur Internet ? Les ressources sont abondantes, pas mal de blogs traitent déjà de pas mal de sujets, techniques ou pas. Je ne vais donc pas m'attarder sur un en particulier, mais plutôt sur un autre concept : les tests de connaissances.

Bien entendu, ce n'est pas l'endroit où aller pour trouver la réponse à une problématique bien précise. Par contre, pour ceux qui maitrisent plus ou moins un sujet, et qui veulent se tester et s'enrichir sur ce sujet, c'est une très bonne option.

J'utilise personnellement le site Quexeo, gratuit, et intégralement en français. Celui là car ce n'est pas uniquement un site de quiz comme on en trouve un peu partout : les questions sont issues de cas réelles d'utilisation des technologies, mais c'est surtout la dynamique qui est intéressante. Plutôt que de partir d'une leçon, puis de vérifier ses connaissance via un test, là c'est tout l'inverse ! Le test permet de se jeter dans le bain immédiatement, puis après l'avoir terminé, on repasse sur toutes les questions avec la réponse et surtout des explications bien fournies du pourquoi de la réponse.

On trouve sur le site pour l'instant trois grands sujets : Linux, les bases de données avec Postgresql et le réseau. Les questions relatives à Linux sont les plus fournies, on y retrouve tout le programme de la certification LPI 101.

Un dessin valant mieux qu'un long discours, voici quelques copies d'écran du site en question, ici sur le sujet "Gestion de processus" sur Linux.

Voici un exemple de question :


A la fin du test, un joli camembert nous présente nos résultat - oui je sais, je n'ai pas été très bon cette fois ci ;)


Et pour finir, voici un exemple d'explication sur une réponse. J'ai inversé pour cette question les signaux TERM et KILL, l'explication est limpide.


Voilà pour aujourd'hui, amusez vous bien et partagez vos scores !
L'url du site : http://www.quexeo.com

mercredi 17 avril 2013

Perl - Installation de module CPAN sans Internet

Cpan, c'est bien pratique pour installer des modules Perl. Mais sans accès à Internet, l'installation des modules devient vite fastidieuse. Il est même parfois inconcevable d'installer en automatique des packages qui tombent du net sur un serveur de prod...

Pour avoir plusieurs fois rencontré la situation et avoir téléchargé les dépendances une à une sur CPAN et les copier sur le serveur au fur et à mesure que l'installation d'un module plante, je me suis dit qu'il doit y avoir plus intelligent...
Il me semblait donc utile de pouvoir récupérer un package de toutes les dépendances de mon appli, avec toutes les dépendances des dépendances et encore les dépendances de ces dernières. CPAN est là pour ça me diriez vous... Effectivement, mais la tâche n'est pas si simple, car sur CPAN les dépendances n'apparaissent pas. Enfin, n'apparaissaient pas car depuis peu CPAN donne accès à un listing des mais qui reste fastidieux car il faut encore aller chercher chaque module à la main.

Il existe plusieurs modules qui pourraient faire l'affaire sur CPAN (CPAN::Dependency ou Module::ScanDeps pour ne citer qu'eux) mais c'est l'occasion d'aller mettre les mains dans le cambouis pour comprendre les coulisses de ce superbe repository, et de créer une archive de tous les packages d'un coup dans la foulée.

L'objectif de ce post est donc de détailler les différentes étapes pour :
  1. Récupérer récursivement toutes les dépendances d'un module
  2. Stocker quelque part toutes les archives des packages à installer
  3. Générer un listing ordonné des packages pour dérouler l'installation
Une fois ces 3 étapes terminées, il restera à déplacer le package sur le serveur cible et :
  1. comparer le listing avec les packages déjà installé
  2. installer tous les packages manquants

La solution CPAN::Mini

Une petite parenthèse sur la solution CPAN::Mini : elle ne permet pas de faire exactement ce que propose ce post, mais est beaucoup plus simple à mettre en oeuvre dans certains cas.
Le CPAN::Mini, ou minicpan, permet d'installer en local une version miniature (uniquement les dernières versions et seulement les fichiers utiles à la commande cpan) du repository CPAN. Le minicpan se comporte alors via à vis de lui même ou d'une autre machine comme un référentiel CPAN et peut ainsi permettre d'installer simplement des modules sur une machine qui n'a pas accès à Internet.

Schématiquement :
Schéma minicpan
Cette solution a l'avantage de permettre au serveur cible d'installer des modules simplement, mais n'est pas toujours réalisable : il faut pouvoir disposer d'un serveur connecté à Internet qui soit accessible du serveur cible.

Pour faire le parallèle avec le monde RedHat & dérivés, elle doit pouvoir être comparable à un référentiel de rpm interne interrogé directement par yum, et bien utilisé elle doit permettre aussi bien la mise à dispo des paquets que la gestion des versions et l'inventaire des paquets installés sur une machine.

A creuser, je ne m'attarde pas plus là dessus dans ce post, l'objectif étant également de comprendre les mécanismes basiques sous-jacent de CPAN.

Petit détour sur la structure de CPAN

Avant de commencer à naviguer programmatiquement dans CPAN, attardons nous un peu sur la structure des infos qu'on peut y trouver. N'ayant jamais utilisé CPAN au delà de cpan install mon_module, j'ai passé pas mal de temps à comprendre cette structure, somme toute assez simple.

Modules & distributions

La recherche sur www.cpan.org se fait via module : par exemple XML::Twig, CPAN::Distribution ou DBD::Oracle.
Les modules sont mis à disposition dans des distributions qui contiennent un ou plusieurs modules : DBD-Oracle-1.44 par exemple pour le module DBD::Oracle. Cette distribution contient d'autres modules, notamment DBD::Oracle::GetInfo ou DBD::Oracle::Object. La distribution est identifié par le fichier archive qui la contient, P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz pour notre exemple.

Ce sont donc les distributions qui vont nous intéresser puisque installer une distribution revient à installer tous les modules qu'il contient. Nous allons donc chercher à établir la liste de toutes les distributions, dans le bon ordre, à installer pour satisfaire toutes les dépendances du module qui nous intéresse.

Le shell CPAN permet d'interroger les modules et les distributions avec les commandes m (comme module) et d (comme distribution) :
cpan> m DBD::Oracle
Module id = DBD::Oracle
    DESCRIPTION  Oracle Driver for DBI
    CPAN_USERID  DBIML (DBI Mailing Lists <dbi-users@perl.org>)
    CPAN_VERSION 1.44
    CPAN_FILE    P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz
    DSLI_STATUS  MmcO (mature,mailing-list,C,object-oriented)
    MANPAGE      DBD::Oracle - Oracle database driver for the DBI module
    INST_FILE    /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/DBD/Oracle.pm
    INST_VERSION 1.21

cpan> d P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz
Distribution id = P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz
    CPAN_USERID  DBIML (DBI Mailing Lists <dbi-users@perl.org>)
    CONTAINSMODS DBD::Oracle::db DBD::Oracle::GetInfo DBD::Oracle::st DBD::Oracle::Object DBD::Oracle DBD::Oracle::dr DBD::Oracle::Troubleshooting
On voit ici qu'installer DBD::Oracle revient à installer la distribution P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz qui contient les modules listés sur la ligne CONTAINSMODS.

Installation

L'installation d'une distribution (et non pas d'un module puisque c'est la distribution qui est téléchargée, compilée et installée) récupérée sur CPAN suit toujours le même schéma :
# perl Makefile.PL
Puis compilation et test du module :
# make && make test
Si le test est OK, il ne reste plus qu'à l'installer :
# make install  
Si des dépendances sont manquantes, soit la compilation échoue, soit le test échoue.

Dépendances

Où sont les dépendances ? C'est bien ce qui nous intéresse mais les commandes m ou d ne les affichent pas. Malheureusement, elle ne semblent pas accessible directement via CPAN et il faut chercher un peu.
Dans la plupart des cas, la distribution contient un fichier META.yml qui décrit le package et contient des 3 sections de dépendance :
  • build_requires
  • configure_requires
  • requires
Si ce fichier n'est pas présent, il faut chercher un peu plus loin dans les fichiers makfile. D'après la doc CPAN, la fonction CPAN::Distribution:: permet de récupérer les dépendances après la compilation avec make. Je n'ai pas été si loin pour l'instant : se baser sur le META.yml sort déjà des résultats assez interessants.

Intéragir avec CPAN en perl

C'est parti pour les choses intéressantes. Le but de la manœuvre est d'avoir un script qui va :
  1. Se connecter à CPAN
  2. Récupérer la distribution du module qui nous intéresse
  3. Extraire les dépendances
  4. Recommencer sur chacune des dépendances
  5. Enregistrer toutes les archives tar.gz récupérée de CPAN dans un coin
  6. Générer une liste des distributions dans l'ordre des dépendances pour pouvoir les installer
A part l'algorithme de parcours des dépendances, la seule difficulté vient de l'interrogation de CPAN pour récupérer les distributions.
Le module CPAN, outre le shell bien pratique, propose des fonctions qui nous permettent d'interagir directement en perl. Les modules et distributions sont représentés par les objets CPAN::Distribution et CPAN::Module.
La documentation de l'inteface Perl du shell cpan n'est pas très fournie, l'essentiel se trouve sur la page du module CPAN : http://search.cpan.org/~andk/CPAN-1.9800/lib/CPAN.pm#Methods_in_the_other_Classes

Un petit exemple sera plus clair qu'un long discours. Reprenons l'exemple ci dessous : récupérer le nom de la distribution contenant DBD::Oracle et récupérer l'objet CPAN::Distribution qui correspond :
# Récupération de l'objet CPAN::Module pour DBD::Oracle
my $mod = CPAN::Shell->expand("Module","DBD::Oracle");
# Récupération du nom de la distribution ($dist_file contient P/PY/PYTHIAN/DBD-Oracle-1.44.tar.gz)
my $dist_file = $mod->cpan_file();
# Récupération de l'objet CPAN::Distribution
my $dist = CPAN::Shell->expand("Distribution",$dist_file);
Il ne nous reste plus qu'à télécharger et extraire la distribution à l'aide de la méthode CPAN::Distribution::get(), et analyser le fichier META.yml qui se trouvera dans le dossier CPAN::Distribution::dir() (là où la distribution a été extraite) pour télécharger l'archive, l'extraire, analyser le fichier META.yml et recommencer !
# Téléchargement et extraction de l'archive
$dist->get();

# Répertoire où est extraite l'archive
my $directory = $dist->dir();
my $meta_file = "$directory/META.yml"
Il n'y a pas de méthode qui donne directement le chemin où l'archive a été téléchargée : dir() ne donne que le dossier où elle a été extraite. En regardant un peu le code de l'objet CPAN::Distribution, je n'ai rien trouvé de mieux que la propriété localfile, mais qui semble n'être initialisée que dans certains cas. Sur les différents tests que j'ai effectué, elle a toujours été définie.
Exemple pour copier l'archive .tar.gz dans un dossier $dossier_sortie :
copy($dist->{localfile}, $dossier_sortie);

Putting it all together : lister les dépendances

L'algorithme est somme toute assez simple : on récupère la distribution, on récupère la liste des dépendances et on exécute le même algo récursivement sur chaque dépendance, en construisant l'arbre de dépendance au fur et à mesure. Pour  éviter de boucler indéfiniment, on enregistre simplement les modules déjà récupérés dans une table.

Arbre de dépendence : structure

L'arbre de dépendence va servir à ordonner la liste des dépendence dans l'ordre d'installation. La structure sera un simple pointeur vers une table, chaque élément étant lui même un pointeur vers une table de hashage des sous-dépendences. A chaque appel récursif, la variable $dependency_tree va pointer sur la table de dépendence du père (donc celui qui dépend du module analyser dans l'appel en cours). L'enregistrement du fils se fait simplement par :
# Ajout de la distribution a l'arbre de dependence
$dependency_tree->{$dist_file} = {};
La table de dépendence de la distribution en cours d'installation est donc $dependency_tree->{$dist_file}. C'est cette valeur qui sera donc passé en paramètre de l'appel récursif de toutes les dépendences trouvées dans le META.ymlde cette distribution.

Pour éviter de boucler indéfiniement, les distributions déjà rencontrées sont enregistrées dans la table %downloaded_dists, en y stockant au passage le nom du module demandé (il nous servira à faire le ménage sur le serveur cible pour n'installer que les distributions qui ne sont pas déjà présentes).

On ne stocke dans l'arbre que les dépendences qui n'ont pas déjà été rencontrée par les autres distributions. Ne pas les stocker permettera de sortir la liste dans l'ordre d'installation en un parcours en profondeur du graph : si une distribution dépend d'un module qui a déjà été rencontré par une autre distribution, ce module aura sera rencontré avant dans le parcours en profondeur.

Une petite exception à celà : le module ExtUtils::MakeMaker est une dépendence de tous les modules, puisqu'il est utilisé par cpan pour l'installation, y compris les modules dont il dépend comme Data::Dumper... On va l'éliminer de l'arbre de dépendence car il crée des dépendences récursives.

Voici par exemple l'arbre de dépendence du module DBD::Oracle :
Graph de dépendence de DBD::Oracle
 Les noeud gris sont les dépendences qui sont analysées, les noeuds orange ExtUtils qui est éliminié de l'analyse (on voit la dépendence récursive en rouge sur la première branche) et ceux en jaune les dépendences déjà rencontrées précédement.
Seuls les noeuds gris sont enregistrés dans l'arbre de dépendence. On voit sur le cas de Test-Simple que le parcours en profondeur permettera de lister le noeud gris avant le noeud jaune.

Récupération des dépendences et appel récursif

Nous avons déjà vu comment récupérer la distribution associée à un module, l'enregistrer dans un coin pour constituer notre package global et la décompresser pour pouvoir accéder au META.yml.
Parser le META.yml est très simple gràce au module YAML :

my $file = "$directory/META.yml";
        if( -f $file) {
            my $meta = YAML::LoadFile($file);
            my $requires = $meta->{'build_requires'};
            my %reqs = %$requires;
            foreach my $required_mod (keys(%reqs)) {
                get_dist_and_dependencies($required_mod,$dependency_tree->{$dist_file},$level+1);
            }
        }

La function get_dist_and_dependencies correspond à l'appel récursif.

Code global

Le code global est publié sur GitHub à l'adresse suivante : https://github.com/...
Il peut bien sur être amélioré pour mieux gérer les erreurs et la sortie. Il a dans sa forme l'avantage d'être simple et facilement comprehensible avec les explications de ce post.

Seul un passage est légèrement obscur :
open STDOUT_OLD,">&STDOUT";
open STDOUT,">/dev/null";
$dist->get();
close STDOUT;
open STDOUT, ">&STDOUT_OLD";
close STDOUT_OLD;
Ce drôle de code sert à éliminer la sortie standard avant l'appel à get() pour éviter d'avoir toute la sortie du log cpan s'afficher et mieux voir l'arbre de dépendence se construire au fur et à mesure des appels récursifs.

Installer le tout sur le serveur cible

 Nous avons maintenant toutes nos distribution sous la main, et l'ordre dans lequel les installer.
Certaines sont peut être déjà installée sur le serveur, autant aller jusqu'au bout de la démarche et n'installer que ce qui manque.
Rappelez vous le petit détail des paragraphes précédents que nous n'avons pas encore exploité : nous avons associé à chaque distribution le nom du module requit qui a ammené à l'inclure.
Cela parce qu'il est beaucoup plus simple de lister les modules installées que les distributions.
ExtUtils::Installed est là pour ça et propose tout simplement une méthode modules() qui liste les modules installés. Et pour faire encore plus simple, le script instmodsh fournit une interface à ExtUtils::Installed, et à modules() avec la commande l. Même pas de Perl à écrire ;)

Donc c'est parti : on extrait la liste des modules installées avec instmodsh, et avant d'installer chaque module on vérifie si il n'est pas présent dans cette liste.

En shell, si le fichier install.txt est la sortie de notre script (au format "distribution;module") et installed le fichier qui contient la liste des modules installés, ça donne :
for i in `cat install.txt `; do
    dist=`echo $i | cut -d";" -f1`;
    module=`echo $i | cut -d";" -f2`;
    if grep -q "^$module$" installed; then
        echo "$dist: SKIP";
    else
        echo "$dist: INSTALL";
        # Decommentez cette ligne pour lancer l'installation dans la foulé
        #(cd `echo $dist | sed -e 's/.tar.gz//'`; perl Makefile.PL && make && make test && make install) || break ;
    fi;
done
On pourrait faire plus propre avec un petit script qui appelle ExtUtils::Installed et qui déroule lui même l'installation (cpan le fait bien !), mais ce sera pour une autre fois ;)

samedi 12 mai 2012

Installation & configuration de l'instant client Oracle

L'instant client Oracle, gratuit, est souvent la solution pour les machines qui doivent interroger des bases Oracle sans héberger de serveur, typiquement comme les machines de supervision.
L'installation est très simple lorsqu'on sait quels fichiers installer, quelles variables positionner et où placer les fichiers de configuration.
Ce post décrit rapidement les étapes d'installation et les chemins clefs, en se basant sur la version 11g.

Installation des binaires

Les binaires se téléchargent sur le site d'Oracle. Recherchez tout simplement dans les menus Downloads -> Instant Client pour trouver tout un listing de plateforme et d'architecture.

Attention au type d'architecture : même si les binaires 32 bits fonctionneront sur une machine 64 bits, le "linkage" d'une application 64 bits après compilation sur une librairie 32 bits ne fonctionnera pas. Ce cas de figure se rencontre en installant par exemple DBD::Oracle pour Perl : si votre machine est 64 bits, la compilation générera par défaut des binaires 64 bits et il vous faudra absolument les librairies Oracle 64 bits.
En cas de doute, une solution est de vérifier le format d'un fichier .o compilé récement. Par exemple pour DBD::Oracle :
# file Oracle.o
Oracle.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped

Pour ma part, pour une utilisation essentiellement via sqlplus et perl, je me contente de 3 packages :
  • Instant Client Package - Basic : les librairies de base de l'Instant Client
  • Instant Client Package - SQL*Plus : le fameux sqlplus, indispensable pour debugguer l'installation
  • Instant Client Package - SDK : le SDK qui nous permettera de compiler les librairies des autres langages, notamment DBD::Oracle de Perl
Je préfère récupérer les versions zip que rpm pour faire l'installation à la main, mais dans ce cas le suivi via le gestionnaire de package est impossible.

Une fois récupéré, l'installation est extrêmement simple : dézipper et déplacer les fichiers dans le dossier cible.
Exemple :
# unzip instantclient-basic-linux.x64-11.2.0.3.0.zip
# unzip instantclient-sdk-linux.x64-11.2.0.3.0.zip
# unzip instantclient-sqlplus-linux.x64-11.2.0.3.0.zip
# mkdir /opt/oracle/instantclient
# mv instantclient_11_2/* /opt/oracle/instantclient

Configuration des variables d’environnement

Deux variables sont indispensables pour faire fonctionner Oracle, en plus du PATH pour sqlplus :
  • ORACLE_HOME : utilisé par Oracle, doit pointer sur le dossier d'installation d'Oracle
  • LD_LIBRARY_PATH : utilisé par l'OS pour trouver les librairies partagées d'Oracle
Les deux doivent pointer sur le dossier d'installation de l'InstantClient.
Si LD_LIBRARY_PATH n'est pas ou mal positionné, le message est clair :
# sqlplus
sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory
Dans l'exemple précédent, les deux variables doivent être positionnées sur /opt/oracle/instantclient.
Pour ne pas avoir à les redéfinir à chaque fois, ajoutez les dans /etc/profile.

Pour finir, tester en lançant sqlplus qui doit demander le login si tout est bien positionné :
# sqlplus

SQL*Plus: Release 11.2.0.3.0 Production on Tue May 12 20:34:35 2012

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Enter user-name:

SQLPlus : petit rappel de syntaxe

Petit rappel de syntaxe de la commande sqlplus car je ne la trouve pas intuitive du tout. En cas de doute, sqlplus -h a la solution :)
  • sqlplus login/password@//ip:port/SID : pour entrer l'adresse complète de la base
  • sqlplus login/password@TNS : si la base est configurée dans un tnsname.ora (normalement ce n'est pas le cas à cette étape de l'installation)

Problème ORA-21561: OID generation failed

Il m'est arrivé plusieurs fois d'obtenir ce message lors du test d'installation en ouvrant réellement une connexion sur un serveur qui fonctionne :
# sqlplus login/password@//198.168.5.4/BASEDETEST

SQL*Plus: Release 11.2.0.3.0 Production on Tue May 12 20:36:22 2012

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

ERROR:
ORA-21561: OID generation failed
Cette erreur apparaît car le nom d'hôte renseigné dans /etc/hosts n'est pas bon. Dans mon cas, j'avais :
127.0.0.1       localhost
Il faut que le nom qui apparait dans /etc/hosts soit le même que celui que renvoie la commande hostname.

Configuration des connexions (tnsnames.ora)

Ce fichier est bien pratique pour centraliser les paramètres de connexion et ne pas avoir à les retaper à de multiples endroits, encore faut-il placer le fichier au bon endroit...
Deux possibilités :
  • $ORACLE_HOME/network/admin/tnsnames.ora : c'est la solution que je préfère, il suffit de créer le dossier network/admin et aucune configuration supplémentaire n'est nécessaire
  • $TNS_ADMIN/tnsnames.ora : permet de mettre le tnsnames.ora n'importe où, éventuellement d'en avoir des différents par utilisateur, mais demande la configuration d'une variable d'environnement supplémentaire
Pour mémoire le format d'une ligne dans ce fichier (en italic orange les valeurs à modifier) :
nom_tns=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=community)(PROTOCOL=TCP)(HOST=adresse_ip_ou_hostname)(PORT=port_1521_par_defaut)))(CONNECT_DATA=(SID=sid)))
Une fois en place, il ne reste plus qu'à tester avec sqlplus (cf ci dessus pour la syntaxe) !

jeudi 3 mai 2012

Installation de PNP4Nagios sur Shinken

PNP4Nagios : pourquoi faire ?

Shinken (ou autres fork de Nagios) récupère les données de performance (perfdata) à chaque exécution de contrôle. Le traitement des perfdata n'est pas intégré dans le noyau, mais externalisé via des commandes externes : host_perfdata_command et service_perfdata_command, ou via un module (NEB pour Nagios, ou un module du broker pour Shinken).
Pnp4Nagios permet de stocker ces données en base RRD (Round-Robin Database) et propose une interface web de visualisation pour les afficher en couleur sur de jolis graphs.

Pnp4Nagios propose plusieurs mode d'interfaçage avec Nagios, très bien décrit sur le site officiel (http://docs.pnp4nagios.org/pnp-0.6/modes). Le plus simple à interfacer avec Shinken étant le 'Bulk Mode with npcdmod', puisque Shinken intègre un module de Broker jouant le même rôle que le NEB npcdmod de Nagios (appelé tout simplement... npcdmod).

Dans ce mode, Nagios (ou Shinken) log les données de performance dans un fichier plat via un Event Broker qui sont ensuite récupérées et traitées par un daemon PNP4Nagios qui consomme ces données. Schématiquement, l'architecture est la suivante :
Schéma d'architecture Shinken/PNP4Nagios
Coté Shinken, les étapes 1 et 2 sont le fonctionnement normal et l'étape 3 est réalisée par le module de Broker npcdmod. Coté PNP4Nagios, l'étape 4 est effectuée à intervale de temps régulier par le daemon npcd (ne pas oublier de le lancer !) qui dans la foulée lance le script process_perfdata.pl qui réalise l'étape 5.

Une fois en place, la console de Pnp4Nagios ressemble à ça :

Screenshot PNP4Nagios
Screenshot PNP4Nagios

Installation

Les étapes de l'installation de Pnp2Nagios, une fois Shinken fonctionnelle, peuvent dans les 5 suivantes :

  1. Compiler PNP4Nagios
  2. Configurer PNP4Nagios
  3. Configurer l'interface web de PNP4Nagios
  4. Execution du daemon npcd
  5. Mettre en place le module Shinken npcdmod

1. Compilation de Pnp4Nagios

La configuration est classique : ./configure; make all; make fullinstall.
Seule petit détail : les flags du configure à positionner selon la configuration de la machine.

Pour ma part, je n'aime pas trop les installations par défauts dans /usr/local, et j'utilise un user shinken plutôt que nagios, donc à indiquer au configure qui ne le devine pas tout seul :
./configure --prefix=/opt/pnp4nagios --with-nagios-user=shinken --with-nagios-group=shinken --with-rrdtool=/opt/rrdtool-1.4.7/bin/rrdtool
Configure indique si tout ce passe bien les paramètres utilisées pour la compilation et l'installation :
*** Configuration summary for pnp4nagios-0.6.17 03-25-2012 ***


  General Options:
  -------------------------         -------------------
  Nagios user/group:                shinken shinken
  Install directory:                /opt/pnp4nagios
  HTML Dir:                         /opt/pnp4nagios/share
  Config Dir:                       /opt/pnp4nagios/etc
  Location of rrdtool binary:       /opt/rrdtool-1.4.7/bin/rrdtool Version 1.4.7
  RRDs Perl Modules:                *** NOT FOUND ***
  RRD Files stored in:              /opt/pnp4nagios/var/perfdata
  process_perfdata.pl Logfile:      /opt/pnp4nagios/var/perfdata.log
  Perfdata files (NPCD) stored in:  /opt/pnp4nagios/var/spool


  Web Interface Options:
  -------------------------         -------------------
  HTML URL:                         http://localhost/pnp4nagios
  Apache Config File:               /etc/httpd/conf.d/pnp4nagios.conf

  Review the options above for accuracy.  If they look okay,
  type 'make all' to compile.


  WARNING: The RRDs Perl Modules are not found on your system

           Using RRDs will speedup things in larger installations.
Si tout est bon pour vous, il ne reste plus qu'à compiler et installer.
D'abord la compilation des binaires :
make all
Puis l'installation de tout ce qu'il faut :
make fullinstall
L'installation peut être faite étape par étape en utilisant make install, install-webconf, install-config, install-init, voir la doc du site officielle pour le détail.

2. Configuration de PNP4Nagios

Si tout s'est bien passé jusqu'ici, Pnp4Nagios est installé et prêt à être utilisé dans /opt/pnp4nagios.
Toute la configuration est effectuée via le fichier etc/npcd.conf qui contient trois sections :
  • Logging (section Logging Options)
  • Configuration du daemon (section NEEDED OPTIONS), notamment la directive perfdata_spool_dir qui indique où le daemon va scruter les fichiers à charger
  • Configuration du module Nagios ou Shinken (section NPCDMOD OPTIONS), notamment la directive perfdata_file qui indique où Nagios/Shinken va stocker les données de perfdata avant de déplacer à intervalle régulier (perfdata_file_processing_interval) le fichier dans le spool
Rien n'est vraiment à modifier par rapport aux fichier d'exemple, à part peut être le logging dans un fichier au lieu de syslog selon les goût

Le chemin des fichiers RDD est codé en dur dans le script ./process_perfdata.pl : var/perfdata relativement au dossier d'installation de Pnp4Nagios et ne peut pas être modifié.

3 Configuration de l'interface Web de PNP4Nagios

Le fichier de configuration d'Apache fourni par défaut utilise l'authentification de Nagios. l'UI de Shinken n'utilise pas Apache, ces directives doivent donc être adaptées en conséquence. Pour simplement supprimer l'authentification, commenter les lignes suivantes :
#       AuthName "Nagios Access"
#       AuthType Basic
#       AuthUserFile /usr/local/nagios/etc/htpasswd.users
#       Require valid-user
L'URL est configurée via la ligne d'alias dans ce même fichier et correspond aux paramètres du ./configure :
Alias /pnp4nagios "/opt/pnp4nagios/share"
Un premier accès au serveur (http://mon_serveur/pnp4nagios) va tomber sur la page de test qui doit être toute verte ;) Si tout est bon, supprimer simplement le fichier share/install.php dans le dossier d'installation de Pnp4Nagios pour accéder au service. Il n'y aura forcement rien à afficher pour l'instant puisque Shinken n'a encore rien envoyé.

4. Execution du daemon npcd

Rien de bien compliqué : le script d'installation a normalement dû déposer un script de démarrage dans /etc/init.d. Lancer donc le daemon classiquement :
/etc/init.d/npcd start
En fonction de la distribution Linux du serveur, ajoutez si nécessaire le lancement au démarrage à l'aide de chkconfig ou des dossier /etc/rcX.d add-hoc.

5. Configuration de Shinken pour alimenter Pnp4Nagios

Il ne reste plus qu'à dire à Shinken de stocker les données de perfdata dans un fichier dump et de l'envoyer dans le spool tel qu'indiqué dans etc/npcd.conf.

 Le module se configure via le fichier de configuration de l'Arbiter (shinken-specific.cfg par défaut) :

define module{
       module_name  NPCDMOD
       module_type  npcdmod
       config_file  /opt/pnp4nagios/etc/npcd.cfg
}
 Puis doit être ajouté dans les modules du broker :
define broker{
       broker_name      broker-1
       ...
       modules          Simple-log,NPCDMOD
 }
Stopper Shinken et le redémarrer : si tout va bien, tout marche bien !
Shinken doit enregistrer les perfdata dans le fichier dump de pnp4Nagios (pnp4nagios/var par défaut) puis déplacer ce dump dans le spool à interval régulier (pnp4nagios/var/spool par défaut) pour être consommé par le daemon ncp et finir en fichier RDD dans pnp4nagios/var/perfdata.

Si rien ne se passe, controler le log du broker qui donnera un indice. Par exemple, si le chemin du fichier npcd.conf dans la définition du module NPCDMOD n'est pas bon, on trouvera cette jolie erreur :
2012-05-03 17:34:52,240 [1336059292] [broker-1] Back trace of this remove : Traceback (most recent call last):
  File "/opt/shinken/shinken/modulesmanager.py", line 171, in get_instances
    inst = module.get_instance(mod_conf)
  File "/opt/shinken/shinken/modules/npcdmod_broker.py", line 55, in get_instance
    instance = Npcd_broker(plugin, config_file, perfdata_file, perfdata_spool_dir, perfdata_spool_filename, sleep_time)
  File "/opt/shinken/shinken/modules/npcdmod_broker.py", line 76, in __init__
    raise Exception('npcdmod: An error occurred process your config file. Check your perfdata_file or perfdata_spool_dir')
Exception: npcdmod: An error occurred process your config file. Check your perfdata_file or perfdata_spool_dir