jeudi 13 février 2014

Couplage nxlog et stack ElasticSearch

Je suis actuellement en train de tester le couple Logstash/ES/Kibana. Dans ce cadre, j'ai voulu regarder différents mécanismes pour remonter des informations venant de mes différentes machines sans avoir pour autant à installer un agent Logstash partout.

J'ai donc commencé à regarder le fonctionnement de nxlog qui permet de faire ce genre de chose.

Mise en place de nxlog

Dans ce qui va suivre, on va remonter les events venant de notre nœud Windows (ici un 2003) dans le serveur Logstash. Le côté intéressant de ce produit est qu'il fonctionne aussi bien sous Windows que Linux et que ce dernier fait de la rétention de message le temps que le serveur Logstash soit de nouveau disponible.

Pour en revenir à nos moutons, ci-dessous un exemple de configuration :

define ROOT C:\Program Files\nxlog

Moduledir %ROOT%\modules
CacheDir %ROOT%\data
Pidfile %ROOT%\data\nxlog.pid
SpoolDir %ROOT%\data
LogFile %ROOT%\data\nxlog.log

<Input in>
    # Module      im_msvistalog
# For windows 2003 and earlier use the following:
    Module      im_mseventlog
</Input>

<Extension json>
    Module      xm_json
</Extension>

<Output logstash>
    Module      om_tcp
    Port        5140
    Host        IP_SERVEUR_LOGSTASH
    Exec        to_json();
</Output>

# Let's tie all pieces together with a NXlog route
<Route local_to_logstash>
    Path        in => logstash
</Route>
En substance, on charge le module im_mseventlog, on indique un point d'envoi (Output logstash) et enfin, on précise un chemin (in => logstash).

Configuration de Logstash

Nous allons maintenant configurer Logstash afin de récupérer les messages de notre ami nxlog.

