"Después del juego es antes del juego"
Sepp Herberger

jueves, 28 de marzo de 2019

VirtualBoxing Windows (Parte IV)

1. Introducción.

Venimos de aquí:


Voy a darle otra vuelta de tuerca al asunto porque me he encontrado con la tarea de montar un aula con 15 máquinas virtuales con Windows 10.

Podría haber hecho la configuración completa en cada una de las máquinas a mano, pero he preferido escribir una tarea puppet que automatice todo lo posible los pasos descritos en los enlaces anteriores por dos motivos:
  1. Me da pereza repetir lo mismo n veces. Soy administrador de sistemas: pienso que mi tarea consiste en trabajar construyendo cosas divertidas que me evitan trabajar repitiendo cosas aburridas.
  2. Porque en Xubuntu 18 me he propuesto hacer todo lo que pueda desde puppet para facilitar cualquier nueva instalación y la migración futura a Xubuntu 22.

2. Tarea puppet.

La tarea puppet tiene esta estructura:
├── files
│   ├── 15-vbox.conf
│   ├── Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack
│   ├── run_vbox
│   ├── vbox_permisos
│   ├── VirtualBox.xml
│   └── Win10.vbox
└── manifests
    └── init.pp
Siendo el init.pp:
# cat init.pp                                                                           

import "/etc/puppet/defines/*.pp"

class xubuntu18_virtualbox {

        #Deja todo preparado para arrancar una máquina virtual con run_vbox
        #Solo haria falta instalar el fichero con permisos 777 .vdi en la ruta /datos/VirtualBox VMs/VirtualBox/Win10-Choco-Autocad-Office.vdi. Si se cambia hay que editar los ficheros Virtualbox.xml y Win10.box

        package {"virtualbox": ensure => installed}

        package {"virtualbox-guest-additions-iso": ensure => installed }

        line { entorno_virtualbox:
                file => "/etc/environment",
                line => 'export VBOX_USER_HOME="/datos/VirtualBox VMs/VirtualBox"',
                ensure => present
        }

        $dirs = [ "/datos", "/datos/VirtualBox VMs","/datos/VirtualBox VMs/VirtualBox","/datos/VirtualBox VMs/VirtualBox/Win10","/datos/VirtualBox VMs/VirtualBox/Win10/Logs" ]

        file {$dirs:
                ensure => 'directory',
                owner  => 'root',
                group  => 'root',
                mode   => '0777',
                before => [File ["/datos/VirtualBox VMs/VirtualBox/VirtualBox.xml"], File ["/datos/VirtualBox VMs/VirtualBox/Win10/Win10.vbox"], File ["extpack"] ]
        }

        file { "/datos/VirtualBox VMs/VirtualBox/VirtualBox.xml":
                owner => root , group => root , mode => 644 ,
                source => "puppet:///modules/xubuntu18_virtualbox/VirtualBox.xml",
        }

        file { "/datos/VirtualBox VMs/VirtualBox/Win10/Win10.vbox":
                owner => root , group => root , mode => 644 ,
                source => "puppet:///modules/xubuntu18_virtualbox/Win10.vbox",
        }

        file { "extpack":
                path =>"/datos/VirtualBox VMs/VirtualBox/Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack",
                owner => root , group => root , mode => 644 ,
                source => "puppet:///modules/xubuntu18_virtualbox/Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack",
                notify => Exec ["install_extpack"],
                }

        #El accept-license del extpack para instalacion desatendida se consigue instalando una vez a mano y cogiendo el código que nos muestra
        exec { "install_extpack":
                path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                command => 'vboxmanage extpack install --replace --accept-license=56be48f923303c8cababb0bb4c478284b688ed23f16d775d729b89a2e8e5f9eb "/datos/VirtualBox VMs/VirtualBox/Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack"',              
                refreshonly => true,
        }


        #El fichero win.desktop para ir a /usr/share/applications se mete desde la tarea pupet xubuntu18_xfce4, junto con el icono. Aqui no lo haremos.

        file {"/usr/bin/run_vbox":
                owner => root , group => root , mode => 777 ,
                source => "puppet:///modules/xubuntu18_virtualbox/run_vbox"
        }

        file {"/usr/bin/vbox_permisos":
                owner => root , group => root , mode => 777 ,
                source => "puppet:///modules/xubuntu18_virtualbox/vbox_permisos"
        }


        case $uso {
                "infolab" : {
                        file {"/etc/lightdm/lightdm.conf.d/15-vbox.conf":
                                owner => root , group => root , mode => 644 ,
                                source => "puppet:///modules/xubuntu18_virtualbox/15-vbox.conf"
                        }
                }
                "siatic"  : {
                        line { permisos:
                                file => "/usr/lib/siatic/poweron.sh",
                                line => "/usr/bin/vbox_permisos",
                                ensure => present
                        }
                        #En las siatic el directorio /datos se monta sobre el disco duro secundario. En los infolabs va en el raiz, ya que hay espacio de sobra en él.
                        line { disco_secundario:
                                file => "/etc/fstab",
                                line => "/dev/sdb1 /datos ext4 rw,relatime,data=ordered 0 0",
                                ensure => present
                        }
                }
                default: { }
        }

}
Básicamente:
  • Instala los paquetes de virtualbox y su "extension pack" (en este caso la 5.2.18, habría que cambiarlo en función del tu Virtualbox).
  • Crea el árbol de directorios /datos/VirtualBox VMs/VirtualBox/Win10, se configura el entorno para que virtualbox trabaje con esos directorios y pone en ellos los ficheros que definen la máquina virtual de Windows 10. Estos 2 ficheros son VirtualBox.xml y Win10.vbox, extraídos de una configuración manual de un virtualbox donde se prepara todo. Aquí cada cual pondrá lo que necesite según su caso.
  • Se instalan los scripts run_vbox, que abrirá la máquina virtual, y vbox_permisos, que en el inicio de sesión configurará los permisos del usuario para hacer funcionar todo.
  • Si es necesario y en función de la máquina, configuramos en fstab la ruta /datos para que se monte sobre la partición de mayor tamaño.

Aquí está el enlace a la tarea puppet completa, con todos los ficheros excepto el .vdi, evidentemente.

La carpeta /datos tiene este contenido (en negrita los ficheros significativos, el resto son creados de forma automática):
datos
└── VirtualBox VMs
        └── VirtualBox
                ├── compreg.dat
                ├── Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack
                ├── selectorwindow.log
                ├── selectorwindow.log.1
                ├── VBoxSVC.log
                ├── VBoxSVC.log.1
                ├── VBoxSVC.log.2
                ├── VBoxSVC.log.3
                ├── VBoxSVC.log.4
                ├── VBoxSVC.log.5
                ├── VBoxSVC.log.6
                ├── VBoxSVC.log.7
                ├── VirtualBox.xml
                ├── VirtualBox.xml-prev
                ├── Win10
                │   ├── Logs
                │   │   ├── VBox.log
                │   │   ├── VBox.log.1
                │   │   └── VBox.log.2
                │   ├── Win10.vbox
                │   └── Win10.vbox-prev
                ├── Win10-Original.vdi
                ├── Win10.vdi
                └── xpti.dat


El fichero Wind10.vdi es la imagen de disco .vdi con el sistema operativo, enlazada desde dentro de Win10.vbox. El fichero Win10-Original.vdi es una copia que hago cada vez que actualizo Win10.vdi, que queda como un fichero de backup por si se estropease la máquina original tener una copia funcional en poco tiempo.

3. Distribución rápida de imágenes vdi.

Los ficheros .vdi son basante pesados (en mi caso una imagen de 27Gb) y distribuirlos por la red entre diferentes máquinas cuando se añade algo y hay que actualizar en todos los puestos se hace interminable.

Para evitarlo lo mejor es que, si tenemos la opción, hagamos esta distribución usando udpcast, que nos permite copiar por multicast una imagen en 15, 20 o más puestos a casi la misma velocidad que si fuese a un único puesto.

La única condición es que todas las máquinas estén conectadas al mismo switch y esté esté configurado para permitir multicast (con IGM Snooping activado y con ciertos controles -dependientes del modelo del switch- para evitar tormentas de red desactivados). Si todo está bien, la transferencia se realizará hacia todas la máquinas receptoras a unos 80-90Mbps, lo cual nos permitirá distribuir la imagen completa en todo el aula en menos de una hora.

La forma de hacerlo es instalar el paquete udpcast en todas las máquinas y en la máquina emisora (que puede ser cualquier PC del aula) hacer:
# udp-sender --file "/datos/VirtualBox VMs/VirtualBox/Win10.vdi" --interface eno1 --min-receivers 15
Mandamos por la tarjeta de red "eno1" hacia 15 receptores.

En los receptores hacemos:
# udp-receiver --file "/datos/VirtualBox VMs/VirtualBox/Win10.vdi" --interface eno1
Como teclear este comando en todos y cada uno de los receptores es bastante aburrido, aconsejo fervientemente usar tmux-cssh recomendado por mi compañero Esteban para abrir una sesión ssh en todos los receptores y escribir/ejecutar en paralelo las órdenes en los 15 puestos. Una pequeña maravilla.

Una vez hecha la copia de la imagen .vdi no hay que olvidar hacer una copia de seguridad en cada máquina y dar permisos 777 a "Win10.vdi" para permitir su acceso desde cualquier usuario que inicie sesión.

Nota: en mi caso he tenido un problema con la transmisión multicast que hacia que la velocidad de copia se redujese a 2-3Mbps. El problema es que en el aula donde estaba trabajando tenía un punto wifi Dlink DIR-860L configurado además como enlace de red entre el emisor y los receptores. El punto wifi limitaba el tráfico sin que yo cayese en ello, y nos ha hecho perder tiempo a mí y a mi compañero David pensando que el problema estaba en el switch del aula. Ojo por tanto con cualquier dispositivo adicional de electrónica de red que pudiera haber el aula, ya que el tráfico multicast puede ser penalizado al pasar por él.

martes, 19 de marzo de 2019

Gestión remota de wifi en un router OpenWRT/LEDE

Tanto en el centro como para usos domésticos tengo varios router con OpenWRT o LEDE donados o recogidos literalmente de la basura. Aunque a veces es dificultoso poner el firmware OpenWRT en los router de las operadoras telefónicas el resultado merece la pena, ya que nos queda un aparatejo con un Linux empotrado y un abanico increíble de posibles usos, una pequeña parte de los cuales ya he tratado aquí. El DD-WRT (primo del OpenWRT) que traen nuestros puntos de acceso D-Link DIR-860L no está mal, pero el OpenwRT es mucho mas versátil, tanto en facilidad de uso como en repositorio de paquetes instalables.

Uno de estos usos es hacerlos funcionar como Puntos de Acceso wifi neutros (Dumb AP) ideales para crear redes wifi por diferentes puntos del edificio.

Al ser un Linux lo que corre por sus entrañas, es sencillo manejar el punto de acceso wifi remotamente desde una aplicación, script y/o consola remota. Ejecutar un comando sobre el router desde otra máquina es tan sencillo como:
# sshpass -p contraseña ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@ip "comando"
Ahora voy a describir 4 secuencias de comandos específicas para manejar la wifi:
  • Encender la wifi:
    wifi up
  • Apagar la wifi:
    wifi down
  • Cambiar la clave de la wifi:
    uci set wireless.@wifi-iface[0].key=clave1234; uci commit wireless;  wifi reload
  • Obtener estado de la wifi (on/off), clave, SSID:
    valor=$(iwinfo | head -1 | wc -l );key=$(uci get wireless.@wifi-iface[0].key);ssid=$(uci get wireless.@wifi-iface[0].ssid);echo $valor:$key:$ssid
Por tanto, para cambiar la clave de la wifi de un punto de acceso desde nuestro PC se haría tecleando:
# sshpass -p contraseña ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@ip "uci set wireless.@wifi-iface[0].key=clave1234; uci commit wireless;  wifi reload"
Con esto queda expuesta la facilidad de manejar estos puntos de acceso remotamente desde cualquier otro entorno con simples comandos. Ahora el límite es nuestra imaginación.



Ya lo sé, tengo debilidad por la Opportunity. Es uno de los aparatos mas condenadamente perfectos que ha hecho nuestra especie.

Su última foto panorámica (hay corrección de color para resaltar los detalles, el tono real es mas rojizo):


Su última foto antes de interrumpir la comunicación (nube de polvo y corte a mitad de la transmisión):


Su próxima foto cuando despierte:

viernes, 15 de marzo de 2019

Clonando por comandos

Normalmente hacemos la clonación de sistemas operativos usando clonezilla, pero me he encontrado con un disco duro con arranque dual en el que la partición de Windows 8 se mostraba especialmente rebelde: hacía la imagen, pero luego al restaurar fallaba con errores de checksum y otros más esotéricos. No es frecuente, pero a veces pasa. Tras intentarlo varias veces con diferentes versiones de clonezilla he cambiado de estrategia para hacer algo que nunca había probado: clonar y restaurar la partición mediante comandos, sin usar clonezilla. Es decir: haré mediante línea de comandos lo que clonezilla hace internamente.

Para ello basta con arrancar la partición de Linux (recordemos que es un sistema dual) o bien arrancar con una distribución live y hacer:
# apt-get install partclone
# partclone.ntfs -c -d -s /dev/sda2  -o /ruta/sda2.img
Esto crea una imagen de la partición sda2 (que es la partición con Windows que me estaba dando la lata) en la ruta indicada. Si es una distribución live deberíamos guardarlo en un dispositivo de memoria externo (o carpeta de red) con capacidad suficiente.

