0

有没有办法让execute面料尊重装饰者(除了host, hosts,role和--- 见这里roles) ,或者其他方式来完成类似的事情)?这是一个用例:exclude_hosts

from fabric.api import task, execute, run, runs_once

@task
def setup_environment():
    # ... set up env.hosts, env.roledefs, env.use_ssh_config, etc.

@task
def provision():
    # ... do some stuff on each host here, e.g. install mongodb

@task
def is_primary():
    return run('mongo --quiet --eval "db.isMaster().ismaster"') == 'true'

@task
@runs_once
def change_to_primary():
    env.hosts = []
    for host, result in execute(is_primary, roles=('mongo',)).iteritems():
        if result:
            env.hosts.append(host)

@task
def add_user():
    # ... do something here that needs to be done on primary

如果我从命令行运行以下任务序列,这很好:

> fab setup_environment provision change_to_primary add_user

但由于我总是运行change_to_primary并且add_user作为配置的一部分,我想修改provision以便我可以运行fab setup_environment provision、拥有set_primaryadd_user执行,如下所示:

@task
def provision():
    # ... do some stuff on each host here, e.g. install mongodb
    execute(change_to_primary)
    execute(add_user)

但是,这会执行change_to_primary很多次(不运行一次),这与命令行用法不同。有没有办法做到这一点?

4

1 回答 1

1

一种方法是mongo使用装饰器在具有角色的所有节点上执行任务roles,并通过检查节点是否实际上是主节点来开始任务:

@task
def provision():
    execute(stuff_to_do_on_all_hosts)
    execute(stuff_to_do_on_mongo_primaries)

@task
def stuff_to_do_on_all_hosts():
    do_stuff()

@task
@roles('mongo')
def stuff_to_do_on_mongo_primaries():
    if not is_primary():
        return
    add_user()
    do_other_stuff()

另一种方法是首先构建初选列表,然后使用hosts参数来execute

@task
def provision():
    # ... do some stuff on each host here, e.g. install mongodb
    execute(stuff_to_do_on_all_hosts)

    # build list of mongo primaries
    primaries = [host for host, result in execute(is_primary, roles=('mongo',)).iteritems() if result]

    # run task only on those hosts
    execute(stuff_to_do_on_mongo_primaries, hosts=primaries)

@task
def stuff_to_do_on_all_hosts():
    do_stuff()

@task
def stuff_to_do_on_mongo_primaries():
    add_user()
    do_other_stuff()

希望这可以帮助。

于 2013-10-22T19:52:55.150 回答