LocoLander

En el último sprint internacional que fui en el laburo se me ocurrió una idea a la que le fui dando forma. Se la he contado a varias personas, y la encontraron interesante.

Es un proyecto donde la idea es dar un servicio gratis a la comunidad de software libre. Esto va más allá que Python, pero si lo podemos hacer desde PyAr para toda la comunidad, no estaría nada mal.

Estoy contando acá entonces de qué va el proyecto, y también voy a poner algo de esto en la página del PyCamp, a ver si genera tracción para ser laburado este Junio.

Contexto

La idea surge de una necesidad en particular. Una gran idea dentro de un proyecto de software es "la revisión por pares" (peer review). En ese contexto, cuando uno escribe el código de un cambio, ese código no va directamente al trunk (main, o head, o lo que sea) del proyecto, sino que uno termina el branch, y lo propone a revisión.

Entonces vienen los "pares" y revisan el código, a veces sugieren mejoras (a veces desaprueban totalmente los cambios, puede pasar) y uno tiene que hacer cambios posteriores, a veces lo aprueban sin más trámite, etc. El punto es que en determinado momento el cambio está listo para ser integrado a trunk (main, head, etc.). La acción de "meter el cambio en trunk" se la denomina muchas veces como landear (el código aterriza en el branch principal del proyecto).

¿Cómo se landea un branch? Bueno, hay formas y formas. Pero la más correcta, o completa, o la que está realmente buena hacer es....

  • agarrar el trunk más reciente, y mergear los cambios del branch en cuestión
  • si no hubo conflicto, correr los tests de integración del proyecto, y cualquier serie de pruebas (por ejemplo, verificadores de código como lint o pychecker).
  • si todo estuvo bien, landear el código (esto es, commitear los cambios al trunk)

¿Cual es el problema de esta secuencia? Uno solo: es mucho trabajo. Entonces, o nadie lo hace, o el que lo hace termina tardando mucho en hacerlo. Y ambas situaciones son malas.

¿Por qué malas? En el primer caso, donde no se hace toda la secuencia, se corre el riesgo de meter en trunk código que rompe el mismo, o que no cumple con los estándares de calidad del proyecto. En el segundo caso, el tardar es malo para la colaboración: (me ha pasado que) a veces alguien externo al proyecto sugiere un cambio y escribe el código, y los desarrolladores del proyecto ven que está todo bien, pero demoran todos estos pasos, y finalmente el resultado es que los cambios propuestos tardan semanas en entrar a trunk, lo cual sólo sirve como desmoralizador de la gente que quiere ayudar.

Ahora, imagínense que uno, como desarrollador del proyecto, pudiera decir "este branch está aprobado, está listo para entrar en trunk", y viniera un bot al ratito, y ejecutase todos esos pasos que indiqué yo antes.

LocoLander

El proyecto

En detalle, lo que LocoLander haría es armar un entorno donde uno luego registraría su proyecto, el cual sería revisado de tanto en tanto, y si hay un branch para landear, se realizarían todos estos pasos automáticamente.

Para lograrlo, se levantaría una máquina virtual con un determinado sistema operativo instalado, se instalarían las dependencias que el proyecto necesite (y declare), se copiaría trunk y se le incorporaría los cambios del branch a probar, se correrían luego todos los tests y verificaciones, y finalmente si todo está como corresponde, se meterían esos cambios en trunk.

Algunas consideraciones:

  • Configuración para el uso: Cuando se quiera usar LocoLander, se deberá dar de alta el proyecto en la página de LocoLander, autenticando de alguna manera para luego poder ver los resultados de cada intento de merge, etc., indicando qué otras personas pueden ver esa información, e ingresando algunos datos del proyecto en sí.
  • Entorno para el proyecto: La idea es que el proyecto lo declare y que el entorno se arme solo en función de las necesidades de cada proyecto. Por ejemplo, que instale un Ubuntu Precise, más estos cuatro paquetes con apt-get, más estos dos con easy_install. Esta información viviría en un archivo especial del proyecto, que LocoLander leería en el momento del armado del entorno. Toda la salida a stdout/stderr de esta etapa quedaría logueada para poder revisarse.
  • Ejecución de las pruebas: LocoLander, una vez armado el entorno y con el código brancheado, ejecutaría un archivo puntual (que también está indicado en el archivo de configuración antedicho). Ese archivo puede correr las pruebas unitarias y cualquier control sobre el proyecto, pero la idea es que termina con el resultado en ok o en error, y esto determina si el branch está listo para mergearse a trunk o no. Como en el caso anterior, toda la salida de stdout/stderr estaría disponible para el usuario.
  • Repositorios: Aunque tenemos mucha variabilidad en el cómo usarlos, la intención es que LocoLander sea multi-repositorio. O sea que trabaje con Launchpad, GitHub, BitBucket, etc. El trabajo de soportar varios varía más que nada en función de las determinades capacidades que tiene cada repositorio y qué API presenta para no tener que andar scrapeando HTML o haciendo cosas locas para laburar autenticado.
  • Autenticación de LocoLander: Esto depende del repositorio en sí, pero en general sería así: LocoLander tendría un usuario en cada repositorio, y si uno quiere usarlo todo lo que tiene que hacer a nivel autenticación es "incorporarlo como colaborador", o "darle permisos de commit en el proyecto", o lo que corresponda en cada repositorio. Lo que no se haría de ninguna manera es poner en el sitio de LocoLander tokens de autenticación de los distintos repositorios. De esta forma, los riesgos de seguridad son mínimos: LocoLander no posee datos críticos de nadie, y el dueño de cualquier proyecto puede en cualquier momento sacarle los permisos de commit a LocoLander.
  • Elección de qué branch está listo para intentar mergear: Este punto también depende de cada repositorio. Por ejemplo, en Launchpad, cuando se hace un "merge proposal", el mismo tiene un "estado" que cualquiera con derecho de commit puede poner como "Aprobado", entonces LocoLander revisaría eso. Hay otros repositorios que no son tan completos, pero siempre se puede solucionar con algún texto especial en los comentarios que se dejan. Creo que este es el punto de más variabilidad.
  • Previniendo abusos del código que se ejecuta: Un detalle importante en el funcionamiento de LocoLander es que hace muchas cosas él mismo (levantar una VM en particular, instalarle paquetes, etc), pero en algún momento ejecuta código que está en el branch. O sea, le está dando el control a alguien más. ¿Qué podemos hacer para evitar abusos (que la máquina no se ponga a mandar spam, o que no sea un nodo de [email protected]...) Creo que el punto crítico acá es que en el momento de tomar el control el proceso potencialmente maligno no pueda acceder a internet para nada, ni a ningún recurso fuera de la máquina virtual en sí. Después se pueden poner condiciones de uso, cortar los procesos que están corriendo más de N minutos, o revisar periódicamente lo que parezca raro, pero creo que ya cortando la posibilidad de conectarse a cualquier lado se está restringiendo bastante la posibilidad de mal uso.
  • Recursos necesarios: ¿Qué máquina se necesita para que esto corra? Mi idea es que no mucha. Quizás el más crítico es la memoria: hay que levantar una VM y ejecutar un proceso adentro que debería disponer de al menos unos centenares de megas para correr. Y también se necesita bastante disco (para guardar snapshots de muchas VMs, principalmente), pero cualquier VPS medio pelo da mucho disco. A nivel de velocidad de la máquina en sí, no me jode mucho: si los tests tardan en correr, alpiste.

Creo que cubrí todos los puntos importantes a la hora de definir el proyecto, pero si alguien tiene una duda, es bienvenido a preguntar.

Comentarios Imprimir

Actualizaciones

Estos días hice dos releases rápidos.

El primero fue de LauncherPosta, porque resulta que en Ubuntu Raring crasheaba mal. O sea, no tiraba un traceback: crasheaba.

¿Lo peor? Es un problema de la librería PyGtk, de cómo está implementado para Gtk 3. ¿Lo peor más peor de todos los peores? Es por diseño, y les parece bien que crashee a la mierda en lugar de tirar un traceback decente (miren el bug que abrí y lo que me respondieron).

En fin, esto refuerza lo que les decía que Gtk3 me gustaba menos y menos y me estoy pasando a Qt.

BTW, de LauncherPosta liberé la versión 1.0, con el casi único cambio de soportar mejor el toqueteo de la configuración del systray bajo Unity (un pedazo de código que luego les compartiré más separadamente).

El segundo release fue de Enjuewemela.

Hace rato que no sacaba una versión del jueguito. Es que aunque le había hecho un montón de correcciones, había un gran feature que estaba esperando: el replayer.

