Instalando dependencias no-libres de JAVA en ambientes pbuilder

El día de hoy asumí la construcción de unos paquetes internos compatibles con Debian 5.0 (a.k.a. Lenny) que anteriormente eran responsabilidad de ex-compañeros de labores. El paquete en cuestión posee una dependencia no-libre, sun-java6-jre. En este artículo se describirá como lograr adecuar su configuración de pbuilder para la correcta construcción del paquete.

Asumiendo que tiene un configuración similar a la siguiente:

$ cat /etc/pbuilderrc
MIRRORSITE=http://example.com/debian
DEBEMAIL="Maintainer Name <[email protected]>"
DISTRIBUTION=lenny
DEBOOTSTRAP="cdebootstrap"
COMPONENTS="main contrib non-free"

Para mayor información sobre estas opciones sírvase leer:

$ man 5 pbuilderrc

Mientras intenta compilar su paquete en el ambiente proporcionado por pbuilder el proceso fallará ya que no se mostró la ventana para aceptar la licencia de JAVA. Podrá observar en el registro de la construcción del build un mensaje similar al siguiente:

Unpacking sun-java6-jre (from .../sun-java6-jre_6-20-0lenny1_all.deb) ...

sun-dlj-v1-1 license could not be presented
try 'dpkg-reconfigure debconf' to select a frontend other than noninteractive

dpkg: error processing /var/cache/apt/archives/sun-java6-jre_6-20-0lenny1_all.deb (--unpack):
subprocess pre-installation script returned error exit status 2

Para evitar esto altere la configuración del fichero pbuilderrc de la siguiente manera:

$ cat /etc/pbuilderrc
MIRRORSITE=http://example.com/debian
DEBEMAIL="Maintainer Name <[email protected]>"
DISTRIBUTION=lenny
DEBOOTSTRAP="cdebootstrap"
COMPONENTS="main contrib non-free"
export DEBIAN_FRONTEND="readline"

Una vez alterada la configuración podrá interactuar con las opciones que le ofrece debconf.

Ahora bien, si usted constantemente tiene que construir paquetes con dependencias no-libres como las de JAVA, es probable que le interese lo que se menciona a continuación.

Si lee detenidamente la página del manual de pbuilder en su sección 8 podrá encontrar lo siguiente:

$ man 8 pbuilder
...
--save-after-login
--save-after-exec
Save the chroot image after exiting from the chroot instead of deleting changes.  Effective for login and execute session.
...

Por lo tanto, usaremos esta funcionalidad que ofrece pbuilder para insertar valores por omisión en la base de datos de debconf para que no se nos pregunte si deseamos aceptar la licencia de JAVA:

# pbuilder login --save-after-login
I: Building the build Environment
I: extracting base tarball [/var/cache/pbuilder/base.tgz]
I: creating local configuration
I: copying local configuration
I: mounting /proc filesystem
I: mounting /dev/pts filesystem
I: Mounting /var/cache/pbuilder/ccache
I: policy-rc.d already exists
I: Obtaining the cached apt archive contents
I: entering the shell
File extracted to: /var/cache/pbuilder/build//27657

pbuilder:/# cat > java-license << EOF
> sun-java6-bin shared/accepted-sun-dlj-v1-1 boolean true
> sun-java6-jdk shared/accepted-sun-dlj-v1-1 boolean true
> sun-java6-jre shared/accepted-sun-dlj-v1-1 boolean true
> EOF
pbuilder:/# debconf-set-selections < java-license
pbuilder:/# exit
logout
I: Copying back the cached apt archive contents
I: Saving the results, modifications to this session will persist
I: unmounting /var/cache/pbuilder/ccache filesystem
I: unmounting dev/pts filesystem
I: unmounting proc filesystem
I: creating base tarball [/var/cache/pbuilder/base.tgz]
I: cleaning the build env
I: removing directory /var/cache/pbuilder/build//27657 and its subdirectories
2 min read

Presentaciones

Desde hace algunos meses he decidido recopilar y organizar algunas de las presentaciones que he dado hasta ahora en eventos de Software Libre, Universidades y empresas privadas.

El software que regularmente utilizo para realizar mis presentaciones es Beamer, una clase LaTeX que facilita enormente la producción de presentaciones de alta calidad, este software trabaja de la mano con pdflatex, también con dvips.

