CDPedia 0.7

Software — Lunes 04 de Julio de 2011, 17:20


Python Argentina (PyAr) se enorgullece de anunciar la versión 0.7 de la CDPedia.  Esta versión fue entregada a Educ.ar para ser distribuida en escuelas del todo el país, y ya está disponible para la descarga pública.

La CDPedia es un proyecto del grupo de usuarios de Python Argentina que permite acceder a la información de la Wikipedia en castellano sin necesidad de una conexión a Internet.  Se puede descargar libremente de la red y grabar a CDs o DVDs para repartirlos sin restricciones.  La CDPedia funciona en cualquier computadora, ya sea que tenga Linux, MacOS o Windows como sistema operativo.

CDPedia

La versión 0.7 de CDPedia en DVD fue recientemente entregada para su evaluación a Educ.ar quien, por medio de un acuerdo con Wikimedia Argentina y PyAr, está por distribuir esta enciclopedia libre en todas las escuelas de Argentina.

Esta misma versión, con contenido de Wikipedia a Febrero de 2011, ya está publicada para descargas libremente en versiones CD y DVD, se puede bajar directamente o usando un torrente. Y planeamos hacer una tirada de mil DVDs para tratar de iniciar algo viral y que llegue a toda la gente posible... te recomiendo (y te agradezco) que copies estos discos y los regales a tus amigos, familia y conocidos. La información debe ser libre, así mejoramos la calidad de nuestra educación. 

Para mayor información e instrucciones para la descarga, visitar la página de CDPedia.


Metiendo la uña del pulgar

Software — Jueves 22 de Julio de 2010, 11:00

"Uña del pulgar", o thumbnail es una versión reducida de una imagen, usada para ayudar a su organización y reconocimiento. En la era de las imágenes digitales, los motores de búsqueda visuales y los programas para organizar imágenes normalmente hacen uso de los thumbnails, así como los sistemas operativos y entornos de escritorio recientes [-]

Hace unos meses mandé a digitalizar unas diapositivas que tenía mi familia. Un par de días atrás empecé a procesarlas, usando el JBrout para agregarle los tags indicando metadata de la imagen (lugar, año, gente que aparece, etc.).

El problema que tuve es que cuando abría con el JBrout fotos que había sacado yo, las veía perfectamente, pero cuando abría las diapositivas, veía una "X" fea que no me decía nada. No tardé demasiado en darme cuenta que el problema era que el JPEG no tenía adentro el correspondiente thumbnail.

Entonces, ¿cómo les metí el thumbnail a cada una?

Luego de buscar un rato por la web (pensé que tenía que haber algún programa que lo hiciera solo y masivo), encontré esta forma (lo más probable es que hayan mil más...).

    convert foto_original.jpg -thumbnail '200x200>' -unsharp 0x.5 thumbnail.jpg

convert es uno de los utilitarios de la fantástica ImageMagick, toma mi foto_original.jpg y me deja thumbnail.jpg. El -thumbnail le dice que voy a generar justamente un thumbnail, lo cual aparte de cambiar el tamaño hace otras cosas (por ejemplo, le saca toda la metadata interna, para que ocupe menos). El '200x200>' es una notación de ImageMagick que indica que la imagen resultante tiene que caber en una zona de 200 por 200 (o sea, me la reduce manteniendo el factor de forma hasta que el alto o el ancho ocupen como mucho 200 pixeles). El -unsharp 0x.5 lo recomiendan para mejorar la visualización de la imagen pequeñita. En esta página tienen otros detalles y temas a considerar al generar thumbnails (que no se aplican en mi caso).

Luego, para poner esa nueva y pequeña imagen dentro de la original, utilicé otro utilitario:

    exiftool '-ThumbnailImage<=thumbnail.jpg' foto_original.jpg

No hay demasiado que explicar en este caso.

Luego de verificar que todo funcionó correctamente, pasé a trabajar todas las diapositivas en masa. Los archivos tenían esta estructura: tres directorios CajaA, CajaB y CajaC (correspondientes a las tres cajas de diapositivas que mandé a digitalizar), con archivos adentro tipo a001.jpg, b033.jpg, etc.

Obviamente no iba a ejecutar esos dos comandos uno por uno para cada imagen, así que pasé a hacer uso del poder de bash, y escribí en la terminal:

    for foto in `find -name "????.jpg"`; do
         echo $foto;
         convert $foto -thumbnail '200x200>' -unsharp 0x.5 $foto.thumb;
         exiftool '-ThumbnailImage<='$foto.thumb $foto;
    done;


Basicamente, un loop sobre todas los archivos, haciendo un echo para ver qué procesaba, más los dos comandos anteriores.

Esto me dejó todo procesado, pero medio sucio, ya que por cada imagen tenía un .thumb, y además un _original que deja el exiftool. Así que procedí a borrar todo eso:

    find -name '*.thumb' -or -name '*_original' | xargs rm

O sea, le dije a find que encuentre todos los archivos que quería borrar, pero en lugar de mostrarlos por pantalla, se los pasé a xargs que los fue tomando y aplicando el rm para borrarlos.

Resultado final: tengo todas mis diapositivas con un thumbnail adentro. Y de paso aprendí un par de utilitarios nuevos, y algunas otras cositas.

Grabando conferencias

Software — Martes 13 de Julio de 2010, 18:37

Es recurrente en todos los eventos nuestros y de amigos el tema de la filmación.

En mi personalísima opinión, el peor pecado en este tema es que se filmen todas las charlas y que luego no se procesen los videos y eso se muera, o se entregue un año después. También es malo que se filme pero que luego no se escuche lo que dice el disertante, o que no se vea, etc.

Creo que la mejor (y casi única) manera de que "filmar las charlas de un evento" sea algo exitoso (obviamente sin gastar cantidades obscenas de dinero como podría/puede hacer la PSF o cualquier evento que maneje presupuestos de cientos de miles de dólares), es lo siguiente:

- Una cámara, manejada por un humano (de acá en más, el "Operador"), en cada aula/lugar donde se dé la charla.

- Un micrófono, ya que sino el audio es feo. Puede ser normal o corbatero, pero tiene que haber alguno.

- Un feed con la imagen que está mostrando la presentación.

La imagen de la cámara, el audio (o la imagen con el audio desde la cámara, no sé), más el feed con la presentación van a un "Elemento Mezclador" (más sobre esto luego), que es controlado por el mismo humano que maneja la cámara (sí, el Operador). Este elemento mezclador basicamente tiene cuatro posiciones:

- Pantalla completa "cámara".

- Pantalla completa "cámara", con cuadrito más pequeño (tipo "picture in picture") del "proyector".

