• slidebg1

Fabric y virtualenvs con Python


fabric

Fabric es una libreria de Python y una herramienta de linea de comandos para ejecutar tareas de deploy a través de SSH o tareas de administración de sistemas.

Hasta no hace mucho esta librería era solo compatible con Python 2.X, pero ahora ya disponesmos de un fork que nos hace posible utilizarla también para Python 3.x.

La página oficial de fabric la podéis encontrar aquí: http://www.fabfile.org/

El fork para Python3 lo tenéis aquí: https://github.com/mathiasertl/fabric/

Muchas veces nos encontramos con el problema de querer ejecutar tareas en las máquinas remotas dentro del un virtualenv creado para nuestro proyecto.

También añadimos el "problema" de haber creado un usuario sin privilegios de administración para ejecutar nuestra aplicación. Pues bien, para poder ejecutar las tareas con ese usuario dentro del virtualenv os dejo el siguiente código de ejemplo.

Como veréis hemos definido una clase Sudosu que su mision es ejecutar los comandos como si fuésemos el usuario propietarios del virtualenv. Es lo mismo que si ejecutáramos "sudo su - user_name" y luego los comando que necesitáramos. Posteriormente para ejecutar el comando dentro del virtualenv, hemos definido un contenxtmanager que nos coloca dentro de dicho virtualenv una vez ejecutados el activate y postactivate del mismo.

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

from fabric.api import *

@task
def staging():
    env.hosts = ["8.8.8.8"]
    env.user = "ubuntu"
    env.key_filename = "~/.ssh/private_key"

    env.directory = '/home/user_name/project'
    env.activate = 'source /home/user_name/.virtualenvs/project/bin/activate'
    env.postactivate = 'source /home/user_name/.virtualenvs/project/bin/postactivate'


class Sudosu(object):
    def __init__(self, user):
        self.user = user

    def __enter__(self):
        self.old_sudo_prefix = env.sudo_prefix
        self.old_sudo_user, env.sudo_user = env.sudo_user, self.user
        env.sudo_prefix = "sudo -S -p '%(sudo_prompt)s' su - %(sudo_user)s -c"

    def __exit__(self, *exc):
        env.sudo_prefix = self.old_sudo_prefix
        env.sudo_user = self.old_sudo_user


@contextmanager
def virtualenv():
    with cd(env.directory):
        with prefix(env.activate):
            with prefix(env.postactivate):
                with cd(env.directory):
                    yield

@task
def mi_tarea():
    with Sudosu(user="user_name"):
        with virtualenv():
            sudo("comando a ejecutar dentro del virtualenv como si fueras el ususario user_name")

Para ejecutar esta tarea con fabric sería algo así:

fab staging mi_tarea

Espero que os sea de utilidad y que vuestos deploys no sean tan complicados ahora ;)

Públicado el 24/06/2016

Comparte este post:

CATEGORÍAS: Actualidad Aprendizaje Desarrollo