Mostrando las entradas con la etiqueta Ubuntu. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Ubuntu. Mostrar todas las entradas

viernes, 6 de abril de 2007

Construyendo proyectos con Maven 2

Maven es una excelente herramienta que nos permite simplificar el proceso de construcción de un proyecto (jar, ear, ejb, war, etc). La herramienta es tan poderosa que se ha convertido en una de mis favoritas, y la uso prácticamente todos los días. Alguna de las características que la han convertido en indispensable son:

  1. Se puede construir, ejecutar tests y empaquetar un proyecto con un solo comando.
  2. Permite administrar las dependencias de un proyecto de forma eficiente
  3. Permite unificar la estructura de los proyectos
  4. Permite generar una pagina web del proyecto con información general y con reportes variados relacionados al proyecto.
  5. Define una guia de buenas practicas de desarrollo

Quizás lo mas interesante es el primer punto ya que es lo que uno hace en el día a día. Por ejemplo, para generar un war el comando seria

$ mvn clean war:war

La definición del proyecto se hace en el archivo pom.xml y debe estar ubicado en el directorio raíz del proyecto. Allí se define información general del proyecto así como todas las dependencias del mismo.

La instalación es bien sencilla:

  1. Bajar maven 2.0.x del site de Apache
  2. Unzip maven en algun directorio. Ejm: /home/usuario/maven
  3. Agregar al PATH el dir bin de maven.

  4. export PATH=$PATH:/home/usuario/maven/bin:

  5. Agregar la variable MAVEN_OPTS al ambiente. Esta variable define parametros del JVM para maven.

  6. $ export MAVEN_OPTS=-Xmx256M

  7. Crear el archivo settings.xml en el directorio {home}/.m2 del usuario. Este archivo contiene variables de configuración globales de MAVEN. A continuación se tiene un ejemplo del archivo

  8. <settings>
    <localRepository>/home/usuario/m2_local_repo</localRepository>
    <proxies />
    <servers />
    <mirrors />
    <profiles />
    </settings>

  9. La entrada localRepository debe apuntar a donde estar el repositorio local de maven. Es aquí donde maven almacena todas las dependencias de nuestros proyectos.
  10. Probar la instalación

  11. $ mvn --version
    Maven version: 2.0.6

  12. Ahora solo falta crear el pom.xml de un proyecto y listo. Supongamos que tenemos un proyecto A que debe generar un war. El pom.xml puede ser como:


  13. <?xml version="1.0" encoding="UTF-8"?>
    <project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.test.maven</groupId>
    <artifactId>proyectoA</artifactId>
    <packaging>war</packaging>
    <name>Proyecto A</name>
    <version>0.0.1</version>
    <description>Test maven</description>
    <dependencies>
    <dependency>
    <groupId>org.apache.geronimo.specs</groupId>
    <artifactId>geronimo-j2ee_1.4_spec</artifactId>
    <version>1.0</version>
    <scope>provided</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>2.0.3</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.0.5</version>
    </dependency>
    <dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.8.1</version>
    </dependency>
    <dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.2.1</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
    </dependency>
    </dependencies>
    </project>

  14. Fijense que se definieron varias dependencias como spring, mysql connectors, etc. Estas dependencias en principio no existen en nuestro proyecto pero al tratar de compilar con maven este se conectara a internet al repositorio global de maven y bajara las versiones de las dependencias que se especifican. El siguiente comando va a bajar las dependencias no presentes, compilar el proyecto, ejecutar cualquier test definido, generar el war y copiar el war en el repositorio local. El nombre del war será proyectoA-0.0.1.war y sera copiado dentro del repositorio local en la ruta definida por el groupId (org.test.maven)


  15. $ mvn clean install
    [INFO] Scanning for projects...
    [INFO] ----------------------------------------------------------------------------
    [INFO] Building Proyecto A
    [INFO] task-segment: [clean, install]
    [INFO] ----------------------------------------------------------------------------
    [INFO] [clean:clean]
    [INFO] Deleting directory /home/usuario/proyector/proyectoA/target
    [INFO] Deleting directory /home/usuario/proyector/proyectoA/target/classes
    [INFO] Deleting directory /home/usuario/proyector/proyectoA/target/test-classes
    [INFO] [resources:resources]
    [INFO] Using default encoding to copy filtered resources.
    Downloading: http://repo1.maven.org/maven2/commons-dbcp/commons-dbcp/1.2.1/commons-dbcp-1.2.1.pom
    6K downloaded
    Downloading: http://repo1.maven.org/maven2/commons-dbcp/commons-dbcp/1.2.1/commons-dbcp-1.2.1.jar
    105K downloaded
    [INFO] [compiler:compile]
    Compiling 8 source files to /home/usuario/proyector/proyectoA/target/target/classes
    [INFO] [resources:testResources]
    [INFO] Using default encoding to copy filtered resources.
    [INFO] [compiler:testCompile]
    Compiling 1 source file to /home/usuario/proyector/proyectoA/target/target/test-classes
    [INFO] [surefire:test]
    [INFO] Surefire report directory: /home/usuario/proyector/proyectoA/target/target/surefire-reports

    -------------------------------------------------------
    T E S T S
    -------------------------------------------------------
    Running test.TestUserDao
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.797 sec

    Results :
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

    [INFO] [war:war]
    [INFO] Exploding webapp...
    [INFO] Assembling webapp ProyectoA in /home/usuario/proyector/proyectoA/target/ProyectoA-0.0.1
    [INFO] Copy webapp webResources to /home/usuario/proyector/proyectoA/target/ProyectoA-0.0.1
    [INFO] Generating war /home/usuario/proyector/proyectoA/target/ProyectoA-0.0.1.war
    [INFO] Building war: /home/usuario/proyector/proyectoA/target/ProyectoA-0.0.1.war
    [INFO] [install:install]
    [INFO] Installing /home/usuario/proyector/proyectoA/target/ProyectoA-0.0.1.war to /home/usuario/m2_local_repo/org/test/maven/ProyectoA/0.0.1/ProeyctoA-0.0.1
    war
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 25 seconds
    [INFO] Finished at: Fri Apr 06 18:37:46 EDT 2007
    [INFO] Final Memory: 5M/15M
    [INFO] ------------------------------------------------------------------------