- Pantalla completa "proyector", con cuadrito más pequeño (tipo "picture in picture") de la "cámara".

- Pantalla completa "proyector".

Ir pasando entre los cuatros es sencillo, y el Operador va prestando atención a la charla y decide al vuelo qué es más interesante mostrar.  El Elemento Mezclador graba directamente el video final teniendo en cuenta esto.

De esta manera, el único trabajo que hay que hacerle al video luego de la conferencia es:

- Ponerle una pantalla inicial con el nombre de la persona, título de la charla, etc. (trabajo humano, pero trivial).

- Reencodear el video a un formato piola para distribuir (lleva tiempo, pero es todo CPU).

- Subir los videos a algún lado (para esto se necesita upload)

Entonces... ¿para qué toda esta explicación? Bueno, la clave de todo esto es el "Elemento Mezclador".

Preguntando en PyAr me recomendaron dvswitch. Me contaron que la gente de Debian hace exactamente lo que cuento todos los años en la DebConf. Para ello desarrollaron DVSwitch hecho en C/C++. Tiene sus limitaciones ya que sólo trabaja con formato DV; pero es lo que necesito.

Habiendo elegido la herramienta, aparecen otros frentes algo complejos.

Como dije, necesitamos un stream de audio, y dos de video. Y dvswitch necesita que los dos stream de video sean en formato DV. El de la cámara que enfoca al disertante es sencillo: la enchufamos por el puerto FireWire (IEEE 1394) y ya está. ¿Y el otro?

Veo tres alternativas:

- Tomamos la salida de video del proyector. Esta es la más piola porque todo lo que haya que cablear o configurar se hace antes. El problema es que se necesita alguna especie de conversor para meterlo en la computadora (o que la misma tenga entrada de video).

- Filmamos la pantalla proyectada con otra cámara. Esta tampoco necesita configuración previa, pero la calidad seguramente será menor. Obviamente se necesita una segunda cámara de video, pero el principal problema que encuentro acá es que se necesitan *dos* entradas FireWire en la computadora.

- Levantamos lo proyectado directamente de la computadora del disertante. No es trivial pero tampoco nada del otro mundo... levantamos un VNC server en la máquina del que da la charla, y en nuestra computadora de control hacemos:

  vncrec -depth 16 <maquinadisertante> -record /dev/stdout | transcode -x vnc -i /dev/stdin -y xvid | ffmpeg -i - - target ntsc-dv salida.dv

En el ejemplo, puse salida.dv, que es un archivo; en la vida real habría que mandar eso a dvswitch. El problema de esta solución es que hay que configurar la computadora del disertante, y eso lleva tiempo. Además, depende de la calidad de la red entre ambas computadoras, lo cual es algo a tomar en cuenta si ambas están conectadas a un switch lento, o por wifi.

En fin... como mi laptop no tiene entrada de video y tiene una sola entrada firewire, voy a seguir experimentando con la tercer solución.

Cualquier idea es bienvenida.

Experimento Cirujano-Copiloto

Software — Viernes 04 de Junio de 2010, 20:15

(Note: There's an English version of this article here)

Los últimos meses en el equipo Ubuntu One Foundations, en Canonical, estuvimos experimentando con la metodología cirujano-copiloto.

¿Qué es eso de cirujano-copiloto? El concepto viene de un libro de los setentas, The Mythical Man Month, donde Frederick Brooks describe un provocativo esquema (propuesto primero por Harlan Mills) para un equipo de desarrollo de diez personas. En el libro, Brooks intenta manejar el hecho de que proyectos grandes de software no pueden ser escritos por una persona, o por un equipo chico, por lo que propone partir el proyecto en partes más pequeñas, prestando especial atención a la optimización de las comunicaciones dentro y entre los equipos.

En el libro, la organización propuesta es poner a un desarrollador Cirujano rodeado de un gran equipo de ayudantes. Hoy en día el entorno de desarrollo es otro; tenemos herramientas como lenguajes de alto nivel, y repositorios de software, y versionado de código, etc. Seguramente no necesitamos a alguien para que nos clasifique las tarjetas perforadas, :)

Sin embargo, este es un concepto que podemos usar hoy, pero achicando el equipo a sólo dos personas: el cirujano, y el copiloto. Traducido del libro...
(el copiloto) es el alter ego del cirujano, capaz de hacer cualquier parte del trabajo, pero menos experimentado. Su función principal es compartir la etapa de diseño, pensando y discutiendo, y evaluando. El cirujano intenta ideas con él, pero no está atado a sus recomendaciones. El copiloto frecuentemente representa a su equipo en discusiones con otros equipos sobre funcionalidades e interfaces. Conoce todo el código íntimamente. Investiga estrategias alternativas de diseño.

Nuestra experiencia

Este experimento fue valioso para nosotros, ya que generó un equipo de dos que al ejecutar el experimento probó ser más eficiente que las dos personas por separado.

Alguno de los casos donde esto fue evidente durante el experimento fue que al discutir problemas o nuevas características, el cirujano (teniendo un conocimiento más profundo del sistema) podía prever fácilmente situaciones, cómo podría diseñarse la característica, resolverse el problema, etc. Entonces el cirujano discutía eso con el copiloto, necesitando explicar el razonamiento lo suficiente como para que se entienda (pero a alguien con experiencia en el sistema), lo que provocaba algunos buenos efectos secundarios:
  • Tener que poner el razonamiento en palabras lo hace más claro tanto para el cirujano como para el copiloto; sin embargo esto no es un gasto notable, ya que ambos conocen el sistema, lo que hace más sencillo la transferencia de conocimientos.
  • Se descubren temprano posibles fallas en el razonamiento, y también se pueden incorporar en este momento ideas frescas del copiloto.
  • Luego que el copiloto entendió la idea, él o ella pueden ayudar al cirujano a implementarla (o directamente hacerlo todo, liberando al cirujano para otras tareas).
Quiero dejar en claro que esto no implica que el copiloto dependa siempre del cirujano para el trabajo diario. Normalmente el copiloto trabaja creativamente y trae nuevas ideas y conocimiento al equipo; sin embargo discutir esta nueva información con el cirujano, de manera de integrarla mejor al sistema actual, hace más eficientes estas contribuciones.

Esto está muy relacionado con otro beneficio interesante del dúo dinámico cirujano/copiloto: entrenamiento. Cuando el copiloto es nuevo al equipo y al sistema, tener a alguien que sabe exactamente los avances que está haciendo al ganar velocidad, revisando y guiando el trabajo, hace más fácil y disfrutable esta etapa inicial (lo que se traduce a una mayor eficiencia y mejores resultados).