Una vez hecha la imagen en el fichero sda2.img, lo llevamos a la maquina destino, arrancamos y hacemos el proceso inverso:
# apt-get install partclone
# partclone.ntfs -r -d  -s /ruta/sda2.img -o /dev/sda2 
A diferencia de con el clonezilla... esta restauración funcionó a la primera. Y el arranque posterior del sistema también, sin que haya encontrado explicación al fallo previo. Decía Arthur C. Clarke que "cualquier tecnología lo suficientemente avanzada es totalmente indistinguible de la magia". En el caso de la informática yo diría que adicionalmente es indistinguible del vudú.

Lo que me queda pendiente de probar es ahorrarme guardar la imagen en una unidad de almacenamiento, sino que conforme la imagen se va haciendo irla enviado por la red con la utilidad netcat hacia la otra máquina, realizando la clonación al vuelo. En el ordenador original se haría:
# partclone.ntfs -c -s /dev/sda2 | nc 192.168.1.33 8000 
Y en el que recibe la imagen (suponemos que tiene la IP 192.168.33):
# nc -l -p 8000 | partclone.ntfs -r -o /dev/sda2
Bueno, pues este método es bastante casero pero nos puede resolver alguna papeleta.

No tan sonado, pero igualmente importante: la Dragon se ha soltado de la EEI y ha vuelto a casa, amerizando sin problema.


Estos son los valientes que entraron en la cápsula una vez acoplada a ver si todo iba bien:


Según comentaron, había un sospechoso olor a "alcohol isopropílico" dentro. Yo me inclino a pensar que llevaba vodka o coñac armenio de contrabando entre los 204Kg de carga útil. Es un clásico subir bebidas espirituosas allá arriba.

jueves, 14 de marzo de 2019

Problemas en el inicio de sesión en thinclients LTSP.

Como ya hemos visto otras veces, en muchos centros seguimos usando el modelo de thinclients con Ubuntu LTSP para seguir sacando partido a máquinas que ya van para 15 años de antigüedad.

Por desgracia, da la impresión que el soporte para thinclients está cada vez mas dejado y nos cuesta trabajito tenerlo operativo.

Durante el todo el curso me han venido advirtiendo de un problema recurrente: cuando un thinclient en el que estaba trabajando un alumno quedaba colgado o se apagaba (el hardware sobre el que corren tiene sus achaques), el alumno ya no podía iniciar sesión en ese u otro thinclient con sus credenciales hasta pasado un tiempo, ya que era expulsado de la sesión a cada intento de entrada. Tenía que usar las de otro usuario para entrar. En los últimos tiempos este problema se había convertido en una manera de interrumpir el desarrollo de la clase para un grupito de alumnos graciosetes.

Mirando lo que pasaba advertimos que se habían quedado un montón de procesos a nombre del usuario abiertos y alguno de ellos bloqueaba el nuevo inicio de sesión. Esto se mantenía así hasta que esos procesos morían (pasado un tiempo o con el reinicio del LTSP).

Una manera rápida de liberar esos procesos es matarlos con uno de los varios comandos que hay para ello, por ejemplo:
# killall -9 -u usuario
Pero esto obliga a que lo haga alguien con permisos de root y acceso a la consola, lo cual no es nada cómodo.

Vamos a repasar como se inicia sesión en un thinclient y dilucidar que está fallando.

1. Proceso de inicio de sesión en thinclients.

Los thinclients usan como display manager ldm, que a diferencia de lightdm y similares, establece una conexión ssh con el servidor de aula para iniciar la sesión en él.

Toda la imagen de disco con el que funcionan los thinclients cuelga de la ruta /opt/ltsp/i386 de los servidores de aula. En esa ruta está el fichero /usr/share/ldm/ldm-script, que se ejecuta desde ldm y que lanza los scripts que hay en /usr/share/ldm/rc.d/.

ldm-script recibe un parámetro en $1 que puede tener los valores init/pressh/start/xsession/stop, tal como se ve en este "case", donde se indica en los comentarios a que evento del inicio de sesión está ligado cada valor:
case "${ACTION}" in
    init)
        # From ldm.c: LDM has just started, X is running, the greeter isn't.
        SCRIPTS="I*"
        ;;
    pressh)
        # From ssh.c: a username/password was provided, no connection yet.
        SCRIPTS="P*"
        ;;
    start)
        # From ssh.c: an ssh connection was established.
        SCRIPTS="S*"
        ;;
    xsession)
        # From plugin.c: an xsession was started (maybe even rdp).
        SCRIPTS="X*"
        ;;
    stop)
        # From screen.d/ldm.c: the xsession has ended.
        SCRIPTS="K*"
        ;;
esac
Lo que hace ldm-script es ejecutar en orden los scripts de /usr/share/ldm/rc.d/ que comienzan por la letra de la variable $SCRIPTS del paso anterior. Esto nos permite tener una secuencia de scripts asociados a cada evento de ldm. Los ficheros contenidos en mi rc.d son:
I00-localapps-cleanup
I01-halt-check
I01-nbd-checkupdate
K99-ltsp-cluster
K99_seguimiento_usuario
P00-ltsp-cluster
S01-setup-xauth
S15-userLoginCheck
S20-restrictUser
S99-debug-terminal
S99-ltsp-cluster
S99_seguimiento_usuario
X01-localapps
X01-remoteapps
X02-genmenu
X10-delayed-mounter
X50-dmrc-processing
X50-generate-env
X50-printers
X51-localapps
X51-opengl
X51-remoteapps
X52-xcompmgr
X95-run-x-session
X98-delayed-mounter
X99-ltsp-logout-action
Como se ve, hay un puñado de ficheros ligado a cada tipo de evento.

2. Inicio de sesión de usuario.

Los scripts comenzados por "S" son los que se ejecutan una vez el usuario ha tecleado usuario y contraseña, se ha establecido conexión ssh y se va a iniciar sesión gráfica.

Entre estos script hay uno llamado /usr/share/ldm/rc.d/S15-userLoginCheck cuya función es comprobar si LDM_LIMIT_ONE_SESSION es true y en caso afirmativo, matar todos los procesos previos del usuario. LDM_LIMIT_ONE_SESSION es una variable definida en /etc/lts.conf y tiene como función "Only allow a given user to log into one thin-client at a time", es decir, solo se permite que un usuario haga login en único thinclient al mismo tiempo. Para ello el script S15-userLoginCheck mata todos los procesos y sesiones previas del usuario.

Bien, pues esto que ha venido funcionando durante años, ahora con Ubuntu 18 ha dejado de funcionar. Y como consecuencia de ello tenemos el problema que estamos comentando en esta entrada.