La lista de presentaciones que he recopilado hasta la fecha son las siguientes:

  • Análisis estático del código fuente en Python: Describe el concepto del análisis estático del código, se indica los pasos a seguir para la detección de errores mediante la herramienta Pylint, se exponen sus funcionalidades, reportes y se muestran ejemplos para corregir los errores encontrados por la herramienta.
  • Desarrollo colectivo en Turpial: Describe la visión del cliente para Twitter Turpial, sus funcionalidades actuales, el uso de herramientas como Transifex, PyBabel, Distutils, Sphinx, dichas herramientas facilitan y mejoran la calidad del software que se desarrolla.
  • Canaima GNU/Linux: Una introducción, se describe la historia, definición del proyecto Canaima, principales características, procesos para colaborar, enlaces de interés, entre otros.
  • Novela gráfica creada con el motor Ren’Py: Relata la experiencia del desarrollo de una novela gráfica para niños de 5to. grado de educación, de acuerdo a currículo impartido en las escuelas venezolanas.
  • Trac: Herramientas libres para el apoyo en el proceso de desarrollo de software, se discute las características y funcionalidades que ofrece el software. Además del proceso de personalización por medio de complementos o plugins.
  • GnuPG, GNU Privacy Guard: Importancia del cifrado de la información, diferencias entre llaves simétricas y asimétricas, criptografía, fiestas de firmado de llaves, beneficios. Instalación y suo práctico de GnuPG.
  • Uso de dbconfig-common: Presentación que es parte de la serie mejores prácticas para el empaquetamiento de aplicaciones en Debian, se describe el uso de la herramienta y su respectiva integración con el asistente debhelper
  • Conociendo el framework web Django: Introducción, historia, características, primeros pasos, instalación y demostración de desarrollo de una aplicación sencilla bajo este excelente framework basado en el lenguaje de Programación Python

Las fuentes en LaTeX de las presentaciones, así como su licencia de uso y proceso de conversión al formato PDF se describe en el proyecto Presentations que he creado en github.

Agradezco enormemente cualquier comentario que pueda hacer respecto a los temas presentados puesto que en el próximo mes trataré de actualizar el contenido, así como incluir nuevas presentaciones. ¿Desearía poder conocer más sobre un tema en particular?, ¿cuál sería ese tema?.

Nota final: Si encuentra algún error por favor notificarlo vía issues del proyecto Presentations.

2 min read

Mejoras en el comportamiento a la hora de eliminar un ForeignKey

Logo de Django Cuando un objeto referenciado por una clave foránea (ForeignKey) es eliminado, Django por omisión emula el comportamiento de la sentencia SQL ON DELETE CASCADE y también se elimina el objeto que contiene el ForeignKey.

A partir de la versión 1.3 de Django el comportamiento descrito en el párrafo anterior puede ser sobreescrito al especificar el argumento on_delete. Por ejemplo, si usted permite que una clave foránea pueda ser nula y usted desea que sea establecida a NULL cuando un objeto referenciado sea eliminado:

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)

Los posibles valores para el argumento on_delete pueden encontrarse en django.db.models:

  • CASCADE: Eliminación en cascada, el comportamiento por omisión.
  • PROTECT: Prevee la eliminación del objeto referenciado al lanzar una excepción del tipo: django.db-IntegrityError.
  • SET_NULL: Establece la clave foránea a NULL, esto solo es posible si el argumento null es True.
  • SET_DEFAULT: Establece la clave foránea a su valor por omisión, tenga en cuenta que un valor por omisión debe ser establecido.
  • SET(): Establece el valor del ForeignKey indicado en SET(), si una función es invocada, el resultado de dicha función será el valor establecido.
  • DO_NOTHING: No tomar acciones. Si el gestor de base de datos requiere integridad referencial, esto causará una excepción del tipo IntegrityError.

A continuación un par de ejemplos de esta nueva funcionalidad:

# models.py
from django.db import models

class Author(models.Model):
    nickname = models.CharField(max_length=32)

    def __unicode__(self):
        return self.nickname

class Post(models.Model):
    author = models.ForeignKey(Author, blank=True, null=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=128)

    def __unicode__(self):
        return self.title

Nuestra sesión interactiva con el API sería similar a la siguiente:

$ python manage.py shell
>>> from ondelete.models import Author, Post

>>> Author.objects.all()
[]
# Creamos el autor
>>> author = Author(nickname='milmazz')
# Guardamos el objeto en la base de datos al usar de manera explícita el método save()
>>> author.save()

# Obtenemos el autor en base a su id
>>> Author.objects.get(pk=1)
<Author: milmazz>

