Instalando PredictionIO en OS X

predictionio logoPredictionIO es una aplicación (concretamente un servidor) que implementa una serie de algoritmos de recomendación para ofrecer servicios de filtrado de información a otros sistemas.

Llevaba tiempo queriendo hincarle el diente para ver qué tal se comporta, y hoy he tenido mi oportunidad. Sin embargo, la documentación para instalar el servidor en mi máquina de desarrollo me ha resultado un poco escasa. Seguramente todo esté ahí, pero no he encontrado un tutorial-receta donde me expliquen paso por paso qué hacer para poder conectarme con mi cliente al servidor.

Una de las cosas que más gracia me ha hecho ha sido el Quick Start. Éste comienza diciendo «para que probéis los clientes, vamos a partir de un servidor ya instalado y configurado». Claro que sí, como somos principiantes, ya hemos instalado el servidor con el comando del poder.

Como ya lo he conseguido, incluyo aquí el paso a paso para quien lo necesite. He de adelantar que uso brew en OS X, así que quien no lo tenga, tendrá que apañárselas para instalar los programas de otra forma. Eso sí, si le apetece ponerlo en los comentarios, genial para todos.

  1. PredictionIO necesita de MongoDB para funcionar (Hadoop no es un requisito, así que no lo incluyo). Para ello, instalamos ambos paquetes a golpe de brew:
    brew install mongo
    brew install predictionio
    
  2. Una vez instalados, hay que arrancar primero el servidor de MongoDB:
    mongod &
    
  3. Lanzamos el script de inicialización de PredictionIO. Suponiendo que se ha instalado la versión 0.7.3 y bajo /usr/local/Cellar/predictionio/, la sentencia será la siguiente:
    /usr/local/Cellar/predictionio/0.7.3/bin/setup.sh
    
  4. Creamos un usuario administrador:
    /usr/local/Cellar/predictionio/0.7.3/bin/users
    
  5. Ya podemos arrancar el servidor como nos dice el tutorial:
    /usr/local/Cellar/predictionio/0.7.3/bin/predictionio-start-all.sh
    

Una vez realizado este último paso, el servidor quedará arrancado y se podrá acceder a la administración a través de http://localhost:9000/ desde el navegador. Si a vosotros, como a mí, no os aparece ningún motor de recomendación a la hora de seleccionar uno, el problema seguramente es porque habéis obviado el paso 3, donde se incluye dentro de MongoDB la información relativa a los motores y sus algoritmos.

Espero que ahora, todos aquellos que quieran comenzar a usar PredictionIO, puedan hacerlo de verdad. ¡Un saludo a todos!

Migración de repositorios GIT

En mi trabajo usamos un esquema centralizado, es decir, un repositorio donde se centraliza todo el código. En éste se encuentran dos ramas, la master, cuyo HEAD apunta siempre a la última versión que se corresponde a la desplegada en producción y la devel, cuyo HEAD apunta a la última versión en desarrollo.

El caso es que tenemos para cada proyecto un repositorio de este tipo en una máquina que, aunque simpática, se nos está quedando corta por lo que estoy migrando los repositorios a otra máquina. Se me ha dado un caso en particular que ha sido la necesidad de migrar el contenido de un repositorio clonado del antiguo a un repositorio ya existente en la máquina destino.

Dado que estamos en un repositorio clonado, éste tendrá una referencia al repositorio del que fue clonado denominada origin. Supongamos que ésta apunta a http://server_orig.com/git/repo/ y que el nuevo repositorio está ubicado en http://server_dest.com/git/repo/ y está vacío. Pues bien, la receta (supongo que una de muchas) que he usado es la siguiente. Desde el directorio donde está ubicado nuestro repositorio clonado:

# Hacemos que nuestro repositorio apunte al nuevo con otro nombre
$ git remote add dest http://server_dest.com/git/repo/
# Enviamos nuestras ramas "master" y "devel" al nuevo repositorio
$ git push -u dest --all
# Eliminamos las referencias a los repositorios remotos existentes
$ git remote rm origin
$ git remote rm dest
# Hacemos que "origin" (remote por defecto) apunte al nuevo repositorio
$ git remote add http://server_dest.com/git/repo/

