web-dev-qa-db-ja.com

ファブリックがエラーを受け取ったときにタスクを続行する方法

複数のリモートサーバーで実行するタスクを定義すると、タスクがサーバー1で実行され、エラーで終了した場合、Fabricはタスクを停止して中止します。ただし、ファブリックでエラーを無視し、次のサーバーでタスクを実行したいと思います。どうすればこれを行うことができますか?

例えば:

$ fab site1_service_gw
[site1rpt1] Executing task 'site1_service_gw'

[site1fep1] run: echo 'Nm123!@#' | Sudo -S route
[site1fep1] err:
[site1fep1] err: We trust you have received the usual lecture from the local System
[site1fep1] err: Administrator. It usually boils down to these three things:
[site1fep1] err:
[site1fep1] err:     #1) Respect the privacy of others.
[site1fep1] err:     #2) Think before you type.
[site1fep1] err:     #3) With great power comes great responsibility.
[site1fep1] err: root's password:
[site1fep1] err: Sudo: route: command not found

Fatal error: run() encountered an error (return code 1) while executing 'echo 'Nm123!@#' | Sudo -S route '

Aborting.
92
Mingo

ドキュメント から:

...ファブリックはデフォルトで「フェイルファスト」動作パターンになっています。ゼロ以外の戻り値を返すリモートプログラムや、fabfileのPythonコードが例外に遭遇したなど)すぐに停止します。

これは通常、望ましい動作ですが、ルールには多くの例外があるため、Fabricはブール設定であるenv.warn_onlyを提供します。デフォルトはFalseで、エラー状態が発生するとプログラムが即座に中止されます。ただし、障害発生時にenv.warn_onlyがTrueに設定されている場合(設定コンテキストマネージャーなどを使用)、Fabricは警告メッセージを出力しますが、実行を継続します。

settings context manager を使用して、エラーが無視される場所をきめ細かく制御できるように見えます。

from fabric.api import settings

Sudo('mkdir tmp') # can't fail
with settings(warn_only=True):
    Sudo('touch tmp/test') # can fail
Sudo('rm tmp') # can't fail
144
Will McCutchen

Fabric 1.5では、これを簡単にするContextManagerがあります:

from fabric.api import Sudo, warn_only

with warn_only():
    Sudo('mkdir foo')

更新:次のコードを使用して、これがipythonで機能することを再確認しました。

from fabric.api import local, warn_only

#aborted with SystemExit after 'bad command'
local('bad command'); local('bad command 2')

#executes both commands, printing errors for each
with warn_only():
    local('bad command'); local('bad command 2')
30
Chris Marinos

スクリプト全体のwarn_only設定をtrueに設定することもできます。

def local():
    env.warn_only = True
13
Rawkcy

abort_exception環境変数を設定して、例外をキャッチする必要があります。

例えば:

from fabric.api        import env
from fabric.operations import Sudo

class FabricException(Exception):
    pass

env.abort_exception = FabricException
# ... set up the rest of the environment...

try:
    Sudo('reboot')
except FabricException:
    pass  # This is expected, we can continue.

Withブロックで設定することもできます。ドキュメントを参照してください here

10
ArtOfWarfare

少なくともFabric 1.3.2では、SystemExit例外をキャッチすることで例外を回復できます。バッチで実行する複数のコマンド(デプロイなど)があり、そのうちの1つが失敗した場合にクリーンアップする場合に役立ちます。

7
zimbatm

Fabric 2.xでは、invokerunwarn = True引数。とにかく、invokeFabric 2.xの依存関係です:

from invoke import run
run('bad command', warn=True)

タスク内から:

from invoke import task

@task
def my_task(c):
    c.run('bad command', warn=True)
7
Qlimax