2

タスクを実行するタスクがあります -

@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_webexecutehosts=[current_host]

私が目指しているのは、展開が悪い場合、サーバーのプールの1つだけをノックアウトして、ロードバランサーがそれを追い出すが、プラットフォームは整合性を維持することです.

既に読んでいます (ファブリック ファイルでローリング展開を行う方法はありますか? )、それは私のdeploy_webタスクの仕組みには当てはまりません。

4

1 に答える 1

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 を使用して領域を決定し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)
于 2013-05-26T01:03:20.790 に答える