Aux console for Docker

Fix https://github.com/GNS3/gns3-gui/issues/1039
This commit is contained in:
Julien Duponchelle committed 2016-03-01 14:53:43 +01:00
1 parent 03ffce0a75
commit dab1b26569
4 files changed
+122 -32

No files matched your search

+57 -12
View File
@@ -58,7 +58,7 @@ READ_SIZE = 1024
class AsyncioTelnetServer:
def __init__(self, reader=None, writer=None):
def __init__(self, reader=None, writer=None, binary=True, echo=False):
self._reader = reader
self._writer = writer
self._clients = set()
@@ -66,6 +66,12 @@ class AsyncioTelnetServer:
self._reader_process = None
self._current_read = None
self._binary = binary
# If echo is true when the client send data
# the data is echo on his terminal by telnet otherwise
# it's our job (or the wrapped app) to send back the data
self._echo = echo
@asyncio.coroutine
def run(self, network_reader, network_writer):
# Keep track of connected clients
@@ -73,10 +79,24 @@ class AsyncioTelnetServer:
try:
# Send initial telnet session opening
network_writer.write(bytes([IAC, WILL, ECHO,
IAC, WILL, SGA,
IAC, WILL, BINARY,
IAC, DO, BINARY]))
if self._echo:
network_writer.write(bytes([IAC, WILL, ECHO]))
else:
network_writer.write(bytes([
IAC, WONT, ECHO,
IAC, DONT, ECHO]))
if self._binary:
network_writer.write(bytes([
IAC, WILL, SGA,
IAC, WILL, BINARY,
IAC, DO, BINARY]))
else:
network_writer.write(bytes([
IAC, WONT, SGA,
IAC, DONT, SGA,
IAC, WONT, BINARY,
IAC, DONT, BINARY]))
yield from network_writer.drain()
yield from self._process(network_reader, network_writer)
@@ -128,7 +148,6 @@ class AsyncioTelnetServer:
return_when=asyncio.FIRST_COMPLETED)
for coro in done:
data = coro.result()
# Console is closed
if len(data) == 0:
raise ConnectionResetError()
@@ -138,11 +157,18 @@ class AsyncioTelnetServer:
if IAC in data:
data = yield from self._IAC_parser(data, network_reader, network_writer)
if len(data) == 0:
continue
if not self._binary:
data = data.replace(b"\r\n", b"\n")
if self._writer:
self._writer.write(data)
yield from self._writer.drain()
elif coro == reader_read:
reader_read = yield from self._get_reader(network_reader)
# Replicate the output on all clients
for writer in self._clients:
writer.write(data)
@@ -199,9 +225,27 @@ class AsyncioTelnetServer:
buf.extend(d)
iac_cmd.append(buf[iac_loc + 2])
# We do ECHO, SGA, and BINARY. Period.
if iac_cmd[1] == DO and iac_cmd[2] not in [ECHO, SGA, BINARY]:
network_writer.write(bytes([IAC, WONT, iac_cmd[2]]))
log.debug("Telnet WON'T {:#x}".format(iac_cmd[2]))
if iac_cmd[1] == DO:
if iac_cmd[2] not in [ECHO, SGA, BINARY]:
network_writer.write(bytes([IAC, WONT, iac_cmd[2]]))
log.debug("Telnet WON'T {:#x}".format(iac_cmd[2]))
else:
if iac_cmd[2] == SGA:
if self._binary:
network_writer.write(bytes([IAC, WILL, iac_cmd[2]]))
else:
network_writer.write(bytes([IAC, WONT, iac_cmd[2]]))
log.debug("Telnet WON'T {:#x}".format(iac_cmd[2]))
elif iac_cmd[1] == DONT:
log.debug("Unhandled DONT telnet command: "
"{0:#x} {1:#x} {2:#x}".format(*iac_cmd))
elif iac_cmd[1] == WILL:
log.debug("Unhandled WILL telnet command: "
"{0:#x} {1:#x} {2:#x}".format(*iac_cmd))
elif iac_cmd[1] == WONT:
log.debug("Unhandled WONT telnet command: "
"{0:#x} {1:#x} {2:#x}".format(*iac_cmd))
else:
log.debug("Unhandled telnet command: "
"{0:#x} {1:#x} {2:#x}".format(*iac_cmd))
@@ -215,15 +259,16 @@ class AsyncioTelnetServer:
return buf
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
loop = asyncio.get_event_loop()
process = loop.run_until_complete(asyncio.async(asyncio.subprocess.create_subprocess_exec("bash",
process = loop.run_until_complete(asyncio.async(asyncio.subprocess.create_subprocess_exec("/bin/sh", "-i",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
stdin=asyncio.subprocess.PIPE)))
server = AsyncioTelnetServer(reader=process.stdout, writer=process.stdin)
server = AsyncioTelnetServer(reader=process.stdout, writer=process.stdin, binary=False, echo=False)
coro = asyncio.start_server(server.run, '127.0.0.1', 2222, loop=loop)
coro = asyncio.start_server(server.run, '127.0.0.1', 4444, loop=loop)
s = loop.run_until_complete(coro)
try: