Clonar un servidor Ubuntu en VirtualBox

Digamos que tienes que crear una red de computadoras virtual o tienes un servidor base que quieres clonar para especializarlo de forma que te ahorres la instalación y actualización de un servidor. VirtualBox permite clonar una máquina virtual y reiniciar el MAC Address de dicha máquina para que la puedas levantar en la red sin que halla colisiones. Esto es fácilmente realizable con nuestro servidor Ubuntu Server y vale mencionar que por cuestiones de licencia ésto no se puede realizar tal cual en servidores Windows.

El problema es que las máquinas clonadas se llaman igual, y una vez de que reinicias el Mac Address las máquinas no vuelven a tener red. Para distinguirlas en la red y hacer que vuelva a funcionar la interfaz eth0 se debe realizar los siguientes pasos:

  1. Cambiar el nombre del sistema.
  2. Cambiar el nombre del sistema en el archivo de hosts.
  3. Eliminar el archivo de red persistente.

1. Cambiar el nombre del sistema:

sudo nano /etc/hostname

Cambiar el nombre del sistema.

2. Cambiar el nombre del sistema en el archivo de hosts:

sudo nano /etc/hosts

Cambiar la línea 127.0.1.1 nombresistema con el nombre del sistema.

3. Eliminar el archivo de red persistente:

sudo rm /etc/udev/rules.d/70-persistent-net.rules

Este archivo contiene los MAC Address y será regenerado cuando se reinicie el sistema.

Finalmente reiniciamos sudo reboot y listo.

Etiquetado , ,

Crear ejecutable (“.exe”) de un programa Python

Programar en Python en nuestro GNU/Linux es una belleza. Pero cuando también nos toca soportar dicho Software en plataformas MS Windows lo vemos más complicado. O tal vez pueda darse el caso de que el profesor solicite entregar la tarea programada en un “.exe” y nos de la libertad de escoger el lenguaje de programación que nosotros queramos (cualquier relación con la realidad es pura coincidencia).

Pero por dicha podemos hacer un freeze de nuestros scripts en Python, es decir, empaquetar en un “.exe” nuestro programa, las bibliotecas Python que utiliza y el mismísimo intérprete Python con lo que podremos distribuir el Software y ejecutarlo sin la necesidad de tener que descargar Python para Windows primero.

Para ello necesitamos tener un MS Windows en el cual realizaremos lo siguiente:

  1. Instalar y configurar Python.
  2. Instalar como administrador Py2Exe.
  3. Crear script de distribución setup.py
  4. Llamar al script de distribución con el parámetro py2exe

Instalar y configurar Python

Es necesario descargar Python para Windows desde la página oficial.

Es importante descargarse la última versión de la rama 2.X ya que py2exe no está disponible para Python 3 todavía (y no creo que pronto). En mi caso para la máquina virtual (mi GNU/Linux es de 64bits, la máquina virtual de 32) descargué la versión Python 2.7.3 para 32bits, es decir Windows x86 MSI Installer.

Una vez descargado se ejecuta e instala para todos los usuarios. Recomiendo cambiar la ruta de C:\Python2.7 a C:\Program Files\Python2.7 por una cuestión de orden.

Una vez instalado se procede a configurar el PATH de Windows para que encuentre el ejecutable de Python, para así no tener que escribir toda la ruta del ejecutable cuando queramos correr un script. Para ello vamos al editor de variables de entorno de Windows. En Windows 7 es:

Inicio -> Click derecho en My Computer -> Propiedades -> Advanced System Settings -> Pestaña Advanced -> Botón Environment Variables

Editamos la que dice Path en el cuadro de variables de entorno y adjuntamos al final del string la ruta de la carpeta de instalación de Python, separándola con un punto y coma ; , es decir:

[lo que habia escrito];[ruta de instalacion python]

En mi caso:

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Python2.7

Ok, ok, ok. Ahora abrimos la PowerShell (que de Power no tiene nada si la comparas con Bash) y escribimos el comando python y debería iniciar el interprete. Para abrir la PowerShell ingresa al menú de inicio y busca PowerShell. Listo.

