2017-05-07 194 views
0

我正在用kivy編寫一個python用戶界面來管理一些具有結構的遠程機器。由於我無法在Windows 10上使用光纖並行實現(請參閱here),我一直希望使用parallel-ssh實際執行並行遠程操作。這個問題似乎是由這些庫之間的交互引起的,而不是其中任何一個問題。一般SSH錯誤 - 讀取SSH協議標題時出錯

我已經試過手動加載我的私有密鑰的建議here

from fabric.api import execute 
import pssh 
from pssh.utils import load_private_key 

hosts = ['192.168.0.2'] 
private_key = load_private_key('C:/Users/democracy/.ssh/id_rsa') 
pssh_client = pssh.ParallelSSHClient(hosts, user='XXX', password='YYY', pkey=private_key) 
output = pssh_client.run_command('whoami', sudo=True) 
pssh_client.join(output) 
for host in output: 
    for line in output[host]['stdout']: 
     print("Host %s - output: %s" % (host, line)) 

上面的代碼導致以下回溯:

Exception: Error reading SSH protocol banner('This operation would block forever', <Hub at 0x242566ab9c8 select pending=0 ref=0>) 
Traceback (most recent call last): 
    File "C:\environments\democracy\lib\site-packages\paramiko\transport.py", line 1884, in _check_banner 
buf = self.packetizer.readline(timeout) 
    File "C:\environments\democracy\lib\site-packages\paramiko\packet.py", line 331, in readline 
buf += self._read_timeout(timeout) 
    File "C:\environments\democracy\lib\site-packages\paramiko\packet.py", line 485, in _read_timeout 
x = self.__socket.recv(128) 
    File "C:\environments\democracy\lib\site-packages\gevent\_socket3.py", line 317, in recv 
self._wait(self._read_event) 
    File "C:\environments\democracy\lib\site-packages\gevent\_socket3.py", line 144, in _wait 
self.hub.wait(watcher) 
    File "C:\environments\democracy\lib\site-packages\gevent\hub.py", line 630, in wait 
result = waiter.get() 
    File "C:\environments\democracy\lib\site-packages\gevent\hub.py", line 878, in get 
return self.hub.switch() 
    File "C:\environments\democracy\lib\site-packages\gevent\hub.py", line 609, in switch 
return greenlet.switch(self) 
gevent.hub.LoopExit: ('This operation would block forever', <Hub at 0x242566ab9c8 select pending=0 ref=0>) 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "C:\environments\democracy\lib\site-packages\paramiko\transport.py", line 1740, in run 
self._check_banner() 
    File "C:\environments\democracy\lib\site-packages\paramiko\transport.py", line 1888, in _check_banner 
raise SSHException('Error reading SSH protocol banner' + str(e)) 
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner('This operation would block forever', <Hub at 0x242566ab9c8 select pending=0 ref=0>) 

General SSH error - Error reading SSH protocol banner('This operation would block forever', <Hub at 0x242566ab9c8 select pending=0 ref=0>) 

上面的代碼工作,如果我之前面料進口PSSH 。不幸的是,看起來如果我這樣做,我的kivy界面上的任何按鈕(在後臺線程中啓動任何操作)都將永久屏蔽。如果我在按下按鈕併發送鍵盤中斷後進入控制檯,kivy會停止攔截並開始清理,但在退出前按下按鈕執行命令。在發送該中斷的堆棧跟蹤低於:

[INFO ] [Base  ] Leaving application in progress... 
Traceback (most recent call last): 
    File "machine_control_ui.py", line 7, in <module> 
DemocracyControllerApp().run() 
    File "C:\environments\democracy\lib\site-packages\kivy\app.py", line 828, in run 
runTouchApp() 
    File "C:\environments\democracy\lib\site-packages\kivy\base.py", line 504, in runTouchApp 
EventLoop.window.mainloop() 
    File "C:\environments\democracy\lib\site-packages\kivy\core\window\window_sdl2.py", line 659, in mainloop 
self._mainloop() 
    File "C:\environments\democracy\lib\site-packages\kivy\core\window\window_sdl2.py", line 405, in _mainloop 
EventLoop.idle() 
    File "C:\environments\democracy\lib\site-packages\kivy\base.py", line 339, in idle 
Clock.tick() 
    File "C:\environments\democracy\lib\site-packages\kivy\clock.py", line 553, in tick 
current = self.idle() 
    File "C:\environments\democracy\lib\site-packages\kivy\clock.py", line 533, in idle 
usleep(1000000 * sleeptime) 
    File "C:\environments\democracy\lib\site-packages\kivy\clock.py", line 717, in usleep 
_usleep(microseconds, self._sleep_obj) 
    File "C:\environments\democracy\lib\site-packages\kivy\clock.py", line 395, in _usleep 
_kernel32.WaitForSingleObject(obj, 0xffffffff) 
KeyboardInterrupt 

*** BUTTON PRESS OPERATION OUTPUTS HERE *** 

```

任何深入瞭解爲什麼這可能發生,我怎麼能避免它,將不勝感激。我可能會研究其他並行的ssh解決方案(儘管我想象使用paramiko的任何東西都會有相同的問題),或者手動啓動每個主機的線程以實現並行操作(可能有其自己的頭痛列表),但是,如果有可行的解決方案,我寧願只使用parallel-ssh庫。

我使用的是平行SSH 0.92.2關於Python 3和Windows 10

回答

1

docs -

平行SSH使用GEVENT的猴子補丁,使Python標準的異步使用 庫的網絡I/O。

確保ParallelSSH導入位於 代碼的任何其他導入之前。否則,在加載標準的 庫之前,可能無法進行修補,這會導致ParallelSSH阻塞。

如果您看到類似此操作的消息將永遠阻止, 這是原因。

猴修補是僅在pssh.pssh_client 和pssh.ssh_client分別做了客戶端的並行和單臺主機的客戶。

新機庫基於下pssh.pssh2_client和 pssh.ssh2_client客戶不執行猴子打補丁,如果 猴子修補是不適用,有一個選項。這些客戶端將在未來的主要版本 - 2.0.0中成爲默認的 。

由於猴子補丁用於您正在使用的客戶端,則threadingsocket的其他用途等模塊在應用程序中也已修補使用GEVENT這意味着他們不再在本地線程,但在運行一個聯合程序/ greenlet。

這就是你的後臺線程操作阻塞的原因,因爲它們在同一個線程而不是新線程的greenlet中運行。

截至1.2.0,基於libssh2代替的paramiko一個新的客戶端可用不使用猴子補丁:

您的應用程序則可以使用標準庫作爲-是
from pssh.pssh2_client import ParallelSSHClient 

<..> 

休息。