<pre>Hi,<br><br> Could someone help me understand how to using threading along with paramiko. For some reason only one of two of the threads returns the output correctly. Some of the threads returns an empty string as command output, but no errors are thrown.<br>
<br> My attempt is pasted below.<br><br>regards,<br>Jacob Abraham<br><br>import time
import socket
import sys
from threading import Thread
import os
from paramiko import AutoAddPolicy, SSHClient, SSHException, AuthenticationException
class SSHCollector(Thread):
def __init__(self, hostname, username, password, proto, loggername, zapiport, sshport=22, keepalive=True, tmo=60):
Thread.__init__(self)
self.hostname = hostname
self.username = username
self.password = password
self.keepalive = keepalive
self.tmo = tmo
self._conn = None
self.success = False
self.client = SSHClient()
self.client.load_system_host_keys()
self.client.set_missing_host_key_policy(AutoAddPolicy())
self.client.set_log_channel(loggername)
def _connect(self):
if None is not self.client.get_transport() and self.client.get_transport().is_active():
return
if None is self.username:
self.client.connect(hostname=self.hostname, timeout=self.tmo)
elif None is self.password:
self.client.connect(hostname=self.hostname, username=self.username, password=self.password, timeout=self.tmo)
else:
self.client.connect(hostname=self.hostname, username=self.username, password=self.password, look_for_keys=False, timeout=self.tmo)
trans = self.client.get_transport()
trans.use_compression(True)
trans.set_keepalive(1)
def close(self):
self.client.close()
__del__ = close
def execute(self, lcmd, auto_close=False, tmo=300, read_max=10*1024*1024):
output = r''
err = r''
self._error = ""
read_max = int(read_max/2)
exit_status = False
self._connect()
chan = self.client.get_transport().open_session()
if not self.keepalive:
self.client.get_transport().set_keepalive(0)
chan.settimeout(tmo)
chan.exec_command(lcmd)
stdin = chan.makefile('wb', -1)
stdout = chan.makefile('rb', -1)
stderr = chan.makefile_stderr('rb', -1)
start_time = time.time()
while True:
if stderr.channel.recv_stderr_ready():
ret = stderr.read()
if ret:
err += ret
if stdout.channel.recv_ready():
try:
ret = stdout.read(read_max)
if ret:
output += ret
except socket.timeout:
pass
exit_status = chan.exit_status_ready()
if exit_status or ((int(start_time) + tmo) < int(time.time())):
timeout = False
if exit_status:
exit_status = str(stderr.channel.recv_exit_status())
else:
self.signal(chan, 'KILL')
exit_status = str(stderr.channel.recv_exit_status())
timeout = True
if stdin:
stdin.channel.shutdown_write()
stdin.close()
if stdout.channel.recv_ready():
ret = stdout.read(read_max)
if ret:
output += ret
stdout.close()
if stderr.channel.recv_stderr_ready():
ret = stderr.read()
if ret:
err += ret
err += "exit_status("+str(exit_status)+") to("+str(timeout)+")"
stderr.close()
break
self.success = True
if auto_close:
self.client.close()
return (output, err)
def setCommand(self, cmd):
self.cmd = cmd
def runcmd(self, cmd):
return self.execute(cmd, auto_close=True)
def run(self):
self.resultset = self.runcmd(self.cmd)
if __name__ == '__main__':
cmd = 'date'
threads = []
a = time.time()
for i in range(3):
collector = SSHCollector('11.11.111.111', 'dummyusername', 'dummypassword', \
'auto', 'dummylogger', None)
collector.setCommand(cmd)
threads.append(collector)
for i in threads:
i.start()
for i in threads:
i.join()
for i in threads:
print i.resultset
b=time.time()
print b-a
</pre>