Katayunos y MerenDojos

Muy interesante esta iniciativa de la que nos informa @penguinjournals: «Oye, te escribo para ver si me ayudas a esparcir un poco la semillita de nuestra iniciativa. A lo largo del año pasado, desde programania hemos estado promoviendo los Katayunos encuentros en los que coders nos juntamos para practicar por parejas TDD enfrentándonos a pequeños desafíos de código donde el objetivo no es resolverlo «sin más» sino hacerlo utilizando TDD y otra serie de buenas prácticas (pairing, clean code, control de versiones…).

Los eventos no tienen formato curso sino mas bien son del tipo «sentarse a cacharrear». No se puede asistir en modo lurker ya que se realizan iteraciones de 45 minutos tras los cuales se anima a la gente a cambiar de pareja, cambiando normalmente también de lenguaje de programación. Pero lo importante es el aprendizaje por participación, luchando un poco contra el formato «clase magistral» al que estamos generalmente habituados.

Este curso nos hemos venido arriba con gente de agile-zona norte y los Katayunos van a pasar a organizarse en Bilbo, Vitoria, Donostia y Pamplona, éste primer Katayuno del día 24 de este mes es el único que se celebrará en las 4 simultaneamente y que tendrá un formato introductorio al TDD, esto no quiere decir que vaya a ser un curso de TDD sino que habrá una introducción que en meses posteriores ya no se hará (no pretendemos ser una academia de programación ;-)»

Así pues, invitados quedáis, amigos lectores, la entrada es gratuita y ya está anunciada la primera Kata, «String Calculator«

Trabajando en la nube Amazon desde la línea de comandos (I)

Hello World! Sí, tras un parón de casi 2 meses sigo vivo 🙂 ¿En qué he estado divirtiéndome todo este tiempo? En redactar mi tesis (y lo que te rondaré, morena), en leer -mucho- sobre análisis de datos con R -y el maravilloso entorno RStudio-, en seguir con el desarrollo de Babelium – API, HTML5, integración con Moodle… – y sus implantaciones en distintos cursos universitarios. Usando para esto último la nube de Amazon (AWS, Amazon Web Services).

Precisamente de AWS quería hablar un poco hoy. Hacía tiempo que no disfrutaba tanto con alguna novedad informática. Desde la línea de comandos puedes lanzar máquinas virtuales (instancias), asignarles IP, cambiarles el disco, ampliar la memoria, la CPU… todo desde la terminal y tu intérprete (ba)sh favorito (o desde scripts en PHP, Python, Perl, Ruby, Java…).

Basta con definir 3 variables de entorno

export EC2_PRIVATE_KEY=/opt/juanan/pk-6OZ6AAAAAAUUXZGNIAAWE63AMBBBBBB.pem
export EC2_CERT=/opt/juanan/cert-6OZ6AAAAAAUUXZGNIAAWE63AMOBBBBBB.pem
export EC2_URL=http://eu-west-1.ec2.amazonaws.com

La primera y la segunda forman tus credenciales (clave privada y certificado X.509).

(sáltate el siguiente párrafo si no quieres saber para qué quiere Amazon estas credenciales, porque no es necesario saberlo para usar el API)

Las consultas/peticiones al API de Amazon se firman con la clave privada. Estas consultas van acompañadas del certificado X.509. Cuando la petición llega a Amazon, el sistema extrae la clave pública de dicho certificado y descifra la firma digital que has realizado con tu clave privada. Si todo va bien, comprueba además que el certificado coincide con el que Amazon tiene guardado y asignado a tu persona (al que firma la petición). Menudo tinglado para una llamada al API, eh? Puedes ver más info en la ayuda de AWS.

La tercera variable de entorno, EC2_URL, sirve para indicar que tus máquinas virtuales (instancias, en terminología Amazon) quieres tenerlas «alojadas», por defecto, en la región de Europa Occidental. Las regiones son: US East – Northern Virginia, US West (Northern California), EU (Ireland), Asia Pacific (Singapore) y Asia Pacific (Tokyo). Hay varias zonas en cada región (realmente hay una región más: AWS GovCloud, destinada en exclusiva a las necesidades del gobierno de EEUU).

Los precios por tener una instancia en marcha varían dependiendo de la región, del tipo de instancia y características que pongas en marcha y del tiempo que estén lanzadas. Supuestamente habría que tener en cuenta no sólo el precio, sino la velocidad de respuesta de las instancias al cliente. Se supone que los clientes de Europa recibirán respuesta más rápida desde instancias alojadas en esa zona… pero tampoco es que lo haya comprobado empíricamente. Por otro lado, por cuestiones de disponibilidad, conviene no dejar todos los huevos (instancias) en el mismo cesto (región y zona), sino diversificar.