Instalar como administrador Py2Exe

Py2Exe es el paquete que hará la magia de crearnos nuestro “.exe”. Descargamos la última versión desde la página oficial para nuestra versión de Python y arquitectura: descargar.

En mi caso, es py2exe-0.6.9.win32-py2.7.exe.

Un vez descargado instalamos el paquete como administrador: click derecho - ejecutar como administrador. Si no lo ejecutamos como administrador el instalador se quedará congelado y no avanzará. Listo.

Crear script de distribución setup.py

Creamos un archivo Python llamado setup.py encargado de la distribución del Software. El estricto mínimo funcional sería:

from distutils.core import setup
import py2exe

setup(console=['nombrearchivo.py'])

Ahora bien un ejemplo más completo sería:

# -*- coding: utf-8 -*-

import sys
from distutils.core import setup

kwargs = {}
if 'py2exe' in sys.argv:
    import py2exe
    kwargs = {
        'console' : [{
            'script'         : 'nombrescript.py',
            'description'    : 'Descripcion del programa.',
            'icon_resources' : [(0, 'icon.ico')]
            }],
        'zipfile' : None,
        'options' : { 'py2exe' : {
            'dll_excludes'   : ['w9xpopen.exe'],
            'bundle_files'   : 1,
            'compressed'     : True,
            'optimize'       : 2
            }},
         }

setup(
    name='nombreproyecto',
    author='Nombre del autor',
    author_email='autor@correo.com',
    **kwargs)

Lo bueno de éste último es que creará realmente un único archivo .exe. Y la verdad se puede volver tan complejo como ustedes quieran. Toda la documentación de cada uno de éstos elementos pueden encontrarlo en la wiki de Py2Exe.

Llamar al script de distribución con el parámetro py2exe

Desde el PowerShell:

cd C:\Carpeta De Proyecto\

python setup.py py2exe

Y luego encontrarán el .exe en la carpeta dist/.

Saludos

Etiquetado ,

Hacer un patch con quilt

Para aquellos que nos estamos adentrando al empaquetamiento con Debian será necesario algunas veces parchear el código fuente del upstream para arreglar algún problema que no ha sido aplicado, no haya un release oficial para ello o sea algo específico para el empaquetado. Para ello podemos aplicar parches en forma de pila (stack), uno sobre otro, para lograr lo que queremos. Debian provee un programa que se llama quilt.

Antes de parchear algún paquete debemos configurar quilt en nuestro entorno:

nano ~/.bashrc

Y agregamos al final:

export QUILT_PATCHES='debian/patches'
export QUILT_REFRESH_ARGS="-p ab --no-timestamp --no-index"

Recargamos el .bashrc:

source ~/.bashrc

Claro, tenemos que instalar quilt:

sudo apt-get install quilt

En mi caso muy particular, un mismo código fuente debe crear tres paquetes binarios (Python2, Python3 y documentación) pero al realizar el proceso se crean conflictos de ciertos archivos de traducción.

Lo que hacemos es irnos a la raíz del paquete (el que contiene el código fuente y la carpeta debian/) y escribimos:

quilt new nombre-parche.diff

Eso creará un nuevo parche en debian/patches con dicho nombre. Ahora debemos agregar los archivos de vayamos a modificar:

quilt add ruta/archivo/algo

Así tantos como sean necesarios. Ahora modificamos dichos archivos y realizamos los cambios necesarios. Una vez hayamos terminado debemos actualizar el archivo de parche con nuestros cambios:

quilt refresh

Podrán abrir el archivo en debian/patches y notarán cómo se registran los cambios. Ahora para terminar salimos del parche que estamos realizando lo que revierte los archivos modificados a su estado original:

quilt pop -a

Ahora el paquete está listo para ser reempaquetado con los cambios realizados. Los parches serán aplicados de forma automática durante el build. Recuerden hacer el bump de la versión debian.

Etiquetado ,

