我有一个如下所示的fabfile:
@hosts('host1')
def host1_deploy():
"""Some logic that is specific to deploying to host1"""
@hosts('host2')
def host2_deploy():
"""Some logic that is specific to deploying to host2"""
def deploy():
""""Deploy to both hosts, each using its own logic"""
host1_deploy()
host2_deploy()
我想做
fab deploy
并且等同于
fab host1_deploy host2_deploy
换句话说,运行每个子任务,并为每个子任务使用其指定的主机列表。但是,这不起作用。相反,deploy()任务需要自己的主机列表,并将其推广到其所有子任务。
这里有没有一种方法可以更新deploy()任务,这样它就可以执行我想要的操作,而让子任务不受影响,因此它们可以单独运行?
从Fabric 1.3开始,execute
帮助器现在可以执行此操作。该文档位于:Intelligently executing tasks with execute。
这是他们使用的示例:
from fabric.api import run, roles, execute
env.roledefs = {
'db': ['db1', 'db2'],
'web': ['web1', 'web2', 'web3'],
}
@roles('db')
def migrate():
# Database stuff here.
pass
@roles('web')
def update():
# Code updates here.
pass
然后从另一个任务migrate
运行web
和deploy
:
def deploy():
execute(migrate)
execute(update)
并且这将尊重这些任务具有的角色和主机列表。
这很la脚,但从Fabric 1.1.2开始有效
def host1_deploy():
"""Some logic that is specific to deploying to host1"""
if env.host in ["host1"]:
pass #this is only on host2
def host2_deploy():
"""Some logic that is specific to deploying to host2"""
if env.host in ["host2"]:
pass #this is only on host2
def deploy():
""""Deploy to both hosts, each using its own logic"""
host1_deploy()
host2_deploy()
这是我的测试代码:
@task
@roles(["prod_web","prod_workers"])
def test_multi():
test_multi_a()
test_multi_b()
def test_multi_a():
if env.host in env.roledefs["prod_web"]:
run('uname -a')
def test_multi_b():
if env.host in env.roledefs["prod_workers"]:
run('uname -a')
也许有更好的方法来处理它,但是您可以将两个主机都传递给deploy(),然后在host1_deploy()和host2_deploy()中检查env.host:
def host1_deploy():
if env.host in ['host1']:
run(whatever1)
def host2_deploy():
if env.host in ['host2']:
run(whatever2)
@hosts('host1','host2')
def deploy():
host1_deploy()
host2_deploy()
尝试这个。显然,您想用run
或sudo
替换local。关键是@hosts
deploy
装饰器from fabric.api import local
from fabric.decorators import hosts
@hosts('host1')
def host1_deploy():
"""Some logic that is specific to deploying to host1"""
local('echo foo')
@hosts('host2')
def host2_deploy():
"""Some logic that is specific to deploying to host2"""
local('echo bar')
@hosts('')
def deploy():
""""Deploy to both hosts, each using its own logic"""
host1_deploy()
host2_deploy()