12 septembre 2014

APACHE 2.2 et Centos 7

Il y a de nombreuses raisons pour vouloir encore utiliser Apache 2.2 et de ne pas migrer vers Apache 2.4. L'une d'entre elles est l'utilisation de mod_perl2 qui ne fonctionne toujours pas correctement avec Apache 2.4.
Malheureusement l’installation d’Apache 2.2 sur centos 7 ne peut pas se faire avec yum car seule la version 2.4 est disponible. Voici comment procéder pour compiler Apache 2.2 et mod_perl2 sur centos 7 et mettre en place les fichiers nécessaires au  démarrage de httpd 2.2 avec systemctl (aka systemd).


1) Il faut avoir les outils de développements


yum group install "Development Tools"



2) Puis on va sur http://www.us.apache.org/dist/httpd/ et on repère la version la plus récente de httpd-2.2
puis on la télécharge et on la décompresse :


wget http://www.us.apache.org/dist/httpd/httpd-2.2.29.tar.gz
tar xvf httpd-2.2.29.tar.gz



On compile et installe apache 2.2.x

On utilise --prefix pour ne pas installer apache par dessus l’éventuelle version 'officielle'.

cd httpd-2.2.29
./configure --prefix=/path/to/apache22
make
make install


On démarre  apache (risque de conflit si une autre version utilise le port 80)


/path/to/apache22/bin/apachectl -k start


Et avec le browser ont doit avoir le classique « It works »


3) Pour compiler mod_perl et tester il y a plus de préparatifs ET une correction de bug:
(peut être certains des packages ci-dessous sont déjà sur votre machine)


yum install perl-ExtUtils-Embed
yum install perl-libwww-perl

yum install perl-CGI
yum install perl-Test-Simple
yum install perl-Linux-Pid
yum install expat

cd /usr/lib64
ln -s libexpat.so.1.x.0 libexpat.so.0


(Adaptez le version de libexpat à votre cas. Pour moi c'est 1.6.0)


4) On va sur http://apache.org/dist/perl/ repérer la dernière version de mod_perl2
puis on la télécharge et on la décompresse :

wget http://apache.org/dist/perl/mod_perl-2.0.8.tar.gz
tar xvf mod_perl-2.0.8.tar.gz
cd mod_perl-2.0.8


 
ATTENTION #1: Dans le fichier t/api/err_headers_out.t il faut remplacer à deux endroits:


     if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION==6.00;
par
  if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION>=6.00;

Enfin on peut exécuter la séquence standard :


perl Makefile.PL MP_APXS=/path/to/apache22/bin/apxs
make
make test
make install



NB: Le fait d'avoir installé apache 2.2.x dans un répertoire spécifique n'implique pas que toute la partie mod_perl aille aussi dans ce répertoire. Une partie ira dans apache/include et apache/module mais les modules perl iront dans /usr/local/lib64/perl5


5) Quand on compile soit même Apache on ne bénéficie pas des petits plus apportés par un package comme par exemple la mise en place du script de démarrage. Voici donc comment installer cela avec un Linux, comme centos os 7, qui utilise systemd (sytemctrl) à la place les scripts init.d. On va créer deux fichiers :

a) Le premier est /etc/sysconfig/httpd22 
Il sert à configurer l’environnement et les paramètres à passer au daemon httpd.


OPTIONS="-f /path/to/conf/httpd22.conf"
LANG=C



b) Le second /etc/systemd/system/httpd22.service
Il est utilisé par systemd pour exécuter les commandes start/reload/stop et il fait référence au fichier créé ci-dessus.

[Unit]
Description=The Apache HTTP Server 2.2.x
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
KillMode=none
PIDFile=/path/to/apache22/logs/httpd.pid



EnvironmentFile=/etc/sysconfig/httpd22

ExecStart=/path/to/apache22/bin/httpd  -DFOREGROUND  $OPTIONS
ExecStop=/path/to/apache22/bin/httpd   -k stop       $OPTIONS
ExecReload=/path/to/apache22/bin/httpd -k restart    $OPTIONS

