Fabric: 部分的な失敗時にThreadingGroupの結果を読み取る方法は?

作成日 2018年05月14日  ·  5コメント  ·  ソース: fabric/fabric

その例をドキュメントにも含めるとよいでしょう。 私がこのコードを持っているとしましょう。

from fabric import ThreadingGroup as Group
from fabric.exceptions import GroupException

hosts = ['web1', 'web2', 'web3']
g = Group(*hosts)

try:
    results = g.run('date', hide='both')
except GroupException as e:
    print e.args # I read from code that arguments are passed to exception but I'm unable to use that. `args` argument in my case is an empty tuple. 

web2が接続に失敗したときにweb1とweb3が成功したか、コマンドがゼロ以外の終了コードで返されたと仮定します。

  • 例外が発生した後、これらの詳細を取得するにはどうすればよいですか?
  • すべての操作が完了した後にのみ例外が発生することが保証されていますか?

どんな助けでも大歓迎です。

最も参考になるコメント

こんにちは、

shadyabhiのコメントに加えて、GroupExceptionを処理するために使用する方法を次に示します。
これがお役に立てば幸いです!!

import logging, socket, paramiko.ssh_exception
from fabric import Connection, Config, ThreadingGroup, exceptions, runners

...

g = ThreadingGroup.from_connections(c)
try:
    result = g.run('hostname' )  # (just a basic command)
except exceptions.GroupException as e:
    i = 0
    for c, r in e.result.items():
        print("Host[{}] = [{}]".format(i,c.host) )
        if isinstance(r,runners.Result) :
            print("ok, fine")
        elif isinstance(r,socket.gaierror) :
            print("Network error")
        elif isinstance(r,paramiko.ssh_exception.AuthenticationException) :
            print("Auth failed")
        else:
            print("something else")
        i+=1



ActivCloudサポートから取得した場合)

全てのコメント5件

ねえ@shadyabhi

特定の例外をキャッチしようとしているのか、それとも別々のスレッドで発生しているすべての例外をキャッチしたいだけなのかわからない。 ThreadingGroupオブジェクトは、すでにキューを使用して例外オブジェクトを渡し、実行中に発生した場合は発生すると思います。 次のコードスニペットを使用して、スタックトレースを確認できました。

def run_data(c):
    c.run('date', hide='both')

<strong i="8">@task</strong>
def thread_exception_example(c):
    hosts = ['localhost', 'fakehost', 'localhost']

    # python list comprehension
    {c: run_data(c) for c in Group(*hosts)}

私が実行したコマンドラインで: fab thread-exception-example

こんにちは@bossjones

返信ありがとうございます。 ただし、私はfabコマンドを使用していませんが、ファブリックをライブラリとして使用してこれらすべてを実行しています。 したがって、回答はまだ保留中であり、いただければ幸いです。

つまり、 fabは、自分のコードで処理したいものを自分で処理しています。 タスクの呼び出し方法をより柔軟にしたいので、 fabコマンドを直接使用したくない理由があります。

ありがとう

皆さんこんにちは、

申し訳ありませんが、詳細を見落としました。 ファブリックコードをチェックして、詳細を入手しました。

GroupExceptionの引数は、キーがfabric.connection.Connectionオブジェクトで、値がfabric.runners.Resultオブジェクトの辞書です。

except GroupException as e:
         for c, r in e.result.items():
             print "Connection: {}, Result: {}".format(c, r)

こんにちは、

shadyabhiのコメントに加えて、GroupExceptionを処理するために使用する方法を次に示します。
これがお役に立てば幸いです!!

import logging, socket, paramiko.ssh_exception
from fabric import Connection, Config, ThreadingGroup, exceptions, runners

...

g = ThreadingGroup.from_connections(c)
try:
    result = g.run('hostname' )  # (just a basic command)
except exceptions.GroupException as e:
    i = 0
    for c, r in e.result.items():
        print("Host[{}] = [{}]".format(i,c.host) )
        if isinstance(r,runners.Result) :
            print("ok, fine")
        elif isinstance(r,socket.gaierror) :
            print("Network error")
        elif isinstance(r,paramiko.ssh_exception.AuthenticationException) :
            print("Auth failed")
        else:
            print("something else")
        i+=1



ActivCloudサポートから取得した場合)

あなたの例をありがとう@akiuni ! 私はPython / Fabricを初めて使用するので、ThreadedGroupを使用してリクエストを行う方法を理解し、例外が発生したときに結果を収集するのに役立ちました。 これがあなたの例の私の拡張バージョンです。 とても有難い! 価値があるので、私はこれをStackoverflowにも投稿しました。

# requires fabric 2.x - run 'pip install fabric' to install it
import logging, socket, paramiko.ssh_exception
from fabric import Connection, Config, SerialGroup, ThreadingGroup, exceptions, runners
from fabric.exceptions import GroupException


# Note: You need to supply your own valid servers here to ssh to of course!
def main():
    testHosts("All should succeed", "validServer1,validServer2,validServer3")
    testHosts("Some should fail", "validServer1,validServer2,BADSERVER1,validServer3,BADSERVER2")

def testHosts(message, hostsAsString):
    print("")
    print(message)

    # Get list of hosts from somewhere, and convert them to connections
    hosts = hostsAsString.split(",")
    servers = [Connection(host=host) for host in hosts]

    # Create a thread group to run requests in parallel
    g = ThreadingGroup.from_connections(servers)
    try:
        command = "df -h / | tail -n1 | awk '{print $5}'"
        results = g.run(command, hide=True)
        for r in results:
            connection = results[r]
            print("{}".format(r.host) )
            print("  SUCCESS, " + connection.stdout.strip())
    except GroupException as e:
        # If an exception occurred, at least one request failed. 
        # Iterate through results here
        for c, r in e.result.items():
            print("{}".format(c.host) )
            if isinstance(r,runners.Result) :
                print("  SUCCESS, " + r.stdout.strip())
            elif isinstance(r,socket.gaierror) :
                print("  FAILED,  Network error")
            elif isinstance(r,paramiko.ssh_exception.AuthenticationException) :
                print("  FAILED,  Auth failed")
            else:
                print("  FAILED,  Something other reason")

main()

このページは役に立ちましたか?
0 / 5 - 0 評価