通过Fabric在服务器上激活virtualenv时遇到问题

问题描述:

我试图在我的登台服务器上通过Fabric运行一些Django管理命令。通过Fabric在服务器上激活virtualenv时遇到问题

问题是,它似乎Fabric无法激活virtualenv,因此在执行命令时使用系统python/libs。

在服务器上的Django应用程序使用的virtualenv运行(不,我不使用virtualenvwrapper可是...)

使用织物(1.0.1)的命令可能是这样的,从我的机器上运行时:

的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) 

输出:

$ 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. 

我当然知道Django命令collectstatic在1.3之前的版本中不存在,导致医生认为系统python(它有Django 1.2)正在被使用。

我fabfile /项目布局是基于great fabfile of the Tribapps guys

所以我创建了一个布的方法来测试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) 

在运行时它提供了以下的输出:

$ 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', 

正如你可以看到它使用系统python而不是我位于home/newsapps/sites/mysite/env的virtualenv

但是,如果我直接在服务器

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

上运行此命令..然后它输出从virtualenv中正确路径

我在做什么错误的,因为这些命令不与来自蟒蛇运行我使用Fabric的virtualenv?

我不打扰激活virtualenv,只是给virtualenv的Python解释器的完整路径。然后将使用正确的PYTHONPATH等。

+0

我在我的virtualenv的postactivate文件中添加我的其他PYTHONPATH条目(如你的项目的根目录)。我会假设这种方法不会增加。我应该把这些放在其他地方吗? – PKKid 2011-06-09 20:44:39

+1

您可以将' .pth'文件添加到您的'/lib/python2.x/site-packages /'目录。这些可以包含一个将被添加到你的'PYTHONPATH'中的路径。我这是做我的部署过程的一部分。 – 2011-06-10 07:11:31

+0

或者,你可以将你的项目变成一个可安装的包(给它一个'setup.py'文件),并使用'pip -e'来安装它,哪一种做同样的事情。 – 2011-06-10 07:12:24

我有同样的问题。解决不了这个简单的方法。所以我只是使用了virtualenv中的python bin文件的完整路径。我不是Python的专家,但我想最后它是一样的。 它是这样的,我晶圆厂文件:

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 

你应该叫从您的virtualenv bin目录中的Python版本,那么你会确保它使用Python的virtualenv中的版本。

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

“-v0”是什么意思? Thx – lajarre 2013-04-09 10:00:58

+1

@lajarre -v VERBOSITY,--verbosity = VERBOSITY Verbosity level; 0 =最小输出,1 =正常输出,2 =详细输出,3 =非常详细的输出 – 2013-04-09 14:14:42

这将很好地工作:)

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')