Si se fijan bien, commons-dbcp no estaba disponible y fue bajado de internet antes de realizar la compilación, también se encontró un test que se ejecutó y funcionó correctamente y al final se generó el war y se publico en el repo local.

Como ven, es muy sencillo instalar, configurar y ejecutar maven. Después que uno se acostumbra a usarlo es difícil volver a ant o a otras herramientas similares. Para los que usan netbeans o eclipse existen plugins que permiten usar maven desde el IDE.

jueves, 22 de marzo de 2007

Subversion + UBUNTU + Apache + MySQL - Parte 5

A continuación les describo los pasos necesarios para que la autenticación de acceso a svn se haga contra una base de datos MySQL y no contra el archivo de passwords generado por htpasswd2.

Lo primero que debemos hacer es instalar mysql y el modulo de autenticación para apache.

$ sudo apt-get install mysql-server libapache2-mod-auth-mysql

Lo segundo es decirle a apache que tiene un nuevo modulo disponible para hacer autenticación.

$ cd /etc/apache2/mods-enabled/
$ sudo ln -s /etc/apache2/mods-available/auth_mysql.load .

Lo siguiente es configurar MySQL para que almacene la información de los usuarios:

Si MySQL no estaba configurado antes debemos asignarle un password al usuario root

$ mysqladmin -u root password

Después debemos crear la base de datos y la tabla de usuarios

mysql -uroot -p

mysql> grant all on svn_auth.* to svn_admin_user@localhost identified by 'password';

mysql> flush privileges;

mysql> create database svn_auth;