Se puede hacer de más formas (borro el origin y lo creo de nuevo apuntando al nuevo, etcétera) pero al menos el concepto queda claro. Hay que tener en cuenta que git push -u dest --all envía todas las ramas de nuestro repositorio al nuevo. Eso quiere decir que si tenemos más ramas en el repositorio original, si no las tenemos en local, no se enviarán.

Espero que os sirva. Que paséis un estupendo fin de semana!

Instalando Confluence en Ubuntu 12.04 LTS

En esta entrada se instalará la herramienta colaborativa Confluence (la versión actual es la 4.2.6) de Atlassian.

La idea es acabar con un servidor a través del cual podamos acceder a Confluence a través de la URL http://nuestro-servidor/wiki/. Para ello haremos uso de Apache como servidor Web, Tomcat como servidor de aplicaciones (que viene empotrado en el paquete standalone de Confluence) y de MySQL como gestor de bases de datos para mantener la información de la Wiki.

Toda la información aquí expuesta es un resumen adaptado a las necesidades que nos hemos encontrado para instalar nuestro Confluence. En la documentación oficial de Confluence de Atlassian (por supuesto servida desde un Confluence :D) está todo explicado estupendamente en caso de que lo aquí expuesto no sea exactamente el entorno que tengáis pensado montar.

Java

Porque sin Java no hacemos nada, instalaremos la JDK con un apt-get instalaremos la JDK. En este caso es opcional, y es posible sólo con la JRE. Sin embargo, como en nuestro caso instalaremos también un servidor de integración continua, aprovecharemos e instalaremos la JDK:

sudo apt-get install openjdk-6-jdk

Si no está instalado, es un buen momento para hacerse un café porque tardará un rato dependiendo de la conexión.

Instalar MySQL

Esto la verdad es que tiene poco misterio. Se instalará a golpe de apt-get de la siguiente manera:

sudo apt-get install mysql-server

En algún momento pedirá la contraseña para el usuario root del gestor. Viene bien sabérsela, pero para Confluence crearemos un usuario propio. De esta forma no usamos a root para todo y tenemos más controlado el acceso al gestor de bases de datos en caso de que no sea la única aplicación que haga uso de éste. Para ello accederemos a la consola de MySQL de la siguiente manera:

mysql -u root -p

Una vez introducido, nos solicitará la contraseña de root. Esperemos que esta sea la última vez que la usamos (por lo menos para esto :D). Una vez dentro, crearemos la base de datos para confluence y el usuario que accederá a ésta de la siguiente manera:

CREATE DATABASE confluence CHARACTER SET UTF8;
GRANT ALL on confluence.* TO 'confluence'@'localhost' IDENTIFIED BY 'cfpass';
FLUSH PRIVILEGES;
EXIT

Y hasta aquí la instalación de MySQL.

Creación de usuario para confluence

Al igual que en en el gestor de bases de datos queremos tener parcelados a los usuarios para que accedan a sus respectivas bases de datos, en el sistema también viene bien que sea así. Por tanto crearemos un usuario para Confluence en el sistema. Para ello:

sudo useradd -s /sbin/nologin confluence

Instalación de Confluence

En nuestro caso para instalar Confluence haremos uso de la versión standalone. Para ello nos la descargaremos en el servidor con wget, lo descomprimiremos y lo pondremos en el «directorio de instalación» (en nuestro caso /usr/local/confluence):

wget http://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-4.2.6.tar.gz
tar -zxvf atlassian-confluence-4.2.6.tar.gz
sudo mv atlassian-confluence-4.2.6 /usr/local/confluence
sudo chown -R confluence /usr/local/confluence/
sudo chgrp -R confluence /usr/local/confluence/