Si miramos en todos los scripts de rc.d vemos que en muchos de ellos se usan las variables LDM_SOCKET, LDM_SERVER y LDM_USERNAME, que deberían contener respectivamente el socket de la conexión ssh entre thinclient y LTSP, la IP del LTSP y el nombre del usuario que está iniciando sesión. Bien, pues aunque antaño estas variables tenían valores correctos, hace ya tiempo que vienen vacías. Esto hace que muchos de los scripts de rc.d no hagan nada.

Podemos solucionar esto dando los valores adecuados a esas variables en cada script, que tras un proceso de investigación averiguamos que consiste en añadir las líneas:
LDM_SOCKET=$(ls -1 /var/run/ldm_socket*  | head -1)
LDM_SERVER=192.168.0.254
LDM_USERNAME=$(ssh -S $LDM_SOCKET $LDM_SERVER "id -un")
pero el hecho de que eso no venga de serie y nadie se ocupe de añadirlo nos da una idea del estado actual de semiabandono del proyecto, pese a lo cual sigue funcionando bastante bien.

Pero es que incluso después de poner las líneas arriba indicadas dentro de S15-userLoginCheck con la esperanza de que volviese a funcionar la matanza de procesos previos del usuario pude comprobar que seguía sin funcionar, y que por desgracia no se podía iniciar sesión por segunda vez. Podría haberme puesto a depurar el código de S15-userLoginCheck, pero antes se me han cruzado un par de asuntos que han solucionado el problema por otra vía.

3. Solución.

Recordé que en /etc/lts.conf había una variable llamada LDM_DIRECTX, que tradicionalmente habíamos tenido con valor False, que es el valor que trae por defecto. Cuando vale False toda la sesión entre thinclient y LTSP se hace cifrada por el túnel ssh, lo cual aporta de seguridad a costa de hacer mas lento el escritorio por sobrecarga de trabajo del thinclient. Un compañero sugirió probar con LDM_DIRECTX = True, que evita el uso de este tunel ssh y lo cierto es que el escritorio de los thinclients iba sensiblemente mas rápido, así que la dejamos con True.

Haciendo caso a un pálpito cambié LDM_DIRECTX = False y regeneré la imagen de thinclients...y ¡voilá!, volvía a funcionar S15-userLoginCheck y un alumno podía iniciar sesión en cualquier lado sin problema, provocando el cierre de la sesión previa. Como contrapartida tenemos que el escritorio de los thinclients quedaba un poco mas lento. ¿Causa de que se arreglase el desaguisado? Je ne sais pas.

No todo queda aquí, en una sincronicidad al poco tiempo otro compañero nos reveló un método para que se liquidasen los procesos de los usuarios que han cerrado sesión, consistente en añadir a /etc/systemd/logind.conf (en nuestro caso, del servidor LTSP) la línea:
KillUserProcesses=yes
con la cual systemd se ocupa de matar procesos de usuarios que han salido del sistema.

No tenía mucha confianza de que funcionase con los thinclients, pero probé a realizar estos pasos:

  1. Añadir KillUserProcesses=yes a logind.conf.
  2. Reiniciar el servicio systemd-logind.
  3. Poner LDM_DIRECTX = True en lts.conf.
  4. Regenerar imagen de thinclients con ltsp-update-image

He podido verificar con alegría que ahora si funcionaba todo bien como antiguamente. Al final el truco para arreglar todo no estaba en nada relacionado con LTSP, sino con logind.conf.

En conclusión: larga vida a los thinclients.


El 22 de febrero pasado la sonda japonesa Hayabusa 2 le dió un piquito al asteoride Ryugu para recoger muestras antes de traerlas a casa:



No es Bruce Willis y su equipo de perforadores de Armageddon, pero la hazaña de llegar hasta un pedrolo de 435 metros, orbitarlo, aterrizar con éxito 2 rovers del tamaño de una Roomba y acercarse a la superficie para chocar suavemente con ella y recoger muestras no es moco de pavo.

En la primera temporada de True Detective el detective Rust observa un grupo de fanáticos religiosos baptistas y sentencia "míralos: estos nunca fisionarán el átomo". Ni aterrizarán en un asteroide.

martes, 12 de marzo de 2019

TVHeadend: configuración y uso (I)


Aquí conté mi interés por ver y grabar determinados programas de TV desde el PC. Esta era una forma artesanal de hacerlo, pero investigando al respecto he hallado una joyita llamada TVHeadend. Aviso de que este post es un tocho con el resumen de lo que he ido montando en las últimas semanas.

1. ¿Qué es TVHeadend?

TVHeadend es una aplicación servidor gestionada por un interface web que puede recibir streams de vídeo de diferentes fuentes:

  • Streams de IPTV por Internet.
  • Señal de TDT recibida por una tarjeta de TDT PCI/USB.
  • Señal de TV analógica recibida por una tarjeta de TV PCI/USB.
  • Señal de TV por satélite recibida mediante una tarjeta SAT PCI/USB.
  • Señal de televisión por cable.
  • Otras emisiones de TV más exóticas

Una vez configurados los streams de vídeo (que se corresponderían con los canales de TV), TVHeadend nos permite:

  • Grabarlos en un dispositivo de almacenamiento, funcionando como un PVR.
  • Retransmitirlos a otros puntos de nuestra red o a Internet.
  • Transcodificarlos a otro formato de vídeo.

La versión de TVHeadend que he usado es la 4.3, que aunque es una versión beta funciona razonablemente bien.

2. Instalación.

Yo lo instalé en un PC que tengo encendido 24/7, pero la mayoría de la gente opta por hacerlo en una Raspberry Pi u otro minipc con un disco externo conectado si desea grabar contenidos. Es el tipo de PC ideal para estos casos, aunque hay incluso una solución todavía mas austera usando OpenWrt.

En mi caso, con Manjaro la instalación es tan sencilla como hacer:
# yaourt -S tvheadend-git
Para Debian/Ubuntu los pasos son igualmente sencillos.

Una vez instalada y arrancada como servicio con
# systemctl restart tvheadend.service
Queda escuchando en el puerto 9981 de la máquina donde está instalado. Accederemos a él desde el navegador web con http://ip:9981.


La primera vez que entramos salta un asistente que nos permite configurar el idioma del interface, la lengua preferida para los canales, nos hace crear un usuario administrador y un usuario raso y, si tenemos un sintonizador de TV instalado, detectar los canales. Como en mi caso no tenía sintonizador pues me salté esta última parte.

Una vez configurado el asistente en mi caso tuve un pequeño problema: no me permitía entrar con los usuarios creados anteriormente. Mirando en Internet comentaban verificar si el programa estaba lanzándose con el parámetro "-C", para ello tuve que mirar el fichero .service:

# cat /usr/lib/systemd/system/tvheadend.service 
[Unit]
Description=Tvheadend - a TV streaming server and DVR
After=syslog.target network.target auditd.service

