31

我有一个如下的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

4 回答 4

31

从 Fabric 1.3 开始,execute现在可以使用助手来执行此操作。文档可在此处获得:使用 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)

这将尊重这些任务所具有的角色和主机列表。

于 2011-11-17T20:02:16.900 回答
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')
于 2011-07-12T20:35:58.950 回答
1

试试这个。显然你想用runor替换本地sudo。关键是空的@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()
于 2011-06-28T07:08:40.663 回答
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()
于 2011-03-18T04:44:23.073 回答