首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Fabric - Sequential元任务?

Fabric - Sequential元任务?
EN

Stack Overflow用户
提问于 2013-05-18 04:41:13
回答 1查看 278关注 0票数 2

我有一个执行任务的任务-

代码语言:javascript
运行
复制
@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内部的循环中使用hosts=[current_host]调用每个execute

我的目标是,如果这是一个糟糕的部署,它只会破坏一个服务器池中的一个,这样负载均衡器就会把它踢出去,但平台会保持一些表面上的完整性。

已读( Is there a way to conduct rolling deployment in fabric files? ),它不适用于我的deploy_web任务的工作方式。

EN

回答 1

Stack Overflow用户

发布于 2013-05-26 09:03:21

对于我的问题,最基本的答案就是这个小帮手函数。

代码语言:javascript
运行
复制
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)

用法是这样的

代码语言:javascript
运行
复制
@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(),但是钩子(在开始之前、完成所有任务、出错等等)都没有简单的机会,所以一个额外的解决方案可能是

代码语言:javascript
运行
复制
@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迭代器,它使用to ~/.boto来决定区域并生成一个env.roledefs,如伪代码所示

{“{ instance.tags中的名称}_{instance.tagsname}":匹配的instance.public_dns_name列表}

此外,对于我目前的webstack,所有实例都有"group“、"type”和可选的"lead“等标签,用于指定安装crontab或执行最终部署脚本的位置。

使用本地任务循环,您需要对execute_serial进行一些细微的修改,特别是env.host_string将等于"{env.user}@127.0.0.1“,这并不理想。

代码语言:javascript
运行
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16617552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档