[Install]
WantedBy=multi-user.target



NB: C'est apache qui gère le fichier .pid. Par défaut il est avec les logs de apache, mais on peut changer sa position avec la directive PidFile. Dans ce cas il faut adapter le PIDFile=... dans notre fichier httpd22.service


Après avoir créé ces deux fichiers (et avoir un fichier httpd.conf correct) faire


systemctl daemon-reload
systemctl start httpd22
systemctl status httpd22


Si tout est ok rendre le démarrage automatique

systemctl enable httpd22

Ces 2 fichiers cohabitent très bien avec ceux de httpd 2.4. Si les eux doivent s’exécuter en même temps il faut faire en sorte qu'ils n'utilisent pas le même port en changeant le paramètre "listen 80" dans la config de l'un ou de l'autre.



ATTENTION #2: Quand on se compile un programme (comme ici Apache 2.2) avec ses propres répertoires d'installation on se retrouve avec des fichiers .h ou des librairies à des endroits non standards. Ceci peut poser problèmes par la suite.
Par exemple, si pour utiliser mod_perl on veut installer la librairies Apache2::Request, qui utilise APR::Request, qui est une interface avec la librairie C libapreq2.so, il faudra que le programme d'installation de APR::Request trouve libapreq2.so dans le répertoire ou on a installé notre version d'Apache.
La solution la plus élégante est d'ajouter un fichier apache22.conf dans le répertoire /etc/ld.so.conf.d/ . Ce fichier contiendra juste une ligne du type:

/path/to/apache22/lib

Après quoi on exécute ldconfig pour que ce nouveau chemin soit pris en compte.


Enjoy  2.2 ;-)

08 août 2014

Controle du daemon Apache 2

Les packages précompilés pour Windows tels que WAMP ou XAMPP sont livrés avec une petite interface graphique pour gérer les divers services (daemon). Quand on se compile tout soit même on n’a pas cet outil. Que cela ne tienne !

Voici un batch pour gérer les arrêts/démarrages du daemon httpd d’Apache 2. Il est très pratique quand on met au point une configuration et qu’il faut souvent la recharger.

Il faut obligatoirement exécuter ce batch en faisant  un clic bouton droit dessus et en choisissant « exécuter en tant qu’administrateur ». Il y a dans le script une tentative d’utiliser « runas » pour le lancer en admin directement en tapant  son nom sur la ligne de commande mais il semble que les droits obtenus avec cette méthode ne soient pas suffisants pour installer le service.

Il faut adapter deux variables au début du fichier:
- le path complet de httpd.exe
- le nom de votre compte ayant les droits d’administrateur,

Il est facile d'étendre ce batch en fonction des besoins. On peut ajouter l’ouverture des fichiers de conf dans un éditeur comme notepad++ et l’affichage des logs (facile à faire si on installe la commande tail de gnuwin32)


@echo off
set HTTPD=C:\Path\to\Apache2\bin\httpd.exe
set ADMUSR=admin

if [%USERNAME%] == [%ADMUSR%] goto :init
@echo.
@echo Droits administrateur requis
runas /profile /user:%ADMUSR% %~dpnx0
if ERRORLEVEL 1 pause
goto :eof

:init
rem Fixe la taille visible de la fenêtre
mode con:cols=80 lines=40
rem Fixe la taille du buffer
powershell -command "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=80;$B.height=300;$W.buffersize=$B;}"
call :do_help

:loop
@echo.
set /P OP="Operation (help): "
2>nul call :do_%OP%
if ERRORLEVEL 1 call :erreur
goto :loop

:do_h
:do_help
@echo.
@echo == Operations :
@echo   h = help
@echo   i = info
@echo   install, uninstall
@echo   start, r = restart, stop
@echo   on=(install + start) off=(stop + uninstall)  info
@echo   q = quit
@goto :done

:do_on
@echo on
%HTTPD% -k install
%HTTPD% -k start
@goto :done

:do_off
@echo on
%HTTPD% -k stop
%HTTPD% -k uninstall
@goto :done