[Service]
EnvironmentFile=/etc/conf.d/tvheadend
ExecStart=/usr/bin/tvheadend -f -p /var/run/tvheadend.pid $OPTIONS
PIDFile=/var/run/tvheadend.pid
Type=forking
Restart=on-failure
RestartSec=54s

# To enable watchdog functionality, uncomment these, remove Type=forking
# and compile with --enable-libsystemd_daemon
#Type=notify
#WatchdogSec=1m
#TimeoutStartSec=5m
#TimeoutStopSec=20

[Install]
WantedBy=multi-user.target
Examinando este fichero determino que la configuración se toma de /etc/conf.d/tvheadend. Allí se define la variable OPTIONS con todos los parámetros usados para levantar el proceso. Entre ellos no estaba "-C", así que lo añado:
# cat /etc/conf.d/tvheadend 
# Configuration file for the tvheadend service.

MALLOC_ARENA_MAX=4
OPTIONS="-u hts -g video -6 --http_port 9981 --htsp_port 9982 -C"
Y luego reinicio el servicio. Despues de esto ya si podía conectarme al interface web con los usuarios creados.

3. Configuración de un stream de vídeo IPTV de entrada.

Como no tengo tarjetas de TV de ningún tipo (vamos, que no me han llegado de Aliexpress) vamos a configurar como fuente una emisión de IPTV. Ya comenté que el mejor sitio para los canales de TV española es éste, ya que se actualiza a menudo (por algún extraño motivo que se me escapa, las cadenas de TV privadas cambian con cierta frecuencia la URL para acceder a sus streamings de vídeo) y está muy ordenadio.

Cogemos la URL de Canal Extremadura:
http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8.
Para ver si funciona, nada mas sencillo que hacer:
# vlc http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8
Entramos en el interface web, en Configuration->DVB Inputs->Networks y creamos una red de tipo IPTV:


A continuación vamos a Configuration->DVB Inputs->Muxes y añadimos un mux. Nos preguntará en que red y diremos que en la creada en el paso anterior. Luego nos sale el formulario:


Debemos rellenar el campo URL con:
pipe:///usr/bin/ffmpeg -i http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8
-vcodec copy -acodec copy -f mpegts pipe:1
En negrita pongo la URL original de acceso a Canal Extremadura online. Con eso construimos una URL de TVHeadend en la que se define el comando que leerá ese streaming.

En Mux name y Service name ponemos "canal-extremadura". Guardamos el mux y esperamos un rato:


Cuando en la columna "Scan result" aparece un OK quiere decir que ha conectado con el streaming. Ahora nos vamos a Configuration->DVB Inputs->Services y vemos que se ha creado un "Servicio" para el streaming:


Ya casi estamos. Nos vamos a Configuration/Channel-EPG/Channel y añadimos el canal:


Completando los campos Name con "canal-extremadura" y Services con el servicio creado anteriormente. Con esto aparece el canal en la lista:


Dando al icono de "Play" de la parte izquierda de la lista se descarga un fichero que al abrirlo lanza el vlc y comienza a visualizarse el canal:


Con esto ya tenemos dado de alta un canal como entrada para TVHeadend. Para dar de alta el resto de canales se procedería igual, incluyendo aquí los canales de TV de pago si disponemos de las URL adecuadas para configurarlos. En Internet hay información de sobra sobre como configurar Movistar+, Canal Satélite, etc con TVHeadend.

4. Clientes TVHeadend.

Una vez tenemos los canales configurados la primera utilidad es poder redirigirlos a otros dispositivos dentro de nuestra red o incluso hacia fuera (por ejemplo, podríamos ver Canal Extremadura en Bulgaria o Movistar+ en la casa del pueblo). Para poder verlos simplemente vale con poner en un navegador "https://ip:9981", validarse (es conveniente usar un usuario no administrador de TVHeadend para poder ver canales) y podremos visualizar los canales configurados.

Pero hay alternativas bastante más elegantes, comentamos algunas:

  • Android: para dispositivos Android hay varias aplicaciones, como TVHClient, TVH Client y muchas más. En general es tan sencillo como dar la IP, el puerto y el usuario/contraseña y la aplicación nos permitirá ver los canales en el móvil
  • Kodi: si tenemos Kodi 18 o superior existe un addon muy potente (más que las aplicaciones Android) llamado "TVHeadend HTSP Client". Se configura rápidamente y tenemos acceso sencillo a muchas funcionalidades. Al ser Kodi multiplataforma podemos instalarlo en casi todos los sistemas operativos.
  • Aparte existen clientes para otros sistemas que funcionan con mayor o menor fortuna.

Mi recomendación es instalar Kodi y el complemento en los PC, tablets y Android Box, y una aplicación Android en los móviles. El addon se integra totalmente en Kodi, como podemos ver:


Si queremos emitir los canales hacia Internet sencillamente bastará con abrir los puertos 9981 y 9982 desde el router y darnos de alta en un servicio de DNS, como se haría para cualquier servicio que queramos ofrecer desde nuestro PC hacia el exterior (por ejemplo, para cámaras de vigilancia, clientes de descarga, servidores web, etc).

5. Cosas que se pueden hacer con el stream de entrada.

Parece que lo único que se puede hacer con el stream de entrada es verlo, pero no es así. Las posibilidades que nos ofrece TVHeadend son muchas más. Podemos:

  • Recodificar: los streams suelen venir en formato H.264 o similar, que son bastante pesados. Puede resultar interesante transcodificar al vuelo a otro formato de de vídeo antes de retransmitirlo. No he estudiado esta vía, así que poco puedo decir al respecto, solo que en Configuration/Stream/Stream Profiles hay diversos perfiles de codificación.
  • Grabar: esta parte es muy interesante para mi. Podemos realizar grabaciones de varios tipos desde la opción Digital Video Recording. Las distintas pestañas son:

    Upcoming/Current Recordings: permite ver las grabaciones pendientes y programar una grabación puntual de un canal en una fecha y hora concreta.


    Timers: permite programar una grabación periódica a unas horas fijas en determinados días de la semana.


    Autorecs: permite programar grabaciones "inteligentes" por distintos criterios (título de programa, intervalo de fecha, etc).


    Finished Recordings
    : permite visualizar, eliminar, descargar, etc las grabaciones que han finalizado. Adicionalmente si usamos el cliente Kodi podemos ver, avanzar y retroceder libremente por las grabaciones que se están efectuando en ese mismo momento.

    Failed Recordings: vemos las grabaciones que han fallado por el motivo que sea.

    Removed Recordings: grabaciones que han sido borradas.

    Todas las grabaciones van por defecto al directorio /home/hts de la máquina donde está TVHeadend (siendo hts el usuario creado en la instalación del programa). Podemos modificar el directorio destino cuando añadimos la grabación.

    En "Configuration/Recordings/Digital Video Recorder Profiles" podemos configurar muchos parámetros sobre como se realizarán las grabaciones, tanto de tiempo como de espacio ocupado. A mi me resulta útil "Recorded file(s) retention period" que dice cuantos días se mantendrá por defecto una grabación en el disco duro antes de ser automáticamente eliminada.

  • Timeshift: esta funcionalidad es la que nos permite "parar la TV" cuando estamos viendo un stream y tenemos una interrupción pero queremos seguir luego por donde ibamos. Lo que realmente se hace al parar el stream es iniciar una grabación que luego podemos poner en marcha y por la que queremos desplazarnos. Se activa y configura en Configuration->Recording->Timeshift.


    Una vez activada, con solo pulsar el botón de "Pause" en el cliente durante la reproducción de un stream empieza a funcionar el timeshift.

