Python Virtualenv Portable

Para los que no conocen el paquete Virtualenv, es una herramienta para crear ambientes de Python aislados, es decir, crea en un directorio toda la estructura de librerias y directorios para ejecutar un interprete python, ya sea 2.7 o 3 y a su vez instalar librerias o paquetes con PIP sin meterse con las librerías del sistema o externas a este ambiente aislado.

USOS
Generalmente lo usamos cuando una aplicación requiere librerías especificas, las cuales no se cumplen con las librerías instalas en el SO, ésto debido a que se requieren obsoletas, últimos releases o entran en conflicto con otras ya instaladas. En ese momento entra VirtualEnv para crear un ambiente limpio para instalar las librerías especificas para tu proyecto.

PROBLEMA
El único problema es cuando haces un tar de tu virtualenv, lo mueves a otra servidor o computadora y al ejecutar source bin/activate te das cuenta que no funciona, los PATH están incorrectos y toda tu trabajo no funciona. Esto debido a que al crear el proyecto, virtualenv utiliza el directorio actual para asignar los PATH’s a los scripts.

CASO PARTICULAR
En mi caso, tengo un Container de Docker ejecutando Nagios y tengo un bind de un directorio con plugin’s en donde mando llamar un script desde Nagios cada que un servicio de AWS se muere y el cual por simplicidad hace uso de un ambiente creado con Virtualenv.

MI SITUACIÓN
El problema reside en que yo cree ese ambiente fuera del container, por lo tanto, al crearlo, todos los python scripts apuntaban al binario de python en una ubicación tipo “/opt/nagios/plugins/aws-cli/bin/python“, mientras que en mi container el bind mount esta en “/data/plugin/aws-cli/bin/python“.

WORKAROUND
Una solución sencilla era modificar todos la primera línea de los python scripts para que apuntaran a la ubicación correcta del container, pero eso movía el error ahora cuando estuviera modificando el script y probandolo, tendría que hacerlo nuevamente a mi ambiente fuera del container.

SOLUCION
En realidad opte por crear un script que arreglara todos los PATHS de manera automática y antes de ejecutar “source bin/activate“, cambiara las rutas a python dentro de los scripts sin importar de donde se ejecutara o si se movió el directorio, automaticamente arregla los path’s.

LO DIVERTIDO

Lo primero que debemos hacer es modificar “bin/activate“, para agregar un pequeño fix en la línea ~43:

VIRTUAL_ENV="/opt/nagios/data/plugin/aws-cli"

y lo cambiamos a:

VIRTUAL_ENV="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" >/dev/null && pwd )"

en palabras sencillas, lo que hacemos es obtener el path donde se encuentra el script activate y bajamos un nivel en el directorio para quedar en la raíz del proyecto.

Ahora solo falta agregar a la raiz del proyecto un script en bash para modificar todos los scripts para corregir el path del interprete.

Para eso creamos el script “fixenv“:

#!/bin/bash
# Obtenemos el PATH de donde se ejecuta el script, en este caso debe estar dentro del proyecto.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# Generamos nuestro path dentro del proyecto de virtualenv
PAT=${DIR}/bin/python
grep -rl --exclude-dir="python2.7" '^#\!\/.*\/python$' | xargs sed -i 's@^#!.*/python$@#!'"${PAT}"'@'

Lo que hace el script es buscar todos los archivos que inicien con "#!/**/python" y sustituir con “sed” el PATH con nuestra variable ${PAT}, la cual previamente realizó el calculo del PATH nuevo al interprete.

En mi script que se ejecuta desde dentro de mi container, lo único que hice fue mandar llamar “fixenv” antes de activar el ambiente.

#!/bin/bash

./fixenv
source bin/activate

...

Y listo! Nuestro proyecto lo podemos mover de directorio, servidor, etc… y podremos ejecutarlo sin problemas.

Alejandro M.

Ingeniero Mexicano especialista en Seguridad Informática. Conocimientos en Cisco con la certificación Cisco Certified Network Professional - Security, Fortinet con ahora NSE-4, Certified Ethical Hacker. Trabajo con sistema operativos Linux para servidores de servicios web, dns, balanceo de carga, etc... Fanático de los MMORPG

Leave a comment

Your email address will not be published. Required fields are marked *