Archives pour avril, 2009

Java : pense-bête JVM & options d’exécution

Un petit pense-bête concernant les différentes options d’exécution de la JVM étant donné que j’arrive pas les retenir.

Journalisation avec fichier de configuration custom pour l’API java.util.logging :

java [...] -Djava.util.logging.config.file=./logging.properties [...]

Monitoring avec jconsole :

  • en local :
java [...] -Dcom.sun.management.jmxremote [...]
  • à distance :
java [...] -Dcom.sun.management.jmxremote \
        -Dcom.sun.management.jmxremote.port=8001 \
        -Dcom.sun.management.jmxremote.authenticate=false \
        -Dcom.sun.management.jmxremote.ssl=false [...]

Remote debug JDPA :

  • avec JVM < 5.0 :
java [...] -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" [...]
  • avec JVM >= 5.0 :
java [...] -agentlib:jdwp=transport=dt_socket,server=y,address="8000" [...]

Eclipse : Remote debugging avec JDPA

Parfois, il est indispensable de tester son application sous un environnement précis. Si cela ne tourne pas rond, un debug est nécessaire. Pour conserver les mêmes conditions d’exécution, un debug distant depuis son IDE est possible. Le principe est qu’une connexion réseau est faite entre le frontend du débogueur (IDE) et un backend au niveau de la JVM (JDPA, Java Debug Architecture). Deux méthodes sont possibles  :

  • « Socket attach » : une socket est en écoute au niveau de la JVM. L’IDE va s’y connecter pour contrôler le flux d’exécution et récupérer les informations de debug.
  • « Socket listen » : une socket est en écoute sur la machine de développement. Dans ce cas, la JVM s’y connecte pour ensuite être contrôlée.

Le choix entre les 2 méthodes dépend du filtrage réseau présent entre les 2 postes. Des options spécifiques sont donc à fournir à la JVM dont l’adresse IP / port de la socket et la méthode de remote debug.

Avec Eclipse, un remote debug par socket attach se fait ainsi :

  1. Compilation des sources avec les options de debug (sans blague)
  2. Déploiement / lancement de l’application sur la machine de test :
    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 [...]
    
  3. Lancer l’application depuis l’IDE avec une configuration de remote debug en précisant l’IP + port du serveur d’exécution : menu Run -> Debug … -> Remote Java Application.

Le reste s’effectue comme un debug traditionnel.

 

Gentoo/amd64 : crash récurrent de nscd

Le démon nscd chargé de gérer le cache de résultats des services de noms a la fâcheuse tendance de crasher toutes les 10 minutes +/- sur un système Linux 64 bits. Ceci est très problématique dans le cas d’un serveur LDAP, car il permet justement d’optimiser les requêtes LDAP courantes. Son crash interrompt de plus le fonctionnement du serveur (et des clients LDAP).

L’unique solution est de privilégier un équivalent – mieux codé – dénommé unscd.

Voici le script de démarrage  que j’utilise pour Gentoo/amd64 et qui manque dans le port :

#!/sbin/runscript
#
# Boris HUISGEN, &lt;bhuisgen@hbis.fr&gt;
depend() {
   use dns ldap net slapd
}
checkconfig() {
   if [ ! -d /var/run/nscd ] ; then
      mkdir -p /var/run/nscd
      chmod 755 /var/run/nscd
   fi
}
start() {
   checkconfig
   ebegin "Starting Micro Name Service Cache Daemon"
   start-stop-daemon --start --quiet --exec /sbin/unscd
   eend $?
}
stop() {
   ebegin "Shutting down Micro Name Service Cache Daemon"
   start-stop-daemon --stop --quiet --exec /sbin/unscd
   eend $?
}

# vim:ts=4

Un joli commentaire de la part de son auteur :

It is well known that nscd provided with glibc is buggy.

This leads people to invent babysitters which restart crashed/hung nscd. This is ugly.

After looking at nscd source in glibc I arrived to the conclusion that it’s flawed by design and cannot be fixed. Even if nscd’s own code is 100.00% perfect and bug-free, it can still suffer from bugs in libraries it calls.

BackupPC : installation sous Mac OS X

J’ai installé le système de backup BackupPC sur mon Mac Mini, afin de sauvegarder facilement des serveurs distants. Voici donc la procédure complète d’installation de BackupPC sous Mac OS X, avec un serveur Web Nginx et support CGI / Perl. En fin d’article, je vous fais part d’une idée de configuration possible pour le stockage sur un disque dur externe / clé USB.