# Creamos par de artículos
>>> article1 = Post(author=author, title="Article 1")
>>> article1.save()

>>> article2 = Post(author=author, title="Article 2")
>>> article2.save()

>>> for article in Post.objects.all():
     print("%s by %s" % (article.title, article.author))
Article 1 by milmazz
Article 2 by milmazz

# Eliminamos el autor
>>> author.delete()

>>> for article in Post.objects.all():
    print("%s by %s" % (article.title, article.author))
Article 1 by None
Article 2 by None

Un segundo ejemplo, ahora haciendo uso del valor SET() en el argumento on_delete:

# models.py
from django.db import models
from django.contrib.auth.models import User

def get_superuser():
    return User.objects.get(pk=1)

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_superuser))
    title = models.CharField(max_length=128)

    def __unicode__(self):
        return self.title

Nuestra sesión interactiva con el API sería similar a la siguiente:

$ python manage.py shell
>>> from ondelete.models import Post
>>> from django.contrib.auth.models import User

>>> User.objects.all()
[<User: milmazz>]
# Creamos un nuevo usuario
>>> author = User(username='milton')
# Guardamos el objeto en la base de datos,
# de manera explícita al invocar el método save()
>>> author.save()
# Vista de los usuarios registrados en la base de datos
>>> User.objects.all()
[<User: milmazz>, <User: milton>]

# Creamos par de artículos
>>> article1 = Post(user=author, title="Article 1")
>>> article1.save()

>>> article2 = Post(user=author, title="Article 2")
>>> article2.save()

>>> for article in Post.objects.all():
     print("%s by %s" % (article.title, article.user))
Article 1 by milton
Article 2 by milton

# Eliminamos el usuario 'milton'
>>> author.delete()

>>> for article in Post.objects.all():
    print("%s by %s" % (article.title, article.user))
Article 1 by milmazz
Article 2 by milmazz
2 min read

Subversion: Notificaciones vía correo electrónico

Al darse un proceso de desarrollo colectivo es recomendable mantener una o varias listas de notificación acerca de los cambios hechos (commits) en el repositorio de código fuente. Para este tipo de actividades es muy útil emplear SVN::Notify.

SVN::Notify le ofrece un número considerable de opciones, a continuación resumo algunas de ellas:

  • Obtiene información relevante acerca de los cambios ocurridos en el repositorio Subversion.
  • Realiza análisis sobre la información recolectada y brinda la posibilidad de reconocer distintos formatos vía filtros (Ej. Textile, Markdown, Trac).
  • Puede obtener la salida tanto en texto sin formato como en XHTML.
  • Le brinda la posibilidad de construir correos electrónicos en base a la salida obtenida.
  • Permite el envío de correo, ya sea por el comando sendmail o SMTP.
  • Es posible indicar el método de autenticación ante el servidor SMTP.

Para instalar el SVN::Notify en sistemas Debian o derivados proceda de la siguiente manera:

# aptitude install libsvn-notify-perl

Una vez instalado SVN::Notify, es hora de definir su comportamiento. Aunque es posible hacerlo vía comando svnnotify y empotrarlo en un script escrito en Bash he preferido hacerlo en Perl, es más natural y legible hacerlo de este modo.

#!/usr/bin/perl -w

use strict;
use SVN::Notify;

my $path = $ARGV[0];
my $rev  = $ARGV[1];

my %params = (
    repos_path      => $path,
    revision        => $rev,
    handler         => 'HTML::ColorDiff',
    trac_url        => 'http://trac.example.com/project',
    filters         => ['Trac'],
    with_diff       => 1,
    diff_switches   => '--no-diff-added --no-diff-deleted',
    subject_cx      => 1,
    strip_cx_regex  => [ '^trunk/', '^branches/', '^tags/' ],
    footer          => 'Administrado por: BOFH ',
    max_sub_length  => 72,
    max_diff_length => 1024,
    from            => '[email protected]',
    subject_prefix  => '[project]',
    smtp            => 'smtp.example.com',
    smtp_user       => 'example',
    smtp_pass       => 'example',
);

my $developers = '[email protected]';
my $admins     = '[email protected]';

$params{to_regex_map} = {
    $developers => '^trunk|^branches',
    $admins     => '^tags|^trunk'
};

my $notifier = SVN::Notify->new(%params);
$notifier->prepare;
$notifier->execute;

Si seguimos con el ejemplo indicado en el artículo anterior, Instalación básica de Trac y Subversion, este hook lo vamos a colocar en /srv/svn/project/hooks/post-commit, dicho fichero deberá tener permisos de ejecución para el Servidor Web Apache.

Con este sencillo script en Perl se ha logrado lo siguiente:

  • La salida se generará en XHTML.
  • Las diferencias de código serán resaltadas o coloreadas, esto es posible por el handler SVN::Notify::ColorDiff
  • El sistema de notificación está integrado a la sintaxis de enlaces de Trac. Por lo tanto, los commits que posean este tipo de enlaces serán interpretados correctamente. Ej. #123 changeset:234 r234

Muestra del coloreado que ofrece SVN::Notify

Aunque el código es sucinto y claro, trataré de resumir cada uno de los parámetros utilizados.

  • repos_path: Define la ruta al repositorio Subversion, la cual es obtenida a partir del primer argumento que pasa Subversion al ejecutar el hook post-commit.
  • revision: El número de la revisión del commit actual. El número de la revisión se obtiene a partir del segundo argumento que pasa Subversion al ejecutar el hook post-commit
  • handler: Especifica una subclase de SVN::Notify que será utilizada para el manejo de las notificaciones. En el ejemplo se hace uso de HTML::ColorDiff, el cual permite colorear o resaltar la sintaxis del comando svnlook diff
  • trac_url: Este parámetro será usado para generar enlaces al Trac para los números de revisiones y similares en el mensaje de notificación.
  • filters: Especifica la carga de más módulos que terminan de difinir la salida de la notificación. En el ejemplo, se hace uso del filtro Trac, filtro que convierte el log del commit que cumple con el formato de Trac a HTML.
  • with_diff: Valor lógico que especifica si será o no incluida la salida del comando svnlook diff en la notificación vía correo electrónico.
  • diff_switches: Permite el pase de opciones al comando svnlook diff, en particular recomiendo utilizar --no-diff-deleted y --no-diff-added para evitar ver las diferencias para los archivos borrados y añadidos respectivamente.
  • subject_cx: Valor lógico que indica si incluir o nó el contexto del commit en la línea de asunto del correo electrónico de notificación.
  • strip_cx_regex: Acá se indican las expresiones regulares que serán utilizadas para eliminar información del contexto de la línea de asunto del correo electrónico de notificación.
  • footer: Agrega la cadena definida al final del cuerpo del correo electrónico de notificación
  • max_sub_length: Indica la longitud máxima de la línea de asunto del correo electrónico de notificación.
  • max_diff_length: Máxima longitud del diff (esté adjunto o en el cuerpo de la notificación).
  • from: Define la dirección de correo que será usada en la línea From. Si no se especifica será utilizado el nombre de usuario definido en el commit, esta información se obtiene vía el comando svnlook.
  • subject_prefix: Define una cadena de texto que será el prefijo de la línea correspondiente al asunto del correo electrónico de notificación.
  • smtp: Indica la dirección para el servidor SMTP que el cual se enviarán las notificaciones de correo electrónico. Si no se utiliza este parámetro, SVN::Notify utilizará el comando sendmail para el envío del mensaje.
  • smtp_user: El nombre de usuario para la autenticación SMTP.
  • smtp_pass: Contraseña para la autenticación SMTP
  • to_regex_map: Este parámetro contiene un hash que mantiene referencias de direcciones de correo electrónico contra expresiones regulares. La idea es enviar las notificaciones si y solo si el nombre de uno o más directorios son afectados por un commit y dicha ruta coincide con las expresiones regulares definidas. Este parámetro resulta muy útil en proyectos de desarrollo de software grandes y donde es posible disponer de varias listas de correo para informar a los desarrolladores interesados en secciones específicas. Para mayor detalle de las opciones mencionadas previamente vea SVN::Notify, acá también encontrará más opciones de configuración.

Observación

Hasta ahora he encontrado que el coloreado o resaltado de la sintaxis no funciona en algunos sistemas Webmail, como por ejemplo Gmail, SquirrelMail. Sin embargo, en otros sistemas Webmail como RoundCube si funciona. Este comportamiento se presenta porque en sistemas como Gmail las hojas de estilos en cascada (CSS) internas no son aplicadas en la interfaz. Es por ello que en estos casos es necesario recurrir a la definición de estilos en línea.

4 min read

Instalación básica de Trac y Subversion

En este artículo se pretenderá mostrarle el proceso de instalación de un ambiente de desarrollo que le permitirá hacerle seguimiento a su proyecto personal, de igual manera se le indicará el modo en el cual puede comenzar a utilizar un sistema de control de versiones. Todas las indicaciones mostradas en este documento han sido probadas en la distribución Debian GNU/Linux 5.0 (nombre código Lenny).

La herramienta de seguimiento o manejo del proyecto que se procederá a instalar es Trac, el sistema de control de versiones que se presentará será Subversion. Todo lo anterior se presentará vía Web haciendo uso del servidor Apache, de manera adicional se utilizará el servidor de bases de datos PostgreSQL como backend de Trac.

Dependencias

En primer lugar proceda a instalar las siguientes dependencias.

# aptitude install apache2 \
libapache2-mod-python \
postgresql \
subversion \
python-psycopg2 \
libapache2-svn \
python-subversion \
trac

La versión de Trac que se encuentra en los archivos de Debian Lenny es estable (0.11.1). Sin embargo, si usted compara esta versión con lo publicado en el sitio oficial de Trac, podrá encontrar que existen nuevas versiones estables de mantenimiento que contienen correcciones a errores de programación y algunas nuevas funcionalidades de bajo impacto, para el momento de la redacción de este artículo se encuentra la versión 0.11.7. Es recomendable que utilice el paquete trac desde el archivo backports de Debian.

# aptitude -t lenny-backports install trac

Si desea usar el paquete proveniente del archivo backports le recomiendo leer las instrucciones de uso de este repositorio de paquetes.

Con el fin de mantener este artículo lo más sencillo y conciso posible se describirá la versión que viene por defecto con la distribución utilizada en este caso.

Versión de desarrollo de Trac

Si desea conocer algunas características interesantes que se han agregado a Trac en las nuevas versiones, o si su interés particular es examinar las bondades que le ofrece Trac en su versión de desarrollo puede hacer uso del comando pip, si no tiene instalado pip proceda como sigue:

# aptitude install python-setuptools
# easy_install pip

Proceda a instalar la versión de desarrollo de Trac.

# pip install https://svn.edgewall.org/repos/trac/trunk

Creación de usuario y base de datos

Antes de proceder con la instalación de Trac se debe establecer el usuario y la base de datos que se utilizará para trabajar.

En el siguiente ejemplo el usuario de la base de datos PostgreSQL que utilizará Trac será trac_user, su contraseña será trac_passwd. El uso de la contraseña lo del usuario trac_user lo veremos más tarde al proceder a configurar el ambiente de Trac.

# su postgres
$ createuser \
--no-superuser \
--no-createdb \
--no-createrole \
--pwprompt \
--encrypted trac_user
Enter password for new role:
Enter it again:
CREATE ROLE

Nótese que se debe utilizar el usuario postgres (u otro usuario con los privilegios necesarios) del sistema para proceder a crear los usuarios.

Ahora procedemos a crear la base de datos trac_dev, cuyo dueño será el usuario trac_user.

$ createdb --encoding UTF8 --owner trac_user trac_dev

Ambiente de Trac

Creamos el directorio /srv/www que será utilizado para prestar servicios Web, para mayor referencia acerca de esta elección se le recomienda leer el documento Filesystem Hierarchy Standard en su versión 2.3.

$ sudo mkdir -p /srv/www
$ cd /srv/www

Generamos el ambiente de Trac. Básicamente se deben contestar ciertas preguntas como:

  • Nombre del proyecto.
  • Enlace con la base de datos que se utilizará.
  • Sistema de control de versiones a utilizar (por defecto será SVN).
  • Ubicación absoluta del repositorio a utilizar.
  • Ubicación de las plantillas de Trac.

En el siguiente ejemplo se omitirán los comentarios brindados por el comando trac-admin.

# trac-admin project initenv
Creating a new Trac environment at /srv/www/project

...

Project Name [My Project]> Demo

...

Database connection string [sqlite:db/trac.db]>
postgres://trac_user:trac_passwd@localhost:5432/trac_dev

...

Repository type [svn]>

...

Path to repository [/path/to/repos]> /srv/svn/project

...

Templates directory [/usr/share/trac/templates]>

Creating and Initializing Project
 Installing default wiki pages

...

---------------------------------------------------------
Project environment for 'Demo' created.

You may now configure the environment by editing the file:

  /srv/www/project/conf/trac.ini

...

Congratulations!

Se ha culminado la instalación del ambiente de Trac, ahora procederemos a crear el ambiente de subversion.

Subversion: Sistema Control de Versiones

La puesta a punto del sistema de control de versiones es bastante sencilla, se resume en los siguientes pasos.

Creación del espacio para prestar el servicio SVN, de igual manera se seguirá los lineamientos planteados en el FHS v2.3 mencionado previamente.

# mkdir -p /srv/svn

Seguidamente crearemos el proyecto subversion project y haremos un importe inicial con la estructura básica de un proyecto de desarrollo de software.

$ cd /srv/svn
# svnadmin create project
$ mkdir -p /tmp/project/{trunk,tags,branches}
$ tree /tmp/project/
/tmp/project/
├── branches
├── tags
└── trunk
# svn import /tmp/project/ \
file:///srv/svn/project/ \
-m 'Importe inicial'

Adding         /tmp/project/trunk
Adding         /tmp/project/branches
Adding         /tmp/project/tags

Committed revision 1.

Apache: Servidor Web

Es hora de configurar los sitios virtuales que utilizaremos tanto para Trac como para subversion.

A continuación se presenta la configuración básica de Trac.

# cat > /etc/apache2/sites-available/trac.example.com <<EOF
> <VirtualHost *>
> ServerAdmin webmaster@localhost
> ServerName trac.example.com
> CustomLog /var/log/apache2/trac.example.com/access.log combined
> ServerSignature Off
> ErrorLog /var/log/apache2/trac.example.com/error.log
> LogLevel warn
> DocumentRoot /srv/www/project
> <Location />
> SetHandler mod_python
> PythonInterpreter main_interpreter
> PythonHandler trac.web.modpython_frontend
> PythonOption TracEnv /srv/www/project
> PythonOption TracUriRoot /
> </Location>
> </VirtualHost>
> EOF

Ahora veamos la configuración básica de nuestro proyecto subversion.

# cat > /etc/apache2/sites-available/svn.example.com <<EOF
> <VirtualHost *>
> ServerAdmin webmaster@localhost
> ServerName svn.example.com
> CustomLog /var/log/apache2/svn.example.com/access.log combined
> ServerSignature Off
> ErrorLog /var/log/apache2/svn.example.com/error.log
> LogLevel warn
> DocumentRoot /srv/svn/project
> <Location />
> DAV svn
> SVNPath /srv/svn/project
> </Location>
> </VirtualHost>
> EOF

De acuerdo a la configuración mostrada es necesario crear los directorios /var/log/apache2/svn.example.com y /var/log/apache2/trac.example.com para mantener por separado el registro de accesos y errores de los sitios virtuales recién creados. De lo contrario no podremos iniciar el servidor Web Apache.

# mkdir /var/log/apache2/{svn,trac}.example.com

Activamos el módulo DAV necesario para cumplir con la configuración mostrada para el sitio virtual svn.example.com.

# a2enmod dav

Activamos los sitios virtuales recién creados.

# a2ensite trac.example.com
# a2ensite svn.example.com

Como la puesta en marcha y configuración de un servidor DNS escapa a los fines de este artículo, simplemente definiremos los hosts en la tabla estática que se encuentra definida en el archivo /etc/hosts de la siguiente manera.

# cat >> /etc/hosts <<EOF
> 127.0.0.1 trac.example.com trac
> 127.0.0.1 svn.example.com svn
> EOF

Finalmente debemos forzar la recarga de la configuración del servidor Web Apache, esto con el fin de cargar el módulo DAV y los sitios virtuales definidos, es decir, trac.example.com y svn.example.com.

# /etc/init.d/apache2 force-reload

¡Felicitaciones!, ya puede ir a su navegador favorito y colocar cualquiera de los sitios virtuales que acaba de definir.

Recomendaciones

Una vez que haya llegado a este sección deberá comenzar a modificar adecuadamente los permisos para el usuario y grupo www-data (Servidor Web Apache) para que escriba en las ubicaciones que sea necesario tanto en Trac como en subversion.

La configuración de Trac podrá encontrarla en /srv/www/project/conf/trac.ini, para mayor detalle acerca de la configuración de este fichero se le recomienda leer el documento TracIni.

Si en su proyecto prevé que participarán otras personas, es recomendable establecer notificaciones de tickets y cambios en el repositorio subversion, para esto último deberá revisar el hook post-commit y la documentación del paquete libsvn-notify-perl que le ofrece una extraordinaria cantidad de opciones.

Conozca el entorno de Trac y Subversion. Si desea agregar nuevas funciones a su instalación le recomiendo visitar el sitio Trac Hacks.

Espero poder mostrarles en próximos artículos algunas configuraciones más avanzadas en Trac, incluyendo la instalación, configuración y uso de plugins.

6 min read