通过fabric以部署用户身份激活虚拟环境
我想在本地运行我的fabric脚本,这个脚本会登录到我的服务器,切换用户到deploy,激活项目的虚拟环境,这样就能进入项目目录并执行git pull命令。
def git_pull():
sudo('su deploy')
# here i need to switch to the virtualenv
run('git pull')
我通常使用virtualenvwrapper中的workon命令,这个命令会加载激活文件,而postactivate文件会让我进入项目文件夹。不过在这种情况下,似乎因为fabric是在shell内部运行的,所以控制权交给了fabric,这样我就不能使用bash的source命令来执行'$source ~/.virtualenv/myvenv/bin/activate'了。
有没有人能给我一个例子,并解释一下他们是怎么做到的?
10 个回答
18
我只是用一个简单的包装函数 virtualenv(),可以用来代替 run()。这个函数不使用 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)
138
关于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')
96
现在,你可以像我一样做,虽然方法有点笨拙,但效果很好*(这里假设你在使用virtualenvwrapper——你应该使用这个——如果没有,你也可以用你提到的那个比较长的'source'命令来替代):
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
就不会执行),或者如果command1
没有正确处理,里面包含了特殊的shell字符等等。