- Tarea puppet para instalación de paquetes: arreglado un bug que provoca un error de puppet cuando coincide la ejecución de la tarea con alguna operación desde otro proceso sobre el sistema de paquetes. Ahora se comprueba si no hay nadie mas manipulando el sistema de paquetes antes de instalarlo.
- Montar una camara web IP mediante OpenWRT y una cámara USB barata: después de varias semanas capturando fotos con gran éxito resultó que al guardar todas las imágenes en un solo directorio superaba algún límite de Linux y era imposible hacer muchas cosas sobre dicho directorio. Modifico el script de captura para que coloque los snapshots en directorios separados por días.
"Después del juego es antes del juego"
Sepp Herberger
viernes, 29 de mayo de 2015
2 cambios recientes en posts anteriores.
Utilidades gráficas para convertir vídeos en Linux.
Esta es la lista en cuestión:
- winff: ya comentada por mi compañero Esteban en esta entrada de su blog. La utilizo normalmente para convertir entre distintos formatos, por ejemplo de mpeg-2 a divx o para convertir un vídeo descargado de Internet en formato .flv o .wmv a formato .mp4.
- ogmrip: una maravilla para convertir un DVD a formato mas manejable. Lo que mas me gusta es que puede convertir el DVD completo a un archivo en formato matroska, conteniendo dentro de un solo fichero .mkv varias pistas de audio y subtítulos. Muy útiles para clases de idiomas o bilingües. Los ficheros .mkv son perfectamente manejables por vlc.
![]() |
| Captura de OGMRip con la seleccion de pistas y capítulos |
- handbrake: es como el ogmrip, pero mas complicado y completo. Aconsejable para usuarios avanzados. Tiene versiones para Linux, OSX y Windows.
![]() |
| Pantalla de Handbrake. A la derecha los formatos destino. |
- makemkv: no he podido probarlo, pero lo tengo apuntado en la cola de cosas por hacer. Parece también bastante sencillo y es multiplataforma, funcionando en Linux, Windows y OSX.
Bueno, pues aqui está la lista para que no se olvide.
Post de prueba desde stackedit.io
Post de prueba
Esto es una prueba de escritura con markdown desde el editor online stackedit.io, ya que ScribeFire ha dejado de funcionar.# wget http://stackedit.io
# ls -l
# exit
- Esto es un punto
- Segundo punto
Cita: esto seria una cita con formato distinto, debería verse embebida en algun tipo de marco.Lorem ipsum es el texto que se usa habitualmente en diseño gráfico en demostraciones de tipografías o de borradores de diseño para probar el diseño visual antes de insertar el texto final.
Aunque no posee actualmente fuentes para justificar sus hipótesis, el profesor de filología clásica Richard McClintock asegura que su uso se remonta a los impresores de comienzos del siglo XVI.1 Su uso en algunos editores de texto muy conocidos en la actualidad ha dado al texto lorem ipsum nueva popularidad.
viernes, 22 de mayo de 2015
Averiguar numero de serie y marca de los monitores.
Cuando estamos inventariando monitores una manera simple de saber su número de serie sin tener que mirar el código de barras por detrás es usar este comando que me descrubrió mi compañero Oscar:
# hwinfo --monitor
Entre otros datos, saldrá el número de serie, la marca, el modelo, etc . Por desgracia, esto no funciona para cualquier monitor ya que no todos tienen el número de serie "grabado a fuego" en su interior, pero al menos para los monitores que tengo en casi todo el centro funciona. También es necesario que al ejecutarse el monitor esté encendido, por motivos obvios: si no está encendido el PC no puede preguntarle nada.
Para automatizar esto podemos hacer un script que se ejecute en el arranque, coja los datos que queramos y lo escriba en algún fichero en alguna ubicación de red. De esta manera podemos inventariar de forma masiva.
Otra opción, si tenemos puppet, es crear un facter que obtenga esos datos y los guarde en los .yaml que crea puppet en el servidor, junto con los otros facter de la máquina. El facter se guardaría en cada PC, en /usr/lib/ruby/vendor_ruby/facter/monitor.rb y su contenido sería (toma Ruby pal cuerpo):
if File.exists?("/usr/sbin/hwinfo")
serial = Facter::Util::Resolution.exec('hwinfo --monitor 2>/dev/null | grep "Serial ID:" | head -1 | cut -d":" -f2')
if not serial.nil?
Facter.add("monitor-serial") do
serial=serial.delete('"').strip
setcode {serial}
end
end
model = Facter::Util::Resolution.exec('hwinfo --monitor 2>/dev/null | grep "Model:" | head -1 | cut -d":" -f2' )
if not model.nil?
Facter.add("monitor-model") do
model=model.delete('"').strip
setcode {model}
end
end
vendor = Facter::Util::Resolution.exec('hwinfo --monitor 2>/dev/null | grep "Vendor:" | head -1 | cut -d":" -f2')
if not vendor.nil?
Facter.add("monitor-vendor") do
vendor=vendor.delete('"').strip
setcode {vendor}
end
end
end
Evidentemente, habría que instalar el paquete hwinfo en las máquinas e incluirlo en el mayhave que tuvieramos en el pkgsync. Si lo probamos en una de las máquinas:
# facter | grep monitor
monitor-model => 151E
monitor-serial => YEPF619484
monitor-vendor => FUS
Eso sería lo que se guardaría en el fichero .yaml de la máquina, en la ruta /var/lib/puppet/yaml/fact del servidor puppet .
Una vez hecho esto, sería sencillo procesar todos los ficheros .yaml con un script que haga el inventario de todas las máquinas conectadas a puppet.
Acceso por VNC a una sesión remota iniciada por un usuario.
Si queremos conectarnos a una sesión de usuario ya iniciada en una maquina remota y ver su escritorio o incluso tomar el control del mismo, estos son los pasos.
# apt-get install x11vnc xvnc4viewer
No olvidar ponerlos en el fichero de mayhave si la máquina está sujeta a pkgsync.
# ssh root@maquina
# who
tylerdurden tty8 2015-05-21 13:37 (:0)
# su tylerdurden
3) Arrancamos servidor VNC en dicha sesión, (suponiendo que está en :0, como en el ejemplo):
$ x11vnc -display :0
4) Y ya, desde otro terminal en nuestra máquina:
$ vncviewer -ViewOnly maquina
Nos unimos a la sesión y ya podemos ver que hace "tylerdurden" en "maquina", ¡gracias, Julio!.
lunes, 18 de mayo de 2015
De Mint a Manjaro, pasando por Elementary.
El PC que uso en el trabajo, con Mint 12 Lisa-Mate ya olía a PPSOE, un olor rancio y anticuado: muchas aplicaciones estaban obsoletas. Como en los otros PC que tengo había instalado recientemente Mint 17 Quiana-XFCE me apetecía probar otras cosas.
Tenía mucho interés en probar Elementary OS, y aprovechando la reciente aparición de su última versión, Freya, con base Ubuntu 14.04 me decidí a encasquetarla en el PC. La instalación fue trivial y tras el arranque me encontré con un entorno muy cool y limpito, como muy para votantes de Ciudadanos, pero con pocas aplicaciones, también como para votantes de Ciudadanos. Lancé la instalación de las aplicaciones que uso normalmente con un apt-get install tocho y cuando acabó me puse a enredar un poco con el entorno. Entonces me di cuenta que la cosa no iba fluída. Intenté reproducir un vídeo muy relajante que tengo para pruebas, descargado con youtube-dl y vi que iba a saltos. Carajo, seguro que es la tarjeta de vídeo, ¿que pasa ahora contigo, Ubuntu?. Bueno, pues abreviando: probé múltiples configuraciones con 3 tarjetas de vídeo distintas (ATI, Nvidia y UniChrome), bastante antiguas, todo hay que decirlo, perdiendo varias horas y no hubo manera: el vídeo y el entorno gráfico tenían un lag considerable. Podía dedicarme a averiguar donde estaba el problema pero no me apetecía.
Llegado a este punto en diversas cuestiones de la vida, siempre me hago la misma pregunta: ¿qué haría Gengis Kan en esta situación?. Efectivamente: mandar a la puñeta al Elementary y machacarlo probando otra cosa.
¿Y ahora que instalaba?. Tenía ganas de seguir probando algo nuevo y tenía otro Linux pendiente en la recámara: Manjaro. Un Linux con fama de ligero y agradable y además basado en Arch Linux, que es una familia con la que nunca he trabajado. Dicho y hecho: bajé e instalé la version XFCE en un periquete. Otra vez la instalación fué sencilla (como ha mejorado la cosa desde mi primer Slackware hace 20 años) y esta vez arranqué y lo primero que hice fue probar el vídeo en cuestión. Para mi sorpresa iba allegro molto troppo, mas fluído que nunca. Y el resto del entorno también: hacía tiempo que no me iba tan ligero el PC.
Instalé varias aplicaciones típicas viendo que el gestor gráfico de paquetes no es muy distinto de synaptic pero ante mi sorpresa... vi que algunos paquetes se descargaban y compilaban en mi máquina antes de instalarse (como un Gentoo Linux, que gracioso) y para otros se descargaba la versión .deb, se hacia algo con ella y se instalaba ya en el formato de Arch. Sorprendente. Incluso pude instalar desde repositorios los drivers de la impresora Brother nueva, cuando en Ubuntu y Debian había tenido que bajar los deb de la página de Brother e instalarlos a mano. Cuando averigüé el nombre de las utilidades de gestión de paquetes de línea de comandos vi que tenían nombres tronchantes: Pacman y Yaourt, parecen dos personajes de Historias Corrientes.
Bueno, pues me gustó tanto que este fin de semana he mandado al averno el Mint que tengo en el Netbook y he instalado el Manjaro Netbook Edition, optimizado para Netbooks con procesador Intel Atom y con un entorno XFCE configurado de forma bastante curiosa, como un Unity de andar por casa:

