Почему paramiko дает ложные результаты при использовании с многопоточностью? - PullRequest
0 голосов
/ 09 июля 2020

Я пробую S SH для хостов (количество в сотнях), используя paramiko с многопоточностью.

Вот мой код с многопоточностью,

import paramiko
from concurrent.futures import ThreadPoolExecutor

# Initialising paramiko SSH Client
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Fetching hosts
file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]

def ssh(host):
    try:
        print("Connecting to", host)
        client.connect(host,
                       username="SOMEUSER",
                       password="SOMEPASS",
                       timeout=1,
                       banner_timeout=1,
                       auth_timeout=1)
        print("Connected to", host)
        # Need to check something here...
        client.close()
        print(f"Connection to {host} closed.")
        return True
    except:
        print("FAILED to connect", host)
        return False

with ThreadPoolExecutor(max_workers=4) as executor:
    results = list(executor.map(ssh, hosts))

for i, host in enumerate(hosts):
    print(host, "=>", results[i])

Q1: I получаю ложные результаты по сравнению с кодом без многопоточности. Что здесь не так с моей многопоточностью и как я могу это сделать?

Q2: Каким-то образом возникает исключение ниже (несколько раз), и я понятия не имею, как это исключение не поймали?

Exception: Error reading SSH protocol banner
Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
    buf = self.packetizer.readline(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
    buf += self._read_timeout(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 619, in _read_timeout
    raise EOFError()
EOFError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
    self._check_banner()
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2216, in _check_banner
    "Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

1 Ответ

1 голос
/ 10 июля 2020

Перемещение инициализации Paramiko S SH Client внутри определения функции помогло мне! Теперь код работает правильно по сравнению с кодом без многопоточности.

Вот мой код после исправления проблемы

import paramiko
from concurrent.futures import ThreadPoolExecutor

file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]

def ssh(host):
    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        print("Connecting to", host)
        client.connect(host,
                       username="SOMEUSER",
                       password="SOMEPASS",
                       timeout=1,
                       banner_timeout=1,
                       auth_timeout=1)
        print("Connected to", host)
        # Need to check something here...
        client.close()
        print(f"Connection to {host} closed.")
        return True
    except:
        print("FAILED to connect", host)
        return False

with ThreadPoolExecutor(max_workers=4) as executor:
    output = list(executor.map(ssh, hosts))

for i, host in enumerate(hosts):
    print(host, "=>", output[i])

Несмотря на то, что теперь код работает так, как я предполагал, ниже исключение не ловится!

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
    buf = self.packetizer.readline(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
    buf += self._read_timeout(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 607, in _read_timeout
    x = self.__socket.recv(128)
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
    self._check_banner()
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2216, in _check_banner
    "Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[Errno 104] Connection reset by peer
...