结构中execute
是否有办法尊重装饰器(host
,hosts
,role
,roles
和{{1}除外} ---看here),或其他方式来完成这样的事情)?这是一个用例:
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
并拥有{{1}并执行fab setup_environment provision
,如下所示:
set_primary
但是,与命令行用法不同,这会多次执行add_user
(不会运行一次)。有没有办法实现这个目标?
答案 0 :(得分: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()
希望这有帮助。