6. EPG.

Para finalizar veremos como conectar TVHeadend con una EPG para tener accesible la programación de los canales desde el interface web y los clientes. Esto no es en absoluto necesario, simplemente es una pijadita para dejarlo todo bonito.


Desde aquí podemos ver la programación y pulsando sobre el icono izquierdo de cada programa, crear un timer con su grabación:


TVHeadend no tiene un sistema propio para obtener la programación de EPG, pero usa un API bastante sencillo que facilita todo el proceso.

Los datos de EPG están en numerosos portales de Internet, por ejemplo FormulaTV, y en distintos formatos. Para extraer estos datos se usan unos programas llamados EPG Grabber, que conectan con el portal, lo parsean y generan un XML con los datos de programación de los canales durante los próximos días.

Hay muchos EPG Grabber, después de echar un vistazo me he decantado por WebGrab+Plus por su completitud. Todos los EPG que puede acceder están ordenados por paises aquí. De ellos yo he elegido FormulaTV para España, ya que es un portal bastante serio que lleva muchos años funcionando.

En Manjaro se instala y configura fácilmente, como vemos aquí. Una vez instalado hay que configurarlo para que se ejecute mediante crontab y que lea los datos de una de las posibles fuentes. La instalación en Manjaro/Arch se realiza sobre /opt/wg++, teniendo dentro un directorio /opt/wg++/siteini.pack/Spain con todos los grabbers para España.
# cd /opt/wg++/siteini.pack/Spain
# find | grep -i formula
formulatv.com.channels.xml
formulatv.com.ini
Vemos aquí que hay dos ficheros: el .ini contiene las instrucciones y configuración para realizar el parseo, esa parte no nos interesa. El fichero .channels.xml tiene la lista de canales que son leidos por el grabber:
# cat formulatv.com.channels.xml
<?xml version="1.0" encoding="UTF-8"?>
<site generator-info-name="WebGrab+Plus/w MDB &amp; REX Postprocess -- version V1.56.14 -- Jan van Straaten" site="formulatv.com">
 <channels>
  <channel update="i" site="formulatv.com" site_id="la1" xmltv_id="La 1">La 1</channel>
  <channel update="i" site="formulatv.com" site_id="la2" xmltv_id="La 2">La 2</channel>
  <channel update="i" site="formulatv.com" site_id="antena3" xmltv_id="Antena 3 Televisión">Antena 3 Televisión</channel>
  <channel update="i" site="formulatv.com" site_id="cuatro" xmltv_id="Cuatro">Cuatro</channel>
  <channel update="i" site="formulatv.com" site_id="telecinco" xmltv_id="Telecinco">Telecinco</channel>
  <channel update="i" site="formulatv.com" site_id="lasexta" xmltv_id="laSexta">laSexta</channel>
  <channel update="i" site="formulatv.com" site_id="movistar0" xmltv_id="#0">#0</channel>
  ....
  <channel update="i" site="formulatv.com" site_id="canal-extremadura" xmltv_id="Canal Extremadura">Canal Extremadura</channel>
  ....
 </channels>
</site>
Ahora debemos configurar un usuario para ejecutar WebGrab+Plus, en mi caso será con el usuario "hts" (ya creado para TVHeadend). En su home debemos copiar la carpeta "/usr/share/wg++" y programar la ejecución periódica del grabber.
# su hts
$ cp -R /usr/share/wg++ /home/hts/wg++
$ crontab -e
Metemos en el crontab del usuario "hts" la ejecución del grabber todos los días a las 2:15:
15 2 * * * /usr/bin/wg++
Ahora vamos a configurar el Grabber en /home/hts/wg++/WebGrab++.config.xml (como el usuario que ejecuta wg++ es "hts" se buscará en esa ruta).
$ cat /home/hts/wg++/WebGrab++.config.xml
<?xml version="1.0"?>
<settings>

<!-- for detailed info about the settings see http://webgrabplus.com/documentation/configuration/webgrabconfigxml -->

<filename>guide.xml</filename>
<mode></mode>
<postprocess grab="y" run="n">mdb</postprocess>
<user-agent>Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0</user-agent>
<logging>on</logging>
<retry time-out="5">4</retry>
<timespan>2</timespan>
<update>f</update>

<channel update="i" site="formulatv.com" site_id="canal-extremadura" xmltv_id="canal-extremadura">Canal Extremadura</channel>
<channel update="i" site="formulatv.com" site_id="laSexta" xmltv_id="laSexta">laSexta</channel>
<channel update="i" site="formulatv.com" site_id="la1" xmltv_id="La 1">La 1</channel>

</settings>
Sobre la configuración anterior resalto en negrita las partes sensibles:
  • La salida de la ejecución de wg++ se guardará en /home/hts/wg++/guide.xml.
  • En "site" se pone el nombre de la fuente tal y como aparece en el site de formulatv.com.channels.xml.
  • Cada canal se define con un site_id exactamente igual a como aparece en formulatv.com.channels.xml.
  • En "timespan" ponemos el número de días en el futuro a descargar. Lo mejor es empezar probando con 2 y luego ir aumentando. Creo que FormulaTV proporciona hasta 7 días.
Con todo esto ya tenemos un programa que se ejecutará a diario y que parseará el EPG de la fuente y canales definidos en /home/hts/wg++/WebGrab++.config.xml y lo dejará en formato XML en /home/hts/wg++/guide.xml. No hace falta esperar a las 2:15 para saberlo, podemos ejecutar wg++ a mano desde el usuario hts para que se genere el guide.xml y verificar que todo funciona.

Ahora falta la última parte: conectar el guide.xml para que lo lea TVHeadend y lo integre en su interface. En la página de WebGrabPlus se documenta cómo hacerlo interactuar con diferentes softwares, entre ellos TVHeadend.