Pour se faire, nous allons créer un fichier logstash.conf avec une entrée (précisant l'encodage) :

input {
  tcp {
    port => 5140
    type => "nxlog"
    codec => line {
      charset => "CP1252"
    }
  }
}

NB : il est possible d'utiliser le codec json directement dans l'input tcp. Le problème est que l'agent nxlog peut renvoyer plusieurs messages JSON d'un seul coup (notamment dans le cas d'un arrêt/relance du serveur Logstash). Dans ce cas, Logstash n'arrive pas à bien l'interpréter et ne récupère les différents champs.

On va ensuite récupérer le contenu et le traiter comme étant du json :

filter {
  if [type] == "nxlog" {
    json {
      source => "message"
    }
    mutate {
      rename => [ "Message", "message" ]
      # remove_field => [ "champ1", "champ2" ]
    }
  }
}

A noter que nxlog renvoie pas mal de champ. Si vous voulez en supprimer quelques uns, décommenter le champ remove_field ci-dessus.

Il ne nous reste plus qu'à renvoyer le contenu sur la sortie standard pour débogage :

output {
  stdout { debug => true }
}

Reste maintenant à lancer notre agent logstash :

java -jar logstash.jar --conf logstash.conf agent

Exemple de message

Une fois lancé, nous pouvons recevoir nos premiers messages :

{
              "message" => "xxx",
             "@version" => "1",
           "@timestamp" => "2014-02-13T14:53:57.156Z",
                 "type" => "nxlog",
                 "host" => "xxxx:xxx",
            "EventTime" => "2014-02-13 15:53:57",
     "EventTimeWritten" => "2014-02-13 15:53:57",
             "Hostname" => "XXX",
            "EventType" => "AUDIT_SUCCESS",
        "SeverityValue" => 2,
             "Severity" => "INFO",
           "SourceName" => "Security",
             "FileName" => "Security",
              "EventID" => 538,
       "CategoryNumber" => 2,
             "Category" => "Ouverture/Fermeture de session ",
         "RecordNumber" => 410222,
               "Domain" => "XXX",
          "AccountName" => "Administrateur",
          "AccountType" => "User",
    "EventReceivedTime" => "2014-02-13 15:53:57",
     "SourceModuleName" => "in",
     "SourceModuleType" => "im_mseventlog"
}

Il ne reste plus qu'à envoyer tout ça dans le moteur ElasticSearch et le tour est joué !

dimanche 26 janvier 2014

Installation de razor (ainsi que puppet, postgresql, tftp et dhcp)

Il y a quelques années, j'avais mis en place un serveur d'installation Linux. C'était basé sur le classique dhcp, tftp et kickstart. Un de mes collègues m'a parlé dernièrement d'un projet relativement intéressant : razor. C'est un projet qui est toujours en cours de développement mais est tout à fait utilisable.

Son principe est assez simple : il se base sur des briques classiques pour gérer la partie boot réseau (DHCP + TFTP + kickstart) et utilise un serveur JBoss couplé à postgresql pour la partie gestion de la configuration.

Pour mémoire, l'installation se fera sur une CentOS 6.5 mais devrait s'adapter très facilement sur une autre distribution.

Mais trêve de bavardage, passons à la mise en oeuvre.

Installation et configuration de postgres

Pour faire fonctionner razor, nous allons avoir besoin d'une version très récente de posgresql (la 9.3). Le repository pour RHEL/CentOS contenant cette version de postgres s'installe avec la commande suivante :

yum install http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm

L'installation de postgresql à proprement parlé se fait ensuite simplement avec yum :

yum install postgresql93-server

De là, il nous faut initialiser le contenu de la base avec la commande suivante :

/etc/init.d/postgresql93 initdb

Ceci fait, nous pouvons démarrer la base :

/etc/init.d/postgresql93 start

Enfin, nous allons créer notre utilisateur ainsi que notre schéma :

psql
create user razor;
create database razor_prd owner razor;
\password razor

Modifier ensuite le fichier /var/lib/pgsql/9.3/data/pg_hba.conf afin de faire apparaître la ligne suivante (vers la fin du fichier) :

local   all         all     127.0.0.1/32        md5

Un arrêt/relance de postgresql plus tard :

/etc/init.d/postgresql restart

Nous voici prêt pour la suite.

Installation de puppet

Par la suite, je m'appuierai énormément sur puppet pour mettre en oeuvre le produit. Je vous invite donc à l'installer avec la série de commandes suivante :

yum install http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
yum install puppet

Installation de razor

Le plus simple et de se servir de puppet pour faire le gros du travail. Pour se faire, lançons l'installation du module razor :

puppet module install puppetlabs-razor

Vous devriez voir le résultat suivant si tout se passe bien :

Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
└─┬ puppetlabs-razor (v0.11.0)
  ├─┬ puppetlabs-java (v1.0.1)
  │ └── puppetlabs-stdlib (v4.1.0)
  └─┬ puppetlabs-tftp (v0.2.1)
    └── puppetlabs-xinetd (v1.2.0)

Passons maintenant à l'installation de razor :

export FACTER_server=ADDRESSE_IP_RAZOR
puppet apply -e "include razor"

Au bout d'un petit moment, vous devriez avoir un process Java JBoss pour héberger l'application razor ainsi qu'un serveur tftpboot fonctionnel (ou presque).

Rendez-vous maintenant dans le répertoire /opt/razor afin de recopier le fichier config.yam.sample en config.yaml :

cd /opt/razor
cp config.yaml.sample config.yaml

Adapter ensuite le contenu du fichier config.yaml à votre plateforme et lancer la commande suivante :

razor-admin -e production migrate-database

De là, il ne nous reste plus qu'à installer une version valide du client razor avec la commande suivante :

puppet resource package razor-client provider=gem ensure=latest

Si vous avez un parefeu sur votre machine, il vous faudra ouvrir le port 8080.

Configuration du tftp

Rien de particulier à signaler si ce n'est de bien faire attention d'ouvrir le port udp 69 sur votre parefeu.

Récupération du microkernel

Nous allons déposer le micro kernel dans un sous répertoire de razor (/var/lib/razor/repo-store). Ci-dessous les commandes à lancer pour le faire :

wget http://links.puppetlabs.com/razor-microkernel-003.tar
tar xfv razor-microkernel-003.tar -C /var/lib/razor/repo-store

Configuration du serveur DHCP

Il existe un fichier d'exemple dans le module puppet que vous pouvez récupérer avec la commande suivante :

cp /etc/puppet/modules/razor/examples/isc-dhcpd-example.conf /etc/dhcp/dhcpd.conf

Reste ensuite à adapter le fichier /etc/dhcp/dhcpd.conf et démarrer notre serveur dhcp en s'assurant qu'il soit démarrer au lancement de la machine :

puppet resource service dhcpd ensure=running enable=true

Nous allons pouvoir commencer quelques tests ...

Installation d'une CentOS 6.5

Création d'un broker par défaut

Avec razor, il est possible de faire tout un tas de chose en post installation. Dans notre cas, on va se contenter quelque chose de simple avant d'aller plus loin :

razor create-broker --name=noop --broker-type=noop

Création d'un repository

Nous allons récupérer un repository CentOS. Cette opération se fait avec la commande razor create-repo :

razor create-repo --name centos-6.5 --iso-url=http://.../CentOS-6.5-x86_64-minimal.iso

Nous pouvons ensuite vérifier la présence de notre repository avec la commande razor repos :

# razor repos
From http://192.168.122.3:8080/api/collections/repos:

    id: "http://...:8080/api/collections/repos/centos-6.5"
  name: "centos-6.5"
  spec: "/razor/v1/collections/repos/member"

Ainsi que le détail du repos en ajoutant son nom :

# razor repos centos-6.5
From http://192.168.122.3:8080/api/collections/repos/centos-6.5:

       id: "http://...:8080/api/collections/repos/centos-6.5"
     name: "centos-6.5"
     spec: "/razor/v1/collections/repos/member"
  iso_url: "http://.../CentOS-6.5-x86_64-minimal.iso"

Création d'un tag

Nous allons procéder à la création d'un tag testant si la machine est virtuelle ou non. Pour se faire, alimenter le fichier virtual.json avec le contenu suivant :

# cat virtual.json
{
  "name": "virtual",
  "rule": ["=", ["fact", "is_virtual"], "true"]
}

Donnons ça à manger à razor avec la commande razor create-tag :

# razor create-tag --json virtual.json
From http://192.168.122.3:8080/api:

    id: "http://localhost:8080/api/collections/tags/virtual"
  name: "virtual"
  spec: "/razor/v1/collections/tags/member"

Création d'une policy

Alimentons maintenant le fichier centos-6.5.json avec le contenu suivant :

# cat centos-6.5.json
{
  "name": "centos-6.5",
  "repo": { "name": "centos-6.5" },
  "task": { "name": "centos" },
  "broker": { "name": "noop" },
  "enabled": true,
  "hostname": "host${id}.local",
  "root_password": "ChangezMoi",
  "max_count": "100",
  "rule_number": "100",
  "tags": [{ "name": "virtual"}]
}

Le contenu du fichier va donner un minimum d'information pour l'installation à savoir :
  • Le nom de la police (centos-6.5) ;
  • Le nom du repository (idem) ;
  • Le type de tâche d'installation (ici une CentOS). Pour connaître la liste complète, on peut utiliser la commande razor tasks ;
  • Le type de broker : Il s'agit d'une espèce de post install. Pour l'instant, l'installation s'arrête là ;
  • Enabled : pour savoir si la police est active ou non ;
  • Un template pour le nom de la machine ;
  • Le mot de passe root ;
  • Le nombre max de création et son numéro ;
  • Enfin, les tags sur lesquels cette police s'appliquera (ici virtual).
Donnons ça à manger à notre ami razor avec la commande razor create-policy :

razor create-policy --json centos-6.5.json

Dès que nous démarrerons une machine virtuelle sur notre réseau, cette dernière commencera son installation. Si vous aviez une machine en attente, cette dernière redémarrera et commencera son installation.

Le mot de la fin

Vous l'avez vu, il s'agit vraiment d'une aide pour mettre en oeuvre razor le plus rapidement possible sans forcément chercher à personnaliser les choses.

J'essaierai dans un second temps de revenir avec un nouvel article pour vous présenter le mécanisme permettant de personnaliser vos installations.

A noter que le produit est en pleine refonte et que certaines parties de ce document vont sûrement être amené à évoluer ou devenir un peu obsolète. Je vous laisse ci-dessous une bibliographie m'ayant permis de mettre en oeuvre le produit.

Bon courage et bon déploiement !

Bibliographie

http://technodrone.blogspot.com/2013/11/installing-razor-yes-new-version.html
http://technodrone.blogspot.com/2013/11/installing-razor-client-and-creating.html

mardi 31 décembre 2013

Installation de Visual Editor sur mediawiki

Mediawiki est le nom du logiciel qui fait tourner les wikis de la fondation wikipedia. Depuis maintenant quelques années, ces derniers cherchent à mettre en place un éditeur de code wiki user friendly et compatible avec le code wiki existant. En effet, la fondation a constaté que la syntaxe du wiki était un obstacle à l'arrivée de nouveaux contributeurs. Même si la situation n'est pas non plus catastrophique, la fondation a donc voulu diminuer cette difficulté en lançant un éditeur plus conviviale.

Les résultats de ces travaux sont l'extension Visual Editor pour mediawiki. Je vous laisse vous rendre sur cette page pour avoir plus de détail : http://meta.wikimedia.org/wiki/VisualEditor/MediaQ%26A

Cette interface a été déployé sur pratiquement tout l'ensemble des serveurs de la fondation wikipedia et fait toujours l'objet de travaux.

Voilà pour le contexte. Voyons maintenant comment nous en servir sur notre propre wiki.

Fonctionnement de Visual Editor

Un des pré-requis de ce logiciel comme je l'expliquais plus haut est de rester compatible avec la quantité énorme d'article déjà existant et donc de respecter le rendu des articles existants. Pour se faire, l'éditeur passe par une phase de rendu du code wiki en HTML en utilisant l'API du wiki avant d'être resservi à l'internaute au travers d'un éditeur HTML. Quand une modification est opérée (sur le code HTML), ce code est renvoyé au travers un sérialiseur qui se chargera de faire une translation inverse et surtout de supprimer les fausses différences. Par fausses différences, j'entends la suppression des espaces surnuméraires, le remplacement des doubles quotes (") par de simple quote (') etc.

Pour les plus curieux, je vous laisse découvrir l'article suivant qui explique ça mieux que moi : https://blog.wikimedia.org/2013/03/04/parsoid-how-wikipedia-catches-up-with-the-web/

Bref, ces deux services sont assurés à l'aide d'un webservice écrit en node.js (serveur d'application en javascript). Vous l'aurez compris, il va donc s'agir dans un premier temps d'installer ce serveur d'application et de l'intégrer ensuite dans notre wiki.

Installation de node.js

Par la suite, nous travaillerons sur une Ubuntu quantal (12.10) mais toutes les versions suivantes devraient fonctionner sans problème. J'ai également réalisé cette installation sur une CentOS 6.4. Il faut juste savoir qu'il faut disposer d'une version node 0.8 ou 0.10 minimum.

Bref, sous Ubuntu, nous allons tout d'abord rajouter les sources qui nous manquent :

add-apt-repository ppa:chris-lea/node.js
apt-get update
apt-get install nodejs

Installation de Parsoid

Node.js est maintenant présent sur la machine, nous allons nous attacher à récupérer les sources de Parsoid. Ce dernier ne fait pas encore l'objet d'une livraison stable mais se récupère directement au niveau du repository git. Cette récupération se fait à l'aide de la commande suivante :

git clone https://gerrit.wikimedia.org/r/p/mediawiki/services/parsoid

Rendons-nous maintenant dans l'arborescence nouvellement récupéré et lançons la récupération des plugins pré-requis :

cd parsoid
npm install

Au bout de quelques temps, nous devrions être en mesure de lancer notre instance Parsoid avec la commande suivante :

node api/server.js

A ce moment, node.js vous lancera des workers Javascript afin de prendre en charge le travail requis pour le webservice dont nous avons parlé plus haut. Pour vous assurez que tout fonctionne, nous pouvez vous rendre sur l'adresse suivante : http://localhost:8000/

Sachez que vous aurez peut-être des choses à adapter à votre configuration en fonction de votre wiki. La personnalisation se fera dans le fichier api/localsettings.js. Sachez qu'il y a un fichier exemple (localsettings.js.example) afin de vous donner des exemples de syntaxe.

Pour plus de détail, je vous laisse consulter l'article sur Parsoid à l'adresse suivante : http://www.mediawiki.org/wiki/Parsoid

Intégration au wiki

Le présent article n'a pas pour vocation d'expliquer comment s'installe mediawiki. Si vous avez besoin d'une piste pour faire cette étape, je vous laisse consulter cet article sur le sujet. Sachez qu'il vous faudra une version récente de mediawiki avec au moins une version 1.22.

Seconde chose, il va nous falloir récupérer une version de l'extension Visual Editor sur le site de mediawiki. La page suivante devrait vous permettre de récupérer ça : http://www.mediawiki.org/wiki/Special:ExtensionDistributor/VisualEditor

Il faudra ensuite :

  • Se rendre dans le répertoire des extensions du wiki : 
cd /var/www/wiki/extensions
  • Décompresser l'extension :
tar xfv .../wikimedia-mediawiki-extensions-VisualEditor-43e96d7.tar.gz
  • Renommer le répertoire :
mv wikimedia-mediawiki-extensions-VisualEditor-43e96d7/ VisualEditor

Enfin, nous pouvons rajouter les lignes suivantes à la fin du fichier LocalSettings.php :

# Parsoid and Visual Editor configuration
require_once("$IP/extensions/VisualEditor/VisualEditor.php");
$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgHiddenPrefs[] = 'visualeditor-enable';

$wgVisualEditorParsoidURL = 'http://localhost:8000';
$wgVisualEditorParsoidPrefix = 'localhost';

Une petite démonstration parlant mieux qu'un long discours, je vous laisse découvrir une petite démo du fonctionnement de ce plugin :


NB : Bonne année à tous !

mardi 1 octobre 2013

Quelques benchs sur Logstash et ElasticSearch

Voilà, je n'ai pas pu y résister. L'autre jour, j'étais tranquillement en train de traîner dans la tribune de rédaction de linuxfr et j'ai aidé à rédiger un article sur ma nouvelle lubie : Logstash, ElasticSearch et Kibana. L'article est relativement pédagogique mais ne pousse pas la réflexion plus loin que la mise en place. Il aurait été intéressant d'ajouter quelques benchs.

Comme de mon côté, je n'avais pas vraiment eu l'occasion de trop pousser le produit non plus (juste au travers un petit POC pas super poussé en terme de volumétrie) je me suis dit qu'après tout ça serait l'occasion de le faire.

Les conditions du test

Comme vous savez sûrement, j'attache énormément d'importance à la pensée Cartésienne. Pour se faire je me dois de vous donner quelques caractéristiques sur la machine sur laquelle je travaille. En voici quelques-unes (ne pas hésiter à me signaler des manquements) :
  • Processeur : AMD Phenom(tm) II X4 965 Processor ;
  • Mémoire : 8 Go - Swap : 8 Go ;
  • Java : OpenJDK (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.13.04.2) ;
  • Taille du fichier : 167997125 (~ 160 Mo) ;
  • Nombre de ligne : 1354848.
Attention : les benchs qui vont être réalisés plus loin sont fait par un néophyte sur ces produits. Si vous pensez que j'ai pu faire des erreurs, n'hésitez pas à me les signaler !

Quelques benchs

Les premiers pas

Pour me faire une idée de la capacité de traitement de logstash, j'ai voulu démarrer par un test très simple : en entrée une socket d'écoute simple et la sortie dans un fichier sans aucun traitement dessus. Pour mémoire, voici le fichier de configuration (bench.conf) que j'ai utilisé :

# Écoute sur le port 2048 de la machine
input {
  tcp {
    port => 2048
  }
}
# Balance le JSON obtenue dans un fichier
output {
  file {
    path => "./bench.json"
  }
}

Le lancement de logstash se fait avec la commande suivante :

java -Xms256m -jar logstash-1.2.1-flatjar.jar agent \
     -f bench.conf

Il ne me reste plus qu'à injecter le contenu de mon fichier dans la socket - ce que je fais à l'aide de la commande nc (netcat) - précédé par la commande time pour avoir une idée du temps que je mets :

time cat /var/log/syslog.1 | nc localhost 2048

Grosso modo, j'arrive donc à un temps de traitement de 41 secondes (soit environ 4 Mo/s ou encore 33045 lignes/s).

Voyons maintenant quelque chose de plus proche de la réalité.

Injection dans un moteur ElasticSearch

J'ai tout d'abord utilisé le moteur ElasticSearch embarqué. La configuration était la suivante :

output {
  elasticsearch {
    embedded => true
  }
}

En lançant le bench, j'obtiens une injection en environ 144 secondes.

Injection dans un moteur ElasticSearch externe

Ici, on va simplement configurer un moteur ElasticSearch afin de le faire tourner dans un process séparé. La configuration est relativement simple puisque nous allons reprendre celle par défaut. Une fois décompresser, le lancement se fait donc avec la commande suivante :

./bin/elasticsearch -f

NB : On procédera également à la suppression des données du moteur entre deux lancements du bench afin d'éviter une influence sur le résultat.

Enfin, du côté de logstash, nous allons simplement modifié la section output de la configuration de la manière suivante :

output {
  elasticsearch {
    host=> "robert"
    cluster => "elasticsearch"
    embedded => false
  }
}

En relançant le traitement, nous obtenons 113 secondes. Bonne nouvelle, c'est mieux.

Quelques modifications de paramètres sur Logstash

Essayons de buffuriser un peu nos écritures afin de voir l'impact que ça pourrait avoir. Le premier sera le paramètre flush_size (nombre maximum d'événement à flusher, par défaut 100). Voici l'impact sur le temps de traitement en fonction de sa valeur :
  • 200 : 114 secondes ;
  • 1000 : 110 secondes ;
  • 10000 : 105 secondes ;
  • 100000 : 101 secondes ;
  • 1000000 : 105 secondes.
Le gain est relatif et on peut voir que nous arrivons à un plafond au delà duquel, nous n'avons plus du tout d'impact sur les performances.

On va maintenant se pencher sur le paramètre idle_flush_time (temps maximum d'attente entre deux flushs, par défaut à 1 seconde). Ici encore, voyons l'impact sur les performances (avec un flush_size à 100000) :
  • 2 s : 104 secondes ;
  • 4 s : 107 secondes.
Bref, ça s'améliore pas. Donc de ce côté ci, on va arrêter les recherches !

Quelques modifications sur ElasticSearch

On va tout d'abord essayer d'espacer les flushs sur disque en bougeant le paramètre index.translog.flush_threshold_period (temps entre deux commits, par défaut 30m). En le passant à 5 s, nous baissons le temps de traitement à 99 secondes.

J'ai ensuite essayé divers modifications en suivant le document suivant : https://gist.github.com/duydo/2427158. Malheureusement, je n'ai jamais trouvé d'autre levier suffisamment efficace pour améliorer les choses. Il semblerait que ma machine manque de puissance pour pouvoir aller plus loin.

Pour conclure

Le but de ce bench était de se faire une idée de la capacité de traitement de notre ami Logstash et de son copain ElasticSearch sur une machine seule. Pour résumer, il faut tout de même se dire qu'on est en mesure de traiter environ 16 000 lignes / secondes ou 1,6 Mo / secondes (ce qui n'est pas mal du tout !). Même si j'ai déjà vu des choses particulièrement atroces qui devait pas être loin de cette volumétrie, je pense que ces produits ont du potentiel.

Autre point, nous sommes sur une infrastructure non distribué avec l'indexeur et le shipper sur la même machine. Je pense qu'il aurait été intéressant de distribuer la charge sur plusieurs machines (notamment pour ElasticSearch). Je vais essayer de voir si je ne pourrais pas récupérer quelques machines pour aller un peu plus loin dans mes tests. Mais en l'état, je pense que je vais arrêter mes tests pour l'instant.

mardi 27 août 2013

Back to basic : maîtriser le multitâche dans une session en mode texte


Bon, je sais, je vais passer pour un vieux schnoque mais voilà : on n'a pas toujours la possibilité d'avoir du multitâche (surtout en SSH sur un serveur dans une DMZ ou connecté en directe sur une console au cul d'un serveur) mais c'est bien pratique de pouvoir passer d'une tâche à une autre. Je ne prétends pas tout connaître mais, je vais vous livrer quelques petits trucs que j'utilise (ou que j'ai eu utilisé) dans le domaine.

Les terminaux virtuels

Je pense qu'il s'agit du mode le plus simple et qu'on privilégiera dans le cas où vous êtes sur une machine Linux sans connexion X. Ici, rien de bien compliqué, vous pouvez passer d'un terminal à un autre en utilisant la combinaison de touche Alt+Fn (il faut rajouter Ctrl dans le cas où vous avez une connexion sous X).

Par ce mécanisme, vous pouvez tout à fait ouvrir un premier terminal puis éditer un fichier à l'aide de vi (ou emacs) et, sur un autre terminal, parcourir une arborescence (par exemple). Dans ma jeunesse (je vous l'avais dit que je passerai pour un vieux teuteu), j'avais l'habitude de lancer l'excellent mpg123 en arrière plan pour écouter mes mp3s sans risque de voir ma session X me planter ma lecture.

Petit problème, si vous travaillé en SSH, ça ne fonctionne plus et en plus de ça, il n'est pas dit que votre vieille version d'Unix propriétaire le gère (en même temps, y'a t'il des fous prêt à travailler avec un M4000 ou autre station à base de Power7 posé sur son bureau ...).

Gérer des tâches en ligne de commande avec votre shell

Voilà, vous êtes maintenant connecté en SSH sur votre serveur, vous êtes en train d'éditer votre fichier et vous avez besoin de jeter un coup d'oeil rapide sur le contenu d'un autre fichier. Bien sûr, il est toujours possible de le faire avec vi (en lançant un shell avec !bash) mais c'est loin d'être pratique. Pourtant il y a beaucoup plus simple : l'utilisation des tâches en shell.

C'est ici qu'entre en scène la combinaison de touche Ctrl+Z. Quand vous faîtes cette combinaison de touche, votre programme en cours d'exécution se retrouve mis en pause et vous vous retrouvez directement sur votre shell qui était resté tranquillement en arrière plan. Ci-dessous voici ce que nous obtenons en faisant cette combinaison de touche dans vi :

[yperre]/home/yannig> vi toto

[1]+  Stopped                 vi toto
[yperre]/home/yannig>

Une fois que vous avez réalisé l'opération que vous vouliez, vous voulez revenir à votre tâche précédente. Tapez simplement la commande fg (foreground) et vous voici de retour dans votre éditeur comme si rien ne s'était passé.

Bon mais voilà, maintenant, vous voulez éditer un second fichier en parallèle. Du coup, vous passer votre première instance vi en arrière plan et vous éditer le fichier titi. Et tout d'un coup, vous voulez revenir à votre première tâche d'édition. Problème, avec fg, vous revenez à la dernière commande que vous avez lancé. Dans ce cas, il suffit de taper %1, %2 etc. en fonction du numéro de la tâche que vous voulez rebasculer en premier plan.

Maintenant, vous êtes en train d'expérimenter un nouveau produit (tomcat, elasticsearch, logstash etc.) mais comme souvent, le shell est mal foutu et se bloque à l'exécution. Problème, vous avez toujours envie de consulter un fichier et vous êtes un peu bloqué. En effet, lorsque vous faîtes Ctrl-Z, votre process est en pause et ne traite plus les requêtes entrante. C'est là qu'entre en scène l'ami bg (background).

Comme vous êtes joyeux et que vous avez lancé plusieurs process en arrière plan et maintenant vous voulez en tuer un ou deux. Alors vous avez toujours la solution du bon vieux kill . Mais sinon, vous pouvez également utiliser kill %1.

Pour conclure

Loin de moi l'idée d'avoir présenter toutes les possibilités dans le domaine. Vous pourrez également vous tourner vers l'utilitaire screen qui a également l'avantage de pouvoir faire persister votre session même si votre connexion SSH se plante lamentablement. Je ne saurais que trop vous conseiller de l'utilisier dans le cas d'un long traitement critique (migration/import de base, recopie de données, mise à jour etc).

vendredi 26 juillet 2013

Installation d'application Ruby on Rails sans connexion internet

Bizarrement, je n'avais jamais trop travaillé sur les applications écrit en rails et par conséquent, je n'avais jamais eu affaire aux désagréments qui vont avec. Bien sûr, je ne parle pas du langage en lui-même ni des frameworks qui vont avec. Non, c'est plutôt dans la gestion des gems avec le fameux utilitaires bundler.

Oui, parce qu'il faut savoir c'est que, si vous avez une connexion internet, ce brave ruby va gérer tout seul ses dépendances et compagnie. Par contre, si vous êtes comme moi dans une DMZ dans laquelle il n'est même pas question d'entendre parler de flux sortant sur un proxy, vous allez vite vous sentir seul.

C'est donc après avoir bien galéré que je me suis dit qu'une petite entrée sur mon blog aurait un double bénéfice (au delà de l'aspect purement narcissique) : me servir de pense bête et vous servir à vous les nombreux lecteurs de ce blog.

Par la suite, nous travaillerons sur l'installation de l'application Kibana (pour faire de la recherche de grosses données dans le nuage, euh, je veux dire, du scoring de big data dans le cloud).

Au début il vous faut quand même une connexion internet

Pour l'installation initiale de votre application, il vous faudra au moins une connexion internet pour commencer. Si vous n'avez pas accès directement à internet, vous pouvez toujours passer par un proxy. Pour cela, il faut exporter la valeur du proxy dans la variable http_proxy :

export http_proxy=http://user:mdp@proxy:port

Une fois ceci fait, vous pouvez lancer le bundle de votre application. Mais vous vous en doutez, avant de le faire il faut installer bundler. A noter que vous devrez installer les packages ruby et rubygems (si vous êtes sous Redhat, ça se fait très rapidement avec la commande yum install ruby rubygems). L'installation de bundler se fait simplement avec la commande suivante :

gem install bundler

Une fois que bundler est installé, nous allons pouvoir maintenant récupérer les gems pour notre application. Prenons le cas de l'application Kibana. Pour se faire, il vous faudra :
  • Décompresser votre application ;
  • Se rendre dans le répertoire décompressé et lancer la commande suivante :
bundle install

De là, l'ami bundle va se connecter sur internet et récupérer toutes les dépendances dont nous avons besoin.

Création d'un bundle

Maintenant que notre application tourne, nous allons maintenant pouvoir faire un bundle de nos dépendances afin de les recopier sur nos serveurs de production qui n'ont pas du tout de connexion internet (les pauvres ...). L'opération est très simple et se fait avec la commande suivante :

bundle package
Your Gemfile contains path and git blablabla.
Resolving dependencies...
Using rake (10.1.0)
Using daemons (1.1.9)
[...]
Your bundle is complete! blablabla.
Updating files in vendor/cache

De là, l'ami bundle devrait vous faire un répertoire vendor/cache avec les fameux gems à installer.

Installation en production

Il ne vous reste plus qu'à faire un transfert de ce répertoire dans le répertoire de l'application sur vos serveurs de production et de lancer la commande suivante :

bundle install --local

Là, bundle devrait comprendre qu'il faut qu'il utilise le contenu du répertoire vendor/cache. Il ne vous restera plus qu'à prendre un café à ma santé.

mercredi 24 juillet 2013

Packager NSClient++ sous Windows (64 bits) à l'aide de puppet

Bon, pas la peine d'en rajouter sur le titre, j'ai honte. Mais bon voilà, j'avais commencé à vouloir packager NSClient++ avec l'OS alternatif propriétaire (avec ce plugin), et je me suis rendu compte que le package NSClient++ était réinstallé tout le temps. J'ai donc voulu savoir pourquoi.

En effet, en lançant l'application du catalogue sur mon noeud, j'avais systématiquement ce message :

Notice: /Stage[main]/Nscp/Package[nscp]/ensure: created
Notice: /Stage[main]/Nscp/File[C:\Program Files\NSClient++\nsclient.ini]/content:

Info: /Stage[main]/Nscp/File[C:\Program Files\NSClient++\nsclient.ini]: Filebucketed C:/Program Files/NSClient++/nsclient.ini to main with sum e3daba1
4bc76433649a9c4af706042ac
Notice: /Stage[main]/Nscp/File[C:\Program Files\NSClient++\nsclient.ini]/content: content changed '{md5}e3daba14bc76433649a9c4af706042ac' to '{md5}38b
2bb3dbe8530f33d983ccfd8394628'
Info: /Stage[main]/Nscp/File[C:\Program Files\NSClient++\nsclient.ini]: Scheduling refresh of Service[nscp]
Notice: /Stage[main]/Nscp/Service[nscp]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 11.64 seconds

En gros, mon package nscp était constamment réinstallé et ce dernier venait également mettre à jour le fichier nsclient.ini. Je me suis donc dit que le package n'avait pas le bon nom et qu'il fallait que je trouve le bon. Après avoir essayé NSClient++, NSClientpp, j'en ai eu marre de chercher et je me suis posé la question de savoir comment avoir le nom de ce fameux package. C'est là que j'ai découvert l'existence de la commande puppet resource package. Ci-dessous un extrait de la sortie de cette commande :

[...]
package { 'NSClient++ (x64)':
  ensure => 'installed',
}
package { 'Puppet Enterprise':
  ensure => 'installed',
}
[...]

J'avais enfin le nom de mon package ('NSClient++ (x64)') et du coup, NSClient arrêtait de s'installer systématiquement et donc, le fichier nsclient.ini n'était plus à mettre à jour. En gros, mon agent n'avait plus rien à faire. Bonne nouvelle donc !