Python Fabric任务能否调用其他任务并尊重它们的主机列表?
我有一个像下面这样的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()这个任务,让它按照我的想法工作,同时又不影响子任务,这样它们就可以单独运行?
4 个回答
1
可能有更好的处理方法,不过你可以把两个主机都传给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()
3
这听起来有点无聊,但在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')
31
从Fabric 1.3开始,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
然后可以从另一个任务deploy
中运行migrate
和web
这两个任务:
def deploy():
execute(migrate)
execute(update)
这样做会遵循这些任务所设定的角色和主机列表。