ファブリックスクリプトをローカルで実行し、サーバーにログインし、ユーザーをデプロイに切り替え、プロジェクト.virtualenvをアクティブにします。これにより、dirがプロジェクトに変更され、git pullが発行されます。
def git_pull():
Sudo('su deploy')
# here i need to switch to the virtualenv
run('git pull')
通常、virtualenvwrapperのworkonコマンドを使用します。このコマンドは、アクティベートファイルとポストアクティベートファイルを取得し、プロジェクトフォルダーに配置します。この場合、ファブリックはシェル内から実行されるため、制御はファブリックに渡されるため、「$ source〜/ .virtualenv/myvenv/bin/activate」にbashのソースビルトインを使用することはできません
誰かがこれをどのように行ったかの例と説明がありますか?
今、あなたは私がしていることをすることができます、それは気味が悪いですが、完全にうまく動作します* 、そうでない場合):
def task():
workon = 'workon myvenv && '
run(workon + 'git pull')
run(workon + 'do other stuff, etc')
バージョン1.0以降、Fabricには prefix
コンテキストマネージャー があり、この手法を使用して、たとえば次のことができます。
def task():
with prefix('workon myvenv'):
run('git pull')
run('do other stuff, etc')
* command1 && command2
が失敗した場合(command1
が実行されない場合)やcommand2
が 'n'でない場合など、command1
アプローチを使用すると破裂する場合がありますt適切にエスケープされ、特殊なシェル文字などが含まれています。
Bitprophetの予測の更新:Fabric 1.0では、 prefix() と独自のコンテキストマネージャーを使用できます。
from __future__ import with_statement
from fabric.api import *
from contextlib import contextmanager as _contextmanager
env.hosts = ['servername']
env.user = 'deploy'
env.keyfile = ['$HOME/.ssh/deploy_rsa']
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')
Run()の代わりに呼び出すことができる単純なラッパー関数virtualenv()を使用しています。 cdコンテキストマネージャーを使用しないため、相対パスを使用できます。
def virtualenv(command):
"""
Run a command in the virtualenv. This prefixes the command with the source
command.
Usage:
virtualenv('pip install Django')
"""
source = 'source %(project_directory)s/bin/activate && ' % env
run(source + command)
virtualenvwrapper
は、これをもう少しシンプルにすることができます
@ nh2のアプローチの使用(このアプローチはlocal
を使用する場合にも機能しますが、workon
が$PATH
にあるvirtualenvwrapperインストール、つまりWindowsの場合にのみ有効です)
from contextlib import contextmanager
from fabric.api import prefix
@contextmanager
def virtualenv():
with prefix("workon env1"):
yield
def deploy():
with virtualenv():
run("pip freeze > requirements.txt")
または、fabファイルをデプロイして、これをローカルで実行します。この設定により、ローカルまたはリモートコマンドのvirtualenvをアクティブにできます。このアプローチは、local
がbash -l
を使用して.bashrcを実行できないことに対処するため、強力です。
@contextmanager
def local_prefix(Shell, prefix):
def local_call(command):
return local("%(sh)s \"%(pre)s && %(cmd)s\"" %
{"sh": Shell, "pre": prefix, "cmd": command})
yield local_prefix
def write_requirements(Shell="/bin/bash -lic", env="env1"):
with local_prefix(Shell, "workon %s" % env) as local:
local("pip freeze > requirements.txt")
write_requirements() # locally
run("fab write_requirements")
これは、ローカル展開でvirtualenv
を使用する私のアプローチです。
ファブリックの path() コンテキストマネージャーを使用すると、virtualenvのバイナリでpip
またはpython
を実行できます。
from fabric.api import lcd, local, path
project_dir = '/www/my_project/sms/'
env_bin_dir = project_dir + '../env/bin/'
def deploy():
with lcd(project_dir):
local('git pull Origin')
local('git checkout -f')
with path(env_bin_dir, behavior='prepend'):
local('pip freeze')
local('pip install -r requirements/staging.txt')
local('./manage.py migrate') # Django related
# Note: previous line is the same as:
local('python manage.py migrate')
# Using next line, you can make sure that python
# from virtualenv directory is used:
local('which python')
投稿されたすべての回答に感謝します。これに対してもう1つの選択肢を追加したいと思います。モジュール fabric-virtualenv があり、同じコードとして機能を提供できます。
>>> from fabvenv import virtualenv
>>> with virtualenv('/home/me/venv/'):
... run('python foo')
fabric-virtualenvはfabric.context_managers.prefix
、これは良い方法かもしれません:)
パッケージを環境にインストールする場合、または環境内のパッケージに従ってコマンドを実行する場合、複雑なファブリックのメソッドを記述したり、新しいOSパッケージをインストールする代わりに、この問題を解決するためにこのハックを見つけました。
/path/to/virtualenv/bin/python manage.py migrate/runserver/makemigrations # for running commands under virtualenv
local("/home/user/env/bin/python manage.py migrate") # fabric command
/path/to/virtualenv/bin/pip install -r requirements.txt # installing/upgrading virtualenv
local("/home/user/env/bin/pip install -r requirements.txt") # fabric command
この方法では、環境をアクティブにする必要はないかもしれませんが、環境の下でコマンドを実行できます。
このアプローチは私のために働いた、あなたもこれを適用することができます。
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ディレクトリであると仮定し、必要に応じてこのメソッドを追加します。
Run/Sudo呼び出しに仮想環境を使用するデコレーターのコードを次に示します。
# This is the bash code to update the $PATH as activate does
UPDATE_PYTHON_PATH = r'PATH="{}:$PATH"'.format(VIRTUAL_ENV_BIN_DIR)
def with_venv(func, *args, **kwargs):
"Use Virtual Environment for the command"
def wrapped(*args, **kwargs):
with prefix(UPDATE_PYTHON_PATH):
return func(*args, **kwargs)
wrapped.__= func.__name__
wrapped.__doc__ = func.__doc__
return wrapped
デコレータを使用するには、デコレータの順序が重要であることに注意してください。
@task
@with_venv
def which_python():
"Gets which python is being used"
run("which python")