web-dev-qa-db-ja.com

SSHの可用性をテストするエレガントな方法

Pythonプログラムを使用して、リモートサーバーをポーリングしてSSH接続を確認し、利用可能になったときに通知します。現在、paramikoを使用してこれを行っています。失敗した場合は接続を試み、待機してください。成功または最大再試行まで再試行します。これは機能しますが、少し不格好です。また、paramikoは接続するか、エラーをスローするようです。そのため、これを行うために確認できる唯一の方法は、try/exceptブロックを使用することでした。悪い方法です。

def check_ssh(self, ip, user, key_file, initial_wait=0, interval=0, retries=1):
    ssh = paramiko.SSHClient()
    ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())

    sleep(initial_wait)

    for x in range(retries):
        try:
            ssh.connect(ip, username=user, key_filename=key_file)
            return True
        except Exception, e:
            print e
            sleep(interval)
    return False

これよりもエレガントな解決策があるはずです。 Paramikoは私の選択したSSHライブラリですが、ここでの提案にオープンです。

明確にするために、コード実行の通常のフローを制御する手段としてtry/exceptを使用しないようにします。これは、不正なホストキー、無効なユーザーなどの実際のエラーをキャッチするために使用する必要があります。

15
nightowl

Frbのコメントで述べたように、try ... exceptブロックは、特定のサービスの可用性をテストするための優れたアプローチです。ただし、「catch-all」_exceptブロックは使用しないでください。ただし、サービスが利用できない場合に発生する特定の例外に限定してください。

ドキュメントによると、 paramiko.SSHClient.connect は、接続中に発生した問題に応じて、異なる例外をスローする場合があります。これらすべてをキャッチしたい場合は、try ... exceptブロックは次のようになります。

try:
    ssh.connect(ip, username=user, key_filename=key_file)
    return True
except (BadHostKeyException, AuthenticationException, 
        SSHException, socket.error) as e:
    print e
    sleep(interval)

これらの例外のサブセットのみがケースに関連している場合は、exceptの後にタプルの例外のみを入れてください。

20
silvado