:do_i
:do_info
%HTTPD% -v -V
%HTTPD% -l
%HTTPD% -M
@goto :done

:do_r
set OP=restart

:do_install
:do_start
:do_restart
:do_stop
:do_uninstall
@echo on
%HTTPD% -k %OP%


:done
@echo off

rem force le errorlevel à zéro
ver > nul
goto :eof

:erreur
@echo.
@echo ERREUR: "%OP%" n'est une opération valide.
goto :eof


:do_q
:do_quit
:do_exit
exit


Bon, effectivement, il existe le très spartiate Apache Service Monitor  mais qui n’est pas extensible comme notre batch. Son avantage est de pouvoir gérer des serveurs Apache s’exécutant sur des machines Windows distantes.


01 août 2014

DBD-pg ActiveState & MSVC2013

Dernière étape de notre périple : compiler le driver DBI pour postgresql 9.3 sous Windows.

On suppose que sont déjà installés ces 3 logiciels :
-    Visual C/C++ (MSVC 2013)   (la version gratuite dite 'express' est suffisante)
-    Perl d’ActiveState 5.16           (vous devez pouvoir l’exécuter depuis la ligne de commande)
-    PostgreSQL 9.3.x                     (vous devez pouvoir vous y connecter en local)

(les versions sont données à titre indicatif. Il peut y avoir de variations)

1) Préparer le Makefile de DBD-pg

Télécharger ici : http://search.cpan.org/~turnstep/DBD-Pg/
puis décompacter les sources de DBD-pg 3.x

Ouvrir une ligne de commande (cmd.exe) à la racine des sources de DBD-pg
et taper ces 3 commandes:(à adapter suivant les versions de Postgres et de VC)
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
"C:\Program Files (x86)\PostgreSQL\9.3\pg_env.bat"
perl Makefile.PL
Si les environnements VC, Perl et PostgreSQL sont corrects tout se passe bien.

2) Compilation de DBD-pg

Taper la commande
nmake  
Si vous avez l’erreur  'C:\Program' is not recognized as an internal or external command, operable program or batch file. Voir dans l’article sur la compilation de mod_perl comment le corriger.

3) Tests de DBD-pg

Avant de lancer les tests il faut créer un rôle de connexion  ‘test’ et une base de donnée ‘test’ appartenant au rôle ‘test’
NB: Si vous utilisez Postgresql 9.0 ou + récent, il faut que ce rôle ai les droits de superviseur sur la base ‘test’.

Adaptez si nécessaire et taper ces 3 commandes :
Set DBI_DSN=dbi:Pg:dbname=test
Set DBI_USER=test
Set DBI_PASS=xxxx
Puis lancer les tests :
nmake test
* Si vous avez des caractères ou des texte bizarres  et/ou si vous avez des erreurs du type
Failed test 'Dollar quotes with invalid characters are not parsed as identifier
C’est parce que les messages d’erreurs de postgresql ne sont pas en Anglais !
Le test attend « syntax error » et il trouve « erreur de syntaxe », et ça lui va pas...

Pour passer les messages du serveur postgresql en anglais :
Éditer le fichier postgresql.conf (il est dans le répertoire data) et remplacer 
  lc_messages = 'French_France.1252'
par 
  lc_messages = 'en_EN.utf8'

Truc : Pour passer la console Windows en UTF8 taper la commande
chcp 65001


Pour que le changement dans postgresql.conf prenne effet arrêter/redémarrer le serveur postgresql depuis une console en admin :
sc stop postgresql-9.3
sc start postgresql-9.3

* Que faire si vous avez l’erreur suivante ?
    error: permission denied for relation pg_largeobject


Depuis PostgreSQL 9.0 il faut être superuser de la base pour accéder à pg_largeobject.
L’erreur est donc normale si le user ‘test’ n’est pas superuser ET si c'est au moins posgres 9. Vous pouvez lui donner ce droit, refaire les tests.

* Si tout se passe bien ça finit par
...
t/99cleanup.t ....... 1/1 Removing test database directory
t/99cleanup.t ....... ok
All tests successful.
Files=16, Tests=2089, 21 wallclock secs
Result: PASS

 

