Python: Retorno en bloque try-except-finally

Bueno saberlo:

En Python se puede tener un bloque try-except-finally, retornar en except y aún así el código finally es ejecutado. Genial!

>>> def function():
...     try:
...         raise Exception()
...     except:
...         return True
...     finally:
...         print 'Finally executed'
...
>>> function()
Finally executed
True

Kölbi datacard en Ubuntu

El ICE ofrece desde hace meses paquetes de Internet por red 3G. Los paquetes incluyen un modem 3G de marca Huawei.

El servicio de Internet por 3G es compartido, es decir, que si hay mucha gente en la red la conexión va a decaer sobremanera. Personalmente lo adquirí para emergencias, viajes, reuniones, etc, en la que no hay una red WiFi decente cerca o esté cerrada.

Configurar el Huawei es sumamente fácil en Ubuntu. Primero es verificar que los paquetes modeswitch estén instalados:

sudo apt-get install usb-modeswitch usb-modeswitch-data

Ahora conectamos el modem, ingresamos el PIN. Click derecho sobre el icono de conexión en la barra superior derecha -> Editar las conexiones… -> Banda ancha móvil -> Añadir

Seleccionamos Costa Rica, siguiente, Mi proveedor no está mostrado, escribimos “kolbi”, siguiente, APN es kolbi3g, siguiente, siguiente.

Bien, esa parte no era muy importante, si se equivocaron no importa, lo importante es seleccionar la nueva conexión hacer click en “Editar”.

Ahora, la conexión debe estar exactamente igual a las siguientes imágenes:

 

Recuerden poner el PIN del modem en la primera pantalla. Cuando conecten el modem se les pedirá el PIN, pueden hacer click en cancelar y seleccionar la conexión de banda ancha y este se encarga de desbloquearlo con el PIN que pusieron en configuración.

Saludos

Yo y el Humble Indie Bundle 3 en Linux

El Humble Indie Bundle 3 está activo en este momento, puede conocer más sobre el mismo en http://www.humblebundle.com

Después de comprar el paquete me decidí a ejecutarlo en mi Ubuntu 10.10. Aquí mi experiencia:

1. Crayon Physics Deluxe

Viene en un tar.gz, se extrae y se ejecuta el ejecutable ‘launcher’. En mi caso:

./launcher
./launcher: error while loading shared libraries: libmikmod.so.2: cannot open shared object file: No such file or directory

Un rápido ‘apt-cache search libmikmod’ arrojó:

libmikmod2 - A portable sound library
libmikmod2-dev - A portable sound library - development files

Seguido de:

sudo apt-get install libmikmod2

Listo… otra vez:

./launcher
./launcher: error while loading shared libraries: libsmpeg-0.4.so.0: cannot open shared object file: No such file or directory

mmm….

sudo apt-get install libsmpeg0

Ahora si, se vuelve a ejecutar y ya funciona. Jugué un rato, es divertido. Al salir, este es el output:

./launcher: /usr/lib/libjpeg.so.62: no version information available (required by /home/havok/Programas/CrayonPhysicsDeluxe/lib32/libSDL_image-1.2.so.0)
./crayon: /usr/lib/libjpeg.so.62: no version information available (required by /home/havok/Programas/CrayonPhysicsDeluxe/lib32/libSDL_image-1.2.so.0)
warning: failed to open directory 'My Solutions'
warning: failed to open directory 'My Solutions'

Tiene varios warnings, pero nada que le impida funcionar.

2. Cogs

Viene en un archivo ejecutable. Entonces le damos permisos de ejecución:

chmod +x cogs-linux-bin
./cogs-linux-bin

Con eso sale un dialogo de instalación… siguiente siguiente y listo. Vas a la carpeta donde se instaló y ejecutas el archivo ‘Cogs’:

./Cogs

Sólo que en mi caso:

Warning: It appears that your hardware doesn't meet the minimum requirements necessary to run Cogs. The following OpenGL extensions are unsupported: GL_EXT_texture_compression_s3tc