CREATE TABLE `clients` (
`username` varchar(25) NOT NULL default '',
`passwd` varchar(25) NOT NULL default '',
`groups` varchar(25) NOT NULL default '',
PRIMARY KEY (`username`),
KEY `groups` (`groups`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


Para insertar usuarios se puede usar el siguiente sql:

INSERT INTO `clients` VALUES ('id del usuario', 'password', 'grupo');

El password se puede crear como encrypt('password') o se puede usar uno generado por el comando htpasswd2

insert into `clients` values ('user', encrypt('user1'), '');

$ htpasswd2 -bnm user user1
user:$apr1$l.Iwf/..$uSY81FEI6BT5SNozcT51t1

insert into `clients` values ('user', '$apr1$l.Iwf/..$uSY81FEI6BT5SNozcT51t1', '');

Ahora solo nos queda modificar Apache para que tome el cambio. Para eso debemos modificar el Location de /svn

$ sudo vi /etc/apache2/apach2.conf


DAV svn
# Directorio padre de todos los repositorios
SVNParentPath /ruta/a/dir/padre/de/repositorios
# Archivo con definicion de acceso a los repositorios
AuthzSVNAccessFile /etc/apache2/.svn_access_control
# Solo usuarios autorizados
Require valid-user
# How to authenticate a user
AuthType Basic
AuthName "Coloque su clave de acceso a Subversion"
# Configuracion de acceso a MySQL
AuthMYSQL on
AuthMySQL_Authoritative on
AuthMySQL_Host localhost
AuthMySQL_DB svn_auth
AuthMySQL_Password_Table clients
# Aqui se deben colocar los datos del usuario con acceso a la BD
AuthMySQL_User svn_admin_user
AuthMySQL_Password svn_admin_user_password
AuthMySQL_Group_Table clients
AuthMySQL_Empty_Passwords off
AuthMySQL_Encryption_Types Crypt_DES PHP_MD5 MD5
# Otros valores posibles
#AuthMySQL_Encryption_Types PHP_MD5 SHA1Sum Crypt_DES Plaintext Crypt_MD5 Crypt MySQL MD5
# Esto ya no hace falta
#AuthUserFile /etc/apache2/.dav_svn.passwd


Por ultimo, reiniciamos Apache

$ sudo /etc/init.d/apache2 force-reload

Y listo, así de fácil se hace la configuración.

lunes, 19 de marzo de 2007

Subversion + UBUNTU + Apache - Parte 4

A continuación voy a describir los pasos para usar Subversion con el protocolo http. Lo primero que debemos hacer es instalar Apache web server y el modulo de Subversion para Apache

$ sudo apt-get install apache2
$ sudo apt-get install libapache2-svn


Una vez instalados vamos a crear el contexto bajo el cual vamos a accesar los repositorios. Para eso debemos editar el archivo de configuracion de Apache

$ sudo vi /etc/apache2/apache2.conf

y agregar la definición del contexto, en este caso lo vamos a llamar /svn. La definición es la siguiente

<location /svn>
DAV svn
SVNParentPath /ruta/a/dir/padre/de/repositorios
AuthzSVNAccessFile /etc/apache2/.svn_access_control
Require valid-user
AuthType Basic
AuthName "Enter password for Subversion Repository"
AuthUserFile /etc/apache2/.dav_svn.passwd
</location>


Esta definición solo permite acceso a usuarios validos (Require valid-user), si se quieren permitir usuarios anónimos o colocar otro tipo de restricciones a los accesos deben consultar la documentación de Apache. Fijense en los 3 valores a modificar

SVNParentPath: debe apuntar al directorio padre de los repositorios
AuthzSVNAccessFile: define los accesos de los usuarios a los repositorios
AuthUserFile: archivo con la definición de usuarios y los passwords

Para definir usuarios se debe usar el comando htpasswd2. Este comando agrega una entrada a un archivo de password por cada usuario registrado. La encriptación es MD5. El archivo de password se especifica en la línea de comando y debe ser el mismo usado en AuthUserFile.

$ sudo htpasswd2 -m /etc/apache2/.dav_svn.passwd user1
New password:
Re-type new password:
Updating password for user user1


Si se quiere limpiar el archivo y definir usuarios desde cero se debe ejecutar el comando (se recomienda hacer esto la primera vez)

$ sudo htpasswd2 -cm /etc/apache2/.dav_svn.passwd svnuser

La definición de los accesos se hace en el archivo definido por la entrada AuthzSVNAccessFile, en nuestro caso es /etc/apache2/.svn_access_control. En este archivo se definen grupos de accesos y perisología de acceso a cada repositorio. Para una descripción detallada ver la documentación ( http://svnbook.red-bean.com/)

$ sudo nano /etc/apache2/svn_access_control

# Se definen los grupos de trabajo
[groups]
devteam=user1, user2
guest=user3, user4
everyone=@devteam, @guest

# Acceso de lectura para todo el mundo
[/]
* = r

# Guest pueden leer pero solo devteam actualizar en
# el repositorio repo
[repo:/]
@devteam=rw
@guest=r

# Todo el musndo puede leer el repo test pero solo
# user5 lo puede modificar
[test:/]
user5=rw
@everyone=r

# Solo el grupo devteam tiene acceso total al
# repositorio bcol. Guest no tienen ningun acceso
[bcol:/]
@devteam = rw
@guest =


Para que Apache tome los cambios se deben habilitar los módulos de svn y reiniciar el servicio

$ sudo a2enmod dav
$ sudo a2enmod dav_svn
$ sudo /etc/init.d/apache2 force-reload


Y por ultimo para probar que todo esta ok ejecutamos desde el browser

http://svn_server/svn/nombre_del_repo

Debe salir una pagina con el titulo "Revision 0: /"

Asi de facil se configura http con svn. Fijense que el esquema es mas seguro que el usado con svnserve porque el archivo de passwords esta encriptado. En la proxima parte vamos a usar MySQL para guardar los passwords, asi agregamos un nivel de seguridad mayor.

jueves, 15 de marzo de 2007

Subversion + UBUNTU - Parte 2

Como les comente en la sección anterior, para poder accesar los repositorios de forma remota debemos utilizar un server de svn. Actualmente hay 2 opciones Apache web server y svnserve. El primero nos permite accesar por http/https y el segundo nos permite accesar por tcp/ip usando un protocolo propietario (svn/svn+ssh). svnserve forma parte de la instalación de svn.

El servidor svnserve se puede invocar de tres formas

  1. Usando inetd: svnserve -i
  2. Standalone : svnserve -d
  3. Modo tunel: svnserve -t

El puerto por defecto es 3690. Para el primer caso se puede modificar en /etc/services, cambiando/agregando las siguientes entradas

svn 3690/tcp # Subversion
svn 3690/udp # Subversion

Si la ejecución es standalone el puerto se puede configurar por linea de comando usando los parametros --listen-port= y --listen-host=

El modo tunel se utiliza con SSH o RSH para autenticar el usuario.

Una vez que svnserve esta corriendo, todos los repositorios en el servidor estan disponibles para ser accesados de forma remota. Si se quiere aumentar la seguridad se puede indicar un directorio raiz y solo los repositorios bajo ese directorio estarán dsiponibles. Esto se logra con el parametro -r :

$ svnserve -d -r /dir/raiz/a/repositorios

Para accesar los repo se usa el url svn o svn+ssh. Aqui tenemos dos ejemplos de como accesar un repo con o sin directorio raiz. Como podran ver con el dierctorio raiz es mas dificil obtener informacion de la configuracion en el servidor.

Sin directorio raiz

$ svn checkout svn://host.svnserver.com/usr/local/svn_repos/proyectoA

Con directorio raiz

$ svn checkout svn://host.svnserver.com/proyectoA

Hasta este momento todo indica que estamos listos para trabajar con el repo, asi que podemos intentar subir algo en el repositorio creado durante la instalación de svn.

$ cd ~/tmp
$ svn import . svn://localhost/prueba --message "Inicio"
svn: Authorization failed


Fijense que aunque el checkout funciono de forma correcta el checkin no nos deja. En la siguiente parte explicare como arreglar este problemita.



viernes, 9 de marzo de 2007

Subversion + UBUNTU

El primer paso para implementar una solución de integración continua consiste en seleccionar una herramienta de control de versiones para centralizar los fuentes. Existen varias opciones comerciales (PVCS, SourceSafe) y open source (CVS, SVN). Todas tienen sus pros y sus contras pero al final todas cumplen con su objetivo. Yo realmente considero que no hay herramienta mala sino mal utilizada. La experiencia me dice que si uno no se organiza y establece procesos claros la herramienta solo servirá para mantener un backup de nuestro propio desastre.

Para nuestro ejemplo voy a utilizar Subversion (SVN) , en primer lugar porque es gratis (viva el software libre), en segundo lugar porque las características que se describen en su site cumplen con mis requerimientos y en tercer lugar porque es popular. La instalación la voy a hacer sobre Ubuntu.

A continuación describo los pasos para hacer la instalación, crear un primer repositorio y accesarlo. Después veremos como usar Apache web server para accesar por http/https los repositorios y por ultimo como usar MySql para guardar la información de autenticación.

  1. Si no se trabaja como root se debe usar un usuario que pueda ejecutar el comando sudo. Esto se puede hacer colocando el usuario en un grupo que este definido en el archivo /etc/sudoers o agregando el usuario al mismo. Cuando se ejecuta el comando sudo el password que pide es el del usuario.
  2. Se debe verificar que se tiene acceso al repositorio universal de Ubuntu. Esto se hace revisando el archivo /etc/apt/sources.list para ver si las siguientes lineas están comentadas o no

    deb http://us.archive.ubuntu.com/ubuntu/ edgy universe
    deb-src http://us.archive.ubuntu.com/ubuntu/ edgy universe

  3. Instalar svn con el comando

    sudo apt-get install subversion

  4. Para probar la instalación usamos

    svn --version

  5. Para crear nuestro primer repositorio vamos a usar el comando svnadmin. Para ser practicos vamos a usar un mismo directorio padre para todos los repositorios. En este ejemplo voy a usar un directorio padre llamado svn_repos en el home del usuario y allí voy a crear un repo llamado prueba

    cd ~
    mkdir svn_repos
    svnadmin create ~/svn_repos/prueba

    Ahora verificamos que el repo se creo de forma correcta

    ls ~/svn_repos/prueba
    conf dav db format hooks locks README.txt


  6. Una vez creado el repo se puede importar data con el comando svn import. Por ejemplo, podemos cargar todo lo que este en ~/bin con el siguiente comando

    cd ~/bin
    svn import . file:///export/home/svn_repos/prueba
    --message 'Version inicial'



Fijense que si estamos en la misma máquina donde esta svn podemos accesar el repositorio usando urls del tipo file:///ruta/repo, pero en la realidad este escenario es muy raro, generalmente los repos se accesan desde máquinas remotas y para eso debemos configurar algun tipo de servicio que nos permita hacerlo. Actualmente svn se puede accesar de 2 formas, usando svnserve o usando Apache. Mas adelante hablare un poco de como usar svnserve y luego de como integrar svn con Apache web server para accesarlo con http/https.