diff --git a/dulwich/contrib/paramiko_vendor.py b/dulwich/contrib/paramiko_vendor.py index db5c6386..541d99b5 100644 --- a/dulwich/contrib/paramiko_vendor.py +++ b/dulwich/contrib/paramiko_vendor.py @@ -1,117 +1,117 @@ # paramiko_vendor.py -- paramiko implementation of the SSHVendor interface # Copyright (C) 2013 Aaron O'Mullan # # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU # General Public License as public by the Free Software Foundation; version 2.0 # or (at your option) any later version. You can redistribute it and/or # modify it under the terms of either of these two licenses. # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # You should have received a copy of the licenses; if not, see # for a copy of the GNU General Public License # and for a copy of the Apache # License, Version 2.0. # """Paramiko SSH support for Dulwich. To use this implementation as the SSH implementation in Dulwich, override the dulwich.client.get_ssh_vendor attribute: >>> from dulwich import client as _mod_client >>> from dulwich.contrib.paramiko_vendor import ParamikoSSHVendor >>> _mod_client.get_ssh_vendor = ParamikoSSHVendor This implementation is experimental and does not have any tests. """ import paramiko import paramiko.client class _ParamikoWrapper(object): def __init__(self, client, channel): self.client = client self.channel = channel # Channel must block self.channel.setblocking(True) @property def stderr(self): - return self.channel.makefile_stderr(mode='rb') + return self.channel.makefile_stderr('rb') def can_read(self): return self.channel.recv_ready() def write(self, data): return self.channel.sendall(data) def read(self, n=None): data = self.channel.recv(n) data_len = len(data) # Closed socket if not data: return b"" # Read more if needed if n and data_len < n: diff_len = n - data_len return data + self.read(diff_len) return data def close(self): self.channel.close() class ParamikoSSHVendor(object): # http://docs.paramiko.org/en/2.4/api/client.html def __init__(self, **kwargs): self.kwargs = kwargs def run_command( self, host, command, username=None, port=None, password=None, pkey=None, key_filename=None, **kwargs ): client = paramiko.SSHClient() connection_kwargs = {"hostname": host} connection_kwargs.update(self.kwargs) if username: connection_kwargs["username"] = username if port: connection_kwargs["port"] = port if password: connection_kwargs["password"] = password if pkey: connection_kwargs["pkey"] = pkey if key_filename: connection_kwargs["key_filename"] = key_filename connection_kwargs.update(kwargs) policy = paramiko.client.MissingHostKeyPolicy() client.set_missing_host_key_policy(policy) client.connect(**connection_kwargs) # Open SSH session channel = client.get_transport().open_session() # Run commands channel.exec_command(command) return _ParamikoWrapper(client, channel)