Loading cccli/commands/console.py +1 −55 Original line number Diff line number Diff line Loading @@ -7,66 +7,12 @@ CloudControl Console related commands from cccli.command import TqlCommand from cccli.exception import * from cccli.printer import FakeTtySocket from sjrpc.core.exceptions import * import fcntl import os import signal import struct import sys import termios import tty class FakeTtySocket(object): ''' Give a tty a socket interface This object cannot handle sigwinch directly because close can be called by remote RPC and by the way, called outside the main thread and fail. ''' def __init__(self): if not os.isatty(0): raise cmdError("stdin is not tty") # flush stdin sys.stdin.flush() # save termios settings self._tc_attr = termios.tcgetattr(0) # set tty in raw mode tty.setraw(0) @staticmethod def recv(size): '''Emulate socket recv''' data = os.read(0, size) if "\x1d" in data: # return empty sting to simulate an EOF instead of raise # and execption return "" return data @staticmethod def send(data): '''Emulate socket send''' return os.write(0, data) @staticmethod def fileno(): '''Emulate socket fileno''' return 0 @staticmethod def setblocking(*args): '''Emulate socket send''' # Do NOT be in non-blocking mode : non-blocking mode # causes rshell to get EAGAIN errors when having to # output loads of data, causing the TTY to break. return def close(self): '''Emulate socket close''' # reset tty original state termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr) class Command_shell(TqlCommand): Loading cccli/printer.py +54 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ import struct import subprocess import sys import termios import tty color = { # regular Loading Loading @@ -299,3 +300,56 @@ class Completion(object): self.readline.set_completer(self._completer) self.readline.parse_and_bind("tab: complete") self.readline.set_completer_delims(" \t") class FakeTtySocket(object): ''' Give a tty a socket interface This object cannot handle sigwinch directly because close can be called by remote RPC and by the way, called outside the main thread and fail. ''' def __init__(self): if not os.isatty(0): raise cmdError("stdin is not tty") # flush stdin sys.stdin.flush() # save termios settings self._tc_attr = termios.tcgetattr(0) # set tty in raw mode tty.setraw(0) @staticmethod def recv(size): '''Emulate socket recv''' data = os.read(0, size) if "\x1d" in data: # return empty sting to simulate an EOF instead of raise # and execption return "" return data @staticmethod def send(data): '''Emulate socket send''' return os.write(0, data) @staticmethod def fileno(): '''Emulate socket fileno''' return 0 @staticmethod def setblocking(*args): '''Emulate socket send''' # Do NOT be in non-blocking mode : non-blocking mode # causes rshell to get EAGAIN errors when having to # output loads of data, causing the TTY to break. return def close(self): '''Emulate socket close''' # reset tty original state termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr) Loading
cccli/commands/console.py +1 −55 Original line number Diff line number Diff line Loading @@ -7,66 +7,12 @@ CloudControl Console related commands from cccli.command import TqlCommand from cccli.exception import * from cccli.printer import FakeTtySocket from sjrpc.core.exceptions import * import fcntl import os import signal import struct import sys import termios import tty class FakeTtySocket(object): ''' Give a tty a socket interface This object cannot handle sigwinch directly because close can be called by remote RPC and by the way, called outside the main thread and fail. ''' def __init__(self): if not os.isatty(0): raise cmdError("stdin is not tty") # flush stdin sys.stdin.flush() # save termios settings self._tc_attr = termios.tcgetattr(0) # set tty in raw mode tty.setraw(0) @staticmethod def recv(size): '''Emulate socket recv''' data = os.read(0, size) if "\x1d" in data: # return empty sting to simulate an EOF instead of raise # and execption return "" return data @staticmethod def send(data): '''Emulate socket send''' return os.write(0, data) @staticmethod def fileno(): '''Emulate socket fileno''' return 0 @staticmethod def setblocking(*args): '''Emulate socket send''' # Do NOT be in non-blocking mode : non-blocking mode # causes rshell to get EAGAIN errors when having to # output loads of data, causing the TTY to break. return def close(self): '''Emulate socket close''' # reset tty original state termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr) class Command_shell(TqlCommand): Loading
cccli/printer.py +54 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ import struct import subprocess import sys import termios import tty color = { # regular Loading Loading @@ -299,3 +300,56 @@ class Completion(object): self.readline.set_completer(self._completer) self.readline.parse_and_bind("tab: complete") self.readline.set_completer_delims(" \t") class FakeTtySocket(object): ''' Give a tty a socket interface This object cannot handle sigwinch directly because close can be called by remote RPC and by the way, called outside the main thread and fail. ''' def __init__(self): if not os.isatty(0): raise cmdError("stdin is not tty") # flush stdin sys.stdin.flush() # save termios settings self._tc_attr = termios.tcgetattr(0) # set tty in raw mode tty.setraw(0) @staticmethod def recv(size): '''Emulate socket recv''' data = os.read(0, size) if "\x1d" in data: # return empty sting to simulate an EOF instead of raise # and execption return "" return data @staticmethod def send(data): '''Emulate socket send''' return os.write(0, data) @staticmethod def fileno(): '''Emulate socket fileno''' return 0 @staticmethod def setblocking(*args): '''Emulate socket send''' # Do NOT be in non-blocking mode : non-blocking mode # causes rshell to get EAGAIN errors when having to # output loads of data, causing the TTY to break. return def close(self): '''Emulate socket close''' # reset tty original state termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr)