MarioDebian, mi devlog

Bitácora de un desarrollador newbie.

Lo bueno si breve dos veces bueno
Via y Openchrome por fin trabajarán juntos.



Alicante TCOS.

 

 

¿Quién hace/es TCOS?

A la izquierda Ignacio Vidal (desarrollador de Lliurex, padre y responsable de toda la parte multimedia de TcosMonitor y un montón de cosas más) y a la derecha yo con una cara de sueño importante...

La noche anterior estuvimos de «Cena de Gala» y tuve el increible gusto de compartir mantel con algunas de las personas más importantes del mundo del software libre en este momento:

  • Steve McIntyre (Debian Leader)
  • Pascal Chevrel (Secretario de Mozilla Europa)
  • Luciano Bello (Debian Developer) ¡qué tio más grande, lo que me pude reir con él!
  • Viejos conocidos como Ismail Alí (MaX Madrid), Rodrigo Salvador (CGA Sevilla) o Miguel Gea (Xerako, Debian Developer).

En la mesa anexa teníamos a:

  • Jon Maddog (Linux Foundation)
  • Alexandro Colorado (OpenOffice.org Hispano, México)
  • Kurt Gramlich (Skolelinux, Alemania)

Una de las anecdotas de la noche fue ver y escuchar la discusión (que nosotros mismos forzamos) entre Luciano y Pascal sobre Iceweasel y Mozilla... y es que aunque puedan existir piques en ciertos asuntos/momentos da gusto saber que realmente todos se llevan muy bien.

Por la tarde (antes de la cena de gala) tuvimos la segunda reunión de desarrolladores de distribuciones y aproveche para hablar con Kurt Gramlich (Debian-Edu/Skolelinux). Hablamos sobre LTSP, sobre ControlAula y estuve haciendo una minidemo de TCOS... creo que el proyecto le gustó mucho y hemos quedado en repasarlo de nuevo para que en un futuro pueda formar parte de la distribución educativa de Debian...

Ya sabe que casi todas las Comunidades Autónomas en España usan o están empezando a usar TCOS y cuando varios miles de equipos usan algo es el momento de publicitarse.

Resumiendo, gente muy simpática y agradable en Alicante, clima primaveral/veraniego, y muchos contactos nuevos. Enhorabuena y muchas gracias a la organización.





Análisis gráfico del arranque de TCOS

Supongo que muchos conocereis el paquete bootchart, que reemplazando a init guarda un registro del arranque del equipo para luego generar unas gráficas bastante chulas.

Pues bien, hasta ahora bootchart sólo trabajaba (que yo sepa) desde el mismo proceso init de la partición de nuestro linux y no había manera de lanzarlo desde el INITRAMFS... con un poco de «hacking» y mucho borrar código que no necesitaba he hecho un tcos-bootchartd para analizar el arranque de TCOS.

La víctima es un terminal ligero eTC3800 y este es el gráfico (pulsar para ver más grande):

Al tiempo total (47 segundos) hay que restar 2 segundos metidos a propósito para que se vean los últimos procesos antes de parar bootchartd.

Conclusiones:

  • La descarga del squashfs es lo que más tiempo tarda (14 segundos) Embarassed
  • Gracias a bootchart he quitado un par de «sleep» que sobraban Tongue out
  • Gracias a bootchart he visto que el sistema de registro de dipositivos que se inyecta en udev (tcos-udev.sh) perdía mucho tiempo cuando aún no es útil por lo que se activa casi al final. Surprised
  • «ldconfig» tarda casi 2 segundos... quizás se pueda mejorar ejecutándolo cuando se genera la imagen con «chroot ldconfig»
  • El arranque tiene picos de 100% CPU sostenidos con udev y Xorg (algo relativamente lógico)
Hace un tiempo el arranque no bajaba de 1 minuto, tener un arranque usable (el terminal muestra GDM antes de los 44) ha sido todo un logro y gracias a bootchart podré saber donde se pierde ese tiempo tan precioso.

Luego lo subo al SVN por si alguien quiere probarlo.



netifaces_0.4-1_amd64.changes ACCEPTED

Ayer me llegaba este correo:

Accepted:
netifaces_0.4-1.diff.gz
to pool/main/n/netifaces/netifaces_0.4-1.diff.gz
netifaces_0.4-1.dsc
to pool/main/n/netifaces/netifaces_0.4-1.dsc
netifaces_0.4.orig.tar.gz
to pool/main/n/netifaces/netifaces_0.4.orig.tar.gz
python-netifaces-dbg_0.4-1_amd64.deb
to pool/main/n/netifaces/python-netifaces-dbg_0.4-1_amd64.deb
python-netifaces_0.4-1_amd64.deb
to pool/main/n/netifaces/python-netifaces_0.4-1_amd64.deb

Override entries for your package: netifaces_0.4-1.dsc - optional python python-netifaces-dbg_0.4-1_amd64.deb - extra python python-netifaces_0.4-1_amd64.deb - optional python Announcing to debian-devel-changes@l.d.o Closing bugs: 500394 Thank you for your contribution to Debian.

No hay mucho más que decir... yeeeepe!!!

Creo que ya se ha compilado en muchas arquitecturas aunque falta alguna.

Para empezar uno de los ftp-master ya me ha creado un bug (realmente no lo ha enviado, me ha mandado un correo)... en la descripción corta debo cambiar iface por interface.





Mi primer paquete en Debian

python-netifaces es un pequeño módulo de python que permite obtener información de los interfaces de red.

Desde hace unas versiones es dependencia de TcosMonitor (encuentra interfaces del tipo eth0:1 cosa que con /sys/class/net no es posible)

Como hay que empezar por algo, entré en el IRC del grupo de empaquetadores de módulos python y me echaron una mano (bastante grande por cierto) para que el paquete estuviese lo mejor posible. Después de haber mandado un ITP, ayer ha sido subido a NEW, y acaba de ser etiquetado como pendiente.

La forma de usarlo es muy sencilla:

$ python
>>> import netifaces
>>> dir(netifaces)
['AF_APPLETALK', 'AF_ASH', 'AF_ATMPVC', 'AF_ATMSVC', 'AF_AX25', 'AF_BLUETOOTH', 'AF_BRIDGE', 'AF_DECnet', 'AF_ECONET', 'AF_FILE', 'AF_INET', 'AF_INET6', 'AF_IPX', 'AF_IRDA', 'AF_KEY', 'AF_LINK', 'AF_NETBEUI', 'AF_NETLINK', 'AF_NETROM', 'AF_PACKET', 'AF_PPPOX', 'AF_ROSE', 'AF_ROUTE', 'AF_SECURITY', 'AF_SNA', 'AF_UNIX', 'AF_UNSPEC', 'AF_WANPIPE', 'AF_X25', '__doc__', '__file__', '__name__', 'ifaddresses', 'interfaces']

>>> netifaces.interfaces()
['lo', 'eth0', 'br0', 'vbox0', 'vbox1', 'vbox2']

>>> for iface in netifaces.interfaces():
...   print "IFACE: ", iface, " ", netifaces.ifaddresses(iface)
...

IFACE:  lo   {17: [{'peer': '00:00:00:00:00:00', 'addr': '00:00:00:00:00:00'}], 2: [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'addr': '::1'}]}
IFACE:  eth0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:1a:6b:6a:xx:xx'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::21a:6bff:fe6a:bec9%eth0'}]}
IFACE:  br0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:1a:6b:6a:xx:xx'}], 2: [{'broadcast': '192.168.0.255', 'netmask': '255.255.255.0', 'addr': '192.168.0.3'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::21a:6bff:fe6a:bec9%br0'}]}
IFACE:  vbox0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:eb:8c:87:f0'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:ebff:fe8c:87f0%vbox0'}]}
IFACE:  vbox1   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:b0:e6:18:e8'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:b0ff:fee6:18e8%vbox1'}]}
IFACE:  vbox2   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:d4:4c:e8:67'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:d4ff:fe4c:e867%vbox2'}]}

Como vemos devuelve un diccionario con la información de cada interfaz, para sacar los datos IPV4 (lo más usual):

>>> netifaces.ifaddresses('br0')[netifaces.AF_INET]
[{'broadcast': '192.168.0.255', 'netmask': '255.255.255.0', 'addr': '192.168.0.3'}]

Quizás como última mejora le falta obtener la puerta de enlace (por ejemplo a través de /proc/net/route, mediante la tercera columna, hay que pasarlo a decimal y rotarlo), yo en tcosmonitor lo he ampliado mediante python.





pam-usb con soporte para TCOS

pam-usb es un módulo de autenticación PAM que, usando una memoria USB, permite hacer login (su, gksu, GDM, KDM, etc...) mediante la verificación del modelo, vendedor fabricante, número de serie y una pareja de claves aleatorias (llamadas PADS) una situada en la memoria USB y otra en la $HOME del usuario.

El módulo funciona muy bien salvo que sólo permite el acceso local en la máquina y he estado pensando que ya que en TCOS tenemos varias formas de llegar a los dispositivos de almacenamiento podemos usar pam-usb para autenticar en remoto.

Como primer acercamiento he estado revisando el código (bastante simple: pam +  dbus + hal) y como en TCOS no hay dbus ni hal en remoto he portado parte de él a llamadas XMLRPC y autenticación mediante la cookie de Xorg.

Funcionamiento

Cuando GDM (o el gestor que sea) recibe un usuario llama a PAM para ver si puede autenticarlo antes de pedirle la contraseña, pam-usb toma el control y comprueba que es una petición remota (la variable $DISPLAY tiene este aspecto: xx.xx.xx.xx:0) entonces dispara mi parte «pusb_remote_auth»

  1. hace una primera llamada XMLRPC para inyectar la cookie de las X como propiedad de la ventana root mediante xprop
  2. GDM sabe el usuario y antes de llegar a mi parte sabe si tiene un dispositivo (Vendedor Fabricante, modelo , número de serie, UUID de la partición) con el UUID hacemos una petición de montaje en el terminal: «mount /dev/disk/by-uuid/$UUID /mnt/$UUID»
  3. Leemos (si existe) el directorio .pamusb del dispositivo y devolvemos en base64 el contenido (clave aleatoria binaria) por XMLRPC que se comparará al PAD que tiene el usuario en su $HOME/.pamusb (en este punto pam-usb original hace la comparación de 2 archivos, yo sólo tengo uno y el base64 de otro por lo que tendré que crear un temporal o hacer la comparación de base64 del remoto y local)
  4. Una vez comparados actualizamos los PAD y mandamos al terminal el base64 del nuevo PAD para que lo guarde en el dispositivo y lo desmonte

Para que todo esto funcione, lógicamente, hay que haber dado de alta un usuario en la configuración /etc/pamusb.conf, para ello hay una herramienta: pamusb-conf (python+dbus+hal) que detecta el dispositivo USB y edita el XML para añadir la pareja dispositivo~usuario, esta herramienta sólo funciona en local y también habrá que hackearla o incluso hacer un frontend gráfico.

De momento no he subido nada al SVN pero supongo que a lo largo de esta semana ya habrá algo de código para ver y probar.

UPDATE: (21:05)

Ya he subido el código al SVN de TCOS [pam-usb-tcos], y de paso he mandado un mail al autor original a ver que le parece la escabechina que he hecho con su aplicación.





Adios VMware (parte2) y nuevo TcosMonitor

Después de actualizar el servidor donde se aloja tcosproject y este blog al kernel 2.6.26 me he dado cuenta que nunca más podré ejecutar VMware y ya iba siendo hora, estoy bastante harto de soluciones no abiertas y que a cada actualización de mi sistema se rompan (esta vez el «any-any» no ha servido para nada) .

Así que a partir de ahora, el blog, el wiki de soleup, la desaparecida web han pasado a ser un VirtualHost de apache , y un interfaz virtual (eth0:1) para absorver la antígua IP de SOLEUP.

El servidor lo ha agradecido, tiene 2 Gb de RAM y después de desinstalar VMware se ha quedado mucho menos cargado y con menos procesos. A las malas pude montar el disco duro virtual y sacar lo que me interesaba.

UPDATE: ¡Qué cosas! Acaban de anunciar que VMWare ha liberado, convertido en gratuito, el Hipervisor de VMware ESXi  [Descargar, aunque se necesita cuenta vmware] ¿Se estarán dando cuenta que ahora con KVM, XEN, VirtualBox estan perdiendo mercado?

En otras cosas he estado hackeando TcosMonitor y tengo lo que puede ser el modo simulación de aula, es decir, mover los equipos a posiciones, y como un video (screencast más bien) vale más que mil imágenes y un millón de palabras aquí teneis una demo de más o menos 1 minuto

(Pulsar en la imagen para ver el screencast formato GIF: 5.7 Mb):

PD.-Al final he usado gtk.Fixed y aunque el soporte drag&drop ha costado no es demasiado complicado. Tengo que depurar el código que detecta si hay un icono cuando arrastramos otro para que no se solapen (función __getoverride), porque es demasiado sensible y no permite poner cerca los iconos.

De paso he ido separando cosas en vistas y controladores y aunque dista mucho para ser un buen programa vamos por buen camino.





Control de __todas__ las tarjetas de sonido, presentando tmixer

ATENCIÓN: Artículo bastante técnico ("tas avisao")

Una de las cosas en la que más ímpetu (y horas) he dedicado en TCOS es el soporte multimedia. Pero las cosas avanzan que es una barbaridad y llevaba casi 2 años sin tocar esta parte tan importante.

Cuando nos ponemos delante de un terminal ligero debemos tener cierta facilidad para acceder a los canales de la tarjeta de sonido ya que no todo es 'Master' o 'PCM'.

PulseAudio es el milagro que hace que el sonido (que se origina en el servidor) se reproduzca transparentemente en el terminal por medio de la variable de entorno «PULSE_SERVER», pero PulseAudio no es perfecto ya que desde su panel de control sólo controlamos el volumen de un canal (¿PCM?) de la tarjeta de sonido no de todos.

En TCOS desde hace tiempo el control de la tarjeta de sonido era bueno pero algo (bastante) lento. A modo de histórico era es la forma en la que funciona tcos-volume-manager:

1.- Se manda la cookie de las X al servidor XMLRPC del terminal y si nos da acceso se lee el nombre de todos los canales (sólo el nombre) del mezclador.

(BREVE INCISO: El mezclador podía ser ALSA o en el peor de los casos OSS para lo cual se necesitaban dos aplicaciones amixer (ALSA) y aumix (OSS) y bastante librerías enlazadas que no se necesitaban como gpm o ncurses )

2.- Una vez que teníamos la lista de canales ibamos preguntando uno por uno el estado del volumen y del mute y construiamos los deslizadores y casillas de mute.

NUEVA FORMA

Se ha desarrollado juntando las fuentes de amixer y aumix (con bastante pegamento por cierto) una nueva aplicación que he bautizado como tmixer.

Esta aplicación hace autodetección para usar ALSA (si existe /proc/asound/card0/id) o usar OSS (si existe /dev/mixer y /dev/dsp no existiendo ALSA) y llama a cada una de las partes, para usar los mismos comandos (scontrols scontents sget sset) y mostrar una salida similar.

La parte ALSA se ha modificado para que se pueda enviar facilmente en una petición XML, comparando la original de amixer:

$ amixer sget Master
Simple mixer control 'Master',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 39
  Mono: Playback 35 [90%] [-6.00dB] [on]

 y ahora mi invento:

$ /usr/lib/tcos/tmixer sget Master
Master,volume|switch|,90,on

Se pierde algo de información por el camino (diferencia estereo en niveles o dB) pero ganamos mucha más claridad para luego leerlo desde un script o desde el mismo python.

En la parte OSS también hay varios cambios:

$ aumix -q
vol 90, 90
pcm 87, 87
mic 100, 100
pcm2 100, 100
igain 0, 0
dig1 0, 0

Con mi juguete:

$ TMIXER_FORCE=oss /usr/lib/tcos/tmixer sget Master
Master,volume|switch|,90,on

Como se ve la salida es muy similar a la de ALSA, de hecho es como debe de ser para que no importe si usamos OSS o ALSA para acceder al mezclador, en OSS he dado alguna cosa por sentada como por ejemplo que todos los canales tienen botón de mute, aunque realmente el mute consiste en bajar el volumen a 0, en ALSA si hay mute real. También se han renombrado a algo un poco más parecido a los nombres que se usan en ALSA.

Como se puede ver en el código fuente de tmixer,  se hacen los test y se llama al main de las otras dos aplicaciones (que aún se pueden compilar por separado). La variable de entorno TMIXER_FORCE sirve para no usar autodetección sino intentarlo directamente con la que se pida.

¿En qué mejora TCOS?

Para empezar y con las modificaciones de la API de sonido de XMLRPC, sólo se hace una petición donde se devuelven todos los canales con sus características:

sh /usr/lib/tcos/soundctl.sh --showcontents
Master,volume|switch|,90,on#Headphone,switch|,on#PCM,volume|,87,#Mic,volume|switch|,100,on#Mic Boost,volume|,0,#IEC958,volume|switch|,0,off#Beep,volume|switch|,100,on#Docking Mic,volume|switch|,0,off#Docking Mic Boost,volume|,0,#Internal Mic,volume|switch|,0,off#Internal Mic Boost,volume|,67,#Speaker,switch|,on#

Esto se parte según el caracter '#' y después cada canal se separa por comas lo que nos da un vector de diccionarios listo para usar en python:

TcosXmlRpc::***NOT CHANNEL*** c=['3D Control Sigmatel - Depth', 'volume|', '']
TcosXmlRpc::***NOT CHANNEL*** c=['Mix', '', '']
TcosXmlRpc::***NOT CHANNEL*** c=['Mix Mono', '', '']
TcosXmlRpc::***NOT CHANNEL*** c=['Sigmatel D']
TcosActions::populate_datatxt() channel=Master ismute=False volume level=100.0 ctype=volume|switch|
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'on', 'type': 'volume|switch|', 'name': 'Master Mono', 'level': '59'}
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'switch|', 'name': '3D Control - Switch', 'level': ''}
TcosActions::populate_datatxt() channel=PCM ismute=False volume level=45.0 ctype=volume|switch|
TcosActions::populate_datatxt() channel=Line ismute=True volume level=0.0 ctype=volume|switch|
TcosActions::populate_datatxt() channel=CD ismute=True volume level=0.0 ctype=volume|switch|
TcosActions::populate_datatxt() channel=Mic ismute=True volume level=0.0 ctype=volume|switch|
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'switch|', 'name': 'Mic Boost (+20dB)', 'level': ''}
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'volume|switch|', 'name': 'Video', 'level': '0'}
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'volume|switch|', 'name': 'Phone', 'level': '0'}
TcosActions::populate_datatxt() channel=PC Speaker ismute=False volume level=80.0 ctype=volume|switch|
TcosActions::populate_datatxt() channel=Aux ismute=True volume level=0.0 ctype=volume|switch|
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'on', 'type': 'switch|', 'name': 'External Amplifier', 'level': ''}
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'switch|', 'name': 'Sigmatel 4-Speaker Stereo', 'level': ''}
TcosActions::populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel={'mute': 'off', 'type': 'switch|', 'name': 'Sigmatel ADC 6dB Attenuate', 'level': ''}

 

Tanto la carga de tcos-volume-manager como de la información de sonido de TcosMonitor son casi instantáneas, los cambios en el código no son muchos pero la mejora es impresionante.

Resumiendo, «me lo he pasado pipa» de nuevo hackeando código de otros proyectos para beneficio propio, programar en C puro no es una delicia pero siempre aprendes muchas cosas modificando y personalizando código de otros y es que amixer y aumix tienen formas de programar muy distintas.

(De paso aunque el proyecto TCOS tiene más código para mantener no me preocupo de los bugs de Ubuntu + aumix)





Prueba de detección de Spam

Me acaban de llegar estos dos correos:

 

 

Hasta aquí todo normal, no me cuenta mucho...

 

 

Una chica guapa sólo quiere algo de sonido !!!!

Esta vez voy a contestar, lo que no se como el filtro de spam no se lo ha comido porque cumple muchos de los requisitos.





Nueva versión de Pulseaudio y más

Hace ya casi 2 años que conozco el proyecto PulseAudio y reconozco que cada día me sorprende más.

Hoy se ha anunciado la nueva versión 0.9.11 con importantes mejoras. [anuncio en la lista]

  • Trae el prometido soporte 'glitch-free' que requiere versiones nuevas del kernel y ALSA (de paso le tira una cuchillada al kernel de Ubuntu indicando que no es el mejor para esta novedad ya que introduce demasiada latencia al llevar tanto driver privativo)
  • Se puede adjuntar a cada canal de audio un icono, ventana, texto... (antes sólo se indicaba el nombre del programa y el título de lo que sonaba si estaba disponible)
  • Modo espacial, esta es muy buena, combinado con libcanberra (libreria de eventos de sonido del mismo autor) permite que los eventos del escritorio se reproduzcan de manera tridimensional, es decir, si hacemos click en el menu superior-izquierdo sonaría más fuerte por el altavoz izquierdo.

Como ya dije, una killer app que revolucionará el sistema de sonido (sino lo ha hecho ya) del escritorio Linux. Usarlo en TCOS ha sido una muy buena decisión.

Otra cosa que he estado haciendo esta tarde es activar la última pieza hardware que no funcionaba en mi portatil ThinkPad R61, el lector de huellas: 147e:2016.

Por fin (ha costado) pero Daniel Drake (un verdadero crack) ha desarrollado un nuevo driver para fprint 147e:2016 (upeksonly) es un lector de huellas sin motor biométrico, solo escanea.

He mezclado los paquetes que hay en Debian experimental con las fuentes GIT del repositorio fprint y he compilado lo siguiente:

fprint-demo_20080724-1_i386.deb
libfprint0_0.1.0~pre1_i386.deb
libfprint-dev_0.1.0~pre1_i386.deb
libpam-fprint_0.2-4_i386.deb
libusb-1_0.9.2-1_i386.deb
libusb1-dev_0.9.2-1_i386.deb

Me he pensado un par de veces instalar libusb-1 ya que muchos paquetes dependen de libusb0 pero al renombrar el paquete a libusb-1 no entra en conflicto y ámbos conviven sin problemas.

Me ha costado entender como funciona el lector de huellas, parece que lee mejor si se pasa suavemente el dedo sin hacer fuerza, de hecho lo he activado en /etc/pam.d/common-auth aunque se me ha roto gksu (parece ser un bug conocido, no se ve), quizás lo active solo en la parte pam de GDM o en su/sudo.

Con esto y si nVIDIA se digna a solucionar los problemas de rendimiento de mi tarjeta, podré decir que el Thinkpad R61 ha sido la compra perfecta.