:( Hasta ahí llegué con Cogs, no pude jugarlo.

ACTUALIZACIÓN: Probé en mi otra computadora con una mejor tarjeta de vídeo y funcionó sin problemas, muy bueno el juego :)

3. VVVVVV

Viene en un tar.gz, se extrae y se ejecuta el archivo ‘VVVVVV’:

./VVVVVV
./VVVVVV_32: error while loading shared libraries: libSDL_mixer-1.2.so.0: cannot open shared object file: No such file or directory

Mmmm….

sudo apt-get install libsdl-mixer1.2

Ahora si, ya funciona. El output es bastante largo, pero ningún warning, sólo datos de información. Buenísimo este juego!!

4. Hammerfight

Este juego viene en un archivo ejecutable.

chmod +x hf-linux-07172011
./hf-linux-07172011

Con eso sale un dialogo de instalación… siguiente siguiente y listo. Vas a la carpeta donde se instaló y ejecutas el archivo ‘Hammerfight’:

./Hammerfight

Listo. Ahhh!! No puedo jugar esto :S

5. And Yet It Moves

Este viene en un paquete Debian, dependiendo de la arquitectura. Yo, de 32bits. Se instala con doble click y el Centro de Software de Ubuntu se encarga del resto. Una vez instalado se encuentra en el menú de Juegos o se puede ejecutar el comando ‘AndYetItMoves’.

Que juego más loco! :P

Eso sería todo :D Que buen Bundle.

Cómo migrar los módulos de Drupal

Cuando empecé en el mundo de Drupal colocaba todos los módulos en sites/all/modules/

Varios de los sitios que hice tienen esa estructura. Más adelante, cuando conocí drush y luego gracias a la excelente guía de Felix Delattre conocí una buena práctica para organizar los módulos que probaría ser indispensable una vez que me metí a programar y parchear módulos:

  • sites/all/modules/contrib :: Todos los módulos contribuidos por la comunidad.
  • sites/all/modules/custom :: Los módulos propios creados para el sitio web.
  • sites/all/modules/features :: Almacena las características exportadas del sitio.
  • sites/all/modules/patched :: Almacena los módulos contribuidos que fueron parcheados por uno mismo.

Lo genial de esta estructura es que Drush la reconoce sin problemas, entonces descarga los módulos bajo contrib y no actualiza los que están bajo patched :D

Como mencioné anteriormente un par de sitios que había hecho no tenían esa estructura y quería mover los módulos, como 40 de ellos. Resultó ser muy simple, sólo es necesario mover los módulos, luego recrear la tabla del sistema y borrar las tablas de caché. En comandos:


cd [...]/sites/all/modules/
mkdir contrib
mv * contrib/
mkdir patched features custom
mv contrib/alguno /carpeta (Se organizan los que eran custom, patched, etc)
drush sm -q
drush cc all

Listo! Lo bueno de esto es que también puede arreglar los típico error de principiante de colocar los módulos contribuidos en /modules/ junto a los módulos del core.

Pathauto idioma neutral

(En inglés ‘Language Neutral Pathauto’)

La versión para Drupal 6 de pathauto tiene un problema con la gestión de los paths en sitios con varios idiomas. El problema es que todos los nodos que cree cualquier usuario se crearán con el path automático en el idioma del usuario, independientemente si el tipo de contenido en particular acepta o no traducción del contenido o contenido en diferente idioma (modula “Content Translate” del core). Esto es un problema porque los usuarios que visiten ese URL que tengan otro idioma no podrán ver el nodo (404) porque no existe ese path para su idioma… de nuevo, es un tipo de contenido que no acepta traducción!!

La problema fue reportado pero los autores justifican que es una característica (yo insisto que es un error, porque es para tipos de contenido que no tengan traducción) y la solución propuesta, agregar una opción en la página de administración no les gustó porque indican que no quieren agregar más opciones al panel de administración (Así? Sin más? Sin proponer otra cosa :S). Al final el error no fue arreglado :S

La solución acá propuesta sigue sin ser perfecta, porque aplicará para todos los nodos nuevos, no por tipo de contenido:


