无法通过Fabric在服务器上激活virtualenv

时间:2011-05-09 08:33:05

标签: python django virtualenv fabric

我试图在我的登台服务器上通过Fabric运行一些Django管理命令。

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

在服务器上使用virtualenv运行Django应用程序(不,我还没有使用virtualenvwrapper ......)

使用Fabric(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之前的版本中不存在,导致med认为系统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而不是我的virtualenv位于home / newsapps / sites / mysite / env

但是,如果我直接在服务器上运行此命令

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

..然后它从virtualenv输出正确的路径

由于使用Fabric从我的virtualenv中使用python运行命令,我做错了什么?

5 个答案:

答案 0 :(得分:5)

你应该从你的virtualenv bin目录调用python版本,然后你会确定它使用了virtualenv的python版本。

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

答案 1 :(得分:4)

我不打扰激活virtualenv,只需提供virtualenv的python解释器的完整路径。那将使用正确的PYTHONPATH等。

答案 2 :(得分:3)

我遇到了同样的问题。无法解决它的简单方法。所以我只使用了virtualenv中python bin文件的完整路径。我不是Python的专业人士,但我想最终会是同样的事情。 在我的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

答案 3 :(得分:2)

这将完美地运作:)

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

答案 4 :(得分:0)

这种方法对我有用,您也可以应用。

from fabric.api import run 
# ... other code...
def install_pip_requirements():
    run("/bin/bash -l -c 'source venv/bin/activate' "
        "&& pip install -r requirements.txt "
        "&& /bin/bash -l -c 'deactivate'")

假设venv是您的虚拟环境目录,并在适当的地方添加此方法。