#python #django #virtualenv #fabric
#python #django #virtualenv #fabric
Вопрос:
Я пытаюсь запустить некоторые команды управления Django через Fabric на моем промежуточном сервере.
Проблема в том, что, похоже, Fabric не может активировать virtualenv и, следовательно, использует системный python / библиотеки при выполнении команд.
На сервере приложение 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 amp;amp; 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 amp;amp; 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 / project основан на отличном fabfile ребят из Tribapps
Итак, я создал метод fabric для тестирования pythonversion:
def pythonver():
require('settings', provided_by=[production, staging])
with settings(warn_only=True):
run('source %(env_path)s/bin/activate amp;amp; 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 amp;amp; 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 amp;amp; echo "import sys; print sys.path" | python
.. затем он выводит правильные пути из virtualenv
Что я делаю не так, поскольку команды не выполняются с python из моего virtualenv с использованием Fabric?
Ответ №1:
Вы должны вызвать версию python из своего каталога virtualenv bin, тогда вы будете уверены, что она использует версию python virtualenv.
/home/newsapps/sites/mysite/env/bin/python /home/newsapps/sites/mysite/repository/mysite/configs/staging/manage.py collectstatic --noinput -v0
Комментарии:
1. @lajarre -v VERBOSITY, —verbosity = уровень детализации МНОГОСЛОВИЯ; 0 = минимальный вывод, 1 = обычный вывод, 2 = подробный вывод, 3 = очень подробный вывод
Ответ №2:
Я бы не стал заморачиваться с активацией virtualenv, просто укажите полный путь к интерпретатору python virtualenv. Затем будет использоваться правильный PYTHONPATH и т.д.
Комментарии:
1. Я добавляю свои дополнительные записи PYTHONPATH (например, корневой каталог вашего проекта) в файл postactivate моего virtualenv. Я бы предположил, что этот метод этого не добавляет. Должен ли я размещать их где-то еще?
2. Вы можете добавлять
<name>.pth
файлы в свой<virtualenv>/lib/python2.x/site-packages/
каталог. Они могут содержать путь, который будет добавлен к вашемуPYTHONPATH
. Я делаю это как часть моего процесса развертывания.3. Или вы можете превратить свой проект в устанавливаемый пакет (предоставить ему
setup.py
файл) и установить его с помощьюpip -e
, который выполняет то же самое.
Ответ №3:
У меня была такая же проблема. Не удалось решить это простым способом. Итак, я просто использовал полный путь к файлу python bin внутри 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
Ответ №4:
Это будет работать отлично 🙂
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')
Ответ №5:
Этот подход сработал для меня, вы тоже можете применить это.
from fabric.api import run
# ... other code...
def install_pip_requirements():
run("/bin/bash -l -c 'source venv/bin/activate' "
"amp;amp; pip install -r requirements.txt "
"amp;amp; /bin/bash -l -c 'deactivate'")
Предполагая, что venv
это ваш виртуальный каталог env и добавьте этот метод везде, где это уместно.