Más aún, este equipo altamente acoplado es especialmente bueno para atacar problemas complejos. Esto se debe principalmente a tener cuatro ojos en lugar de dos, pero con la ventaja que ambas personas tienen baja impedancia entre ellas. Sin embargo, ser explícitos sobre quien es responsable de tomar las decisiones es algo muy bueno en la interacción entre el equipo y otros jugadores externos (jefes, líderes técnicos, usuarios): queda claro que el cirujano es responsable por las  decisiones tomadas, de una manera u otra.

Una ventaja adicional de formar el par cirujano/copiloto es que si el equipo prueba ser exitoso (lo cual depende de muchos otros factores más allá de esta configuración en particular, somos mayormente humanos) se puede mantener a futuro, sabiendo que esas dos personas trabajando juntas son buenas para determinadas tareas, y usarse de esa manera (lo cual concuerda con el concepto de desarrollo ágil de asignar trabajo a equipos, no personas a tareas).


Un caso real

Quiero explicar uno de los casos donde trabajamos como cirujano/copiloto durante estos meses, sólo como una muestra que quizás ayude a entender mejor los conceptos anteriores.

Este fue uno de los problemas más grandes encontrados en el Ubuntu One Syncdaemon luego de la liberación de Karmic, generando de los usuarios un quintillón de reportes de bugs: el States de Syncdaemon. Era un pedazo de código que arrancó chico y creció orgánicamente mientras aprendíamos qué debía hacer para manejar todas las complejidades de Syncdaemon. Al final, era un módulo grande, construido de una manera que no permitía realmente ser probado, y difícil de leer y entender, que generó un montón de problemas muy visibles (normalmente, hacía que Syncdaemon se trabara y no trabajara más hasta que se lo reiniciase).

El objetivo para el equipo era simplemente "arreglarlo". Sin embargo, un análisis simple probó que se necesitaba reescribir desde cero, y el reemplazo debía estar literalmente libre de problemas (no podíamos darnos el lujo de perder dos meses encontrando detalles en el nuevo código estando tan cerca de Lucid).

Ejecutamos el proceso de "arreglar States" en varios pasos bien definidos:

Análisis: Acá estudiamos el código anterior, encontrando los casos explícitos e implícitos que manejaba. Definimos qué necesitábamos cambiar, y qué necesitábamos escribir de nuevo (notablemente, encontramos acá algo inesperado: debíamos rehacer el cómo Syncdaemon manejaba las conexiones de red a través de Twisted).

En esta etapa, el tener un equipo altamente acoplado funcionó muy, muy bien. La misma tarea no podría haber sido ejecutada tan eficientemente si la hacía una sola persona, o si un equipo se involucraba en profundas discusiones. Debo mencionar que este trabajo se hizo cara a cara durante un sprint (difícilmente se podría haber hecho remotamente y tener el mismo resultado).


(click para ver la imagen en una resolución entendible)

Diseño: También durante el sprint diseñamos un nuevo modelo para la bestia, tratamos de simplificar y generalizarlo, y discutimos todo esto con los autor(es) anterior(es) del módulo.

El tener un cirujano con más experiencia en esta fase, mezclado con las nuevas ideas del copiloto, provocaron un buen diseño, simple y poderoso. Una sola persona o dos trabajando por separado no podrían haber diseñado el nuevo States de forma tan limpia como sucedió en este caso.

Implementación: esto se hizo completamente en paralelo y remotamente, en las semanas siguientes al sprint. Sin embargo también incluyeron largas conversaciones por teléfono donde se discutieron detalles específicos o nuevas ideas.

En esta etapa también notamos que el equipo tenía el tamaño ideal: un sólo par de ojos seguramente no habrían visto los detalles más complicados, y más gente no podría haber trabajado en paralelo en la misma implementación como lo hicieron dos personas.


(click para descargar los tres .SVG actualizados del diseño)

Puesta en funcionamiento: realmente no fue un paso, ya que no hubo ningún problema... fue sólo un tema de hacer el commit a trunk, y hacer un seguimiento los próximos días.

El resultado de esta experiencia fue muy satisfactorio: reemplazamos algo que era muy doloroso para usuarios y desarrolladores en favor de algo que fue invisible luego de la instalación: funcionó tan bien que nadie lo notó más.


Conclusiones

Estoy muy contento con el resultado de este experimento, y con los objetivos que logramos mientras lo hacíamos. El trabajo producido durante esos meses fue muy bueno, considerando especialmente que venía Lucid.

Sin embargo, es mucho más valioso encontrar dos personas que trabajen tan bien juntos, incluso si no hay una diferencia de experiencia entre ellos para que califique dentro de la estructura cirujano/copiloto. No siempre se tiene que un equipo de dos desarrolladores produce más que los dos desarrolladores por separado... entonces cuando se encuentra, es buena idea mantenerlo.

Recomiendo hacer experimentos similares en Canonical, especialmente como una oportunidad de aprendizaje para personas que recién entraron en la compañía, o al hacer rotaciones entre equipos. En estos casos, el tener un entrenador que tiene más experiencia al menos en lo que está haciendo el departamento, ayuda mucho al desarrollador nuevo, y al final mejora el rendimiento de todo el equipo.

Haciendo pruebas

Software — Miércoles 26 de Mayo de 2010, 16:01