Je vous renvoie en premier lieu à mes articles précédents :

Les modules Perl Compress::zlib et File::RsyncP sont à installer, comme toujours par MacPorts :

sudo port install p5-compress-zlib
sudo port install p5-file-rsyncp

Au niveau des scripts de démarrage de BackupPC, pkill et cie sera nécessaire :

sudo port install proctools

Je vais effectuer l’installation de BackupPC dans /opt/local pour rester dans l’esprit MacPorts :

cd /opt/local/src
tar xzf BackupPC.tar.gz
sudo perl configure.pl
--> Full path to existing main config.pl []?
--> Are these paths correct? [y]?
--> BackupPC will run on host [bhuisgen.local]?
--> Install directory (full path) [/usr/local/BackupPC]? /opt/local/share/backuppc
--> Data directory (full path) [/data/BackupPC]? /Volumes/WORK/backup/backuppc
--> Compression level [3]?
--> Apache image directory (full path) []? /opt/local/www/backuppc/images
--> URL for image directory (omit http://host; starts with '/') []? /backuppc/images
--> CGI bin directory (full path) []? /opt/local/www/backuppc

L’installation effectue la copie des fichiers de configuration dans /etc. Cà ne me va pas du tout et les majuscules dans les répertoires je déteste ; donc fix direct :

sudo mv BackupPC/ /opt/local/etc/backuppc
sudo mv /var/log/BackupPC/ /opt/local/var/log/backuppc
sudo chown root:admin /opt/local/etc/backuppc
sudo chown root:admin /opt/local/var/log/backuppc/

Il faut ensuite modifier le fichier /opt/local/share/backuppc/lib/BackupPC/Lib.pm pour lui préciser les répertoires /opt/local/etc/backuppc et /opt/local/var/log/backuppc car les répertoires sont codés en dur (pas bien bouh) :

--- Lib.pm.old  2009-04-10 00:56:46.000000000 +0200
+++ Lib.pm      2009-04-10 00:57:33.000000000 +0200
@@ -128,8 +128,8 @@
             useFHS     => $useFHS,
             TopDir     => $topDir,
             InstallDir => $installDir,
-            ConfDir    => $confDir eq "" ? '/etc/BackupPC' : $confDir,
-            LogDir     => '/var/log/BackupPC',
+            ConfDir    => $confDir eq "" ? '/opt/local/etc/backuppc' : $confDir,
+            LogDir     => '/opt/local/var/log/backuppc',

Dans le fichier principal de configuration /opt/local/etc/backuppc/config.pl, il faut également modifier les répertoires :

$Conf{TopDir}      = '/Volumes/WORK/backup/backuppc';
$Conf{ConfDir}     = '/opt/local/etc/backuppc';
$Conf{LogDir}      = '/opt/local/var/log/backuppc';
$Conf{InstallDir}  = '/opt/local/share/backuppc';
$Conf{CgiDir}      = '/opt/local/www/backuppc';

Vérifiez également que root est bien l’utilisateur exécutant le démon BackupPC :

$Conf{BackupPCUser} = 'root';

Remarque : vous pouvez autrement laisser l’utilisateur backuppc, mais il faut le créer et modifier en conséquence le script de démarrage du démon (sans compter la partie CGI).

Ensuite, j’autorise par défaut tous les droits d’administration :

$Conf{CgiAdminUserGroup} = '';
$Conf{CgiAdminUsers}     = '*';

La configuration est à présent terminée. A présent un petit lien symbolique qui simplifie l’accès web :

$ cd /opt/local/www/backuppc
$ sudo ln -s ./BackupPC_Admin index.cgi

Il reste à créer le script de démarrage de BackupPC. J’ai donc fait un wrapper et un script launchd s’appuyant sur daemondo de MacPorts :

$ cd /opt/local/etc/LaunchDaemons/fr.hbis.backuppc
$ more backuppc.wrapper
#!/bin/sh
#
# daemondo support script for BackupPC
#
# Boris HUISGEN <bhuisgen@hbis.fr>
#

# backuppc directory, needed to pkill
BACKUPPC_DIR="/opt/local/share/backuppc/"
# command to start daemon
CMD="/opt/local/bin/perl /opt/local/share/backuppc/bin/BackupPC"

#
# Init
#
prefix=/opt/local

#
# Start
#

Start()
{
 $CMD
}

#
# Stop
#

Stop()
{
 pkill -f $BACKUPPC_DIR
}

#
# Restart
#

Restart()
{
 Stop
 Start
}

#
# Run
#

Run()
{
 case $1 in
 start  ) Start   ;;
 stop   ) Stop    ;;
 restart) Restart ;;
 *      ) echo "$0: unknown argument: $1";;
 esac
}

