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

sábado, 24 de septiembre de 2016

VirtualBoxing Windows (Parte II)

En la anterior entrada vimos como virtualizar Windows dentro de nuestros Xubuntu para satisfacer en nuestros Infolab las necesidades de todos, les haga falta Windows o no.

Con el sistema ya en despliegue tuve que hacer varias correciones menores que cuento aquí:

1. Cambios en la BIOS para que funcione VirtualBox.

Los PC usados son HP ProDesk 600 G2 SFF, que tienen Secure Boot activado en la BIOS por defecto. Los últimos kernel de Ubuntu están viniendo configurados para que si se detecta Secure Boot activado los drivers de terceros deban estar firmados para cargarlos en memoria. El driver de virtualbox es un problema aquí y firmarlo es un proceso complicado que habría que repetir con frecuencia con cada actualización.

La solución mas rápida es entrar con la tecla F10 en la BIOS durante el arranque, desactivar Secure Boot, borrando las claves del mismo y poniendo que el arranque sea solo en modo Legacy. Al guardar y reiniciar nos pedirá un código numérico a modo de CAPTCHA cutre para confirmar que lo hemos hecho a propósito y ya está. El driver de virtualbox podrá cargarse sin problema. Todo esto ya lo contamos en el apartado 2 de esta entrada.

También será necesario en la parte Avanzada de la BIOS activar el VTx para permitir la virtualización, ya que si no el virtualbox se queja al arrancar y aborta.

2. Cambios en el script de arranque.

Para poder arrancar la máquina virtual cpm un click del usuario, verificando que ya no había otra corriendo y mapear la carpeta $HOME del usuario dentro de la máquina virtual usábamos un script.

Tras varias pruebas apareció el problema de que la carpeta compartida se quedaba mapeada en la máquina virtual, lo cual daba problemas al cambiar de usuario. Con la línea en negrita que añado en el script se soluciona el problema: desmapeamos la carpeta compartida antes de mapearla de nuevo.
# cat /opt/VirtualBox\ VMs/run_vbox 
#!/bin/bash

#Poniendo esto  /etc/environment
#export VBOX_USER_HOME="/mnt/VirtualBox VMs/VirtualBox"
#en el arranque lo tendremos para todos los usuarios. Maquinas virtuales en local.

#Si cierran la ventana a lo bruto se hace un shutdown de la máquina. Esto al .vbox de 
#la máquina
#    

machine="Win10"

running=$(VBoxManage list runningvms | grep $machine)
if  [ -n "$running" ]
then
   zenity --error --text "La máquina $machine ya está funcionando"  
else
  #Si cierran la ventana a lo bruto se hace un shutdown de la máquina. Esto al .vbox de la máquina
  #    
  #o bien VBoxManage...
  VBoxManage setextradata $machine "GUI/LastCloseAction" "Shutdown"
  VBoxManage sharedfolder remove "$machine" --name "compartido"
  VBoxManage sharedfolder add "$machine" --name "compartido" --hostpath "$HOME" --automount
  VirtualBox --startvm $machine
fi

3. Problemas de permisos.

Como la máquina virtual completa es compartida por todos los usuarios y está en una carpeta común (/opt/VirtualBox VMs) hay varios ficheros que deben tener como propietario al usuario actual, para que pueda ejecutarla sin problema.

