私の質問に対する非常に基本的な答えは、この小さなヘルパー関数を使用することです。
def execute_serial(func, *args, **kwargs):
a2set = lambda x : set(getattr(func, x)) if hasattr(func, x) else None
func_hosts = a2set('hosts')
func_roles = a2set('roles')
should_exec = False
if 'host' not in kwargs:
kwargs['host'] = my_host = env.host_string
if func_hosts and my_host in func_hosts:
should_exec = True
if func_roles:
for func_role in func_roles:
if func_role in env.roledefs and my_host in env.roledefs[func_role]:
should_exec = True
if should_exec:
return execute(func, *args, **kwargs)
そして、使用法は次のようになります
@roles('group_django')
@task
def deploy_web():
execute(pre_deploy)
execute_serial(fix_srv_perms)
execute_serial(force_checkout_branch_to_production)
execute_serial(update_sources)
execute_serial(pip_install_requirements)
#these won't work correctly anymore
execute(bounce_workers)
execute(bounce_uwsgi)
execute(clear_cache)
私は fabric.main.main() を調べましたが、フックの簡単な機会 (開始前、すべてのタスクの完了、エラー時など) がないため、代わりに追加の解決策が考えられます
@roles('local') # defined in roledefs as {'local':'127.0.0.1'}
@task
def deploy_web():
execute(pre_deploy) #This is already role('local') with @runonce
for host in env.roledefs['group_django'].values():
execute_serial(fix_srv_perms, host = host)
execute_serial(force_checkout_branch_to_production, host = host)
execute_serial(update_sources, host = host)
execute_serial(pip_install_requirements, host = host)
#These will pickup the @role decorators
execute(redeploy_web_crontab)
execute(redeploy_work_crontab)
execute(bounce_workers)
execute(bounce_uwsgi)
execute(clear_cache)
追加情報、私はこのようなことを数回書きましたが、 ~/.boto を使用して領域を決定しenv.roledefs
、擬似コードに示されているように生成する boto イテレータがあります。
{ "{instance.tags の名前}_{instance.tags[name]}": [一致する instance.public_dns_name のリスト] }
さらに、現在の Webstack では、すべてのインスタンスに「group」、「type」、オプションで「lead」などのタグがあり、crontab をインストールする場所や最終的なデプロイ スクリプトを実行する場所を指定します。
execute_serial
ローカル タスク ループを使用すると、特に env.host_string が "{env.user}@127.0.0.1" に等しくなるように若干の変更を加える必要がありますが、これは理想的ではありません。
def execute_serial(func, *args, **kwargs):
a2set = lambda x : set(getattr(func, x)) if hasattr(func, x) else None
no_user = lambda x: x.split("@")[-1]
func_hosts = a2set('hosts')
func_roles = a2set('roles')
should_exec = False
my_host = env.host_string
my_host = env.host_string = kwargs['host']
if func_hosts and no_user(my_host) in func_hosts:
should_exec = True
if func_roles:
for func_role in func_roles:
if func_role in env.roledefs and no_user(env.host_string) in env.roledefs[func_role]:
should_exec = True
break
if should_exec:
return execute(func, *args, **kwargs)