#
# Run a phase based on the selector
#
Run $1
$ more fr.hbis.backuppc.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Debug</key>
   <false/>
   <key>Label</key>
   <string>fr.hbis.backuppc</string>
   <key>OnDemand</key>
   <false/>
   <key>ProgramArguments</key>
   <array>
      <string>/opt/local/bin/daemondo</string>
      <string>--label=backuppc</string>
      <string>--start-cmd</string>
      <string>/opt/local/etc/LaunchDaemons/org.macports.backuppc/backuppc.wrapper</string>
      <string>start</string>
      <string>;</string>
      <string>--stop-cmd</string>
      <string>/opt/local/etc/LaunchDaemons/org.macports.backuppc/backuppc.wrapper</string>
      <string>stop</string>
      <string>;</string>
      <string>--restart-cmd</string>
      <string>/opt/local/etc/LaunchDaemons/orgs.macports.backuppc/backuppc.wrapper</string>
      <string>restart</string>
      <string>;</string>
      <string>--pid=none</string>
   </array>
   <key>RunAtLoad</key>
   <false/>
</dict>
</plist>

On référence le script pour démarrer BackupPC :

$ sudo launchctl load -w fr.hbis.backuppc.plist

Si tout est OK, http://localhost/backuppc/ doit vous afficher l’interface de gestion de BackupPC. Il vous reste à configurer les serveurs à sauvegarder, partie hosts. Le reste peut se faire avec la documentation accessible depuis l’interface.

Dans le cas de sauvegardes manuelles sur un volume externe, launchd peut détecter le montage de périphérique et lancer un script particulier. Cette fonctionnalité peut être utilisée pour détecter la présence effective de votre volume externe (pour ma part /Volumes/WORK) et lancer un job manuel de backup de vos serveurs gràce à /opt/local/share/backuppc/bin/BackupPC_serverMesg. Je pense que je vous ferai un article d’ici peu avec les scripts adéquats…

Serveur Web Nginx/PHP/MySQL sous MacOS X

Après différents essais d’utilisation Apache / MySQL / PHP sous MacOS X que ce soit avec les versions out-of-the box d’Apple ou les packages spécifiques qui ne fonctionnent pas bien/du tout comme ca, çà, et çà, la raison m’a amené à compiler/installer une suite Web complète : plus d’Apache mais du Nginx (et çà j’y tiens), un PHP 5 avec les extensions standards et en exécution CGI, et enfin un MySQL 5.

Alors quelle solution permet de faciliter tout çà ? La réponse se trouve dans MacPorts : un système de ports pour MacOS,  fortement inspiré des ports BSD.  Un port est un package permettant de télécharger/compiler/installer les sources d’un logiciel. Une unique commande permet de remplir ce rôle. Donc autant vous le dire, une fois qu’on l’a utilisée, on s’en passe plus. Il faut uniquement mettre à jour de temps à autre l’arborescence des ports pour récupérer et mettre à jour les dernières versions. Tous les programmes sont installés dans /opt/local ce qui fait que rien n’est touché au système. Bref, la complexité est de ce niveau à peu près.

Installation de MacPorts : http://www.macports.org/install.php. N’oubliez pas d’installer la dernière version des outils XCode et le serveur X11 pour pouvoir compiler certains ports.

A partir de maintenant, le terminal est notre ami. Voici les commandes courantes de MacPorts :

port search <string> : chercher un port par son nom
port info <port> : affiche les informations du port
port variants <port> : afficher les options de compilation du port
port install <port> : installe le port, les variants sont à fournir à la suite et préfixées par +
port uninstall <port : désinstalle le port
port deps <port> : les dépendances du port
port contents <port> : les fichiers installés par le port

Avant de débuter l’installation des ports, une mise à jour de l’arborescence des ports s’impose :

$ sudo port -v selfupdate

Installation de Nginx :

$ sudo port install nginx

Il faut copier les fichiers exemples et éditer le fichier de configuration :