Para ello hace falta meter un script que se ejecute en el inicio de sesión y que lo haga como root (hay que cambiar permisos a unos ficheros de los que no somos propietarios). Está ultima condición descarta el uso de /etc/xdg/autostart/* y /etc/X11/Xsession.d/*. Para ejecutar un script en el inicio de sesión como root tenemos que usar la configuración de ligthdm, nuestro gestor de sesiones, metiendo un fichero en /etc/lightdm/lightdm.conf.d/ como.
# cat /etc/lightdm/lightdm.conf.d/15-vbox.conf 
[SeatDefaults]
# Seat defaults
# display-setup-script = Script to run when starting a greeter session (runs as root)
# greeter-setup-script = Script to run when starting a greeter (runs as root)
# session-setup-script = Script to run when starting a user session (runs as root)
# session-cleanup-script = Script to run when quitting a user session (runs as root)
session-setup-script=/opt/VirtualBox\ VMs/vbox_permisos
El script llamado es vbox_permisos, que hace:
# cat vbox_permisos 
#!/bin/bash
#Cambia el propietario de las ficheros de VirtualBox, para permitir el acceso al usuario que hace login
chown $USER:$USER "/opt/VirtualBox VMs/VirtualBox/VirtualBox.xml"
chown $USER:$USER "/opt/VirtualBox VMs/Win10/Win10.vbox"
Como se puede ve, hace se propietario al usuario que inicia sesión de "/opt/VirtualBox VMs/VirtualBox/VirtualBox.xml" y "/opt/VirtualBox VMs/Win10/Win10.vbox", que son los dos ficheros necesarios para arrancar la máquina virtual.

Con esto ya está todo solucionado y funciona sin problemas.... de momento.

Por último, recordemos la conveniencia de tener una copia de estos 2 últimos ficheros, los scripts y el fichero .vdi con la máquina virtual en lugar seguro de la máquina física, para hacer una restauración rápida si algún usuario avanzado de Windows nos desconfigura o borra algo.

miércoles, 21 de septiembre de 2016

Depurar errores de importación en controlies

Estamos a principios de curso y nuestro controlies echa humo con la importación de alumnos y profesores desde Rayuela. Antes de seguir, unos consejos para refrescar lo importante:
  • Controlies sólo importa ficheros de profesores y de alumnos. No de grupos, ya que esos datos van implícitamente dentro de los alumnos. El fichero XML de Grupos bajado de Rayuela no tiene ningún valor para controlies.
  • El formulario para importar los datos es el mismo tanto profesores como para alumnos...¿cómo distingue entre unos y otros?: pues por la extensión: si el fichero es un XML interpreta que es de profesores, si es un ZIP (que contiene un XML y las fotos) se interpreta que es de alumnos.
  • La casilla de "Borrar datos" solo debe marcarse en la primera importación del curso (normalmente hay varias importaciones a lo largo del año ya que las matriculaciones se realizan en varias oleadas) ya que borra todos los profesores/alumnos (según el caso) previos del árbol ldap antes de iniciar el proceso a modo de limpieza de datos obsoletos.
  • Si no se marca la casilla "Borrar datos" se integrarán los datos importados con los ya existentes previamente, siendo ignorados los profesores/alumnos que ya estuvieran en ldap. Por eso es aconsejable marcar la casilla al menos una vez con los alumnos y así deshacernos de aquellos que hayan abandonado el centro.
  • No hay que olvidar lanzar después el script crearCarpetas en el servidor principal para crear los homes Linux de los usuarios añadidos a ldap.

Cuando se realiza la importación no es infrecuente que se aborte con un "Internal server error" o similar. Veamos como solucionar esto o al menos saber que ha pasado:
  • Debemos asegurarnos de que no hay ninguna partición al 100% en el servidor principal. La importación se hace descomprimiendo datos en /tmp/rayuela-ldap y si la partición que contiene esta ruta se llena todo se va al traste.
  • Borrar /tmp/rayuela-ldap antes de importar tampoco viene mal, para liberar espacio y quitar "basura" de importaciones antiguas que pudieron quedar a medias.
  • Si sigue fallando hay que depurar, para ello borramos /var/web2py/applications/controlies/errors/* y lanzamos la importación para que se produzca de nuevo el error. En /var/web2py/applications/controlies/errors/... debería haberse creado un fichero con el volcado del error y en /tmp/rayuela-ldap deben estar además los ficheros temporales usados durante la importación.

El fichero en /var/web2py/applications/controlies/errors/... es un típico fichero de volcado de pila de web2py horrible y farragoso:
(dp1
S'output'
p2
S" 'ascii' codec can't encode character u'\\xe2' in position 2: ordinal not in range(128)"
p3
sS'layer'
p4
S'/var/web2py/applications/init/controllers/gestion.py'
p5
sS'code'
p6
S'# coding: utf8\nfrom applications.controlies.modules.Hosts import Hosts\nfrom applications.controlies.modules.Rayuela2Ldap import Rayuela  \nfrom applications.controlies.modules.SQLiteConnection import SQLiteConnection\nfrom applications.controlies.modules.Laptops import Laptops\nfrom applications.controlies.modules.LaptopsHistory import LaptopsHistory\nfrom applications.controlies.modules.Config import Config\nfrom applications.controlies.modules.Thinclients import Thinclients\nfrom applications.controlies.modules.Utils import Utils\nfrom applications.controlies.modules.Utils import LdapUtils\nimpo
......
......
......
S"u'Jo\\xe2o'"
p7197
sS'resultado'
p7198
S"u'Jo\\xe2o'"
p7199
sS'self'
p7200
S''
p7201
sssS'traceback'
p7202
S'Traceback (most recent call last):\n  File "/usr/lib/pymodules/python2.7/gluon/restricted.py", line 205, in restricted\n    exec ccode in environment\n  File "/var/web2py/applications/init/controllers/gestion.py", line 748, in \n  File "/usr/lib/pymodules/python2.7/gluon/globals.py", line 173, in \n    self._caller = lambda f: f()\n  File "/usr/lib/pymodules/python2.7/gluon/tools.py", line 2575, in f\n    return action(*a, **b)\n  File "/var/web2py/applications/init/controllers/gestion.py", line 218, in rayuela\n    todos=rayuela.gestiona_archivo()\n  File "applications/controlies/modules/Rayuela2Ldap.py", line 437, in gestiona_archivo\n
self.parsea_archivo("/tmp/rayuela-ldap/Alumnos.xml","alumno")\n  File "applications/controlies/modules/Rayuela2Ldap.py", line 249, in parsea_archivo\n    self.parse_nodo(nodo)\n  File "applications/controlies/modules/Rayuela2Ldap.py", line 236, in parse_nodo\n    usuario[info.nodeName]=self.asegura_codigos(dato)\n  File "applications/controlies/modules/Rayuela2Ldap.py", line 121, in asegura_codigos\n    return str(resultado).strip()\
nUnicodeEncodeError: \'ascii\' codec can\'t encode character u\'\\xe2\' in position 2: ordinal not in range(128)\n'
p7203
s.
La parte final es la interesante, he puesto en negrita lo relevante: se produce un error en /tmp/rayuela-ldap/Alumnos.xml, relacionado con la codificación Unicode de la cadena que aparece mas arriba S"u'Jo\\xe2o'. Habría que buscar esa cadena en Alumnos.xml por ver si viene en alguna codificación extraña y arreglarlo mano. Esto pasa a veces ya que los datos vienen desde Rayuela con codificaciones o caracteres extraños que controlies no sabe manejar.

Si no encontramos nada queda una última opción: seguir una estrategia "divide y vencerás" y realizar la importación grupo a grupo, en lugar de todo el alumnado completo, hasta dar con el que produce el error. Luego, dentro de ese grupo, hacerlo alumna a alumno hasta pillar al "culpable" y depurar.

Una vez localizado el dato erróneo será cuestión de editar el XML a mano para quitar lo que causa el fallo y lanzar de nuevo la importación. Si es el fichero de Alumnos no olvidar volver a meter Alumnos.xml dentro del ZIP para importar, respetando la estructura del ZIP original: el fichero Alumnos.xml en la raíz del mismo y las fotos en un directorio.

Bueno, pues esperemos que este año no haya muchos errores en estas lides.

lunes, 19 de septiembre de 2016

Configurando la VGA en los HP ProDesk 600 G2 SFF (Parte II)

Bueno, bueno, volvemos del verano con las uñas afiladas y muchas cosas en el tintero. Vamos a ampliar un post antiguo sobre los Infolab.

1. Usar driver propietario nvidia desde un repositorio PPA.

En la Parte I miramos como configurar la VGA de nuestro HP ProDesk en distintos escenarios. Recordemos que teníamos 2 tarjetas VGA
00:02.0 8086:1912 VGA compatible controller: Intel Corporation Sky Lake Integrated Graphics (rev 06) 
01:00.0 10de:1287 VGA compatible controller: NVIDIA Corporation GK208 [GeForce GT 730] (rev a1)  
Y que la nvidia la configurabamos con el driver propietario oficial de nVidia. Como este driver se instalaba mediante un fichero NVIDIA-Linux-x86_64-361.28.run y con varias preguntas de forma interactiva, era un proceso bastante poco operativo para hacer un despliegue masivo por muchas máquinas. Mis compañeros sugirieron otra forma que yo no había advertido para instalar el driver: mediante un repositorio PPA de Ubuntu que se actualice con los drivers propietarios nVidia. Para ello añadimos el repositorio:
# add-apt-repository ppa:graphics-drivers/ppa
# apt-get update
Y ahora el paquete con el driver:
# apt-get install nvidia-364
Hay varios paquetes que se informa que han funcionado: nvidia-361, nvidia-364 y nvidia-367. Pongo nvidia-364 porque al parecer es el que más compañeros han usado. Y ya está, de esta forma conseguimos tener el driver propietario de las nVidia sin tener que descargar el .run y ejecutarlo a mano. El resto del artículo anterior se mantendría igual.

2. Evitar problemas entre el Secure Boot de la BIOS UEFI y los drivers de terceros.

Otro problema que se nos puede presentar es que no se cargue el driver en el arranque. Es decir que:
# lsmod | grep -i nvidia
No muestre nada. Si intentamos cagarlo a mano:
# modprobe nvidia
Nos contestará con algo asi como "Required key not available" La causa de se explica en este enlace: básicamente consiste en que el kernel tiene activada una opción por la cual si encuentra en la BIOS UEFI el Secure Boot activado solo permitirá cargar drivers de terceros firmados previamente. Firmar drivers es un proceso bastante farragoso que habrá que repetir cada vez que se actualice el driver o el kernel.

Es mas sencillo para nuestro caso desactivar el Secure Boot, aunque implique ir por los PC uno a uno ya que no se puede automatizar. En caso el de los HP Prodesk 600 G2 pulsaremos F10 al arrancar en el equipo para entrar en la BIOS UEFI, iremos a Opciones Avanzadas/Seguridad y una vez allí desactivamos en el combo que sale el arranque Seguro UEFI, dejando solo el Legacy activado, y borramos las claves Secure Boot marcando la casilla. Una vez hecho esto guardamos y salimos de la BIOS.

En el siguiente arranque pide teclear a mano un úmero aleatorio de 4 digitos para confirmar que se quiere desactivar el arranque seguro, una vez hecho ya vuelve a cargar el driver nvidia y el problema desaparece. De igual manera que con el driver de la nvidia, esto soluciona problemas con otros drivers de terceros tales como:

-El driver de audio de este post.
-El driver nw_fermi de las pizarras Smart.
-El driver de VirtualBox.
-Etc, etc, etc.

Nos vemos pronto y ten por seguro que seguiremos sin Gobierno.