我有一个执行任务的任务 -
@roles('group_django')
@task
@serial
def deploy_web():
execute(pre_deploy)
execute(fix_srv_perms)
execute(force_checkout_branch_to_production)
execute(update_sources)
execute(pip_install_requirements)
#execute(bounce_workers)
execute(bounce_uwsgi)
execute(clear_cache)
在deploy_web中是否可以,因为提供的主机可以按顺序执行,但是一起执行。
假设角色“group_django”有4个服务器,它将从该角色中的第一个主机开始并执行每个执行然后重复。或者我是否需要预先做更多的腿部工作并抓住当前的env.hosts
并在deploy_web
内的循环中使用execute
呼叫每个hosts=[current_host]
我的目标是,如果它的部署不好,它只会淘汰一个服务器池中的一个,这样负载均衡器就可以解决它,但平台会保持一定的完整性。
已经阅读(Is there a way to conduct rolling deployment in fabric files?)并且它不适用于deploy_web
任务的工作方式。
答案 0 :(得分:1)
我的问题的基本答案是这个小助手功能。
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迭代器,它使用〜/ .boto来决定区域并产生一个env.roledefs
,如伪代码所示< / p>
{&#34; {name in instance.tags} _ {instance.tags [name]}&#34;:[匹配的instance.public_dns_name列表}}
另外,对于我当前的webstack,所有实例都有标签,如&#34; group&#34;,&#34; type&#34;,以及可选&#34; lead&#34;用于指定安装crontabs的位置,或执行最终部署脚本。
使用本地任务循环,您需要对execute_serial
稍作修改,特别是env.host_string等于&#34; {env.user} @ 127.0.0.1&#34;这不太理想。
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)