(Note: There's an English version of this report here)

Mandé este mail originalmente a la lista interna de Canonical donde discutimos temas técnicos:



"Testing" (o testeo, o realizar pruebas) es un terreno resbaladizo en el desarrollo de software. Es como dejar de fumar: todo el mundo sabe que es algo bueno, pero pocos tienden naturalmente a hacerlo.

Además tiene facetas muy diferentes: pruebas de unidad, pruebas de integración, interfaces gráficas. Incluso en las interfaces gráficas, no es lo mismo hacer pruebas en PyGTK, o en interfaces web.

Por ejemplo, yo estoy convencido de que debemos hacer pruebas cuando desarrollamos software, que es una buena manera de evitar (o minimizar) deuda técnica, y que no sólo te mejora la calidad del producto, sino que tiene características más difíciles de medir (como innovación: nadie va a tocar un proyecto grande que no tiene pruebas sólo para probar algo nuevo).

Pero, todavía tengo algunas dudas, y mucho que aprender en este campo. ¿Es valioso en todos los casos? ¿Cual es el balance correcto entre pruebas de unidad y pruebas de integración? ¿Y qué hacemos con las interfaces gráficas?

Y un tópico probablemente controversial: yo sé que tenemos que hacer pruebas, pero gente en mi equipo no, ¡ayúdenme a convencerlos!

En cualquier caso, es algo para hablar. Podemos arrancar una charla acá, y luego agendar un par de reuniones para cubrir algunos temas particulares, una vez que sepamos cuales, o quizás encontrarnos en el UDS para discutirlo personalmente.

Estoy seguro que dentro de Canonical "Testing" se usa en todos lados, y podemos aprender unos de otros.

Ideas? Preocupaciones? Experiencias?


Esto generó un gran árbol de discusiones, con un montón de puntos en los que todos estaban de acuerdo, y un montón que fueron un poco controvertidos.

Entonces, luego de que el polvo se asentó, escribí un resumen de toda la conversación:



Esto es una especie de resumen con conclusiones y comentarios del hilo sobre Testing de los últimos días.


Es mejor mostrar ventajas sobre algo a la gente que forzarlos a usarlo. Hay un par de situaciones "fáciles de ver" donde las pruebas de unidad son claramente algo bueno. Jamu K. agregó algunos puntos a lo que yo mencioné en el correo original:
  • Te dicen cuando cometiste un error y rompiste algo. Cuanto antes detectes el error será más barato arreglarlo. Si un problema entra a un sistema en producción y afecta a los clientes, costará mucho en términos de satisfacción del usuario y tiempo para arreglarlo.
  • Son material educativo que ayuda un principiante (o alguien experimentado) a entender la lógica en una manera que no es posible simplemente al leer el código mismo. Esto es especialmente verdad cuando las pruebas ejercitan condiciones de error que no se desprenden de forma obvia del código.
  • Te ayudan a mantener una velocidad consistente. Es mucho menos probable que encuentres un problema que te haga perder dos días revisando y corrigiendo cuanto tenés buenas pruebas.
  • Te permiten optimizar la implementación con la confianza de que no rompiste ninguna API. "Primero hacelo bien, luego hacelo rápido" es bastante duro, y lo es aún más sin buenas pruebas.
  • Por definición, hacen que tu implementación se pueda probar. Te ayudan a entender cuando amontonaste demasiados detalles y te llevan a un mejor diseño.
Algunas ventajas son más conceptuales: muy claras a la gente que ya probó pruebas de unidad, pero no tan fáciles de ver para gente que realmente nunca lo hizo. Un ejemplo de esto es que diseñar para ser probado frecuentemente lleva a una mejor API (sin embargo, algunas veces lleva a una API más fea, porque estás forzado a agregar parámetros que sólo son útiles en un entorno de pruebas; como en todo, el equilibrio es el mejor de los consejos).

Una buena frase del hilo que me gustó como razón para hacer pruebas:
El código que estás escribiendo será usado por años. Será actualizado al cambiar los requerimientos. Y de vez en cuando, alguien que no es familiar al código como lo estás vos ahora estará en apuros para corregir un problema en él. ¿Qué previsión razonable podés hacer para ayudar a esa persona? Pensalo un minuto. Acordate, esa persona podrías ser vos.
¿Y qué desventajas hay? La gente a veces se queja de que si hacen pruebas, tardan más en escribir código. Sin embargo, lo que sucede es que las pruebas no cambian realmente el total de tiempo que toma desarrollar software, sólo cambia el cuando se paga ese costo. Sí, para software con pruebas, el beta inicial es mucho más completo y mejor probado, pero aparece más tarde en el ciclo, lo que puede ser un problema si no podés entregar ese código al usuario.

En todo el hilo, sólo se mencionó una desventaja real de TDD: puede pasar a veces que en lugar de realmente pensar profundamente un detalle del código, sólo lo vas toqueteando hasta que pasás las pruebas: esto puede llevar a código que esté menos pensado que lo que debería, ya que programás contra una luz verde, no contra un modelo mental limpio.

Hay que aclarar que no hay nada malo en no hacer TDD, pero que entrega resultados muy distintos con respecto a hacer las pruebas como corresponde, y se podría decir que al no hacer TDD los resultados son peores. ¿Está bien tener malos resultados? En algunos entornos, apuesto a que sí; sin embargo en Canonical queremos entregar lo mejor. Jamu lo dijo bien claro: si estás escribiendo código de producción sin hacer pruebas, entonces no estás haciendo tu trabajo correctamente. Mark S. lo reforzó con:
Deberíamos requerir pruebas para el código que somos responsables, y las excepciones que haya (seguro las habrán) necesitan justificarse y documentarse, no al revés.

Hacer pruebas es algo cultural, necesitamos encontrar cómo hacerlo crecer culturalmente: contratar gente que ya entienda y actúe con ese conocimiento, y entrenar a aquellos que todavía no tienen confianza en esto.

Hubo un montón de charla alrededor de hacer pruebas, pero nadie hizo distinción sobre que tipos de pruebas eran. Parece que las pruebas de unidad y de integración, o probar bibliotecas o interfaces gráficas, es todo lo mismo al discutir el tema.

Sin embargo, alguien preguntó específicamente sobre pruebas en interfaces gráficas. Realmente no sé sobre eso (¡quiero aprender!), pero creo que es un área menos conocida que las "pruebas sobre bibliotecas".

También se mencionó un tipo de pruebas que es raramente comentado fuera de los círculos de administradores de sistemas: cuando se maneja un servicio que se tienen que monitorear, es vital disponer de una manera de poder probar al servicio de manera frecuente y repetida tal que se pueda asegurar que sigue funcionando.  Entonces, también se necesitan pruebas de reglas y procesos de negocios para los sistemas funcionado.


Hubo un poco de discusión acerca de las pruebas de documentación. "Doctests" son un buen material de aprendizaje para las bibliotecas, y pueden escribirse para mostrar funcionalidad y guiar por arriba a los usuarios. Pueden ser muy buenas para dar impresiones generales sobre el módulo.

Pruebas de documentación bien escritas son excelentes para documentar APIs, porque podés hacer que el conjunto de pruebas ejecute también aquellas, de manera de asegurarte que la documentación siempre permanece actualizada. Estás haciendo pruebas sobre la documentación, no usando la documentación para probar nada.

Quedó claro que las pruebas de documentación no reemplazan las pruebas de unidad, las complementan.


La discusión más grande del hilo fue sobre si TDD era útil en código experimental, o en etapas muy tempranas del desarrollo. Se aseguró que TDD funciona mucho mejor con códigos maduros que con código experimental. Esto se aplica también a características experimentales dentro de proyectos maduros. Básicamente se reduce a esto: si tenés una buena visión de lo que necesitás, escribir las pruebas primero te ayudan a señalizar el camino que vas a tomar. Si no tenés ni siquiera una buena idea de para qué dirección vas, TDD es un esfuerzo desperdiciado.

Esto generó algo de controversia, hasta que se explicó que "experimental" no es la mejor palabra para explicar que: estás en una fase de aprendizaje porque realmente estás tratando de entender mejor el problema. Una vez que entendiste el problema lo suficientemente bien como para tener una visión de la solución, volvés a TDD. Son realmente dos actividades distintas.

Esto normalmente sucede cuando la gente que escribe el código en modo "experimentación" sólo quiere ver si una idea loca va a funcionar o no, lo que muchas veces resulta en descubrir que todavía no se entiende el problema completamente.

Por otro lado, está la situación donde se necesita código en producción, y realmente no hay tiempo de hacer pruebas. Sí, ya sabemos, tendrá defectos, y a largo plazo es más caro, pero "lo necesitamos ya". Esto pasa en la vida real más veces que con las que estaría cómodo... Gustavo N. dijo algo que comparto completamente:
Si estás en una startup en una situación de vida o muerte (para la compañía), seguro... podés optar por ir realmente rápido, obtener un montón de mercado, y luego estabilizarte si resultó bien (mirá Twitter :-). Si sos parte de un contexto más grande (como nosotros), y tu producto no va a desaparecer pronto (ni la compañía que tiene una marca asociada con el producto), entonces estas rupturas pueden dañar realmente al producto y a la marca.


Entonces, como conclusión, por favor compartí sobre hacer pruebas en esta lista.  Preocupaciones, ideas, tecnologías, si deberías o no hacer algo, etc.; este no es un tema donde todo es blanco o negro, o donde está todo dicho.

Si con el tiempo encontramos que es necesario una reunión para discutir algo (o incluso un grupo que se reúna regularmente), podemos ir a por ello. Mientras tanto, charlemos por acá.

Localizate, chabón

Software — Viernes 26 de Marzo de 2010, 18:22

Uno de los bugs críticos que tenía en Enjuéwemela era el de internacionalizarlo/localizarlo.

Este proceso (que tiene en inglés nombres tan complicados que se los refiere normalmente como i18n y l10n, deduzcan ustedes por qué) basicamente permite al programa mostrar todos los textos en el lenguaje del usuario.

Obviamente, para que todos los textos de un programa estén en varios idiomas, la gente tiene que traducirlos, y aparte el programa tiene que mostrar los textos correspondientes en el lugar adecuado, en función del idioma del usuario. La forma de hacer esto está establecida desde hace varios años, y está armada especialmente para facilitar que colaboradores creen nuevas traducciones y se agreguen al sistema.

Esta tecnología se conoce como Gettext, y se puede utilizar desde todos (o casi todos) los lenguajes existentes. Pero una cosa es utilizarlo, y otra es armar el programa para que pueda utilizarlo, y que se puedan agregar nuevas traducciones, etc.

Recuerdo que cuando lo hice para Typus Pocus no salió fácil, y tuve que leer bastante. Casi me pongo a pensar nuevamente como era, pero se me prendió la lamparita y me acordé que en su momento había escrito en ese proyecto un procedimiento_locale.txt, así que lo tomé y usé.

Para que estos pasos los puedan usar todos, los dejo acá. Pero ojo, no muestran como usar gettext desde tal o cual lenguaje (eso lo verán ustedes), sino cómo preparar los archivos y directorios para que luego puedan usar gettext desde sus programas. Por otro lado, los ejemplos son las lineas que tiré para Enjuéwemela, así que están orientados a Python, sepan adaptar.

Entonces...

Creamos el directorio para guardar nuestra estructura de traducciones:
mkdir locale
Editamos todos nuestros archivos y metemos todos los textos que queramos internacionalizar en la llamada a función _().  O sea, que si teníamos el texto "click here" y queremos que ese texto se internacionalice, tenemos que dejar _("click here"). Esto es vital para el próximo paso, y para el funcionamiento luego, ya que _() será la función de gettext que reemplazará lo que está escrito en el código con lo que se mostrará al usuario en función de su lenguaje.

Generamos el archivo .pot con todos los textos que utilizamos en nuestro programa. Para ello utilizamos xgettext y le pasamos todos los .py que usamos (esta utilidad revisará las fuentes y tomará los textos que tienen el _() que agregamos antes):
xgettext *.py --output=locale/core.pot
Este .pot es el archivo template que distribuiremos a todos aquellos que deseen traducir nuestro programa. Antes de distribuirlo, deberíamos abrirlo con un editor y completar ciertos campos que están listos para ser rellenados (título, autor, etc.).

La preparación propiamente dicha del sistema ya está completa, los pasos a continuación muestran qué hacer con el .pot si queremos generar la traducción para un nuevo lenguaje.

Generamos el .po, renombrando la base del archivo para incorporarle las dos letras del idioma que estamos utilizando. Si es la primera vez, sólo copiamos el .pot al mismo...
cd locale
cp core.pot core_es.po
..., pero si ya teníamos el .po de antes y ahora tenemos un nuevo .pot (porque aparecieron nuevos textos en el programa, o cambiaron los que estaban de antes), tenemos que mergear los archivos de la siguiente manera:
cd locale
msgmerge core_es.po core.pot > /tmp/po_temporal
mv /tmp/po_temporal core_es.po
El próximo paso es abrir el core_es.po con un editor de texto y traducir todas las cadenas. Luego, tenemos que compilar el .po al .mo, que es el archivo que levantará realmente el sistema gettext:
msgfmt core_es.po
Y finalmente, movemos el archivo compilado a un directorio que tiene que seguir la estructura preestablecida aquí mostrada (prestar atención al renombre del archivo en sí, y a que en el directorio está el idioma utilizado en la traducción):
mkdir -p es/LC_MESSAGES
mv messages.mo es/LC_MESSAGES/core.mo
Como último detalle, quiero aclarar que hay muchos editores especializados que muestran los .po y .pot uno al lado del otro, especialmente útiles cuando los programas a traducir son muy grandes o contienen muchos textos, pero que realmente uno se puede arreglar con un editor de textos común y corriente.

Copias de resguardo

Software — Martes 05 de Enero de 2010, 16:47

Siempre, siempre, siempre, ante un problema con el disco rígido de una computadora, la palabra "backup" es la más mencionada y maldita por los usuarios.

Todos sabemos que tenemos que hacer backup. Pero muy pocos lo hacen. Y todos nos acordamos nuevamente del mismo cuando la máquina de repente no arranca, o arranca por la mitad, o se apaga de repente con un ruido raro.

El problema de hacer backup es la constancia. Lo hacemos una vez... quizás lo repetimos una vez más... y nos volvemos acordar cuando el problema nos muestra sus dientes gritando "¡tus datos están perdidos!".

Y no importa si sos un principiante en el mundo de la informática, o un avezado experto: hacer backups con constancia es complicado... no por el conocimiento técnico involucrado, sino porque uno no es constante.

Hasta hace una semana atrás yo tenía backups de pocas cosas:
  • Todas las fotos que fui sacando las tengo en el disco rígido y en DVD, pero también las subo a Flickr, en tamaño original. Esto no es gratis, ya que el servicio de Flickr sin costo no permite tanto almacenamiento, pero creo que vale los 25 dólares que pago por año.
  •  Este blog y los archivos aledaños se copian cada tres días al disco rígido de mi computadora. Entonces, si algo le pasa al server, sé que la info la tengo en otro lado.
  • La música que tengo en mp3 está en mi computadora de escritorio y en la laptop, más una copia de backup en DVD.
Ahora, finalmente, armé una solución para proteger de incidentes mis datos diarios, que son los más complicados de todos.

¿Por qué son complicados? Porque cambian todo el tiempo, y si uno pasa cinco meses sin hacer backup, los cambios son muchos y están todos desparramados... ver qué cambió y hacer un backup parcial es complicado, y hacer backup de todo de nuevo es una putada.  Se podrían hacer backups parciales y diferenciales, pero la info no son dos gigas, y armar algo en múltiples DVDs es más complicado de lo que parece.

La solución

Lo que armé es básicamente una solución RAID, en configuración espejo, que se ve como un directorio normal pero que realmente duplica los datos en dos discos físicamente separados, de manera que si se rompe uno toda la info está a salvo en el otro.

Además, armé un crontab para que me haga copias de determinados directorios cada tanto y de forma diferencial, lo cual es bastante eficiente.

¿Cómo armé esto? Así...

Un par de semanas atrás compré un segundo disco rígido, al que le instalé Karmic Koala desde cero, luego de particionarlo.

No voy a entrar en detalles de cómo particioné el disco nuevo y qué usé del viejo, sólo es importante que dejé una partición vieja del disco anterior y una del disco nuevo del mismo tamaño, como podemos ver en el siguiente reporte:

$ df -m
S.ficheros         Bloques de 1M   Usado    Dispon Uso% Montado en
/dev/sdb5                93872       188     88916   1% /backup
...
/dev/sda1                93872       188     88916   1% /mnt/old-barra


La partición nueva es /backup y la vieja es /mnt/old-barra. Se puede ver que son dos discos físicos distintos porque uno es sda y el otro es sdb. Ambas particiones están montadas porque las dejó así el instalador del Ubuntu (y además yo necesitaba rescatar info de la partición vieja).

El primer paso para armar el RAID usando estas particiones es desmontarlas:

$ sudo umount /backup
$ sudo umount /mnt/old-barra/


Luego, creamos el dispositivo que será el que utilicemos como entrada/salida:

$ sudo mknod /dev/md0 b 9 0

Luego le indicamos a mdadm (el programa que nos arma el RAID) que queremos hacer sobre el dispositivo que recién creamos un RAID tipo mirror utilizando las dos particiones antes mencionadas. El programita nos va a dar información de las particiones, preguntar si estamos seguros, y hacer el laburo:

$ sudo mdadm --create /dev/md0 --level=mirror --raid-devices=2 /dev/sda1 /dev/sdb5
mdadm: /dev/sda1 appears to contain an ext2fs file system
    size=97659100K  mtime=Mon Dec 21 23:26:54 2009
mdadm: /dev/sdb5 appears to contain an ext2fs file system
    size=97659100K  mtime=Mon Dec 21 20:18:02 2009
Continue creating array? yes
mdadm: array /dev/md0 started.


Podemos ver la info de RAID que tenemos armada mirando el contenido de un archivo en /proc:

$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb5[1] sda1[0]
      97659008 blocks [2/2] [UU]
      [>....................]  resync =  1.0% (1036096/97659008) finish=26.4min speed=60946K/sec

unused devices: <none>


Luego, para hacer utilizable la partición, tenemos que crear el sistema de archivos en el disco RAID... y aquí vemos como ya no usamos las particiones de los discos físicos, sino el dispositivo especial que creamos:

$ sudo mkfs.ext4 /dev/md0
mke2fs 1.41.9 (22-Aug-2009)
Etiqueta del sistema de ficheros=
Tipo de SO: Linux
Tamaño del bloque=4096 (bitácora=2)
Tamaño del fragmento=4096 (bitácora=2)
6111232 nodos-i, 24414752 bloques
1220737 bloques (5.00%) reservados para el superusuario
Primer bloque de datos=0
Número máximo de bloques del sistema de ficheros=0
746 bloque de grupos
32768 bloques por grupo, 32768 fragmentos por grupo
8192 nodos-i por grupo
Respaldo del superbloque guardado en los bloques:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624, 11239424, 20480000, 23887872

Escribiendo las tablas de nodos-i: hecho
Creating journal (32768 blocks): hecho
Escribiendo superbloques y la información contable del sistema de ficheros: hecho

Para que esta partición esté montada siempre, agregamos al archivo /etc/fstab la siguiente linea:

/dev/md0   /backup   ext4   defaults,user 0 0

Y la montamos al directorio donde la queremos usar (como tenemos la info en el fstab no hace falta especificarla aquí de nuevo):

$ sudo mount /backup

Se puede ver entonces que el dispositivo que habíamos creado originalmente está montado en el directorio indicado, listo para usar:

$ df -m
S.ficheros         Bloques de 1M   Usado    Dispon Uso% Montado en
...
/dev/md0                 93872       188     88916   1% /backup


Lo podemos usar sin problema... pero luego de reiniciar la máquina, vi que no tenía el RAID funcionando! Luego de buscar un poco en la web, entendí que mi archivo de configuración no tenía la info necesaria, vaya uno a saber por qué.

Así que le dije al programita que administra el RAID que busque en lo que tiene armado y agregue la configuración actual al archivo:

sudo mdadm --examine --scan >> /etc/mdadm/mdadm.conf

Una vez hecho esto, reinicié y encontré todo fantásticamente bien.

Ahora que tenemos una partición "a prueba de roturas de un disco", tenemos que hacer backup regularmente ahí. Lo mejor que encontré para esto es el programita rdiff-backup (gracias Chaghi), que backupea un directorio en otro (el directorio destino termina con una copia del directorio fuente, pero se guardan diffs extras en un directorio especial de manera que se puede recuperar no sólo la última versión sino también anteriores).

Entonces, todo lo que hice fue poner unas llamadas a este programita en mi crontab, para que se ejecute cada tres días a la madrugada y me haga el backup de algunos directorios específicos en la nueva partición RAID:

 0 4 */3 * * rdiff-backup /home/facundo/dir1 /backup/dir1
30 4 */3 * * rdiff-backup /home/facundo/dir2 /backup/dir2
 0 5 */3 * * rdiff-backup /home/facundo/dir3 /backup/dir3


¡Y listo! La solución funciona, es eficiente, y no tengo que hacer nada de forma manual, :)