Declaradas dichas variables de entorno, ya podemos lanzar nuestra primera orden en la línea de comandos (una simple descripción de regiones disponibles):

$ ec2-describe-regions
REGION	eu-west-1	ec2.eu-west-1.amazonaws.com
REGION	us-east-1	ec2.us-east-1.amazonaws.com
REGION	ap-northeast-1	ec2.ap-northeast-1.amazonaws.com
REGION	us-west-1	ec2.us-west-1.amazonaws.com
REGION	ap-southeast-1	ec2.ap-southeast-1.amazonaws.com

Otro ejemplo, para ver las zonas disponibles para la región eu-west-1:

$ ec2-describe-availability-zones --region=eu-west-1
AVAILABILITYZONE	eu-west-1a	available	eu-west-1	
AVAILABILITYZONE	eu-west-1b	available	eu-west-1	
AVAILABILITYZONE	eu-west-1c	available	eu-west-1

Sin embargo, los ejemplos anteriores son un poco pobres. Veamos un ejemplo final más interesante para finalizar esta primera parte:

$ ec2-run-instances  ami-359ea941  --instance-count 1 --instance-type t1.micro --key juanan --group default

Aquí hemos lanzado una instancia EC2 (una máquina virtual en la nube Elastic Cloud de Amazon) usando como base la AMI con identificador ami-359ea941. Una AMI, o Amazon Machine Image, es una especie de plantilla de máquina virtual. En términos de Prog. Orientada a Objetos, sería una Clase que puede ser instanciada y generar… je :-), instancias. AWS tiene su propio buscador de imágenes pero yo recomiendo éste otro catálogo: http://thecloudmarket.com/. Por cierto, la ami-359ea941 es una AMI oficial de Ubuntu, y tiene una «plantilla» con Ubuntu 11.04 en arquitectura x86 de 32 bits, para la región eu-west-1.

Siguiendo con la línea de lanzamiento de nueva instancia, la parte «–instance-count 1» indica que sólo queremos una unidad (puedes lanzar hasta 20 de este tipo a la vez…). La parte «–instance-type t1.micro» indica el tipo de máquina virtual que quieres: t1.micro es lo más pequeño que hay (y gratis por un año!). A partir de ahí, puedes tener gigantescos monstruos a 1 click de distancia.

La parte «–key juanan» indica que quieres acceder vía SSH a tu instancia con una clave privada SSH que lleva asociado este nombre. Al lanzar la instancia, Amazon deja la parte pública de esa clave SSH en el archivo .ssh/authorized-keys y sólo si tienes la parte privada en tu PC podrás acceder a esa instancia.

Finalmente, la parte «–group default» identifica la lista que define qué puertos TCP/UDP quieres tener abiertos o cerrados. Como sólo tengo una, especifico default (sin poner el nombre en concreto)

Nota: todo lo que indico sólo funcionará si tienes instalado el paquete ec2-api-tools de Ubuntu.

Ale, cierro el post, y sigo otro día con el tema AWS que da mucho, pero que mucho juego. Espero que os sea de utilidad.

Receta: Integrar R y MySQL

Vamos a por una receta rápida que permite ejecutar desde el entorno R sentencias SQL contra una BD MySQL remota (así te ahorras tener que ejecutar las sentencias en MySQL, exportar el resultado e importarlo luego en R)

Primero, asumo que la BD es remota y no hay acceso directo (el puerto 3306 está filtrado) PERO sí tenemos acceso vía SSH. Así que construyo un túnel SSH contra MySQL (en un extremo del túnel tenemos localhost, escuchando en el puerto 3307. En el otro extremo, MySQL en su servidor, escuchando en el puerto habitual, 3306)

$ ssh -L 3307:localhost:3306  usuario@IP_SERVIDOR

Ok, ahora vamos a instalar la magia: el paquete r-cran-rmysql permite lanzar sentencias SQL contra una BD MySQL remota. Y lo tenemos paquetizado en Ubuntu 🙂

$ sudo apt-get install r-cran-rmysql

Para que las conexiones a MySQL desde R no requieran que tengamos que acordarnos continuamente del login, pass, db, etc. las apuntamos en my.cnf

$ sudo vi /etc/mysql/my.cnf
[nombreGrupo]
user            = usuario
password        = password
host            = 127.0.0.1
port            = 3307
database        = nombre_de_bbdd

¡Listo! Que empiece la fiesta:

$ R
> library(RMySQL)
Loading required package: DBI
> con <- dbConnect(MySQL(), group="nombreGrupo")
> dbListTables(con)

La primera línea carga el entorno R. La segunda carga la biblioteca RMySQL. La tercera lista las tablas de la BD.