************************************************************************
File: pathauto/pathauto.admin.inc
Line: 29
Function: pathauto_admin_settings()
Hack:

// HACK: Pathauto ignore language setting
$form['general']['pathauto_ignore_language'] = array(
'#type' => 'checkbox',
'#title' => t('Force Language Neutral'),
'#default_value' => variable_get('pathauto_ignore_language', FALSE),
'#description' => t('Create path in language neutral mode'),
);

************************************************************************

************************************************************************
File: pathauto/pathauto.inc
Line: 427
Function: _pathauto_set_alias($path, $existing_alias = NULL, $op = NULL)
Hack:

// HACK: Should we ignore language setting
if ((bool) variable_get('pathauto_ignore_language', FALSE)) {
// _pathauto_verbose('pathauto_ignore_language is TRUE. Current language: ' . $path['language']);
$path['language'] = '';
}

************************************************************************

Heredar grupo con setgid

Muchas veces nos interesa que todos los archivos nuevos en una carpeta hereden el grupo al que pertenece la carpeta. Son muchos los casos, los más comunes son que se tiene, por ejemplo, un servidor web, y se desea que todos los archivos que vas creando (p.e, instalando módulos de Drupal) estén accesibles para el usuario del web server, claro, sin tener que estar haciendo un chgrp recursivo a cada rato. Otra es si se tiene un volumen o carpeta compartida, cuando un usuario crea un archivo en dicha carpeta por defecto el archivo tiene el dueño y el grupo mapeados al usuario que creó el archivo, y no al grupo donde se encuentra, por ende no es visible a los demás usuarios que usan la carpeta.

Esto es muy fácil de solucionar, solo hay que activar el bit/flag setgid (similar al bit a r-w-x) a la carpeta (ojo, carpeta nada más, en archivos significa otra cosa) para que los nuevos archivos dentro de la misma hereden el grupo de la carpeta. Como vimos en un post anterior, podemos poner dicho bit de forma recursiva a todas las carpetas dentro de una carpeta:

find /ruta/al/directorio -type d -exec chmod g+s '{}' \;

Claro, para que eso tenga sentido lo mejor sería primero ponerle a todos los archivos el grupo que deseamos que hereden:

chgrp -R grupo /ruta/al/directorio

Saludos

Crear base de datos y usuario en MySQL

En nombre del post era más largo, era así:

Crear base de datos y usuario con todos los permisos sobre esa y sólo sobre esa base de datos en MySQL.

Siempre paso haciendo ésto, pero por más que lo haga una y otra vez siempre se me olvida el SQL de los permisos, por eso lo pongo acá para estar acordándome.

Primero, iniciamos una sesión de shell:

mysql -u root -p

(En humano dice: Inicie MySQL como el usuario root y pregúnteme el password).

Luego creamos la base de datos (en éste caso llamada exampledb):

mysql> CREATE DATABASE exampledb;

Ahora creamos un usuario y le damos todos los permisos sobre esa base de datos (todo en un mismo paso; la creación del usuario no es explícita pero se lleva a cabo):

mysql> GRANT ALL PRIVILEGES ON exampledb.* TO 'usuario'@'localhost' IDENTIFIED BY 'clave';

Claro, cambiamos ‘exampledb’, ‘usuario’ y ‘clave’ por los valores reales. Podemos dejar las comillas simples, es recomendado.

Saludos!

Instalar SuperCollider en Ubuntu

SuperCollider es un entorno y lenguaje de programación para síntesis de sonido en tiempo real y composición de algoritmos. Pueden conocer más de SuperCollider en la página de Wikipedia.

Cómo instalar SuperCollider en Ubuntu:

1. Agregar repositorio PPA:

shell> sudo add-apt-repository ppa:supercollider

2. Actualizar el índice de repositorios:

shell> sudo apt-get update

3. Instalar SuperCollider y el plugin para gedit:

shell> sudo apt-get install supercollider supercollider-gedit