muy adecuado para pantallas pequeñas. He estado afinándolo en ratos muertos y ciertamente el Netbook ha revivido.
Para acabar, en Un mundo feliz, de Aldous Huxley, dicen que el soma tiene "todas las ventajas del cristianismo y del alcohol; y ninguno de sus inconvenientes". Bueno, pues Manjaro-Arch tiene todas las ventajas de Debian y Slackware, y ninguno de sus inconvenientes. Creo que este es el comienzo de una larga amistad.
miércoles, 13 de mayo de 2015
Tarea puppet para instalación manual de paquetes
root@servidor:/etc/puppet/modules/instala_paquete/manifests# cat init.pp
define instala_paquete($version,$fichero) {
exec { "descarga_$fichero":
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
command => "mkdir -p /root/descargas; wget -q http://servidor/ficheros/$fichero -O /root/descargas/$fichero",
unless => "dpkg -l |grep $title | grep $version | grep ii",
notify => Exec["instala_$fichero"]
}
exec { "instala_$fichero":
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
command => "dpkg -i --force-architecture /root/descargas/$fichero; apt-get -y -f install",
refreshonly => true,
require => Exec["descarga_$fichero"]
}
}
El uso del recurso sería poner en la clase específica correspondiente algo como: ......
instala_paquete {"master-pdf-editor":
version=>"2.2.15",
fichero=>"master-pdf-editor_2.2.15_i386.deb"
}
......
.....
instala_paquete {"autolabel":
version=>"0.1-1",
fichero=>"autolabel_0.1-1_all.deb"
}
.....
lsof /var/lib/dpkg/lock
define instala_paquete($version,$fichero) {
exec { "descarga_$fichero":
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
command => "mkdir -p /root/descargas; wget -q http://servidor/ficheros/$fichero -O /root/descargas/$fichero",
unless => "dpkg -l |grep $title | grep $version | grep ii",
notify => Exec["instala_$fichero"]
}
exec { "instala_$fichero":
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
command => "lsof /var/lib/dpkg/lock || (dpkg -i --force-architecture /root/descargas/$fichero; apt-get -y -f install)",
refreshonly => true,
require => Exec["descarga_$fichero"]
}
}
miércoles, 6 de mayo de 2015
OpenWrt+USBIP+Smartboard 680 (Episodio II)
Recapitulemos: ya teníamos nuestra pizarra conectada al USB del router y compartida por IP a través del servicio usbipd. Ahora nos falta un cliente que se conecte a ella.
En el caso que me ocupa, el cliente era un ordenador con Windows, asi que me bajo el fichero "usbipwindowsv0.2.0.0signed.zip" desde
http://sourceforge.net/projects/usbip/files/usbipwindows/.
Descomprimiendo el fichero vemos que su contenido es:
- USAGE
- usbip.exe
- usb.ids
- usbipenum.cat
- USBIPEnum.inf
- USBIPEnumx64.sys
- USBIPEnumx86.sys
USAGE es un pequeño manual de instalación del driver usbip, mientras que usbip.exe es el programa cliente que usaremos para conectarnos al servidor usbip remoto. El resto de ficheros son el driver en si, que debemos instalar en nuestro sistema operativo para que todo funcione. Hemos dicho que dentro de USAGE está el manual de instalación, copio el contenido aquí:
To install the virtual usb bus driver on Windows XP:
1. Uncompress the downloaded binary package to a directory.
2. Double-click the 'Add Hardware' wizard in Control Panel.
3. At the 'Welcome to the Add Hardware Wizard', click 'Next'.
4. Select 'Yes, I have already connected the hardware', then click Next.
5. Select 'Add a new hardware device' from the list, then click Next.
6. Select 'Install the hardware that I manually select from a list(Advanced)', and then click next.
7. Select 'System Devices', then click Next.
8. Click 'Have Disk', click 'Browse', choose the uncompressed directory, and click OK.
9. Click on the 'USB/IP Enumerator', and then click Next.
10. At 'The wizard is ready to install your hardware', click Next.
11. Click Finish at 'Completing the Add/Remove Hardware Wizard.'
For Window 7 :
1. (Only necessary for custom builds: For x64 allow unsigned drivers: Enter "bcdedit /set testsigning on" in an administrative cmd window)
2. Uncompress the downloaded binary package to a directory.
3. Start a the Device Manager
4. Click Any hardware node
5. Choose "Add Legacy Hardware" from the "Action" menu
6. At the 'Welcome to the Add Hardware Wizard', click 'Next'.
7. Select 'Install the hardware that I manually select from the list'
8. click 'Next'
9. Click 'Have Disk', click 'Browse', choose the uncompressed directory, and click OK.
10. Click on the 'USB/IP Enumerator', and then click Next.
11. At 'The wizard is ready to install your hardware', click Next.
12. Click Finish at 'Completing the Add/Remove Hardware Wizard.'
Básicamente la instalación consiste en meter el driver a mano como si instalásemos un dispositivo que no es plug'n'play, ya que no hay proceso de autodetección que valga. Una vez instalado el driver tenemos que reiniciar el sistema. Yo ademas copio el fichero usbip.exe a la ruta c:\windows, para tener el ejecutable accesible siempre. Cuando hemos reiniciado, podemos probar a mirar el equipo remoto abriendo una ventana de comandos y tecleando:
c:\> usbip -l 192.168.1.1
Asumimos que 192.168.1.1 es la dirección del router, que cada cual ponga la que corresponde en su caso. Esto nos dará:
usbip for windows ($Id$)
- 192.168.1.1
1-1: unknown vendor : unknown product (0b8c:0001)
: /sys/devices/platform/ifxusb_hcd/usb1/1-1
: (Defined at Interface level) (00/00/00)
: 0 - unknown class / unknown subclass / unknown protocol (03/00/00)
Como vemos, ahi está la pizarra, con su identificador 0b8c:0001. Si queremos conectarnos a ella lo mejor es hacer un pequeño script .bat que pondremos en el escritorio:
rem conectar-pizarra.bat
@echo off
c:\windows\usbip -a 192.168.1.1 1-1
Al ejecutar el script veremos que el Windows y la pizarra reaccionan como si los hubiésemos conectado el uno al otro por un cable USB directamente. En la pizarra el led pasa de rojo a verde estable, indicando que ha sido detectada e inicializada por el driver.
En el Windows veremos que aparece un nuevo dispositivo HID llamdo SMART Board en el administrador de dispositivos:
Y que en el system tray, el icono correspondiente a la pizarra Smart (el círculo blanco dentro de un recuadro azul) se activa y muestra un tooltip de aviso de que se ha detectado un dispositivo. Ni que decir tiene que previo a todo esto debemos haber instalado el software Smart Notebook con sus drivers en el Windows que estamos usando.
Con esto ya podemos trabajar con la pizarra a un porrón de metros del ordenador y conectada a través del túnel usbip como si hubiese una conexión directa: todas las pulsaciones son recibidas en el PC cliente.
Antes de acabar con esta parte, comentar un pequeño problema: una vez está conectada la pizarra, si intentamos cerrar sesión o apagar el ordenador la cosa se queda como bloqueada, sin llegar a cerrarse nunca. La causa es que antes de salir hay que desconectar la pizarra con este script de desconexión:
rem desconectar-pizarra.bat
@echo off
c:\windows\usbip -d 1
Al ejecutarlo sería como si quitásemos el cable usb, quedando la pizarra con su luz roja:
Y el PC el icono de SmartBoard en el systray con el aspa roja:
En ese momento ya se puede cerrar sesión o apagar el PC sin problema.
En cuanto a Linux como cliente.... la historia es mas escabrosa, ya que no he podido hacer funcionar un cliente usbip. El primer problema es que hay dos versiones del paquete usbip, una en Debian Wheezy y otra en Ubuntu-Mint.
En Wheezy sería:
# apt-get install usbip
# dpkg -l | grep usbip
ii usbip 1.1.1+3.2.17-1 i386 USB device sharing system over IP network
# usbip version
usbip (usbip-utils 1.1.1)
# usbip list -r 192.168.1.1
Exportable USB devices
======================
- 192.168.1.1
1-1: SMART Technologies Inc. : unknown product (0b8c:0001)
: /sys/devices/platform/ifxusb_hcd/usb1/1-1
: (Defined at Interface level) (00/00/00)
: 0 - Human Interface Device / No Subclass / None (03/00/00)
#
Como vemos, es la versión 1.1.1, la misma que en vimos en el Openwrt:
openwrt# opkg update
openwrt# opkg list-installed | grep usbip
kmod-usbip - 3.10.49-1
kmod-usbip-client - 3.10.49-1
kmod-usbip-server - 3.10.49-1
usbip - 1.1.1-2
usbip-client - 1.1.1-2
usbip-server - 1.1.1-2
openwrt# usbip version
usbip (usbip-utils 1.1.1)
Ahora si queremos enlazar desde Wheezy con el servidor usbip remoto haremos:
# usbip attach -h 192.168.1.1 -b 1-1
usbip: error: open vhci_driver
usbip: error: query
Hemos olvidado cargar el driver en memoria, lo haremos con:
# modprobe usbip_core vhci_hcd
# usbip attach -h 192.168.1.1 -b 1-1
# lsusb
Bus 006 Device 002: ID 05e3:0716 Genesys Logic, Inc. USB 2.0 Multislot Card Reader/Writer
Bus 009 Device 002: ID 0b8c:0001 SMART Technologies Inc.
#
Bueno, pues se supone que tenemos conectada a nuestro Debian la pizarra como dispositivo usb local a traves del túnel IP, pero lo cierto es que no funciona. El software y el driver de la pizarra dicen que no hay nada. Para despejar dudas probé con otros dispositivos USB: pendrives, webcams, impresoras usb, ratones y siempre tenía problemas de todo tipo, no llegando a funcionar ninguno. Por ejemplo, el pendrive decía en el syslog:
hub 9-0:1.0: Cannot enable port 1. Maybe the USB cable is bad?"
Y no funcionaba. La webcam no llegaba a crear el dispositivo /dev/video0, y así sucesivamente. No se si estoy haciendo algo mal o es que la implementación del cliente usbip en Linux es peor que la de Windows, pero es lo que hay.
En cuanto a la versión cliente de Ubuntu/Mint, la cosa es peor:
# apt-get install usbip
# dpkg -l | grep usbip
ii libusbip0 0.1.7-3 i386 USB device sharing system over IP network (shared library)
ii usbip 0.1.7-3 i386 USB device sharing system over IP network
# usbip -v
usbip 0.1.7 ($Id: vhci_attach.c 42 2007-09-07 12:07:51Z hirofuchi $)
Como vemos, es una versión antiquísima que ni siquiera permite listar los dispositivos usb remotos:
# usbip -l 192.168.1.1
- 192.168.1.1
usbip err: usbip_network.c: 119 (usbip_recv_op_common) recv op_common, -1
usbip err: vhci_attach.c: 202 (query_exported_devices) recv op_common
usbip err: vhci_attach.c: 417 (show_exported_devices) query
# usbip -a 192.168.1.1 1-1
usbip err: usbip_network.c: 119 (usbip_recv_op_common) recv op_common, -1
usbip err: vhci_attach.c: 324 (query_import_device) recv op_common
usbip err: vhci_attach.c: 362 (attach_device) query
pc usbip #
Nótese que la sintaxis del comando usbip es diferente de la sintaxis de la versión de Debian Wheezy, mucho mas "moderna". Después de la sorpresa inicial estuve investigando y comprobé que la causa de esto es que el paquete usbip (0.1.7-3) que viene con ubuntu está obsoletísimo y siguen metiéndolo en repositorios. En este hilo hablan del tema y de la solución: el paquete usbip obsoleto sigue ahi hasta que alguien lo purgue. Los comandos usbip y usbipd correctos vienen ahora en otros paquetes distintos de utilidades relacionadas con el núcleo, siendo así:
- linux-tools-generic-lts-utopic en versiones antiguas de Ubuntu. Los comandos usbip y usbipd buenos se instalan en /usr/lib/linux-tools/.
- linux-tools-generic en versiones mas modernas (utopic con kernel 3.16 o posteriores).
Otra opción es la descarga independiente de unos paquetes actualizados desde este repositorio PPA.
El hecho de que tengamos las versiones correctas de usbip y usbipd en Ubuntu no hace que funcionen: fallarán como fallaban en Wheezy. Me sabe mal decir que algo pensado originalmente para Linux me funciona en Windows y no en Linux, pero hay que ser honestos y dar al César lo que es del César. Si algún día encuentro el porqué de este malfuncionamiento y lo soluciono lo postearé aquí, hasta entonces ajo y agua.
Y con esto acaba mi segunda historia con OpenWrt. Si hago funcionar como repetidor wifi un OpenWrt en un router similar lo contaré en estos lares.
jueves, 30 de abril de 2015
OpenWrt+USBIP+Smartboard 680 (Episodio I)
Ye he relatado mas de una vez la relación de amor/odio que tengo con las pizarras SmartBoard. En este caso me tocó enfrentarme con una SmartBoard 680: recordemos que tanto la alimentación como el flujo de datos van por el mismo cable USB, de tal forma que si el cable es demasiado largo (mas de 2 o 3 metros) la conectividad de la pizarra se resiente bastante, perdiendo la señal continuamente y haciendo inmanejable el instalache.
En este caso tengo un aula con una organización peculiar que hace que la distancia del PC a la pizarra fuese de mas de 10m. En principio compramos un cable USB activo, porque nos aseguraron que eso iba a funcionar. Ni de coña: la señal de la pizarra era solo un poco mas estable, pero al final acababa perdiendose la conexión y fallando el driver en el momento mas inoportuno.
¿Estaba todo perdido?. Pues no nos resignamos: el que no llegue el cable USB no quiere decir que no se pueda meter la señal USB por un ordenador o dispositivo, encapsularla en paquetes TCP/IP y hacerla llegar hasta el ordenador del profesor en el cual está el software de la pizarra: es lo que se llama USBIP. La idea es sencilla:
- Conectamos la pizarra a la entrada USB un "servidor usbip" que esté cercano, para poder usar un cable corto que nos garantice una conexión estable.
- En ese "servidor usbip" comparte desde su IP la conexión USB a la pizarra mediante el demonio "usbipd".
- El ordenador del profesor actúa de "cliente usbip" y se conecta al dispositivo USB compartido desde el "servidor usbip" mediante el programa cliente "usbip", creando un puerto usb virtual, que está enganchando mediante un túnel TCP con la conexión USB de la pizarra.
- El resultado final es que se engaña al driver, que se piensa que la pizarra (o el dispositivo que sea) está efectivamente conectada a un puerto USB del ordenador del profesor.
Un esquema visual:
¿Que utilizamos como "servidor usbip"?. Primero pensé en algún PC antiguo, con pocos recursos ya que no se necesita mucho hardware para ejecutar el servicio. Luego pensé en una Raspberry Pi, que además es pequeña y resultona. Pero al final escogí lo mas divertido: podía usar un router ADSL viejo que tuviese entrada USB y permitiese instalar OpenWrt, ya que tiene soporte para usbip.
El router ADSL elegido es un ARV7518PW, que era un router blanco Astoria que daba Ya.com:
Es un router que tiene un puerto USB, memoria flash de 8Gb y en el que, con ciertas precauciones, se puede instalar OpenWrt. También tenia el modelo anterior, un ARV4518PW de color gris, pero no lo usé ya que solo tiene una memoria flash de 4Gb y andaba un poco justito para meter el Openwrt.
La instalación de OpenWrt es un poco mas complicada que la que hice hace un tiempo para un Huawei, ya que hay que conectar por el puerto serie interno del router y reemplazar el brnboot por uboot (esto es como la bios+grub del router) y enviar la imagen con el OpenWrt. No es difícil siguiendo estas guías paso a paso:
- http://wiki.openwrt.org/toh/astoria/arv7518pw
- http://blogs.guifi.net/tonic/2012/11/01/openwrt-en-un-arv7518pw/
En ambas guías se habla de instalar (o compilar desde cero) la versión 12.09 (Attitude Ajustement) de OpenWrt, pero yo me decanté por usar la versión 14.07 (Barrier Breaker), ya que cuando se hicieron esas guías todavía no había salido una versión estable de ésta. La causa es que el software es mas moderno y que se soluciona un bug en el driver la tarjeta wifi que hacía que solo funcionase a una potencia de 3db, permitiendo ahora ponerla hasta 20db y freir el cerebro de todos los hipocondriacos en varios cientos de metros a la redonda. La URL del sistema Barrier Breaker para este router, ya preparado para flashear es: https://downloads.openwrt.org/barrier_breaker/14.07/lantiq/xway/openwrt-lantiq-xway-ARV7518PW-squashfs.image.
Bueno, una vez tenemos el Barrier Breaker en el router, lo hemos conectado a la red por cable, puesto una IP fija y hemos cambiado la contraseña de root, nos conectamos a él por ssh como a cualquier otro Linux OpenWrt y empezamos a configurarlo para convertirlo en un servidor usbip, vamos allá:
# opkg update
# opkg install kmod-usbip kmod-usbip-client kmod-usbip-server
# opkg install kmod-usb-ohci
# opkg install libsysfs libwrap
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip_1.1.1-2_lantiq.ipk
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip-client_1.1.1-2_lantiq.ipk
# opkg install http://downloads.openwrt.org/attitude_adjustment/12.09/lantiq/danube/packages/usbip-server_1.1.1-2_lantiq.ipk
# reboot
Con esto instalamos los drivers y el software, después de reiniciar verificamos si está todo:
# opkg list-installed | grep usbip
kmod-usbip - 3.10.49-1
kmod-usbip-client - 3.10.49-1
kmod-usbip-server - 3.10.49-1
usbip - 1.1.1-2
usbip-client - 1.1.1-2
usbip-server - 1.1.1-2
#
Ahora enchufamos la pizarra al puerto USB del router y vemos si la detecta:
# opkg update
# opkg install usbutils
# lsusb
Bus 001 Device 001: ID 0b8c:0001 SMART Technologies Inc.
#
Ahi está. Veamos si se puede compartir con usbip:
# usbip list -l
Local USB devices
=================
- busid 1-1 (0b8c:0001)
1-1:1.0 -> usbip-host
#
Ahi está, conectada al bus 1-1, que es como lo identifica usbip. Para que se comparta el usb cada vez que arranque el sistema operativo del router lo mejor es meter en /etc/rc.local el código siguiente:
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
usbipd -D &
sleep 1
usbip bind -b 1-1
exit 0
Son dos instrucciones: "usbipd -D", que arranca el servidor en modo daemon, y "usbip bind -b 1-1" , que enlaza el servidor usbip con el dispositivo conectado al bus 1-1, en este caso la pizarra Smart, de tal manera que dicho dispositivo queda compartido por el demonio.
Reiniciamos y, suponiendo que 172.20.41.57 es la IP del router donde tenemos conectada la pizarra, al hacer:
# usbip list -r 172.20.41.57
Exportable USB devices
======================
- 172.20.41.57
1-1: SMART Technologies Inc. : unknown product (0b8c:0001)
: /sys/devices/platform/ifxusb_hcd/usb1/1-1
: (Defined at Interface level) (00/00/00)
: 0 - Human Interface Device / No Subclass / None (03/00/00)
Nos aparece la pizarra lista para conectar a ella. Una comprobación mas:
# netstat -alpt
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3240 0.0.0.0:* LISTEN 1079/usbipd
tcp 0 0 0.0.0.0:domain 0.0.0.0:* LISTEN 1015/dnsmasq
Ahí tenemos el demonio usbipd esperando conexiones por el puerto 3240, para exportar la conexión USB de la pizarra a quien quiera conectarse a él.
Bueno, ya tenemos la parte servidora. En la próxima entrada veremos la parte cliente, que puede ser en Windows o en Linux.
martes, 21 de abril de 2015
Forzar la impresión en escala de grises en una impresora en color usando tea4cups.
Recientemente hemos adquirido una impresora Brother DCP-9020CDW. Mi intención era definir sobre ella dos colas, que se comportarían como dos impresoras virtuales: una para imprimir en blanco y negro y la otra para imprimir en color. La causa es que si dejo una sola cola, seguramente la mayoría de las veces la impresión será en color por simple descuido o dejadez a la hora de configurar las propiedades del trabajo de impresión, con el consiguiente desperdicio de dinero que necesitamos para pagar el billón de euros de deuda pública.
La primera idea fue manipular el fichero .ppd, haciendo una versión del mismo que dijese que la impresora era en blanco y negro, y usar dicho fichero .ppd para dar de alta la impresora correspondiente. Pues no funcionó: si se manda imprimir en color desde un puesto el trabajo salía en color independientemente de lo que dijese el .ppd que estaba permitdo.
No me quedaba otra que usar tea4cups, esa estupenda navaja suiza para las colas de impresión. Descargamos el fichero de http://www.pykota.com/software/tea4cups/download, lo descomprimimos e instalamos cada cosa en su sitio:
- El fichero tea4cups en el directorio de backends de impresión: /usr/lib/cups/backend/
- El fichero tea4cups.conf en el directorio de configuración de cups: /etc/cups/..
Una vez hecho esto, modificamos tea4cups.conf según nuestras necesidades. El fichero está profusamente autodocumentado con varios ejemplos de todas las virguerías que se pueden hacer con las colas de impresión, yo lo he modificado mínimamente añadiendo al original las líneas en rojo:
server:~# cat /etc/cups/tea4cups.conf
# $Id: tea4cups.conf 120 2006-08-10 21:42:16Z jerome $
#
# Tea4CUPS : Tee for CUPS
.......
[global]
......
debug : yes
........
directory : /var/spool/cups/
.........
prehook_accounting : /root/scripts/seguimiento_impresion
..................................
...................
# posthook_dialog2 : cat >/tmp/result2
#Se incluye un filtro para la cola "BN_SALAPROFESORES" que convierte a BN los trabajos de impresión
#mandados a color, modificando el .prn bruto antes de ser procesado.
[BN_SALAPROFESORES]
filter : sed "0,/@PJL SET RENDERMODE=COLOR/{s/@PJL SET RENDERMODE=COLOR/@PJL SET RENDERMODE=GRAYSCALE/}"
El fichero /root/scripts/seguimiento_impresión del prehook_accounting será el script que se ejecutará cada vez que se mande un trabajo a cualquier impresora de CUPS. En mi caso lo uso para llevar una contabilidad de los trabajos de impresión y para otras tareas de depuración. Su contenido es:
server:~# cat /root/scripts/seguimiento_impresion
#!/bin/bash
function valid_ip()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
#URLEncode para el titulo del documento
TEATITLE=$(python -c "import sys, urllib as ul; print ul.quote_plus(sys.argv[1])" "$TEATITLE")
#Echo copia en /tmp/ el trabajo de impresión en bruto para depuración.
#cp "$TEADATAFILE" "/tmp/$TEAJOBID.prn"
dominio=$(host -d -t CNAME servidor | grep domain | cut -f1 -d".")
paginas=$(pkpgcounter "$TEADATAFILE")
#Hay que convertir el valor de TEACLIENTHOST en un nombre de equipo.
if [ "$TEACLIENTHOST" == "localhost" -o "$TEACLIENTHOST" == "" ]
then
equipo=$(hostname -s)
else
if valid_ip $TEACLIENTHOST
then
equipo=$(host $TEACLIENTHOST | cut -d" " -f5 | cut -d"." -f1)
else
equipo=$TEACLIENTHOST
fi
fi
#Con todos estos parámetros que vienen del backend de /usr/lib/backend/teac4cups podemos llevar la contabilidad....
#En el ejemplo es un simple fichero de log, pero podría llevarse a un fichero .csv, guardarse en una BBDD o enviarse a una
#aplicacion web.
echo $TEAPRINTERNAME $TEAJOBID $TEAUSERNAME $TEATITLE - $equipo.$dominio - $TEACOPIES `pkpgcounter $TEADATAFILE` $TEAJOBSIZE>>/var/log/printaccounting.log
exit 0
Para que nuestros trabajos de impresión pasen por el backend de tea4cups y sean enviados a este script anterior, hay que modificar su definición en el el fichero /etc/cups/printers.conf, retocando el DeviceURI tal que así (ojo al parche, esto hay que hacerlo con el servicio CUPS parado):
server:~# cat /etc/cups/printers.conf
# Printer configuration file for CUPS v1.5.3
# Written by cupsd
# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING
<Printer BN_SALAPROFESORES>
UUID urn:uuid:b21a4e7f-1d82-35aa-63cc-440dad3b7ada
Info BN_SALAPROFESORES
Location Sala de Profesores-Blanco y Negro
MakeModel Brother DCP-9020CDW CUPS
DeviceURI tea4cups://socket://172.19.196.23
State Idle
..........
</Printer>
<Printer COLOR_SALAPROF>
UUID urn:uuid:2336104b-3317-3748-702f-3063db09d1fe
Info COLOR_SALAPROF
Location Sala de Profesores-Color
MakeModel Brother DCP-9020CDW CUPS
DeviceURI tea4cups://socket://172.19.196.23
State Idle
..........
</Printer>
Siendo 172.19.196.23 la IP de nuestra impresora en la red.
En cuanto a:
filter : sed "0,/@PJL SET RENDERMODE=COLOR/{s/@PJL SET RENDERMODE=COLOR/@PJL SET RENDERMODE=GRAYSCALE/}"
esa línea es la madre del cordero y la que se encarga de dar el cambiazo de color a blanco y negro a cualquier trabajo enviado a la cola de impresión BN_SALAPROFESORES. ¿Cómo funciona esto?. Bueno, pues hay repasar como procesa los datos CUPS:
- Las aplicaciones mandan los trabajos de impresión a CUPS. Originalmente esos trabajos están en el formato de la aplicación: odt, pdf, jpeg, xls, lo que sea.
- CUPS procesa con el driver el trabajo de impresión y lo convierte a un lenguaje inteligible por la impresora destino. Este lenguaje puede ser PCL3/4/5, PCLXL, PostScript, ZJS, HBP, etc, etc, etc.
- Este fichero en bruto en uno de los formatos indicados anteriormente se envía directamente a la impresora, que con su firmware lo interpreta e imprime.
En mi caso se trataba de averiguar en que formato estaba el fichero en bruto enviado para la impresora en cuestión. Eso se hace fácilmente capturando dicho fichero mediante tea4cups, en el script seguimiento_impresion:
......
......
#Echo copia en /tmp/ el trabajo de impresión en bruto para depuración.
cp "$TEADATAFILE" "/tmp/$TEAJOBID.prn"
......
......Así conseguiremos una copia del fichero en bruto una vez procesado por el driver en /tmp/$jobid.prn. Simplemente mandamos imprimir algo por la impresora y una vez impreso nos vamos a /tmp/$jobid.prn" y husmeamos que hay dentro. En nuestro caso es lo siguiente (marco en rojo las partes relevantes):
ESC%-12345X@PJL
@PJL SET REPRINT=OFF
@PJL SET HOLD=OFF
@PJL SET USERNAME="root"
@PJL SET JOBNAME="Manual Centralita 7962G.pdf"
@PJL SET LOGINUSER="root"
@PJL JOB NAME="Manual Centralita 7962G.pdf"
@PJL PRINTLOG ITEM = 1,PRINTER
@PJL PRINTLOG ITEM = 2,Tue,14 Apr 2015 13:47:5
@PJL PRINTLOG ITEM = 3,Administrador
@PJL PRINTLOG ITEM = 4,CONSERJERIA
@PJL SET JOBTIME = "20150414134705"
@PJL SET STRINGCODESET=HPROMAN8
@PJL COMMENT ECONOMODE=OFF
@PJL SET ECONOMODE=OFF
@PJL SET RENDERMODE=COLOR
@PJL SET COLORADAPT=OFF
@PJL SET APTMODE=OFF
@PJL SET LESSPAPERCURL=OFF
@PJL SET FIXINTENSITYUP=OFF
@PJL SET RESOLUTION=600
@PJL ENTER LANGUAGE=XL2HB
) BROTHER XL2HB;1;0
<C0>^@<F8><86><D1>X^BX^B<F8><89>A<C0>^@<F8><88><C0>^A<F8><82>H<C0>^@<F8>(<C0>^A<F8>&<C0>^B<F8>%<C8><C0>^HdRegular<F8>'<C0>^@<F8>4C<D3>d^@d^@<F8>*u<C0>^@<F8>d<C0>^@<F8>b<C1><A0>^R<F8>l<C1><9E>^Z<F8>kѠ^R<9E>^Z<F8>g<C9><C1>^W^@^@^@^C^@^@^@^A^@^E^@^@^@^D^@^H^D^A^@^E^@^A^@^D^@^Q^D^A^@^E^@^B^@^D^@^Q^D^A^@^E^@^C^@^D^@
..........
..........
Este fichero se compone de una cabecera, legible, seguida por los datos de impresión ya en el formato interno de la impresora. El lenguaje de impresión es XL2HB, que buscando un poco en internet resulta ser una versión de PCLXL hecha por Brother.
La cabecera está también en un formato bastante popular llamado PJL, que es un lenguaje de control de trabajos de impresión. La parte interesante es esta:
@PJL SET RENDERMODE=COLOR
que es donde se define si el trabajo está en blanco y negro o en color. Esta claro que si justo antes de enviarlo a la impresora, hacemos una búsqueda en el fichero en bruto y cambiamos la línea anterior por:
@PJL SET RENDERMODE=GRAYSCALE
el trabajo llegará en blanco y negro, habiendo dado el cambiazo en el último momento. Esto se hace con una orden sed de sustitución ya archiconocida de Linux y Unix:
# sed "0,/@PJL SET RENDERMODE=COLOR/{s/@PJL SET RENDERMODE=COLOR/@PJL SET RENDERMODE=GRAYSCALE/}" < infile >outfile
Esta linea dice "búscame la primera aparición de @PJL SET RENDERMODE=COLOR y, si la hay, cámbiala por @PJL SET RENDERMODE=GRAYSCALE"
Al estar la orden dentro del fichero teacups.conf, en la clausula filter y en la sección de BN_SALAPROFESORES:
[BN_SALAPROFESORES]
filter : sed "0,/@PJL SET RENDERMODE=COLOR/{s/@PJL SET RENDERMODE=COLOR/@PJL SET RENDERMODE=GRAYSCALE/}"se aplicará a todo trabajo de impresión que pase por la cola BN_SALAPROFESORES antes de enviarlo a la impresora, como era nuestro objetivo inicial.
Nota adicional: el formato XL2HB no está inicialmente soportado por pkpgcounter, por lo que da un número de páginas estrambótico al hacer la contabilidad. No problem, existe un parche sencillo sobre /usr/share/pyshared/pkpgpdls/pclxl.py (recordemos que es una variante de PCLXL) para que funcione:
Y con esto acabamos por esta vez.. Le estoy dando una caña tremenda al OpenWrt sobre los Astoria ARV7518PW, a ver si pronto tengo algo que contar, pero los Linux embebidos son duros...