¿Qué es el replayer? Es un modo de ejecución de Enjuewemela que le decís que te reproduzca un juego anterior (le tenés que pasar el log que generó la jugada), y podés ir viendo exactamente el juego que hiciste, avanzando y retrocediendo con las flechas. Esto más que nada lo hice porque era necesario para poder detectar algunos crashes raros, y porque era divertido de hacer, :)

Los cambios más interesantes para esta versión 0.5, aparte de la habilidad de "re-jugar un log", son:

  • Alienta cuando hay múltiples coincidencias
  • Cambia el tablero cuando cambia de nivel
  • Múltiple fondos
  • Correcto manejo de los highscores
  • Otras pequeñas mejoras y un montón de correcciones.

La verdad es que estoy un poco harto de Enjuewemela. Hay que ponerle un montón de laburo para "hacerlo más lindo" al juego, y la verdad es que "hacerlo lindo" no es algo que me divierta.

Así que creo que sacaré un gran último feature, y luego creo que lo paso a mantenimiento, porque tengo otros proyectos bastante más interesantes para empujar.

Ya los comentaré por este mismo canal. Stay tuned.

Comentarios Imprimir

Vela

Esta foto la saqué en un monasterio tibetano, en un viaje que hice con motivo de una capacitación de Python para un programa que necesitaban para calcular un nombre.

Vela

O quizás la saqué en un patio de Paternal, en un cumpleaños. Ponele.

Comentarios Imprimir

Migrando Encuentro a PyQt

Este no es un post sobre Encuentro precisamente, sino sobre la experiencia de migrar Encuentro a Qt.

O, mejor dicho, a PyQt. ¿Qué es PyQt? Sencillo: una capa de unión para poder usar Qt desde Python. ¿Y qué es Qt? Qt es una biblioteca multiplataforma para desarrollar aplicaciones con interfaz gráfica. En otras palabras, una biblioteca para hacer las ventanas, botones, y todo eso que arma la interfaz gráfica de un programa de escritorio.

Con esa descripciones no tendríamos diferencia entre PyQt/Qt y PyGtk/Gtk, que es lo que usaba Encuentro hasta ahora. Entonces, ¿por qué migrar?

Son varias las razones... pero principalmente porque empaquetar PyGtk en un .exe es un dolor de muelas, y eso llevó a que la última versión que corre en windows es la que no funciona porque cambió todo el backend web (cuando los videos pasaron de ser hosteados por Encuentro a estar en Conectate). En otras palabras: la última versión de Encuentro que corre en windows no sirve para nada, y básicamente es culpa de Gtk.

Otras razón de menor importancia es que no me gustó como Gtk evoluciona. El futuro del framework es Gtk3, y ya estuve tirando código para usarlo, y lo que usé me gustó menos que Gtk2, así que me pareció un buen momento de cambiar. Finalmente, es una buena excusa para aprender Qt, ;)

Qt

En fin. La migración ya está terminada, pude hacer en Qt todo lo que tenía que hacer en función de la interfaz de Encuentro. ¿Qué me pareció? Bueno, las sensaciones son varias.

Me gustó Qt, mucho más cuadradito, más pytónico especialmente en la versión 4 que es la que yo estoy usando. Aunque la mayoría del código es muy similar, hay varias cosas que son más sencillas que en Gtk, aunque no todas, y hay bordes que limar.

(En este punto quiero aclarar que en ningún punto usé Qt Creator, el constructor gráfico de interfaces, sino que hice todo todo a mano, lo cual me permitió meterme bien adentro del framework y aprender mucho de su estructura subyacente.)

Un ejemplo de borde sencillo: no se puede saber si una señal está conectada o no. Entonces, por ejemplo, yo tengo un botón que muta de función, y a veces tiene que tener una señal conectada, y a veces otra (para que al hacer click haga una cosa u otra; en particular en el contexto de Encuentro: que el botón dispare la descarga del episodio, o la reproducción). Cuando el contexto cambia y se hace la revisión del estado del botón, no puedo decirle que desconecte cualquier señal que tenga, o preguntar qué señal tiene y desconectarla, tengo que (a mano) guardar en algún lado la señal que había conectado antes para desconectarla y conectar la nueva que corresponda.