4. Reiniciar la máquina o cerrar la sesión y volver a entrar (esto porque el usuario a sido agregado a otro grupo y los permisos han variado, para poder darle al usuario más control de prioridades y sobre la tarjeta de sonido).

5. Iniciar gedit y activar el modo SuperCollider:

Herramientas -> Modo SuperCollider

6. Iniciar el servidor SuperCollider:

SuperCollider -> Iniciar servidor

Ahora al escribir código pueden evaluarlo con el menú o con Ctrl+E

Configurar sudo para Debian (Squeeze y Gnome)

sudo .vs. root … no me interesa ver los pros y contras, ni me interesa explicar cuales son las diferencias. Pero por si las dudas, un muy buen artículo a forma de resumen:

http://www.berthon.eu/ice_and_fire/?p=11

En todo caso, yo uso ambos, dependiendo del caso :D

En Debian, la configuración por defecto es utilizar una cuenta de root, a diferencia de Ubuntu, en el cual la configuración por defecto es utilizar sudo.

Para muchos que queremos éste comportamiento en Debian se puede hacer complicado. ¿Por qué? Porque por alguna razón cuando escribo “SUDO Debian” en Google me salen links que no sirven para nada:

Los primeros 8 resultados no sirven! Son incompletos, incorrectos, obsoletos, viejos, enfocados en otros aspectos, excesivamente largos y avanzados. Incluso el mismo Wiki de Debian es muy incompleto en ese sentido: http://wiki.debian.org/sudo

(Algún listillo dirá “Y por qué no corriges el wiki”. Respuesta: Favor traduce mi explicación al inglés y elimina las expresiones de catarsis :D ).

Pero bueno, manos a la obra. Para configurar el sudo en Debian requieres 4 pasos:

  1. Verificamos si está instalado el paquete sudo, si existe el grupo sudo y si éste tiene los permisos.
  2. Agregar tu usuario a ese grupo.
  3. Configurar el PolicyKit para que ahora nos pida la clave del usuario y no la de root.
  4. Configurar el gksu para que ahora nos pida la clave del usuario y no la de root.

Para el paso 1 al 3 requerimos el estar logeado como usuario root, el paso 4 requiere el estar logeado como el usuario que desea utilizar el sudo.

PASO 1 (root)

  1. Verificamos si el paquete sudo está instalado (no voy a cubrir los detalles de cómo instalar un paquete)
  2. Verificamos si existe el grupo “sudo” cat /etc/group | cut -d: -f1 | grep sudo
    • Si existe (encuentra el grupo): seguimos al paso 1.2
    • No existe (no encuentra el grupo): groupadd sudo
  3. Verificamos los permisos: cat /etc/sudoers y buscan la línea %sudo ALL=(ALL) ALL
    • Si existe (encuentran la línea): seguimos al paso 2
    • No existe: visudo -f /etc/sudoers y la agregamos.

PASO 2 (root)

Agregamos nuestro usuario al grupo sudo: usermod -a -G sudo $USUARIO

PASO 3 (root)

Agregamos la siguiente regla en un archivo nuevo en la carpeta de configuración de PolicyKit:

cd /etc/polkit-1/localauthority.conf.d/
nano 51-debian-sudo.conf

Y agregamos las siguientes líneas en ese archivo:

[Configuration]
AdminIdentities=unix-group:sudo

PASO 4 (usuario)

Escribimos:

gconf-editor

Y vamos a apps -> gksu -> sudo-mode : CHECK. Es decir, verificamos que la clave “sudo-mode” del registro del programa gksu esté habilitada.

PASO 5

Ya sé que dije sólo 4 pasos, pero por si acaso: CIERREN SESIÓN Y VUELVAN A ENTRAR. O bien, reinicien.

Ahora pueden observar como Synaptic y el Gestor de actualizaciones les solicita la clave de su usuario y no la de root, y además, ya pueden utilizar el comando sudo como prefijo para ejecutar cualquier comando como root con su clave de usuario.

Saludos y espero les haya servidor.

Iniciar máquinas virtuales de VirtualBox al inicio

