5

paramiko python モジュール (1.7.7.1) を使用して、リモート サーバーのグループに対してコマンドや xfer ファイルを並行して実行しようとしています。1 つのタスクは次のようになります。

jobs = []   
for obj in appObjs:
    if obj.stop_app:
        p = multiprocessing.Process(target=exec_cmd, args=(obj, obj.stop_cmd))
        jobs.append(p)
        print "Starting job %s" % (p)
        p.start()

「obj」には、とりわけ、paramiko SSHClient、トランスポート、および SFTPClient が含まれています。appObjs リストには、これらのオブジェクトが約 25 個含まれているため、25 の異なるサーバーへの 25 の接続が含まれています。

バックトレースでparamikoのtransport.pyで以下のエラーが出ます

raise AssertionError("PID check failed. RNG must be re-initialized after fork(). 
Hint:   Try Random.atfork()")

https://github.com/newsapps/beeswithmachineguns/issues/17の投稿に基づいて /usr/lib/python2.6/site-packages/paramiko/transport.py にパッチを適用しましたが、効果がないようです。上記のパスの transport.py が使用されていることを確認しました。paramiko メーリング リストが消えたようです。

これは paramiko の問題のように見えますか、それとも multiprocessing モジュールを誤解/誤用していますか? 実用的な回避策を提案してくれる人はいますか? どうもありがとう、

4

2 に答える 2

1

Paramiko の問題内の 1 つのコメントが言及しているように、RNG エラーは、プロセスごとに 1 つの個別の ssh ハンドルを開くことで回避できます。その後、paramiko はもう文句を言いません。このサンプル スクリプトは、これを示しています (プロセスの代わりにプールを使用しています)。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import ssh
from multiprocessing import Pool
import getpass

hostnames = [HOST1, HOST2]
user = USERNAME
pw = getpass.getpass("Enter ssh password:")

def processFunc(hostname):
    handle = ssh.SSHClient()
    handle.set_missing_host_key_policy(ssh.AutoAddPolicy())
    handle.connect(hostname, username=user, password=pw)
    print("child")
    stdin, stdout, stderr = handle.exec_command("ls -l /var/log; sleep 5")
    cmdOutput = ""
    while True:
        try:
            cmdOutput += stdout.next()
        except StopIteration:
            break
    print("Got output from host %s:%s" % (hostname, cmdOutput))
    handle.close()

pool = Pool(len(hostnames))
pool.map(processFunc, hostnames, 1)
pool.close()
pool.join()

## If you want to compare speed:
# for hostname in hostnames:
#     processFunc(hostname)
于 2012-05-07T12:43:46.717 に答える