mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
Aux console for Docker
Fix https://github.com/GNS3/gns3-gui/issues/1039
This commit is contained in:
4 files changed
+122
-32
No files matched your search
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user