4) Installation de DBD-pg

Dernière commande:
nmake install
Il s’agit juste de copier des fichiers donc pas de problèmes attendus.


Partez pas !
Il reste à supprimer la base de donnée et le rôle utilisé pour les tests.


31 juillet 2014

mod_perl ActiveState & MSVC 2013

Après ce mémo sur compilation de Apache 2.2.x avec MSCV 2013 voici la compilation de mod_perl 2.0.x en utilisant le perl de ActiveState. (Avec Strawberry c’est encore plus compliqué car il utilise le compilateur gcc de MinGW)

Le Perl utilisé doit être au minimum 5.8.2 et être compilé avec les options usethreads , useithreads et usemultiplicity.  Pour le vérifier taper: perl –V:uses.+

En théorie il suffit de 4 commandes pour installer mod_perl
perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x
nmake
nmake test
nmake install
Malheureusement il y a quelques bugs…


1) Première étape, premier bug

Télécharger les sources de mod_perl 2.0.x ici : http://apache.org/dist/perl/

Assurez vous d’avoir le Perl et le bin de msvc dans le PATH puis, depuis la racine des sources de mod_perl, tapez ces 3 commandes:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
set MP_USE_MY_EXTUTILS_EMBED=1
perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x


Premier problèmes; Vous n’avez pas la librairie apxs.
Il propose de la télécharger, mais l’url est invalide.

Install apxs now? [yes]
Download of http://perl.apache.org/dist/win32-bin/apxs_win32.tar.gz failed


La bonne url est: https://archive.apache.org/dist/perl/win32-bin/apxs_win32.tar.gz

Il faut éditer le fichier build\win32_fetch_apxs et remplacer
    my $remote = 'http://perl.apache.org/dist/win32-bin/' . $file;
par
    my $remote = 'https://archive.apache.org/dist/perl/win32-bin/' . $file;

Cette fois le commande perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x  doit aboutir.


2) Deuxième étape (compilation), deuxième bug

L'étape suivante consiste à exécuter (toujours depuis la racine des sources de mod_perl)
nmake
Mais ça ne marche pas car on obtient :

'C:\Program' is not recognized as an internal or external command, operable program or batch file.
NMAKE : fatal error U1077: 'cd' : return code '0x1'
Stop.


Il faudrait éditer le fichier Makefile et ajouter les quotes au path de MAKE.

MAKE = C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\nmake.exe

mais ce bug est dans tous les Makefile des sous répertoires. Au total cela en fait plus de 60 !

La solution que j’utilise est d'éditer le module \Perl\lib\ActivePerl\Config.pm  et d’ajouter des quotes autour de $prog
for (@make) {
    if (my $prog = _find_prog($_)) {
    $_[0] = $OVERRIDE{$key} = "\"$prog\"";
Mais en ajoutant ces quotes on rend une expression régulière invalide. Il faut éditer \Perl\lib\ExtUtils\MM_Win32.pm et corriger la fonction is_make_type() en supprimant le $ de la fin de l’expression régulière
sub is_make_type {
    my($self, $type) = @_;
    return !! ($self->make =~ /\b$type(?:\.exe)?$/);
}
Avec ces 2 modifs on peut exécuter nmake sans avoir d'erreurs.


3) Troisième étape (tests), troisième bug
nmake test
Le daemon httpd.exe va être exécuté, certains tests ne sont pas exécutés s’il manque des dépendances mais certains vont échouer (en tout cas avec la version mod_perl 2.0.8) !
t/api/err_headers_out.t (Wstat: 0 Tests: 6 Failed: 3)
Failed tests: 2-3, 5
Files=1, Tests=6, 2 

Result: FAIL
Failed 1/1 test programs. 3/6 subtests failed. 

Solution: Dans le fichier t\api\err_headers_out.t il faut remplacer à deux endroits:
  if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION==6.00;
par
  if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION>=6.00;

Avec ces 2 modifs on peut exécuter nmake test sans avoir d'erreurs.


4) Dernière étape
nmake install
et ça marche (enfin) !