Bonus track: rdiff-backup funciona también a través de la red, lo cual es útil para hacer backup desde o en otras máquinas a las que tengamos accesso SSH. Hay un sólo detalle, y es el tema de que nos pida clave para entrar en la máquina remota: el ssh-agent nos va esconder este paso cuando lo probamos a mano, pero va a fallar cuando lo pongamos en el crontab. Para solucionar esto, encontré que se puede hacer lo siguiente:

0 3 * * * SSH_AUTH_SOCK=$(find /tmp -name 'socket.ssh' -user $USER 2>/dev/null); export SSH_AUTH_SOCK; rdiff-backup ...

Un bug! Un bug!

Software — Sábado 05 de Diciembre de 2009, 18:22

Varias veces hablé acá de los bugs, pequeños errores en los programas que hacen que no funcionen como originalmente estaban planeado. Una definición más formal sería algo como Un defecto de software (computer bug en inglés), es el resultado de un fallo o deficiencia durante el proceso de creación de programas de ordenador o computadora (software) [-].

El término bug o bicho viene de cuando se encontró una falla en la ejecución de un programa en una computadora debido a que una polilla se había metido en el medio de un relé de la computadora (estamos hablando del Mark II, construido en 1944... estas máquinas eran bien distintas de lo que son ahora).

