147
class LoopbackSFTP(object):
148
"""Simple wrapper for a socket that pretends to be a paramiko Channel."""
150
def __init__(self, sock):
153
def send(self, data):
154
return self.__socket.send(data)
157
return self.__socket.recv(n)
159
def recv_ready(self):
163
self.__socket.close()
147
166
SYSTEM_HOSTKEYS = {}
148
167
BZR_HOSTKEYS = {}
209
230
def __del__(self):
210
231
"""Should this warn, or actually try to cleanup?"""
211
232
if self.lock_file:
212
warn("SFTPLock %r not explicitly unlocked" % (self.path,))
233
warning("SFTPLock %r not explicitly unlocked" % (self.path,))
215
236
def unlock(self):
675
695
vendor = _get_ssh_vendor()
696
if vendor == 'loopback':
697
sock = socket.socket()
698
sock.connect((self._host, self._port))
699
self._sftp = SFTPClient(LoopbackSFTP(sock))
700
elif vendor != 'none':
677
701
sock = SFTPSubprocess(self._host, vendor, self._port,
679
703
self._sftp = SFTPClient(sock)
691
715
t = paramiko.Transport((self._host, self._port or 22))
716
t.set_log_channel('bzr.paramiko')
693
718
except paramiko.SSHException, e:
694
719
raise ConnectionError('Unable to reach SSH host %s:%d' %
869
894
s, _ = self._socket.accept()
870
895
# now close the listen socket
871
896
self._socket.close()
872
self._callback(s, self.stop_event)
898
self._callback(s, self.stop_event)
900
pass #Ignore socket errors
902
# probably a failed test
903
warning('Exception from within unit test server thread: %r' % x)
875
906
self.stop_event.set()
876
# We should consider waiting for the other thread
877
# to stop, because otherwise we get spurious
878
# bzr: ERROR: Socket exception: Connection reset by peer (54)
879
# because the test suite finishes before the thread has a chance
880
# to close. (Especially when only running a few tests)
907
# use a timeout here, because if the test fails, the server thread may
908
# never notice the stop_event.
883
912
class SFTPServer(Server):
884
913
"""Common code for SFTP server facilities."""
886
def _get_sftp_url(self, path):
887
"""Calculate a sftp url to this server for path."""
888
return 'sftp://foo:bar@localhost:%d/%s' % (self._listener.port, path)
890
915
def __init__(self):
891
916
self._original_vendor = None
892
917
self._homedir = None
893
918
self._server_homedir = None
894
919
self._listener = None
895
920
self._root = None
921
self._vendor = 'none'
896
922
# sftp server logs
925
def _get_sftp_url(self, path):
926
"""Calculate an sftp url to this server for path."""
927
return 'sftp://foo:bar@localhost:%d/%s' % (self._listener.port, path)
899
929
def log(self, message):
900
"""What to do here? do we need this? Its for the StubServer.."""
930
"""StubServer uses this to log when a new server is created."""
901
931
self.logs.append(message)
903
933
def _run_server(self, s, stop_event):
914
944
ssh_server.start_server(event, server)
916
946
stop_event.wait(30.0)
919
"""See bzrlib.transport.Server.setUp."""
920
# XXX: 20051124 jamesh
921
# The tests currently pop up a password prompt when an external ssh
922
# is used. This forces the use of the paramiko implementation.
923
949
global _ssh_vendor
924
950
self._original_vendor = _ssh_vendor
951
_ssh_vendor = self._vendor
926
952
self._homedir = os.getcwdu()
927
953
if self._server_homedir is None:
928
954
self._server_homedir = self._homedir
939
965
_ssh_vendor = self._original_vendor
942
class SFTPAbsoluteServer(SFTPServer):
968
class SFTPServerWithoutSSH(SFTPServer):
970
Common code for an SFTP server over a clear TCP loopback socket,
971
instead of over an SSH secured socket.
975
super(SFTPServerWithoutSSH, self).__init__()
976
self._vendor = 'loopback'
978
def _run_server(self, sock, stop_event):
979
class FakeChannel(object):
980
def get_transport(self):
982
def get_log_channel(self):
986
def get_hexdump(self):
989
server = paramiko.SFTPServer(FakeChannel(), 'sftp', StubServer(self), StubSFTPServer,
990
root=self._root, home=self._server_homedir)
991
server.start_subsystem('sftp', None, sock)
992
server.finish_subsystem()
995
class SFTPAbsoluteServer(SFTPServerWithoutSSH):
943
996
"""A test server for sftp transports, using absolute urls."""
945
998
def get_url(self):
947
1000
return self._get_sftp_url(urlescape(self._homedir[1:]))
950
class SFTPHomeDirServer(SFTPServer):
1003
class SFTPHomeDirServer(SFTPServerWithoutSSH):
951
1004
"""A test server for sftp transports, using homedir relative urls."""
953
1006
def get_url(self):