Configuración dinámica en Apache ~ Nov 15, 2008
Una de las cosas más bonitas que puedes hacer gracias a mod_perl, son las PerlSections.
Básicamente con éstas, lo que puedes hacer es definir dinámicamente directivas de configuración de Apache y hacer cosas bien interesantes. Por ejemplo, recientemente, para Planeta Linux quería tener una sola configuración de Apache para los virtual hosts que son repetitivos dada cada instancia (mx.planetalinux.org, ve.planetalinux.org, gt.planetalinux.org, etc). Precisamente lo que quiero evitar es tener que poner una interminable lista de VirtualHost's, así que lo puedo hacer con secciones en Perl (que son denotadas en cualquier archivo de configuración en Apache con <Perl> y </Perl>):
<Perl>
my $names = { cl => 'PlanetaLinuxChile', co => 'PlanetaLinuxColombia', cr => 'PlanetaLinuxCostaRica', ec => 'PlanetaLinuxEcuador', sv => 'PlanetaLinuxElSalvador', es => 'PlanetaLinuxEspana', gt => 'PlanetaLinuxGuatemala', mx => 'PlanetaLinuxMexico', ni => 'PlanetaLinuxNicaragua', pa => 'PlanetaLinuxPanama', pe => 'PlanetaLinuxPeru', ve => 'PlanetaLinuxVenezuela', debian => 'PlanetaDebian', };
Defino una referencia a hash en $names que lista contra los "TLDs" de cada instancia y con su nombre largo.
my $instancias = [keys %{$names}];
Para facilitar trabajar con las llaves, creo una referencia a un arreglo que contiene exclusivamente las llaves del hash que previamente tenía definido.
$VirtualHost{"*:80"} = [];
Como voy a definir todos mis VirtualHost's apuntando hacia "*:80", defino el valor de la llave "*:80" del hash pre-definido $VirtualHost (pre-definido por mod_perl), hacia una referencia de arreglo vacío (por el momento).
for my $pais(@{$instancias}) {
Empiezo a interar cada uno de los elementos de $instancias y asigno cada valor en la interación a $pais.
my $vhost = $pais.".planetalinux.org"; if ($pais eq 'debian') { $vhost = 'planeta.debian.net'; }
El nombre del servidor será $pais.".planetalinux.org", a menos que sea "debian", que no lleva el dominio de Planeta Linux.
my $virtualh = { SuexecUserGroup => ["planetalinux", "planetalinux"], ServerAdmin => 'planetalinux@googlegroups.com', ServerName => $vhost, DocumentRoot => "/var/www/planetalinux/".$vhost, ErrorLog => "/var/log/apache2/planetalinux_".$pais."_error", CustomLog => ["/var/log/apache2/planetalinux_".$pais."_access", "combined"], LogLevel => "info", Alias => ["/images/", "/home/planetalinux/current/www/instancias/".$pais."/images/"], Redirect => ["/rss20.xml", "http://feedproxy.google.com/".$names->{$pais}], };
Aquí defino la referencia al hash principal del virtual host. Los valores son definidos con los nombres de las directivas que utiliza Apache:
SuexecUserGroup, pues utilizamos suexec en el servidor se asigna a una referencia de arreglo anónima con dos valores, que son los dos valores que se le pasan a Apache en sus directivas regulares.ServerAdmin, es el mismo para todas las instancias, nuestra lista de correos.ServerName, es el nombre que definí previamente como$vhost.DocumentRoot, depende también de$vhostpues así lo tenemos definido en nuestro sistema de archivos.ErrorLog, caso similar aDocumentRoot.CustomLog, caso similar a ErrorLog, pero defino, igual que enSuexecUserGroup, un arreglo anónimo con los dos valores que toma este parámetro.LogLevel, igual que en Apache.Alias. Defino un alias simple.Redirect, puedo utilizar cualquier tipo de directivas,Alias,Redirect, lo que sea. En este caso, realizo la redirección de los viejos feeds"/rss20.xml"hacia la nueva URL de FeedBurner, que es ahora como manejamos los feeds en Planeta Linux. El valor que se concatena al final es el valor del hash%{$names}dada la llave$pais.
push @{$VirtualHost{"*:80"}}, $virtualh;
Agrego cada $virtualh al arreglo de VirtualHosts en "*:80". Si tuviera una IP por cada uno de los VirtualHosts, no es necesario hacer push a un arreglo, simplemente tendría que declarar las variables $VirtualHost con la IP como llave. Sin embargo, si declaro muchas veces la misma variable, como en este caso, $VirtualHost{"*:80"}, en cada interación el valor se reescribirá, es por eso que mod_perl nos ofrece definir esa variable como referecia a arreglo en donde podemos meter cuantos virtual hosts como queramos.
}
Termino el ciclo for.
</Perl>
Las posibilidades son muchas para la configuración dinámica de Apache y en secciones Perl puedes utilizar cualquier cosa, abrir tus archivos para ver otros parámetros de configuración, conectarte a bases de datos para sacar información, lo que sea.
Si te interesa ver todo el archivo de configuración, está acá, en el GitHub público de Planeta Linux.




Se ve muy chido, solo faltaria probarlo.
Lo que no me queda claro es si la seccion de perl va dentro del httpd.conf o apache2.conf.
Y ¿qué pasaría si en otra parte si tuviera definida alguna directiva que tambien se definiera dentro de un bloque de perl?
¿Para usarlo sólo se requiere instalar mod_perl? o hay otra configuracion, modulo, o truco que hacer antes de usarlo?
Juan Lopez
17 Nov 08 at 1:32 pm
@Juan Lopez:
1. En realidad lo puedes incluir en cualquier archivo de configuración. Lo ideal desde mi punto de vista es que lo agregues en tus archivos en sites-available y luego simplemente lo actives con a2ensite. O, que lo pongas dentro de conf.d/.
2. Puedes definir tantos PerlSections como quieras, algo como:
<Perl>
$ServerName = `host`;
</Perl>
ServerAlias midominio.estatico
<Perl>
ErrorLog = ["una cosa", "otra"]
</Perl>
¿Te refieres a eso?
3. Para utilizarlo, al menos en sistemas Debian sólo basta con que instales libapache2-mod-perl2 y luego habilites el módulo en apache con: a2enmod perl
admin
17 Nov 08 at 1:38 pm