Superviser une application Linux dans SCI/GA/GAX

Mise à jour du 31/03/2020 :
Pardonnez moi cher lecteurs car j’ai pêché. En effet, et contrairement à mes habitudes, j’ai écrit cet article en me basant sur mes notes et sur mes souvenirs, ce qui fait que certaines parties étaient trop rapides ou absentes. D’où cette mise à jour. Décidément, Cassandra est bien compliqué à comprendre 😉

Sur les applications les plus récentes de Genesys, on note de plus en plus l’utilisation de solutions “libres”. Je veux parler par exemple d’applications telles que les bases de données Cassandra, les serveurs web Apache ou Tomcat, Kafka,… Problème, ces solutions, telles qu’elles, ne sont pas intégrées aux outils de supervision de Genesys que sont SCI, GA ou GAX. Or si elles plantent, votre solution sera tout aussi inutilisable que si c’était un composant Genesys qui se vautrait… Nous allons donc remédier à cela, en prenant pour exemple cette bonne vieille Cassandra !

Oui faire du NoSQL, ça peut rendre ronchon !

Le modèle, c’est important

Tout d’abord, il faut savoir que Genesys propose de créer des modèles d’application pour ces serveurs tierces parties, alias comme le disent nos amis d’outre manche “Third Party Server“.
Rien de spécial dans la création de ce template, je vais donc me limiter à une capture d’écran.

Oui, je déborde d’imagination pour mes noms de templates…

Maintenant que le template est créé, nous pouvons attaquer la création de l’application elle-même. Bien sûr celle-ci sera basée sur ce nouveau template “Cassandra Node”.

C’est toujours up ?

Pour vérifier que notre composant est toujours bien en mémoire, nous allons devoir nous assurer que le LCA de la machine hôte retrouve bien dans les process ce composant qui nous intéresse. Ici plusieurs écoles existent sous Linux, voici la mienne :

  • Répertoire de travail : “/” (oui, simplement /)
  • Ligne de commande : “bin/sh” (à adapter bien sûr si vous utilisez un autre shell). Celui-ci sera donc combiné avec notre répertoire de travail pour faire un bon vieux “/bin/sh”
  • Arguments de ligne de commande : ici on arrive dans la partie intéressante où on va spécifier le chemin vers nos exécutables. Cela dépendra forcément de votre installation mais vous devriez arriver à quelque chose du genre : “/LE_REPERTOIRE_D_INSTALLATION_DE_MON_CASSANDRA/bin/cassandra -f”

Avec ces options, vous devriez… pas pouvoir faire grand chose ! En effet, quand vous lancez cassandra en ligne de commande avec cette commande, il s’agit en fait d’un script qui s’exécute et qui va lancer la ligne de commande java “qui va bien” avant de disparaître tout en lui redonnant son PID. Nous allons donc modifier le script “cassandra” de lancement afin qu’il ne disparaisse pas.
Pour cela, éditez ce script et remplacez dedans :

# The cassandra-foreground option will tell CassandraDaemon not
# to close stdout/stderr, but it's up to us not to background.
if [ "x$foreground" != "x" ]; then
    cassandra_parms="$cassandra_parms -Dcassandra-foreground=yes"
    if [ "x$JVM_ON_OUT_OF_MEMORY_ERROR_OPT" != "x" ]; then
        exec $NUMACTL "$JAVA" $JVM_OPTS "$JVM_ON_OUT_OF_MEMORY_ERROR_OPT" $cassandra_parms -cp "$CLASSPATH" $props "$class"
    else
        exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"
    fi
# Startup CassandraDaemon, background it, and write the pid.
else
    if [ "x$JVM_ON_OUT_OF_MEMORY_ERROR_OPT" != "x" ]; then
        exec $NUMACTL "$JAVA" $JVM_OPTS "$JVM_ON_OUT_OF_MEMORY_ERROR_OPT" $cassandra_parms -cp "$CLASSPATH" $props "$class" <&- &
        [ ! -z "$pidpath" ] && printf "%d" $! > "$pidpath"
        true
    else
        exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class" <&- &
        [ ! -z "$pidpath" ] && printf "%d" $! > "$pidpath"
        true
    fi
    true
fi

par :

