私はSSH接続にparamikoを使用するテストケースを探しています。テストケースには、通常、paramiko.exec_command()
コールが含まれています(これはrun_command()
と呼ばれます)。ここでself.ssh
は、paramiko.SSHClient()
のintanceです。私はデコレータを使用して、各呼び出しの前にssh接続を確認します。それは時々起こることが私のリモートノードが再起動するまで、完璧に動作paramiko SSHチャネルが切断されているかどうかを知る方法?
def check_connections(function):
''' A decorator to check SSH connections. '''
def deco(self, *args, **kwargs):
if self.ssh is None:
self.ssh = self.get_ssh()
else:
ret = getattr(self.ssh.get_transport(), 'is_active', None)
if ret is None or (ret is not None and not ret()):
self.ssh = self.get_ssh()
return function(self, *args, **kwargs)
return deco
@check_connections
def run_command(self, command):
''' Executes command via SSH. '''
stdin, stdout, stderr = self.ssh.exec_command(command)
stdin.flush()
stdin.channel.shutdown_write()
ret = stdout.read()
err = stderr.read()
if ret:
return ret
elif err:
return err
else:
return None
(self.get_ssh()
は、接続をネゴシエート)。それが発生すると、次のrun_command()
コールはsocket.error
例外を生成します。問題はparamiko.Transport
オブジェクトは例外がスローされるまでアクティブな状態のままにしているように見えることを、次のとおりです。
Python 2.7.3 (default, Mar 7 2013, 14:03:36)
[GCC 4.3.4 [gcc-4_3-branch revision 152973]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> print ssh
<paramiko.SSHClient object at 0x7f2397b96d50>
>>> print ssh.get_transport()
None
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.load_host_keys(os.path.expanduser('~') + '/.ssh/known_hosts')
>>> ssh.connect(hostname = '172.31.77.57', username = 'root', password = 'rootroot', timeout = 5.0)
>>> print ssh
<paramiko.SSHClient object at 0x7f2397b96d50>
>>> print ssh.get_transport()
<paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>
>>> print ssh.get_transport().is_active()
True
>>> ssh.exec_command('ls')
(<paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>)
>>> print ssh
<paramiko.SSHClient object at 0x7f2397b96d50>
>>> print ssh.get_transport()
<paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>
>>> print ssh.get_transport().is_active()
True
>>> ssh.exec_command('reboot')
(<paramiko.ChannelFile from <paramiko.Channel 2 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 2 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>, <paramiko.ChannelFile from <paramiko.Channel 2 (open) window=2097152 -> <paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>)
>>> print ssh
<paramiko.SSHClient object at 0x7f2397b96d50>
>>> print ssh.get_transport()
<paramiko.Transport at 0x97537550L (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>
>>> print ssh.get_transport().is_active()
True
>>> ssh.exec_command('ls')
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/pytest/lib/python2.7/site-packages/paramiko/client.py", line 370, in exec_command
chan = self._transport.open_session()
File "/home/pytest/lib/python2.7/site-packages/paramiko/transport.py", line 662, in open_session
return self.open_channel('session')
File "/home/pytest/lib/python2.7/site-packages/paramiko/transport.py", line 764, in open_channel
raise e
socket.error: [Errno 104] Connection reset by peer
>>> print ssh
<paramiko.SSHClient object at 0x7f2397b96d50>
>>> print ssh.get_transport()
<paramiko.Transport at 0x97537550L (unconnected)>
>>> print ssh.get_transport().is_active()
False
>>>
質問:どのように私は、接続が本当に有効かそうでないことを確認することができますか?
+1それは私のための解決策よりもむしろ回避策です...私はparamikoが必要なものを欠いていると思います... – Milo
@milo - あなたはParamikoにもっと良い解決策を見つけましたか?私はあなたとまったく同じ位置にいます。 –
いいえ、私は最近それについての研究を行っていません。私はそれがこのように行われなければならないと思います。 (返事が遅いのは申し訳ありません) – Milo