Tengo una máquina virtual que quiero que inicie cada vez que bootea el servidor. Tanto mi VM como el servidor físico son Debian Lenny, ambos con openssh-server instalado como demonio de SSH para administrarlos, por lo que adrede no habilito el RDP de la VM y la corro como headless.

1. Iniciar las máquinas virtual

Para iniciar las máquinas ponemos esto en nuestro archivo /etc/rc.local :

#/bin/bash -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# VirtualBox start virtual machines on boot
# VMs Run user
RUN_USER=userexecutesvm
# VM run type. Options are [gui|sdl|vrdp|headless]. Check 'VBoxManage startvm'
VM_RUN_TYPE=headless
# Put the ID of the VMs. You can put the unique id (ex. da52db1a-5b6e-4297-b4b6-aa9e293efcc8)
# or the human friendly VM name (ex. "Name of the VM").
# Check 'VBoxManage --nologo list vms' for information about your VMs
# Example variable:
# VMS=("Name of the VM 1" "Name of the VM2" da52db1a-5b6e-4297-b4b6-aa9e293efcc8)
VMS=("Name of the VM")
# Check for missing binaries
VIRTUALBOX_BIN=/usr/bin/VBoxManage
test -x $VIRTUALBOX_BIN || { echo "$VIRTUALBOX_BIN not installed"; exit 5; }
# Start the VMs
for i in "${VMS[@]}"
do
su - $RUN_USER -c "$VIRTUALBOX_BIN --nologo startvm '${i}' --type $VM_RUN_TYPE"
done
exit 0

En WordPress se ve muy mal, pueden revisar el script en http://www.cjenkins.net/files/rc.local

Es importante que cambien el usuario con el que ejecutarán las VM y que no sea root por seguridad. Está de más decir que el usuario es el mismo que con el que ejecutan normalmente la VM. El script /etc/rc.local es llamado sin argumentos por el script /etc/init.d/rc.local , pueden revisarlo para conocer como funciona. Ese script se encuentra enlazado como S99rc.local en los Run Levels 2 al 5 (link simbólico /etc/rcX.d/S99rc.local), que en Debian significan lo mismo. Por lo que entonces tenemos cubierto el inicio de la VMs.

2. Detener las VMs

Inicialmente cree mi propio script para detener las VMs. Sin embargo noté que existe el script /etc/init.d/vboxdrv . Al revisarlo, observé una buena implementación llamada stop_vms. El encabezado de la función menciona:

# enter the following variables in /etc/default/virtualbox:
# SHUTDOWN_USERS="foo bar"
# check for running VMs of user foo and user bar
# SHUTDOWN=poweroff
# SHUTDOWN=acpibutton
# SHUTDOWN=savestate
# select one of these shutdown methods for running VMs

Por lo que creamos el archivo /etc/default/virtualbox (ya que por defecto no existe) de esta forma:

host:~# nano /etc/default/virtualbox

SHUTDOWN_USERS="usuarioejecutavms"
SHUTDOWN=savestate

Ese script se encuentra enlazado como S20vboxdrv en los Run Levels 2 al 5 (link simbólico /etc/rcX.d/S20vboxdrv). Y como K20vboxdrv en los Run Levels 0, 1 y 6 (link simbólico /etc/rcX.d/K20vboxdrv). Es decir, que se llamará el script /etc/init.d/vboxdrv con el argumento stop cuando se apague el sistema (Run Level 0), se inicie como single-user mode (Run Level 1) o se reinicie el sistema (Run Level 6). El script vboxdrv sólo llama a stop_vms cuando se le llama con el argumento stop. Es decir, que las máquinas virtuales de los usuarios de la variables se apagarán usando el método especificado (en mi caso puse savestate) en dichos casos.

Con esto ya queda funcionando el sistema.

En resumen: El sistema al ejecutar rc.local se encarga de iniciar nuestras VMs. Al apagar o reiniciar vboxdrv se encarga de apagar nuestras VMs de forma como lo configuramos en /etc/default/virtualbox.

Seguir

Get every new post delivered to your Inbox.