2011-05-09 6 views
10

Estoy intentando ejecutar algunos comandos de administración de Django a través de Fabric en mi servidor de transferencia.Problema al activar virtualenv en el servidor a través de Fabric

El problema es que parece que Fabric no puede activar el virtualenv y, por lo tanto, usa el sistema python/libs al ejecutar los comandos.

En el servidor de la aplicación de Django se ejecuta utilizando un virtualenv (no, Yo no utilizo virtualenvwrapper sin embargo ...)

El uso de Tela (1.0.1) un comando podría tener este aspecto cuando se ejecuta desde mi caja :

El método fabfile:

def collectstatic(): 
    require('settings', provided_by=[production, staging]) 

    with settings(warn_only=True): 
     run('source %(env_path)s/bin/activate && python %(repo_path)s/%(project_name)s/configs/%(settings)s/manage.py collectstatic --noinput -v0' % env) 

La salida:

$ fab staging master collectstatic 
[myserver.no] Executing task 'master' 
[myserver.no] Executing task 'collectstatic' 
[myserver.no] run: source /home/newsapps/sites/mysite/env/bin/activate && python /home/newsapps/sites/mysite/repository/mysite/configs/staging/manage.py collectstatic --noinput -v0 
[myserver.no] Login password: 
[myserver.no] out: Unknown command: 'collectstatic' 
[myserver.no] out: Type 'manage.py help' for usage. 

Sé, por supuesto, que el comando Django collectstatic no existe en versiones anteriores a la 1.3 lo que lleva a pensar que ese sistema python (que tiene Django 1.2) está siendo utilizado.

Mi diseño fabfile/proyecto se basa en la great fabfile of the Tribapps guys

así que creé un método de tela para probar pythonversion:

def pythonver(): 
    require('settings', provided_by=[production, staging]) 

    with settings(warn_only=True): 

    run('source %(env_path)s/bin/activate && echo "import sys; print sys.path" | python ' % env) 

Cuando ejecutarlo da el siguiente resultado:

$ fab staging master pythonver 
[myserver.no] Executing task 'master' 
[myserver.no] Executing task 'pythonver' 
[myserver.no] run: source /home/newsapps/sites/mysite/env/bin/activate && echo "import sys; print sys.path" | python 
[myserver.no] Login password: 
[myserver.no] out: ['', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/dist-packages', '/usr/lib/pymodules/python2.6', '/usr/lib/pymodules/python2.6/gtk-2.0', 

Como puede ver, usa el sistema python y no mi virtualenv ubicado en home/newsapps/sites/mysite/env

Pero si me quedo este comando directamente en el servidor

source /home/newsapps/sites/mysite/env/bin/activate && echo "import sys; print sys.path" | python 

.. entonces se visualizan los caminos correctos de la virtualenv

¿Qué estoy haciendo mal ya que los comandos no se ejecutan con la pitón de mi virtualenv usando Fabric?

Respuesta

4

No me molestaría en activar el virtualenv, simplemente dale la ruta completa al intérprete de pitón del virtualenv. Eso utilizará entonces la PYTHONPATH correcta, etc.

+0

añado mis entradas PYTHONPATH adicionales (tales como el directorio raíz de su proyecto) en el archivo de mi postactivate virtualenv. Yo asumiría que este método no agrega eso.¿Debo colocar estos en otro lugar? – PKKid

+1

Puede agregar los archivos ' .pth' a su directorio' /lib/python2.x/site-packages/'. Estos pueden contener una ruta que se agregará a su 'PYTHONPATH'. Lo hago como parte de mi proceso de implementación. –

+0

O bien, puede convertir su proyecto en un paquete instalable (proporcionarle un archivo 'setup.py') e instalarlo usando' pip -e', que hace lo mismo. –

3

Tuve el mismo problema. No pudo resolverlo de la manera fácil. Así que acabo de usar la ruta completa al archivo bin de python dentro del virtualenv. No soy un profesional en Python, pero supongo que es lo mismo al final. Es algo parecido a esto en mi archivo fab:

PYTHON = '/home/dudus/.virtualenvs/pai/bin/python' 
PIP = '/home/dudus/.virtualenvs/pai/bin/pip' 

def update_db(): 
    with cd(REMOTE_DIR + 'application/'): 
     run('%s ./manage.py syncdb --settings="%s"' % 
      (PYTHON, SETTINGS)) # syncdb 
     run('%s ./manage.py migrate --settings="%s"' % 
      (PYTHON, SETTINGS)) # south migrate 
5

debe llamar a la versión de Python desde el directorio bin virtualenv, entonces usted estará seguro de que utiliza la versión de la virtualenv de pitón.

/home/newsapps/sites/mysite/env/bin/python /home/newsapps/sites/mysite/repository/mysite/configs/staging/manage.py collectstatic --noinput -v0 
+0

¿Qué significa "-v0"? Thx – lajarre

+1

@lajarre -v VERBOSITY, --verbosity = VERBOSITY Nivel de verbosidad; 0 = salida mínima, 1 = salida normal, 2 = salida detallada, 3 = salida muy detallada –

2

Esto funciona perfectamente :)

from __future__ import with_statement 
from fabric.api import * 
from contextlib import contextmanager as _contextmanager 

env.hosts = ['servername'] 
env.user = 'username' 
env.directory = '/path/to/virtualenvs/project' 
env.activate = 'source /path/to/virtualenvs/project/bin/activate' 

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

def deploy(): 
    with virtualenv(): 
     run('pip freeze') 
Cuestiones relacionadas