Ahora habrá que configurar el «directorio de trabajo» donde Confluence ficheros de configuración, locks y temporales (entre otros artefactos). Esto se en el fichero confluence-init.properties que en el caso del ejemplo se encuentra en la ruta /usr/local/confluence/confluence/WEB-INF/classes/confluence-init.properties. Nosotros estableceremos la ruta /var/confluence como directorio de trabajo y por tanto añadiremos la siguiente línea al fichero de configuración:

confluence.home=/var/confluence

Y crearemos el directorio al que hacemos referencia:

sudo mkdir /var/confluence
sudo chown -R confluence /var/confluence
sudo chgrp -R confluence /var/confluence

Por último cambiaremos tanto el contexto en el que se despliega la aplicación como el puerto en el que escucha (nos vendrá bien para más adelante). Para ello habrá que modificar el fichero /usr/local/confluence/conf/server.xml y modificar las líneas pertinentes. En nuestro caso desplegaremos la aplicación en el contexto /confluence escuchando por el puerto 9090. Para ello habrá que modificar el atributo port del elemento Server (para que no entre en conflicto con otros posibles servidores que tengamos en el servidor), el elemento port del elemento Connector y el atributo path del elemento Context. Pongo un fragmento del código (desde el comienzo del fichero hasta la modificación del contexto, que es la última) para que se vea cómo ha quedado después de la modificación:

<server port="9000" shutdown="SHUTDOWN" debug="0">
  <service name="Tomcat-Standalone">
      <connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="9090" minProcessors="5" maxProcessors="75" enableLookups="false" redirectPort="8443" acceptCount="10" debug="0" connectionTimeout="20000" useURIValidationHack="false" URIEncoding="UTF-8"/>
      <engine name="Standalone" defaultHost="localhost" debug="0">
        <host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="false">
          <context path="/confluence" docBase="../confluence" debug="0" reloadable="false" useHttpOnly="true">
      ...

Y hasta aquí la configuración de Confluence propiamente dicha. Sin embargo, como queremos que Confluence se arranque cada vez que se arranca la máquina, añadiremos el script de arranque /etc/init.d/confluence con el siguiente contenido:

#!/bin/sh -e
# Confluence startup script

APP=confluence
USER=confluence
CATALINA_HOME=/usr/local/confluence
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64

case "$1" in
  start)
    echo "Starting $APP"
    sudo /bin/su -m $USER -c "$CATALINA_HOME/bin/startup.sh &amp;> /dev/null"
    ;;
  stop)
    echo "Stopping $APP"
    sudo /bin/su -m $USER -c "$CATALINA_HOME/bin/shutdown.sh &amp;> /dev/null"
    echo "$APP stopped successfully"
    ;;
  restart)
    $0 stop
    sleep 5
    $0 start
    ;;
  *)
    echo "Usage: sudo service $APP {start|restart|stop}"
    exit 1
    ;;
esac

exit 0

Para arrancarlo basta con hacerlo ejecutable y lanzar el script de arranque como cualquier otro script.

sudo chmod u+x /etc/init.d/confluence
sudo service confluence start

Para instalarlo en el arrranque, con el siguiente comando se instala en todos los runlevels:

sudo update-rc.d confluence defaults

Si todo ha ido bien, en http://localhost:9090/confluence deberá aparecer la siguiente pantalla que indica que Confluence está arrancado y necesita la activación para continuar.

Nosotros le introduciremos nuestra clave y seleccionaremos la opción «Product installation». La siguiente pantalla (no la pongo) da a elegir entre base de datos empotrada o base de datos externa. Nosotros que molamos más que los Peta Zetas vamos a usar una base de datos externa de MySQL seleccionando dicha opción en el desplegable. Una vez hecho esto llegaremos a la siguiente pantalla donde elegiremos conectarnos vía JDBC. Una vez hecho esto nos aparecerá la pantalla de configuración

Configuración de la base de datos

