Проблема с активацией virtualenv на сервере через Fabric

Я пытаюсь запустить некоторые команды управления Django через Fabric на моем промежуточном сервере.

Проблема в том, что, похоже, Fabric не может активировать virtualenv и, следовательно, использовать системные python / libs при выполнении команд.

На сервере приложение Django запускается с использованием virtualenv (нет, я еще не использую 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, что заставляет медиков думать, что используется системный python (с Django 1.2).

Макет моего fabfile / проекта основан на отличном fabfile ребят из Tribapps

Итак, я создал метод ткани для проверки версии python:

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.

Но если я запустил эту команду прямо на сервере

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

.. затем он выводит правильные пути из virtualenv

Что я делаю неправильно, поскольку команды не запускаются с питоном из моего виртуального сервера с использованием Fabric?


person Anders E    schedule 09.05.2011    source источник


Ответы (5)


Вы должны вызвать версию python из своего каталога bin virtualenv, тогда вы будете уверены, что она использует версию python virtualenv.

/home/newsapps/sites/mysite/env/bin/python /home/newsapps/sites/mysite/repository/mysite/configs/staging/manage.py collectstatic --noinput -v0
person Ken Cochrane    schedule 09.05.2011
comment
@lajarre -v VERBOSITY, --verbosity = VERBOSITY Уровень детализации; 0 = минимальный вывод, 1 = нормальный вывод, 2 = подробный вывод, 3 = очень подробный вывод - person Ken Cochrane; 09.04.2013

Я бы не стал заморачиваться с активацией virtualenv, просто предоставил полный путь интерпретатору python virtualenv. Затем будет использоваться правильный PYTHONPATH и т. Д.

person Matthew Schinckel    schedule 09.05.2011
comment
Я добавляю дополнительные записи PYTHONPATH (например, корневой каталог вашего проекта) в файл postactivate virtualenv. Я предполагаю, что этот метод не добавляет этого. Следует ли мне разместить их в другом месте? - person PKKid; 10.06.2011
comment
Вы можете добавить <name>.pth файлы в свой <virtualenv>/lib/python2.x/site-packages/ каталог. Они могут содержать путь, который будет добавлен к вашему PYTHONPATH. Я делаю это в процессе развертывания. - person Matthew Schinckel; 10.06.2011
comment
Или вы можете превратить свой проект в устанавливаемый пакет (дайте ему setup.py файл) и установите его с помощью pip -e, который делает то же самое. - person Matthew Schinckel; 10.06.2011

У меня такая же проблема. Не мог решить это простым способом. Поэтому я просто использовал полный путь к bin-файлу python внутри файла virtualenv. Я не профессионал в 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
person Eduardo    schedule 09.05.2011

Это будет отлично работать :)

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')
person Neeraj Sharma    schedule 17.07.2015

Этот подход сработал для меня, вы тоже можете его применить.

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 - ваш виртуальный каталог env, и добавьте этот метод, где это необходимо.

person Manikanta    schedule 23.10.2018