Básicamente, hay que bajar un script y ponerlo en la ruta "/usr/bin/tb_grab....". Esto hará que TVHeadend lo reconozca automáticamente como un "grabber interno" y lo ejecute de forma periódica y automática para realizar la sincronización. Los pasos para instalarlo son:
$ sudo wget -O /usr/bin/tv_grab_wg++ http://www.webgrabplus.com/sites/default/files/tv_grab_wg.txt
$ sudo chmod +x /usr/bin/tv_grab_wg++
Después hay que modificar el script para decirle donde está el guide.xml:
$ cat /usr/bin/tv_grab_wg++ 
#!/bin/bash
#xmltv_file_location=~/.wg++/guide.xml
xmltv_file_location=/home/hts/wg++/guide.xml
dflag=
vflag=
...
...
Al ejecutarse desde el servicio TVHeadend el script /usr/bin/tv_grab_wg++ procesará guide.xml y generará unos datos EPG que se insertarán en el formato interno de TVHeadend, del cual desconocemos los detalles. Una cosa muy importante ya comentada en el enlace indicado anteriormente es que el nombre del canal en wg++ debe coincidir con el nombre del canal en TVHeadend. En este caso "canal-extremadura" debe ser igual en ambos sitios, ya que si no es así no podrá establecerse una relación directa entre canal de TVHeadend y canal obtenido de la EPG, y por tanto TVHeadend no podrá mostrar la programación aún cuando esté ahí.

El siguiente paso es activar el grabber en TVHeadend. Para ello iremos a Configuration->Channel/EPG y a las pestaña EPG Grabber Modules(1) activando en la lista que se muestra allí el grabber tv_grab_wg++ y ejecutando luego "Rerun Internal EPG Grabbers" para que se aplique de forma inmediata.


En las pestañas EPG Grabber Channels y Channels revisaremos que está la conexión entre los canales EPG y los canales de TVHeadend.



En la pestaña EPG Grabber podemos configurar ciertos aspectos de ejecución del grabber, como las horas de ejecución y la actualización de diversos datos.


(1) Aquí me he encontrado con un problema que me hizo perder un par de días: en el interface web no se veían las pestañas EPG Grabber Modules y EPG Grabber Channels en Configuration->Channel/EPG. Por tanto no podía activar el grabber interno. Tras mucho probar encontré en este enlace la causa: es un bug del interface web de TVHeadend, que oculta esas pestañas por defecto si no estás en modo de interface "Expert". La solución consiste en cambiar el modo de visualización general de Basic a Expert en General->Base->Default View Level. De esta manera ya aparecen ambas pestañas y podemos configurar el grabber.


Bueno, una vez hecho esto ya tenemos la EPG con los títulos y horas de los programas disponible en todos los interfaces y clientes de TVHeadend y doy por concluido el artículo. De momento no me interesa tocar más hasta que no reciba el adaptador USB de DVB.

7. Enlaces y ampliación.

Unos cuantos enlaces que me han servido de guía y en los que hay más información para seguir profundizando:


Dos fotos llenas de significado:



Son dos imágenes tomadas por el orbitador LRO de la Nasa de la sonda Chang'e 4 de China en la cara oculta de la Luna. Los americanos demostrando que los chinos han llegado a la Luna. En el año del 50 aniversario de alunizaje del Apolo XI estos gestos son muy importantes.

Siempre algún conspiranoico podrá decir que todo esto es CGI, pero junto con la Queqiao se lanzó un microsatelite Longjiang-2 que está realizando fotos y pueden ser descargadas desde la Tierra por cualquier radioaficionado con el equipo adecuado que apunte a Lagrange-2 en las frecuencias 435.400 y 436.400 MHz. Ahora vas y lo cascas.

martes, 5 de marzo de 2019

Preparación de tablets Android para uso compartido.

Nos han llegado unos tablets para su uso con Librarium en las bibliotecas escolares. A lo largo del tiempo han ido llegando diversos modelos, siendo los últimos unos marcados como TECHcomputer-Tablet PC F101 (aunque internamente se identifican como Tablet L108MR, ya que son simplemente un remarcado de un modelo importado). Estas son sus características:

  • CPU: MTK cortex A7 1.5Ghz Quad Core.
  • Pantalla: 10.1" 1280 x 800 IPS lo que garantiza excelentes ángulos de visión.
  • Memoria de Almacenamiento: 32Gb.
  • Memoria RAM: 2Gb.
  • Cámara: Delantera: 2.0Mp, Trasera: 5.0Mp.
  • Almacenamiento: Soporta tarjeta Micro SD de hasta 32Gb.
  • Batería: 6000 mAh, 4.5 horas de duración reproduciendo vídeo.
  • Bluetooth y WIFI: 4.0, Wifi b/g/n.
  • Carcasa: Aluminio.
  • S/O: Android 8.1.
  • Puertos: 1 x Micro USB, 1 x Auricular, 1 x Micro SD.
  • Dimensiones / Peso: 24.2 x 17.2 x 0.9cm / 450gr.
  • Accesorios: Cargador micro USB.
  • Opcionales: Funda con teclado.

Antes de ponerlos a disposición de los usuarios es conveniente realizar una configuración básica común, que puede servirnos para cualquier tablet que tengamos que distribuir para su uso compartido en una comunidad. Las directrices son:

  • Instalar los programas básicos solicitados.
  • Asociar todos los tablets con una única cuenta de Gmail que permita su fácil administración. Esta puede ser una cuenta @gmail.com creada por nosotros o bien solicitar una cuenta GAFE corporativa (en nuestro caso @educarex.es).
  • Instalar un software de bloqueo que impida a los usuarios comunes la instalación/desinstalación de aplicaciones y el cambio de ajustes.

Los pasos a seguir han sido descritos por varios de mis compañeros de los IES Zurbarán e IES Javier Garcia Téllez a lo largo de las últimas semanas. Yo me he limitado a recogerlos y enumerarlos (no es una secuencia exacta, puede variar algo):