$ cd /opt/local/etc/nginx
$ sudo cp mime.types.example mime.types
$ sudo cp nginx.conf.example nginx.conf
$ sudo cp fastcgi_params.example fastcgi_params
$ sudo nano nginx.conf

Vérifiez que le répertoire root de l’hôte prédéfini est valide.

Installation de MySQL :

$ sudo port install mysql5-server

Une fois installé, il faut installer les db de gestion de MySQL  :

$ sudo /opt/local/bin/mysql_install_db5 --user=mysql

Installation de PHP et son extension MySQL :

$ sudo port install php5 +fastcgi +pear
$ sudo port install php5-mysql

Le mode d’exécution CGI est nécessaire pour Nginx et son module FastCGI. Il faut également créer le fichier php.ini :

$ cd /opt/local/etc/php5
$ cp php.ini-production php.ini

Pour le support FastCGI/PHP, je vous invite à consulter mon article traitant de ce sujet (et la configuration de Nginx pour le support PHP). Il faudra installer le port  spawn-fcgi :

$ sudo port install spawn-fcgi

Concernant le script FCGI-PHP, j’utilise une socket UNIX dans /opt/local/var/run/nginx/.

Installation de PHPMyAdmin :

$ sudo port install phpmyadmin

Si besoin, copiez le répertoire /opt/local/www/phpmyadmin (ou faites un lien symbolique) vers votre répertoire root.

A présent que tout est installé, il convient de lancer les logiciels. Il existe deux méthodes : la méthode manuelle  par scripts start/stop et la méthode launchd. Si la seconde permet d’automatiser le lancement automatique, la première est préférable sur une station de développement, notamment en cas d’erreur dans le fichier de configuration Nginx.

Les scripts manuels start / stop sont les suivants :

$ more /opt/local/etc/nginx/start.sh
#!/bin/sh
/opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper start
nginx
/opt/local/etc/nginx/fcgi-php.sh start
$ more /opt/local/etc/nginx/stop.sh
#!/bin/sh
/opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper stop
kill `cat /opt/local/var/run/nginx/nginx.pid`
/opt/local/etc/nginx/fcgi-php.sh stop

Si vous préférez la méthode launchd :

$ sudo launchctl load -w /opt/local/etc/LaunchDaemons/org.macports.mysql5/org/macports.mysql5.plist
$ sudo launchctl start org.macports.mysql5
$ sudo launchctl load -w /opt/local/etc/LaunchDaemons/org.macports.nginx/org.macports.nginx.plist
$ sudo launchctl start org.macports.nginx

Le script FCGI-PHP est à lancer manuellement (cf script start/stop).

Une fois le serveur MySQL en exécution, n’oubliez pas de modifier le mot de passe root :

$ mysqladmin5 -u root password 'new-password'

Un test de navigation sur http://localhost doit valider l’installation de Nginx. Créez un fichier PHP avec une sortie phpinfo () pour valider l’interprétation PHP-CGI.

Votre Mac dispose à présent d’une suite Web complète digne de ce nom.

OpenSSL : tester un certificat

Intégrant en elle-même un client telnet sécurisé, la commande openssl permet également de lancer un serveur HTTPS afin de tester un certificat SSL de manière élégante :

>openssl s_server -cert file.pem -www

Ainsi, si le certificat file.pem est valide, il ne reste plus qu’à pointer votre navigateur Web sur l’URL http://localhost:4433 pour checker le certificat SSL.

Git : package binaire Mac OS X

Un package binaire de Git pour Mac OS X est disponible à cet adresse :

http://code.google.com/p/git-osx-installer/downloads/list?can=3

htscanner : patch correctif pour la version 0.9.0

htscanner est une extension PHP permettant de parser les fichiers .htaccess d’Apache, afin d’y récupérer les variables d’exécution fixées par php_flag et php_value. Cette extension est indispensable dans le cadre d’une exécution PHP par CGI car ni le serveur Web ni php-cgi ne peuvent les récupérer.

Ayant déjà soumis un patch pour fixer la récupération des valeurs entre simple/double quotes, en voici un nouveau pour la version 0.9.0 qui n’est toujours pas exempte de problèmes avec son parseur.

patch-htscanner-parser-20090401

– interprétation correcte des retours à la ligne (EOL) quelque soit la plateforme.
– restriction du parsing pour les php_flag, seules les valeurs on/off sont acceptées (cf documentation PHP).

Mise à jour du 2009-04-05 : j’ai intégré ce patch dans la version CVS ; vivement la release 0.9.1 !

Haut de page