Configurar msmtp para enviar correos desde la terminal

Para enviar correos desde la terminal podemos utilizar muchas herramientas. Vamos a configurar una en particular que se llama msmtp que permite enviar correos utilizando tu cuenta de Gmail que tenga el SMTP habilitado.

sudo apt-get install msmtp

Luego, creamos el archivo de configuración del mismo:

nano ~/.msmtprc

Y copiamos la siguiente configuración (ojo, está para Gmail, para otros proveedores de cuentas de correo tienen que cambiar los parámetros):

# Provider configuration
defaults
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log

# Account configuration
account default
host smtp.gmail.com
port 587
auth on
from tucorreo@gmail.com
user tucorreo@gmail.com
passwordeval gpg -d ~/.msmtp.password.gpg

La documentación completa para el archivo de configuración se encuentra aquí y aquí pueden encontrar un buen ejemplo de archivo de configuración. Noten que solo creamos la cuenta default, msmtp permite crear varias cuentas y luego enviar correos con cada cuenta independiente. También noten que lo anterior también funciona para correos de otros dominios que estén configurados para usar el email de Gmail vía GoogleApps.

Como verán, la clave del correo no está en texto plano en el archivo de configuración (NUNCA!!). Debemos crear el archivo cifrado ~/.msmtp.password.gpg:

nano ~/.msmtp.password

Escribimos la clave del correo en el editor, luego salimos con Ctrl+o (Guardar), Ctrl+x (Salir). Luego, ciframos el archivo:

gpg -c ~/.msmtp.password

Nos va a pedir una clave, puede ser lo que quieran, no es necesario que sea la del correo. Eso creará el archivo ~/.msmtp.password.gpg cifrado, por lo que deben eliminar el archivo original que contiene la clave en texto plano:

rm ~/.msmtp.password

Ahora, estamos listos para probar mandar un correo:

msmtp paraalguien@eldominio.com

Eso iniciará msmtp y ejecutará la acción que definimos para cargar la clave, en cuyo caso es decifrar el archivo que acabamos de crear. Introducimos la clave y luego escribimos en la terminal lo siguiente:

To: paraalguien@eldominio.com
Subject: El título del correo.

Cuerpo, blah blah.

Para enviar el correo introducimos un EOF con dos Ctrl+D seguidos.

Noten que el To no es necesario ya que lo introdujimos como parámetro al llamar a msmtp, pero si no lo ponen sería un envío tipo copia carbón oculta y no se mostrará el remitente. El From no es necesario pues puede ser solo uno, el que tenemos configurado en la cuenta del msmtp que estamos usando, en este caso la default.

Con eso ya deberían ver el correo después de unos segundos en su correo de salida en el webmail.

Saludos

Etiquetado , ,

Use GtkSourceView widget in Glade

I’m developing an application that uses syntax highlight with PyGObject (Gtk+ 3.0 dynamic python bindings). If like me you need to use the GtkSourceView widget in Glade you need to follow this steps:

  1. Install gtksourceview development package:
    sudo apt-get install libgtksourceview-3.0-dev
    This will install the Glade catalog in /usr/share/glade/catalogs/gtksourceview.xml and the library in /usr/lib/x86_64-linux-gnu/libgtksourceview-3.0.so.
  2. Link library so Glade can find it:
    Glade will be unabled to find the library to load the catalog because is not in it’s search path with and error:
    (glade:7010): GladeUI-CRITICAL **: Unable to load module 'gtksourceview-3.0' from any search paths
    Solution: sudo ln -s /usr/lib/x86_64-linux-gnu/libgtksourceview-3.0.so /usr/lib/glade/modules/libgtksourceview-3.0.so

That’s it, now you have the new widget in your Glade.

GtkSourceView in Glade 3.12.0

If you’re using your Glade file with PyGObject you will need to register the new GtkSourceView type in GObject like this before calling GtkBuilder’s add_from_file():

from gi.repository import Gtk, GtkSource, GObject
from os.path import abspath, dirname, join