Ojo con la cadena de conexión porque si usamos MySQL y queremos usar «non-latin characters» hay que añadir sí o sí el trozo useUnicode=true&characterEncoding=utf8. También en la cadena de conexión se encuentra el nombre de la base de datos, así que si la hemos llamado de otra forma distinta a confluence habrá que modificar la cadena con el nuevo nombre. Una vez le demos a continuar se crearán todas las tablas (tardará un rato) y nos dará a elegir distintas opciones que no merece la pena contar aquí. A partir de este punto tenemos nuestro Confluence instalado y funcionando. Ahora sólo nos queda configurar Apache para servir confluence a través del contexto /confluence.

Configuración de Apache

Configuraremos apache a través del módulo mod_proxy. Para ello instalaremos el módulo con apt-get.

sudo apt-get install libapache2-mod-proxy-html
sudo a2enmod proxy_html
sudo a2enmod proxy_http

Una vez instalado, crearemos un nuevo fichero para el sitio de confluence en los sitios de apache (en nuestro caso se encuentra en /etc/apache2/sites-available) con el siguiente contenido:


  Order deny,allow
  Allow from all

 
ProxyRequests       Off
ProxyPreserveHost On
ProxyPass           /confluence       http://localhost:9090/confluence
ProxyPassReverse    /confluence       http://localhost:9090/confluence

Por último habrá que activar el sitio para que apache lo reconozca y reiniciar apache. Para ello, un par de comandos:

sudo a2ensite confluence
sudo service apache2 restart

Ya debería estar instalado y funcionando en http://localhost/confluence.

Sin embargo, por lo menos en mi caso y seguramente a todo el que use la versión de 64 bits de Ubuntu Server, puede que nos dé un error de librerías. Esto es debido a que en la versión de 64 bits la librería libxml2.so.2 no está en /usr/lib sino que (después de un rato buscándola) resulta que está en /usr/lib/x86_64-linux-gnu/ (vaya por dios :D). Así que la solución en este caso es editar el fichero /etc/apache2/mods-available/proxy_html.load y cambiar la línea donde se hace referencia a la librería por la nueva, es decir, de:

LoadFile /usr/lib/libxml2.so.2
LoadModule proxy_html_module /usr/lib/apache2/modules/mod_proxy_html.so

a:

LoadFile /usr/lib/x86_64-linux-gnu/libxml2.so.2
LoadModule proxy_html_module /usr/lib/apache2/modules/mod_proxy_html.so

Para concluir

Como bonus track de todo esto está el hecho de que otras aplicaciones como Jira o Bamboo siguen el mismo patrón de instalación, y por tanto pueden instalarse con la misma guía casi cambiando únicamente el nombre. Bueno, es cierto que también habría que cambiar puertos y contextos, pero la caso es que es fácilmente reproducible.

Cualquier mejora a este proceso es bienvenida :D. Que paséis un feliz fin de semana!.

IP estática en Ubuntu 12.04 LTS (y en prácticamente todas las ditribuciones de GNU/Linux)

Para configurar con IP estática un ordenador ya configurado con DHCP basta con cambiar el contenido del fichero /etc/network/interfaces. En caso de estar configurado con DHCP tendrá un aspecto similar al siguiente:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

Bueno, he copiado hasta los comentarios del fichero, pero así no hay duda de a qué fichero nos referimos. El caso es que tenemos que modificar la línea de dhcp de nuestro interfaz de red (en el caso del ejemplo, iface eth0 inet dhcp con la configuración de la IP estática. Por ejemplo, en el caso de nuestro servidor, el fichero (sin comentarios) quedaría como sigue:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
  address 192.168.0.10
  netmask 255.255.255.0
  network 192.168.0.0
  broadcast 192.168.0.255
  gateway 192.168.0.1

Por último, ejecutamos el siguiente comando y ya quedará configurado con ip estática por los tiempos de los tiempos:

sudo service networking restart

Si hubiera algún problema, la solución típica es tirar y levantar el interfaz de red. Esto se hace de la siguiente manera:

sudo ifdown eth0
sudo ifup eth0

¡Un saludo gigante para todos y que disfrutéis lo que queda de día!