¿Más ejemplos?

> rs <- dbSendQuery(con, "select * from tabla");
> dbHasCompleted(rs)
> data <- fetch(rs, n=50);
> data[1,]

La primera línea lanza una consulta SQL. La segunda recoge los resultados (50 tuplas para empezar). La tercera muestra la primera fila de esos resultados. Para recoger TODOS los resultados/tuplas, podríamos haber hecho:

> data <- fetch(rs, n=-1);

Las consultas también pueden lanzarse y visualizarse directamente así:

> dbGetQuery(con, "show tables");

Finalmente, si no quieres crear un fichero /etc/mysql/my.cnf, también puedes pasar los datos directamente desde la línea de comandos:

> library(RMySQL)
> drv <- dbDriver("MySQL")
> con <- dbConnect(drv, user="usuario", password="contraseña", dbname="nombreDB", host="127.0.0.1", port=3307)

Para más detalles, RTFM 😉

Bonus: R insiste en mostrar los resultados sólo a 80 columnas. Si tienes una pantalla grande, igual te interesa saber que a R se le puede indicar que hay espacio de sobra 🙂 así :

> options(width=150)

Indicator bug: conoce al instante los bugs de tu aplicación

Mi amigo Oier Mees nos habla de su nueva creación:

Indicator-Bug es un indicador para Ubuntu 11.04 y 11.10 que muestra y actualiza regularmente una lista de bugs para un determinado proyecto de Launchpad. También avisa cuando haya nuevos bugs, cambiando el color del icono, que cumplan los criterios de búsqueda especificados. Además, haciendo click en la entrada un bug, se abre la página correspondiente de Launchpad en el navegador. El usuario puede especificar qué tipo de bugs le interesan, por ejemplo, que aparezcan bugs que contengan ciertos tags, bugs marcados como críticos etc. Para evitar llenar la pantalla de listas interminables, sólo se muestran las primeras 8 entradas y por otro lado, también se acorta el titulo en caso de que sea demasiado largo.

La idea surgió porque buscaba una forma de estar informado en cuanto se dieran nuevos bugs en Ubuntu dentro de la categoría «bitesize», que significa que son relativamente fáciles resolver, y no quería estar haciendo búsquedas en la web de Launchpad cada x tiempo. Por otra parte, también me inspiré en Jono Bacon, que publicó un post en el que describía una aplicación parecida. Finalmente, era una buena oportunidad para conocer mejor el ciclo de desarrollo en Ubuntu y sus herramientas y poner en práctica lo aprendido sobre Python.

La aplicación está escrita en Python y usa GTK. Como sistema de control de versiones usa bzr, ya que es el que mejor integrado está con Launchpad. Mencionar también que actualmente la aplicación está traducida a media docena de idiomas, aunque por el momento falta el castellano 😉 Si tenéis ganas de probar Indicator-Bug tengo un PPA dónde se publican paquetes diarios con las últimas mejoras y ahora estoy intentando que lo acepten en el repositorio universe de Ubuntu para que los usuarios de Oneiric puedan instalarlo sin tener que añadir el PPA.

Para instalar Indicator-Bug: $ sudo apt-add-repository ppa:oier/indicator-bug $ sudo apt-get update & sudo apt-get install indicator-bug

Agradecería mucho que lo probéis y me mandéis sugerencias, mejoras o incluso un bug-report si descubrís errores. Para lo último, como hace uso de Apport, os debería de dar la opción de mandar un informe de fallos automáticamente si la aplicación deja de funcionar repentinamente.

Una china en el autocompletamiento Bash

No una china en el zapato… sino en el autocompletamiento Bash. Los usuarios de la línea de comandos solemos «volar» literalmente mientras escribimos comandos en terminal. Pero usamos un truco: el autocompletamiento Bash. Si quieres ver el contenido del directorio /tmp/algo/muy/largo basta con teclear (donde TAB es el tabulador):

ls /t<TAB>a<TAB>m<TAB>l<TAB>

y Bash lo autocompletará así:

ls /tmp/algo/muy/largo

Sin embargo, desde la versión de Bash que nos trajo Natty (Ubuntu 11.04), al teclear

ls /t<TAB>_

el autocompletamiento añadía un espacio en blanco a la derecha del TAB y por tanto se rompía la magia (no es posible seguir tecleando y pulsando TAB a partir de ese espacio)

En este hilo de discusión al respecto de este bug, el usuario Silas da con la clave para arreglar este comportamiento tan errático: basta con editar el fichero /etc/bash_completion, línea 1587 y donde pone -o default poner- o filenames. Guardamos los cambios y a partir de la siguiente terminal que abramos, el problema estará solucionado.