WHERE_AM_I = abspath(dirname(__file__))

class MyApp(object):

    def __init__(self):
        self.builder = Gtk.Builder()
        self.glade_file = join(WHERE_AM_I, 'test.glade')
        GObject.type_register(GtkSource.View)
        self.builder.add_from_file(self.glade_file)

if __name__ == '__main__':
    try:
        gui = MyApp()
        Gtk.main()
    except KeyboardInterrupt:
        pass

I’ve found very scarse documentation about this, and most of it is outdated (gtksourceview 2.0, Glade 2, PyGtk, Gtk+ 2.0, etc). So this apply to:

  • Ubuntu Precise 12.04
  • Glade 3.12.0
  • libgtksourceview 3.0
  • Gtk+ 3.0
  • PyGObject

Kind regards

Etiquetado , ,

Clone a MongoEngine object (Python MongoDB layer)

Now, imagine you have something like:

class Company(Document):
    name            = StringField(required=True)
    company_id      = StringField(required=True)
    phone           = StringField()

For some reason, you want to clone this object on the DB. That’s is, you want to create another exact object in the DB without the need to create another object manually an copy all it’s attributes. You can do it if you add the following method (a real hack, because MongoEngine doesn’t support cloning objects):

def clone(self):
        del self.__dict__['_id']
        del self.__dict__['_created']
        del self.__dict__['_changed_fields']
        self.id = ObjectId()

Note: If you have a SequenceField() you will need to delete it too so it can step up when you save the new object.

Don’t forget to:

from bson import ObjectId

So you can do:

obj = Company.objects(name='MyCompany')
obj.clone()
obj.name = 'MyOtherCompany'
obj.save()

Really useful, specially if your object has 8+ fields and one of more of it’s fields is a EmbeddedDocument.

Kind regards

Etiquetado , ,

Ordenar una lista de diccionarios basado en un criterio variable ordenado

Que que? xD

Ok, se tiene una lista de diccionarios Python, se quiere ordenar según un criterio ordenado de valores que puede tomar un determinada llave de un diccionario. Ash, no se como decirlo más fácil. Mejor un ejemplo:

Se tiene la siguiente lista de diccionarios:

[{'foo': FOO1}, {'foo': FOO2}, {'foo': FOO10}]

Y se tiene la siguiente lista de criterio de ordenación:

[FOO10, FOO2, FOO1]

Se espera que la lista resultante esté ordenada de la siguiente manera:

[{'foo': FOO10}, {'foo': FOO2}, {'foo': FOO1}]

Python es el mejor. Acá cómo hacerlo:

>>> to_sort = [{'foo': FOO1}, {'foo': FOO2}, {'foo': FOO10}]
>>> criteria = [FOO10, FOO2, FOO1]
>>> to_sort.sort(key=lambda x: criteria.index(x['foo']))
>>> to_sort
[{'foo': FOO10}, {'foo': FOO2}, {'foo': FOO1}]
Etiquetado , ,

Perdí mi llave privada :(

Bueno, historia larga corta:

– El disco duro de mi laptop murió de la noche a la mañana.
– No encuentro el backup de la llave por ningún lado.
– El certificado de revocación que tenía en mi KeePassX era de la llave pasada, ash! se me había olvidado actualizarlo :S

Entonces me pasa lo peor que le puede pasar a alguien, que mi llave firmada por varia gente esté perdida y eternamente presente en los keyserver de Ubuntu :S

Si alguien tiene mi llave por favor borrenla:
gpg –delete-key 9EE171C8

😦

Etiquetado

Molesto Gtk WARNING en Ubuntu 11.10

Hay un warning muy común en Ubuntu 11.10 muy molesto cuando uno usa mucho la terminal. Típicamente es:

Gtk-WARNING **: Imposible encontrar el motor de temas en la ruta al _modulo: «pixmap»,

Cuatro, cinco, seis veces :S Para eliminarlo:

sudo apt-get install gtk2-engines-pixbuf

Saludos

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
Etiquetado ,