def default_from_node(cls, node): """ Create a default environment for this node to run. It will be attached to stdin/stdout and commands will be logged to stdout. The is the most obvious default to create an ``Env`` instance. :param node: :class:`~deployer.node.base.Node` instance """ from deployer.pseudo_terminal import Pty from deployer.loggers import LoggerInterface from deployer.loggers.default import DefaultLogger pty = Pty(stdin=sys.stdin, stdout=sys.stdout, interactive=False, term_var=os.environ.get('TERM', '')) logger_interface = LoggerInterface() logger_interface.attach(DefaultLogger()) return cls(node, pty=pty, logger=logger_interface, is_sandbox=False)
def start(settings): """ Start the deployment shell in standalone modus. (No parrallel execution, no server/client. Just one interface, and everything sequential.) """ # Make sure that stdin and stdout are unbuffered # The alternative is to start Python with the -u option sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0) sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) # Create Pty object pty = Pty(sys.stdin, sys.stdout) def sigwinch_handler(n, frame): pty.trigger_resize() signal.signal(signal.SIGWINCH, sigwinch_handler) # Initialize settings settings = settings() # Loggers logger = create_logger() history_logger = HistoryLogger() extra_loggers = settings.Meta.extra_loggers logger_interface = LoggerInterface() logger_interface.attach(logger) logger_interface.attach(history_logger) for l in extra_loggers: logger_interface.attach(l) # Start shell command loop StandaloneShell(settings, pty, logger_interface, history_logger.history).cmdloop() for l in extra_loggers: logger_interface.detach(l)
def run(thr): # Set stdin/out pair for this thread. sys.stdout.set_handler(self.pty.stdout) sys.stdin.set_handler(self.pty.stdin) # Authentication if self.requires_authentication: try: self.username = pty_based_auth() authenticated = True except NotAuthenticated: authenticated = False else: authenticated = True if authenticated: # Create loggers logger_interface = LoggerInterface() in_shell_logger = DefaultLogger(self.pty.stdout, print_group=False) # Monitor for m in monitors: m.session_created(self) # Run shell shell = WebShell(settings, self.pty, logger_interface, username=self.username) shell.session = self # Assign session to shell self.shell = shell # in_shell_logger: Displaying of events in the shell itself logger_interface.attach(in_shell_logger) if self.command: shell.handle(self.command) else: shell.cmdloop() logger_interface.detach(in_shell_logger) # Monitor for m in monitors: m.session_closed(self) # Remove references (shell and session had circular reference) self.shell = None shell.session = None # Session done del active_sessions[self.id] sys.__stdout__.write('Ended session, id=%s...\n' % self.id) sys.__stdout__.flush() # Write last dummy character to trigger the session_closed. # (telnet session will otherwise wait for enter keypress.) sys.stdout.write(' ') # Remove std handlers for this thread. sys.stdout.del_handler() sys.stdin.del_handler() if self.doneCallback: self.doneCallback() # Stop IO reader self.reader.stopReading()