El motivo de este post es que hoy me encontré con esta imagen:

El bicho original

Es un recorte de la imagen original, que como dice acá es el primer /bug/ de una computadora, que se encontró atrapada en el relé #70 del panel F de la Mark II mientras se estaba probando en la Universidad de Harvard en Septiembre de 1945.

¡No sabía que se tenía un registro del bicho este!

Herramientas digitales

Software — Viernes 19 de Junio de 2009, 18:00

Siempre que se habla de la brecha digital, siento que se tiende a simplificar todo demasiado. Quizás esto sea inevitable, porque es normal que conceptos complejos se reduzcan hasta que pierden cuerpo cuando alcanzan medios masivos de comunicación.

Pero incluso fuera de los medios masivos, creo que muchas veces se maneja el uso de las computadoras como algo con dos capas, especialmente al hablar de contenidos: consumir contenidos, y crear contenidos.

Yo quiero traer a colación una tercer capa, más profunda que las anteriores.

Volviendo al contenido, por ejemplo, se viene hablando hace rato que hay un cambio de comportamiento con respecto al uso de herramientas digitales; los usuarios estás pasando de sólo consumir contenido a través de la computadora, a también crearlo (se habla mucho de los blogs, compartir videos caseros, etc).

Pero, expresando de otra manera estos dos comportamientos, podemos ver que se está pasando de usar herramientas para el consumo de contenido, a usar herramientas para la creación de contenido. Puesto de esta forma, es casi obvia la tercer capa o fase... ¿y qué pasa con la creación de herramientas?