1. Configuración de las tablet.

  1. Encendemos la tablet.
  2. Cuando pida un nombre para la tablet le damos algun normalizado. Yo he usado "tab-bib-XX" siendo XX=01, 02, 03, …
  3. Cuando busque redes wifi para conectar, decimos que se salte ese paso. De momento no vamos a conectar a ninguna red ni configurar ninguna cuenta Gmail. Esto hace que el Asistente de Configuración quede "dormido" en segundo plano. No importa, más tarde acabaremos con él.
  4. Decir "SI" a las preguntas sobre Servicios Google.
  5. Si pregunta sobre creación de copia seguridad en Drive decir que "SI".
  6. No definimos patrón ni pin de bloqueo.
  7. Esperar hasta que nos salga el escritorio Android.
  8. Nombre de la tablet: si queremos cambiar el nombre de la tablet lo haremos en Ajustes -> Red e Internet -> Wi-Fi -> Preferencias de Wi-Fi -> Ajustes Avanzados -> Wi-Fi Direct -> Cambiar nombre del dispositivo.
  9. Conectamos la tablet a una red wifi. Ahora si.
  10. Entramos en Google Play, momento en el que nos pide una cuenta Gmail para el tablet. En mi caso introduzco la cuenta GAFE corporativa de @educarex.es. La otra opción es introducir una cuenta @gmail.com
  11. Ya en el Play instalamos las siguientes aplicaciones: Librarium, Microsoft Word/Excel/Powerpoint, Adobe Reader, Diccionario RAE, WordReference, Smart AppLock Libre [ver nota al final 30/07/2020], Wifi Connection Manager[ver nota al final 30/07/2020], Google Classroom y todas las que se quieran instalar en función de nuestras necesidades.
    • En el primer tablet esta instalación se hace buscando aplicaciones en Google Play una a una.
    • En las siguientes basta con entrar en Google Play a "Mis aplicaciones" -> "Mi colección" y allí estarán todas las aplicaciones listas para instalar. Esto es debido a que como compartimos cuenta gmail entre todas las tablets las aplicaciones quedan vinculadas a dicha cuenta.
  12. Dentro del Google Play, en la parte superior veremos que el Asistente de Configuración sigue pendiente de completarse. Sale porque en el inicio no definimos una wifi ni una cuenta gmail. No debemos completarlo, simplemente hay que pulsar como si quisieramos acabar la configuración, cerrarlo y decir que no queremos continuar "Nunca". Si intentamos completarlo podemos tener problemas que nos lleven a un callejón sin salida (que explicaremos luego) con la cuenta asociada a los tablets.
  13. Hora: configuramos en Ajustes como "no automática" y zona horaria Amsterdam (+1).
  14. Notificaciones correo: para evitar avisos molestos de Gmail todo el tiempo (recordemos que la cuenta es la misma para todas las tablets de nuestro centro) vamos a Configuración->Aplicaciones y Notificaciones->Notificaciones->Notificaciones de aplicaciones->Gmail->Desactivar.
  15. Configuración de bloqueo de funcionalidades con SmartAppLock [ver nota al final 30/07/2020]:
    • Menú Sistema: activamos bloqueo de instalación/desinstalación y bluetooth.
    • Menú Ajustes:
      • Habilitar bloqueo: esta opción activa el servicio SmartAppLock en el Tablet. Nos hace definir un patrón de desbloqueo y luego realizar 2 pasos para dar permisos a SmartAppLock para llevar a cabo el bloqueo del entorno Android. Una vez acabado aparece un botón “Hecho”, quedando activado.
      • Bloqueo: en mi caso activo el bloqueo por contraseña, aunque también es posible usar bloqueo por pin o por patrón.
      • Puerta secreta: OFF.
      • Bloqueo nueva aplicacion instalada: OFF. De esta manera si instalamos nuevas aplicaciones por defecto quedan como accesibles.
      • Alerta intrusion: OFF.
    • Aplicaciones a bloquear (en mi caso 9 en total): Play Store, Ajustes, Gmail, Play Peliculas, Play Musica, Contactos, Files, Drive, Archivos. De esta manera, para entrar en estas aplicaciones el usuario deberá meter la contraseña.
  16. Al bloquear la aplicación Ajustes en SmartAppLock nos encontramos con que el usuario no puede añadir/quitar/modificar conexiones wifi, lo cual es una limitación importante. La solución para ello es que use la aplicación Wifi Connection Manager [ver nota al final 30/07/2020] que instalamos anteriormente, ya que está desbloqueada y nos permite manipular libremente las conexiones wifi.
  17. Aviso importante: si vamos a desinstalar SmartAppLock hay que desactivar previamente todos los bloqueos. En caso contrario puede quedar "pillada" la tablet.

2. Reseteo de la tablet: cómo hacer un Factory Reset

En el caso de que la tablet quede bloqueada o atascada sin posibilidad de hacer que funcione normalmente lo mas conveniente es entrar en el modo Recovery y realizar un Factory Reset. Los pasos son:

  1. Partiendo del tablet apagado, pulsamos Bajar Volumen (Izq) y a la vez Power sin soltar ambas teclas.
  2. Esperamos que arranque y entre en una pantalla con un muñeco de Android y el texto “No Command”.
  3. Pulsamos sin soltar el botón Power y a continuación pulsamos Bajar Volumen una sola vez brevemente y soltamos. Entrará en menú Recovery. Soltamos el botón Power.
  4. Elegimos la opción Factory Reset y después hacemos un Reboot.
  5. La tablet arranca limpia y empieza el asistente de configuración.

3. Problemas que nos podemos encontrar.

En relación al asistente de configuración puede haber varios problemas:

  • Como todas las tablets se configuran con la misma cuenta de correo, el asistente de configuración lo detecta y asume que la cuenta de @educarex.es usada debe ser una "cuenta de administrador de G-suite", que es una cuenta especial para administración de dominios corporativos. Como nuestra cuenta no ha sido creada con esa característica, el proceso de configuración se queda atascado ahí. Ese es el motivo por el cual es crucial abortar la configuración inicial (saltando la conexión a una red wifi) y acabarla de forma manual mas tarde, eludiendo el asistente.
  • En el caso de llegar a un bloqueo de configuración debemos volver al inicio haciendo un Factory Reset.
  • Si configuramos un tablet varias veces haciendo pruebas, puede que detecte que ha sido antes asociado a una cuenta de correo e intente asociarlo otra vez, produciendo una situación de bloqueo. En ese caso se debe desasociar entrando en
    https://myaccount.google.com/device-activity con la cuenta @educarex.es con la que lo asociamos la primera vez. Una vez allí desvinculamos el tablet en cuestión de la cuenta.

En fin, con esto creo que tenemos unas directrices claras para configurar la tablet. Me huelo que cada vez serán mas necesarias conforme vayan llegando mas dispositivos de este tipo a los centros.

Nota 30/07/2010: para el curso 20/21 he hecho 2 cambios a lo dicho en este artículo:
  • SmarApp Lock Libre: durante este tiempo la aplicación se ha complicado y perdido usabilidad. La sustituyo por otra mucho más ligera y prometedora: Lock App - Smart App Locker.
  • Wifi Connection Manager: a partir del verano de 2020 no lo usamos ya que preconfiguramos para conectar de forma automática a la red wifi de Escuelas Conectadas.


Hace un par de días la Dragon 2 se ha acoplado a la ISS con éxito.


Aunque las Soyuz son un ejemplo de máquina perfecta, está muy bien que les haya salido competencia y que ahora haya más sistemas capaces de subir personas (incluidos terraplanistas) al cielo. Un tanto más para Space-X y su apuesta por convertir el viaje al espacio en una industria superando su etapa de artesanía.

Lo mejor de todo es su pasajero, Ripley:


No entiendo como los cosmonautas de la ISS han abierto la escotilla tras el acoplamiento. ¿Quién en su sano juicio abre una cápsula con un único pasajero llamado Ripley? Lo siguiente tras eso es tener un xenomorfo en la nave y ya la tendremos liada.