Skip to content

Commit de59418

Browse files
author
Dan
committed
Merged master branch
2 parents 286c9ae + e30ad87 commit de59418

File tree

10 files changed

+113
-122
lines changed

10 files changed

+113
-122
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
language: python
2+
sudo: false
23
python:
34
- 2.6
45
- 2.7
File renamed without changes.

fake_server/fake_server.py renamed to embedded_server/embedded_server.py

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,17 @@
3939
import time
4040
from stub_sftp import StubSFTPServer
4141
from tunnel import Tunneler
42+
import gevent.subprocess
4243

43-
44-
logger = logging.getLogger("fake_server")
44+
logger = logging.getLogger("embedded_server")
4545
paramiko_logger = logging.getLogger('paramiko.transport')
4646

4747
host_key = paramiko.RSAKey(filename = os.path.sep.join([os.path.dirname(__file__), 'rsa.key']))
4848

4949
class Server (paramiko.ServerInterface):
50-
def __init__(self, transport, cmd_req_response = {}, fail_auth=False,
50+
def __init__(self, transport, fail_auth=False,
5151
ssh_exception=False):
5252
self.event = Event()
53-
self.cmd_req_response = cmd_req_response
5453
self.fail_auth = fail_auth
5554
self.ssh_exception = ssh_exception
5655
self.transport = transport
@@ -102,31 +101,18 @@ def check_channel_forward_agent_request(self, channel):
102101

103102
def check_channel_exec_request(self, channel, cmd):
104103
logger.debug("Got exec request on channel %s for cmd %s" % (channel, cmd,))
105-
# Remove any 'bash -c' and/or quotes from command
106-
cmd = cmd.replace('bash -c ', "")
107-
cmd = cmd.replace('\"', "")
108-
cmd = cmd.replace('\'', "")
109-
if not cmd in self.cmd_req_response:
110-
return False
111104
self.event.set()
112-
# Check if response is an iterator in which case we
113-
# do not return but read from iterator and send responses.
114-
# This is to simulate a long running command that has not
115-
# finished executing yet.
116-
if hasattr(self.cmd_req_response[cmd], 'next'):
117-
gevent.spawn(self._long_running_response,
118-
channel, self.cmd_req_response[cmd])
119-
else:
120-
channel.send(self.cmd_req_response[cmd] + os.linesep)
121-
channel.send_exit_status(0)
105+
process = gevent.subprocess.Popen(cmd, stdout=gevent.subprocess.PIPE, shell=True)
106+
gevent.spawn(self._read_response, channel, process)
122107
return True
123108

124-
def _long_running_response(self, channel, responder):
125-
for response in responder:
126-
channel.send(response + os.linesep)
127-
gevent.sleep(0)
128-
channel.send_exit_status(0)
129-
channel.close()
109+
def _read_response(self, channel, process):
110+
for line in process.stdout:
111+
channel.send(line)
112+
process.communicate()
113+
channel.send_exit_status(process.returncode)
114+
logger.debug("Command finished with return code %s", process.returncode)
115+
gevent.sleep(0)
130116

131117
def make_socket(listen_ip, port=0):
132118
"""Make socket on given address and available port chosen by OS"""
@@ -140,12 +126,13 @@ def make_socket(listen_ip, port=0):
140126
return
141127
return sock
142128

143-
def listen(cmd_req_response, sock, fail_auth=False, ssh_exception=False,
129+
def listen(sock, fail_auth=False, ssh_exception=False,
144130
timeout=None):
145-
"""Run a fake ssh server and given a cmd_to_run, send given \
146-
response to client connection. Returns (server, socket) tuple \
147-
where server is a joinable server thread and socket is listening \
148-
socket of server."""
131+
"""Run server and given a cmd_to_run, send given
132+
response to client connection. Returns (server, socket) tuple
133+
where server is a joinable server thread and socket is listening
134+
socket of server.
135+
"""
149136
listen_ip, listen_port = sock.getsockname()
150137
if not sock:
151138
logger.error("Could not establish listening connection on %s:%s", listen_ip, listen_port)
@@ -157,18 +144,18 @@ def listen(cmd_req_response, sock, fail_auth=False, ssh_exception=False,
157144
logger.error('*** Listen failed: %s' % (str(e),))
158145
traceback.print_exc()
159146
return
160-
handle_ssh_connection(cmd_req_response, sock, fail_auth=fail_auth,
147+
handle_ssh_connection(sock, fail_auth=fail_auth,
161148
timeout=timeout, ssh_exception=ssh_exception)
162149

163-
def _handle_ssh_connection(cmd_req_response, transport, fail_auth=False,
150+
def _handle_ssh_connection(transport, fail_auth=False,
164151
ssh_exception=False):
165152
try:
166153
transport.load_server_moduli()
167154
except:
168155
return
169156
transport.add_server_key(host_key)
170157
transport.set_subsystem_handler('sftp', paramiko.SFTPServer, StubSFTPServer)
171-
server = Server(transport, cmd_req_response=cmd_req_response,
158+
server = Server(transport,
172159
fail_auth=fail_auth, ssh_exception=ssh_exception)
173160
try:
174161
transport.start_server(server=server)
@@ -189,7 +176,7 @@ def _handle_ssh_connection(cmd_req_response, transport, fail_auth=False,
189176
gevent.sleep(.2)
190177
channel.close()
191178

192-
def handle_ssh_connection(cmd_req_response, sock,
179+
def handle_ssh_connection(sock,
193180
fail_auth=False, ssh_exception=False,
194181
timeout=None):
195182
conn, addr = sock.accept()
@@ -200,7 +187,7 @@ def handle_ssh_connection(cmd_req_response, sock,
200187
gevent.Timeout(timeout).start()
201188
try:
202189
transport = paramiko.Transport(conn)
203-
_handle_ssh_connection(cmd_req_response, transport, fail_auth=fail_auth,
190+
_handle_ssh_connection(transport, fail_auth=fail_auth,
204191
ssh_exception=ssh_exception)
205192
except Exception, e:
206193
logger.error('*** Caught exception: %s: %s' % (str(e.__class__), str(e),))
@@ -211,16 +198,16 @@ def handle_ssh_connection(cmd_req_response, sock,
211198
pass
212199
return
213200

214-
def start_server(cmd_req_response, sock, fail_auth=False, ssh_exception=False,
201+
def start_server(sock, fail_auth=False, ssh_exception=False,
215202
timeout=None):
216-
return gevent.spawn(listen, cmd_req_response, sock, fail_auth=fail_auth,
203+
return gevent.spawn(listen, sock, fail_auth=fail_auth,
217204
timeout=timeout, ssh_exception=ssh_exception)
218205

219206
if __name__ == "__main__":
220207
logging.basicConfig()
221208
logger.setLevel(logging.DEBUG)
222209
sock = make_socket('127.0.0.1')
223-
server = start_server({'fake' : 'fake response'}, sock)
210+
server = start_server(sock)
224211
try:
225212
server.join()
226213
except KeyboardInterrupt:
File renamed without changes.
File renamed without changes.
File renamed without changes.

fake_server/tunnel.py renamed to embedded_server/tunnel.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ def tunnel(self, dest_socket, source_chan):
4646
logger.debug("Tunnel waiting for data..")
4747
data = source_chan.recv(1024)
4848
dest_socket.sendall(data)
49+
gevent.sleep(.1)
4950
response_data = dest_socket.recv(1024)
5051
source_chan.sendall(response_data)
5152
logger.debug("Tunnel sent data..")
52-
gevent.sleep(1)
53+
gevent.sleep(0)
5354
finally:
5455
source_chan.close()
5556
dest_socket.close()

pssh.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ def exec_command(self, command, sudo=False, user=None, **kwargs):
247247
logger.debug("Running command %s on %s", command, self.host)
248248
channel.exec_command(command, **kwargs)
249249
logger.debug("Command started")
250-
while not (channel.recv_ready() or channel.closed):
250+
while not (channel.recv_ready() or channel.closed or
251+
channel.exit_status_ready()):
251252
gevent.sleep(.2)
252253
return channel, self.host, stdout, stderr
253254

@@ -623,8 +624,8 @@ def get_stdout(self, greenlet, return_buffers=False):
623624
'stdout' : <iterable>,
624625
'stderr' : <iterable>,}}``
625626
"""
626-
warnings.warn("This method is being deprecated and will be removed in \
627-
future releases - use self.get_output instead", DeprecationWarning)
627+
warnings.warn("This method is being deprecated and will be removed in"
628+
"future releases - use self.get_output instead", DeprecationWarning)
628629
gevent.sleep(.2)
629630
channel, host, stdout, stderr = greenlet.get()
630631
if channel.exit_status_ready():

0 commit comments

Comments
 (0)