# The cassandra-foreground option will tell CassandraDaemon not
# to close stdout/stderr, but it's up to us not to background.
if [ "x$foreground" != "x" ]; then
    cassandra_parms="$cassandra_parms -Dcassandra-foreground=yes"
    $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"
# Startup CassandraDaemon, background it, and write the pid.
else
    $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class" <&- &
    [ ! -z "$pidpath" ] && printf "%d" $! > "$pidpath"
    true
fi

(Oui c’est barbare et je n’y comprends pas grand chose. Merci à mon collègue Antoine qui m’a filé cette astuce, un barbu par l’esprit, même sans la pilosité).
L’idée générale est la suppression des commandes “exec” qui vont permettre de ne plus faire disparaître le script cassandra après qu’il ait lancé cassandra même.

Pour confirmer le bon fonctionnement de cette manipulation, allez faire un tour en ligne de commande sur votre hôte et faites un bon vieux “ps -aux | grep cassandra” (avec Cassandra actif).
Ainsi vous devriez retrouver la ligne de commande que cherche LCA (en plus de la ligne commençant par “java”), et qui doit correspondre à la concaténation de “Répertoire de travail” + “Ligne de commande” + “Arguments de ligne de commande”. Si ce n’est pas le cas, faites les ajustements nécessaires.

Dans le doute, reboot !

Bon, maintenant on peut voir si l’état de notre application, et ça c’est bien. Mais pas moyen de l’allumer/éteindre via notre interface !
Rien de plus simple :

  • Un tour dans l’onglet “Options” de l’application (et non dans “Options de l’application”). OK en anglais c’est plus simple avec “Annex” et non “Options”…
  • Création d’une section nommée “start_stop”
  • Création des options start_command et stop_command Celles-ci devront correspondre aux commandes vous permettant de lancer et arrêter votre application

Sous Red Hat/CentOS 7, j’essaye de créer systématiquement un service pour gérer le process Cassandra. Ainsi ces fameuses options ont pour valeur “systemctl start cassandra” et “systemctl stop cassandra”.
Attention, en fonction de l’utilisateur qui fait tourner votre process LCA, il sera peut-être nécessaire d’ajouter “sudo” avant, et de rajouter ce fameux utilisateur à la liste des sudoers (voir /etc/sudoers).
Et vu que je suis dans un jour de bonté, un exemple de fichier .service servant de définition :

[Unit]
Description=Cassandra
After=network.target

[Service]
User=genesys
Group=genesys
Type=simple
WorkingDirectory=/LE_REPERTOIRE_D_INSTALLATION_DE_MON_CASSANDRA/bin
ExecStart=/LE_REPERTOIRE_D_INSTALLATION_DE_MON_CASSANDRA/bin/cassandra -f 

[Install]
WantedBy=multi-user.target

Avec tout ceci, vous devriez donc désormais pouvoir voir l’état de vos base de données Cassandra, contrôler leur arrêt/démarrage et même les ajouter à des solutions. Elle est pas belle la vie ?
Et pour rappel, cette méthode générale est applicable à d’autres process Linux 🙂

PS : dans la mythologie, Cassandra a toujours raison, mais personne ne la comprend. En l’appliquant à ma propre relation avec cette base de données, je trouve le nom très bien choisi 😀

Bonus CentOS6 :
Et oui forcément, une fois qu’on a une méthode pour un OS, il faut le faire sur un autre… Bref. Me voici sur une CentOS6 et pas de service à l’horizon.
Du coup, j’ai remplacé la valeur de start_command par :
– “/LE_REPERTOIRE_D_INSTALLATION_DE_MON_CASSANDRA/bin/cassandra -f “
et celle de stop_command par :
– “/LE_REPERTOIRE_D_INSTALLATION_DE_MON_CASSANDRA/bin/stop_cassandra”
Votre esprit affuté remarque que “stop_cassandra” n’existe pas par défaut. C’est un mini script que j’ai placé à cet endroit et dont le contenu est le suivant :

user=`whoami`
pgrep -u $user -f cassandra-pidfile | xargs kill

ATTENTION : celui-ci va par contre couper TOUS les Cassandra tournant actuellement sur votre host et avec le user utilisé par LCA. Moche si vous avez des noeuds co-localisés…
Si vous avez une solution, la zone commentaire sera ravie de l’accueillir 🙂