Hay una analogía, que aunque no exacta, puede ser ejemplificadora. Tomemos el caso del motor del auto. Todos lo usamos, cuando usamos un auto (lo que equivaldría a consumir el contenido). Algunos, hasta saben arreglarlo, modificarlo (lo que equivaldría a generar el contenido); los talleres mecánicos son los centros especializados en estos cambios. Pocos talleres, sin embargo, tienen la capacidad de crear sus propias herramientas para arreglar los motores.

En la computadora la dinámica es distinta. A diferencia del motor, donde muchos lo usan, pocos lo saben arreglar, y menos aún pueden crear sus propias herramientas para arreglarlo, tenemos que no hay una barrera física entre el usuario y el objeto. Sí, la computadora sale dinero, ponerla a funcionar sale dinero, y esto es una barrera entre la persona y su acceso a la computadora. Pero una vez que accedió a la misma, no hay mayor barrera  entre usar herramientas para consumir contenido, usar herramientas para producir contenido, y construir otras nuevas herramientas.

La única barrera es el conocimiento.

¿Pero por qué no se habla tanto de esta tercer fase? No lo sé... quizás sea que todavía es temprano en la adopción de la informática por parte de la gente (tenemos computadoras desde hace más de 60 años, sólo en los últimos 20 es algo masivo como tecnología, y todavía es un bien de consumo caro), o quizás es que a muchos no les conviene que la única barrera sea el conocimiento (por ejemplo, a menos que uses software libre, las herramientas de desarrollo son caras, más caras que la computadora misma).

La OLPC (el proyecto que pretendía entregar una laptop a cada chico) revolucionó el mundo en algunas formas, por ejemplo porque forzó a los fabricantes de computadoras a la creación del segmento netbook (laptops del orden de los 200 dólares, con menos capacidades que una notebook grande, pero con las suficientes para hacer el 90% de lo que uno hace en la notebook o computadora de escritorio; este segmento todavía no explotó, pero se viene!).

Sin embargo, la OLPC era visionaria en otros aspectos, como en la de consumo/creación de contenidos: el set de herramientas básicas apuntaba a que los niños no sólo consuman contenido, sino que lo creen y que lo hagan de forma colaborativa con otros niños. Entonces, tenía herramientas para escribir, para dibujar, para hacer música, fotos, videos, todo integrado en la máquina, y listo para que dos chicos en dos máquinas (o más), trabajen colaborando en el mismo texto, canción, etc.

Pero hay un detalle que es poco conocido de la OLPC, y es que también apuntaba a facilitar el salto a la tercer fase. Ya que tanto las aplicaciones como la interfaz gráfica de la OLPC estaban hechas en Python (donde el código que uno ve es el código que la máquina interpreta), los chicos tenían la posibilidad de, al estar usando cualquier cosa, apretar un botón y ver el código de esa cosa. Y no sólo verlo, también tocarlo en el mismo momento, facilitando el aprendizaje necesario para la modificación (y luego naturalmente la creación de) las herramientas de uso diario.

No sé qué pasará a futuro. La creación de herramientas, hoy por hoy, es algo que conlleva conocimiento especializado, y tiempo. Estoy seguro que todos alcanzaremos esta tercera fase, aunque quizás para que esto suceda la computadora tendrá que evolucionar lo suficiente como para que la creación de herramientas sea algo sencillo. Quizás que uno pueda expresar casi verbalmente en el lenguaje humano al que está acostumbrado, o que uno tenga maneras gráficas e intuitivas de construir lo que se necesita.

