- start = time()
- self._ssh.connect(node['host'], username=node['username'],
- password=node['password'])
- self.__existing_connections[node_hash] = self._ssh
- logger.trace('connect took {} seconds'.format(time() - start))
-
- def exec_command(self, cmd, timeout=10):
+ try:
+ start = time()
+ pkey = None
+ if u"priv_key" in node:
+ pkey = RSAKey.from_private_key(StringIO(node[u"priv_key"]))
+
+ self._ssh = SSHClient()
+ self._ssh.set_missing_host_key_policy(AutoAddPolicy())
+
+ self._ssh.connect(
+ node[u"host"], username=node[u"username"],
+ password=node.get(u"password"), pkey=pkey,
+ port=node[u"port"]
+ )
+
+ self._ssh.get_transport().set_keepalive(10)
+
+ SSH.__existing_connections[node_hash] = self._ssh
+ logger.debug(
+ f"New SSH to {self._ssh.get_transport().getpeername()} "
+ f"took {time() - start} seconds: {self._ssh}"
+ )
+ except SSHException as exc:
+ raise IOError(f"Cannot connect to {node[u'host']}") from exc
+ except NoValidConnectionsError as err:
+ raise IOError(
+ f"Unable to connect to port {node[u'port']} on "
+ f"{node[u'host']}"
+ ) from err
+
+ def disconnect(self, node=None):
+ """Close SSH connection to the node.
+
+ :param node: The node to disconnect from. None means last connected.
+ :type node: dict or None
+ """
+ if node is None:
+ node = self._node
+ if node is None:
+ return
+ node_hash = self._node_hash(node)
+ if node_hash in SSH.__existing_connections:
+ logger.debug(
+ f"Disconnecting peer: {node[u'host']}, {node[u'port']}"
+ )
+ ssh = SSH.__existing_connections.pop(node_hash)
+ ssh.close()
+
+ def _reconnect(self, attempts=0):
+ """Close the SSH connection and open it again.
+
+ :param attempts: Number of reconnect attempts.
+ :type attempts: int
+ """
+ node = self._node
+ self.disconnect(node)
+ self.connect(node, attempts)
+ logger.debug(
+ f"Reconnecting peer done: {node[u'host']}, {node[u'port']}"
+ )
+
+ def exec_command(self, cmd, timeout=10, log_stdout_err=True):