Un ejemplo de algo complicado de hacer en Qt (que en Gtk es trivial): QTreeWidget no soporta HTML en el texto. Esto es, la habilidad de insertar tags para cambiar el tipo de texto (en el caso de Encuentro, yo lo necesito para resaltar en amarillo el fondo de las letras que coinciden con lo que el usuario ingresó en el campo de filtrar). Finalmente lo pude hacer, adaptando un ejemplo que Roberto Alsina encontró en la web, pero lo hace más lento, le agrega pequeños glitches que aunque no me joden, no deberían estar, y me mete a mí código oscurísimo que no es ni cerca de fácil de debuguear.

Por último, la integración con Twisted no es trivial. Hay cosas que en Encuentro están hechas con Twisted que podrían hacerse con herramientas más propias de Qt, sí, pero en este caso de migración, ya estaban hechas en Twisted y mi idea era aprovecharlas. Pero tuve que meter en el proyecto todo un módulo de integración y levantar la aplicación y cerrarla de una manera no trivial (y que me costó tiempo y sudor hacer que funcione correctamente, especialmente la parte de cerrar la aplicación, porque tuve que apagar los hilos de Twisted a mano).

La conclusión es que Qt me gustó bastante, y aunque extraño algunas cositas de Gtk, seguramente mis nuevos proyectos estarán usando PyQt.

Comentarios Imprimir

¡Hola Malena!

La fecha original (esa que se calcula desde el principio del embarazo) para el nacimiento de Malena era por alrededor del veintipocos de Abril.

Más entrados en los meses del embarazo, y ya viendo que iba a cesárea por el tamaño que venía Male y el historial de alta presión de Moni, se fijó la fecha para el 5 de Abril.

Sin embargo, llegando a fin de Marzo, al ver que todo venía muy bien, decidimos pasar esa fecha una semanita más. Que sea el 12.

Este martes pasado, 9 de abril, Moni fue a un control y tenía alta presión, y le dijeron "te quedás". Yo cerré (operativamente) mil cosas de emergencia, y salí corriendo.

A las 18:51 nació Malena (por cesárea), pesando 3766g (150g más que Felipe) y midiendo 50cm (dos cm más larga que el hermano).

Malena

Yo estuve en el parto, como la otra vez, y fue todo más o menos igual, desde mi punto de vista. Todos los partos son distintos, sin embargo, para la madre.

Sí, también era una cesárea, pero era la segunda. Y los dolores son diferentes, las cositas que pasan son distintas, etc. Moni estuvo el primer día con mucho dolor y con un pico de alta presión por ese motivo, pero luego de alguna intervención especializada, todo volvió a su correcto cauce.

Male se prendió bastante bien a la teta (lo cual fueron excelentes noticias luego del baile que tuvimos con Felu por tener succión aplanada), y aunque las primeras 36h estuvo muy molesta por cólicos, se la nota algo pancha :)

Hablando de Felu... él se quedó con mi vieja estos días, y el primer día lo trajeron a que la conozca. Aunque siempre tuvo muy buena relación con "la panza", estábamos curiosos de cómo iba a resultar el "primer encuentro".

La verdad, estuvo genial. Entró preguntando por Male, y aunque paró un segundo para darle a la madre un ramo de rosas que le habían comprado, su atención fue para la hermana. Se sentó en la cama y la miraaaba, :).

Ya es hermano mayor :D

Y la tocaba, medio bruto porque obviamente todavía no sabe tocar a un bebé, pero la acariciaba y le hacía mimos. Y preguntaba... ¿por qué llora? ¿por qué abre y cierra los ojos? ¿por qué hace tal ruido? etc. O directamente daba órdenes: "mamá, dale la teta a Male que llora".

Lo importante es que estuvo muy cariñoso, nada celoso (vamos a ver cómo evoluciona esto cuando la vea "ocupar espacios" en casa), y se portó bien todo el tiempo. Incluso en el momento de irse, que se fue con sus abuelos sin problema (nosotros teníamos la preocupación de si iba a querer irse "sin Moni").

Volviendo a Male y estos días en la clínica... por suerte los grandes dolores del primer día pasaron rápido, el miércoles estuvo mucho mejor, y hoy jueves la verdad es que estuvimos bastante tranquilos, incluso con algunas visitas.

Male y Moni

Nos queda mañana viernes, y suponemos que el sábado a la mañana estaremos yendo a casa. Moni y Male están muy bien, así que mañana recibiremos más visitas y nos prepararemos para el gran segundo cambio en la dinámica de familia, estar los cuatro en casa :D

Comentarios Imprimir