Creo que no llegaremos a una etapa en donde todos sepan programar. Tener la capacidad de programar es algo que implica un nivel de abstracción alto, poder pensar lógicamente, etc. La humanidad sabe matemática desde hace miles de años, y hoy por hoy una persona promedio no sabe dividir mentalmente, así que no veo la evolución necesaria por este lado.

Pero la fase de creación de herramientas digitales existe, y a por ella vamos.

Nota: Donde dice "...a menos que uses software libre..." antes decía "...a menos que uses Linux...", y lo corregí por indicación de Fede Heinz en un comentario aquí mismo (además, ahora representa mejor lo que quise decir originalmente).

Cuidando al usuario

Software — Jueves 28 de Mayo de 2009, 23:41

Acabamos de tener una sesión en UDS donde discutimos cómo iba a ver, un usuario que está instalando Ubuntu, que tiene la opción de configurar UbuntuOne.

Queremos que todo el mundo tenga una cuenta UbuntuOne, ya que muchas aplicaciones de escritorio van a tener mejoras a través de este servicio, incluso aunque nunca pagues un peso.

Entonces la discusión es: armamos un servicio, agregamos funcionalidad, gratis, y queremos que la gente al instalar Ubuntu se configure una cuenta, para que su experiencia sea mejor.

¿Cómo lo hacemos? En cualquier otra compañía, habría venido la gente de Marketing y habría dicho "hay que hacerlo así y así". Esto es un diferencial de cómo hacemos las cosas en Canonical, de la cual estoy muy contento: estuvimos durante una hora, más de treinta personas (algunas trabajan en la empresa, otras no, todas cuidando tener un mejor Ubuntu), discutiendo cual sería la manera menos intrusiva de ofrecerle la opción al usuario.

Por ejemplo, la manera más fácil de hacerlo es poner un icono en el escritorio del usuario. ¡Pero no queremos eso! A ninguno de nosotros nos gustaría que el proceso de instalación nos deje "cosas" en nuestro entorno, y como no nos gusta que nos lo hagan a nosotros, tampoco se lo haríamos al usuario...

Parece fácil de "pensarlo", ¿no? Bueno, no. Hay que encontrar un equilibrio entre ser visible y no, y hay muchas variables que uno no tiende a considerar. Y este tipo de sesiones, donde gente de la comunidad y la empresa con experiencia en la interacción con el usuario durante el proceso de instalación piensan juntos, es la mejor manera de lograr un mejor producto a futuro.

Educación libre

Software — Jueves 11 de Septiembre de 2008, 07:50

Bajo la convocatoria de Cáritas San isidro, la Escuela de Oficios San Cayetano (CFP401), Gleducar y la Fundación Vía Libre, se realizará el Primer Encuentro por una Educación Libre, EPUEL08, el 12 de septiembre de 9 a 19hs. en la sede de Cáritas San Isidro,  Ituzaingo 90.   La jornada contará con alrededor de 15 ponencias, charlas y experiencias sobre uso de Software Libre en el sistema educativo, además de la discusión sobre los materiales que producimos en el ámbito de la escuela y el uso de conocimiento libre en la educación. Cuando hablamos de conocimiento y software libre, nos referimos a materiales y programas que se pueden usar con cualquier propósito, adaptar a las propias necesidades, copiar y distribuir copias legalmente, mejorar y redistribuir los materales y los programas mejorados.  Algunos modelos exitosos de construcción colaborativa de software libre son, por ejemplo, los contenidos de la enciclopedia libre Wikipedia o numerosos programas de software libre como GNU/Linux.

Entre los objetivos de este evento se destacan el difundir el Software Libre en el ámbito educativo, compartir con comunidades educativas vecinas del área la experiencia de trabajo con software libre como alternativa madura en educación, formalizar una propuesta educativa a las autoridades del área a nivel provincial y nacional, y construir un lazo con las empresas y emprendimientos del sector informático para trabajar la inserción laboral de nuestros estudiantes.

Pueden ver la oferta de charlas para mañana. Hay muchas interesantes, lástima que no puedo ir, :(.

La Escuela de Oficios San Cayetano, uno de los organizadores del evento, está actualmente dando cursos de Python como parte de su oferta educativa (Python es un lenguaje muy útil para enseñar programación debido a su clara y simple sintáxis, su curva de aprendizaje suave, y la calidad de su comunidad).

En función de esto, y de tratar de devolver a la comunidad algo de lo que la comunidad nos da, PyAr se enorgullece de ser uno de los sponsors del evento.

Jugando con la red

Software — Miércoles 24 de Octubre de 2007, 09:59

Hace rato que venía manejandome diariamente con túneles SSH (o puentes, llamados por algunos). Pero esta semana aprendí un par de cosas más.


Túnel local

Un túnel SSH, de la manera que yo lo hacía, me permitía llegar a un destino específico a través de otra máquina. Esto lo hacía porque no podía llegar directamente a ese destino específico, pero sí a la máquina intermedia.

Por ejemplo, en el laburo, cuando no tengo trabajo, entro al canal de PyAr en IRC (#pyar en Freenode). Pero si yo quiero alcanzar el puerto 6667 del servidor irc.freenode.org desde el trabajo, no puedo. Pero sí puedo llegar a mi casa con SSH. Entonces hago un puente como el siguiente:

  ssh -L 4567:irc.freenode.org:6667 lamaquinademicasa.net


Entonces, el SSH desde la PC del laburo se conecta a la máquina de mi casa (previa autenticación mía). Luego apunto al programita de chat para que se comunique con la PC del laburo, al puerto 4567, y automágicamente termina llegando a irc.freenode.org al puerto indicado, y voilá.


Túnel dinámico


En la máquina del laburo tengo un VirtualBox con un Ubuntu instalado adentro. Si yo quiero navegar desde ahí, sin salir por el proxy del laburo, tenía que hacer también un puente SSH. Pero en el caso anterior el destino es fijo, y uno cuando navega en Internet quiere acceder a muchos destinos... ¿cómo se hace? Solución: un túnel dinámico!

  ssh -D 4567 lamaquinademicasa.net

 
Luego agarro el navegador, y lo configuro como que tengo instalado un proxy tipo SOCKS en la PC del laburo, en el puerto 4567. Y listo, funciona perfecto.


It's the proxy, stupid!

Pero luego quise utilizar una herramienta a la que no se le puede configurar el proxy SOCKS (el Synaptic...), ¿cómo podía hacer?

Ahí encontré el programita tsocks (tienen una linda explicación en castellano aquí). Lo instalé, lo configuré, y luego ejecuté Synaptic de la siguiente forma:

  sudo tsocks synaptic

(el sudo es porque Synaptic tiene que levantar con permisos de superusuario)

Y listo! :)

Powered by LifeType