Esempio n. 1
0
        def thread():
            """
            Run the shell in a normal synchronous thread.
            """
            # Set stdin/out pair for this thread.
            sys.stdout.set_handler(self.pty.stdout)
            sys.stdin.set_handler(self.pty.stdin)

            # Authentication
            try:
                self.username = pty_based_auth(
                    self.auth_backend, self.pty) if self.auth_backend else ''
                authenticated = True
            except NotAuthenticated:
                authenticated = False

            if authenticated:
                # Create loggers
                logger_interface = LoggerInterface()
                in_shell_logger = DefaultLogger(self.pty.stdout,
                                                print_group=False)

                # Create options.
                options = Options()

                # Run shell
                shell = WebShell(self.root_node,
                                 self.pty,
                                 options,
                                 logger_interface,
                                 username=self.username)

                shell.session = self  # Assign session to shell
                self.shell = shell

                with logger_interface.attach_in_block(in_shell_logger):
                    with nested(*[
                            logger_interface.attach_in_block(l)
                            for l in self.extra_loggers
                    ]):
                        shell.cmdloop()

                # Remove references (shell and session had circular reference)
                self.shell = None
                shell.session = None

            # 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
            reactor.callFromThread(self.reader.stopReading)
    def __init__(self, connection, clone_shell=None, cd_path=None):
        self.connection = connection

        # Create loggers
        self.logger_interface = LoggerInterface()

        # Run shell
        self.shell = SocketShell(connection.root_node, connection.pty, connection.runtime_options,
                                self.logger_interface, clone_shell=clone_shell, connection=connection)
        self.cd_path = cd_path
def start(root_node, interactive=True, cd_path=None, logfile=None,
                action_name=None, parameters=None, shell=StandaloneShell,
                extra_loggers=None):
    """
    Start the deployment shell in standalone modus. (No parrallel execution,
    no server/client. Just one interface, and everything sequential.)
    """
    parameters = parameters or []

    # Enable logging
    if logfile:
        logging.basicConfig(filename=logfile, level=logging.DEBUG)

    # 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, interactive=interactive)

    def sigwinch_handler(n, frame):
        pty.trigger_resize()
    signal.signal(signal.SIGWINCH, sigwinch_handler)

    # Initialize root node
    root_node = root_node()

    # Set process title
    setproctitle('deploy:%s run -s' % root_node.__class__.__name__)

    # Loggers
    in_shell_logger = DefaultLogger(print_group=False)

    logger_interface = LoggerInterface()
    extra_loggers = extra_loggers or []

    with logger_interface.attach_in_block(in_shell_logger):
        with nested(* [logger_interface.attach_in_block(l) for l in extra_loggers]):
            # Create shell
            print 'Running single threaded shell...'
            shell = shell(root_node, pty, logger_interface)
            if cd_path is not None:
                shell.cd(cd_path)

            if action_name:
                try:
                    return shell.run_action(action_name, *parameters)
                except ActionException, e:
                    sys.exit(1)
                except:
                    import traceback
                    traceback.print_exc()
                    sys.exit(1)
Esempio n. 4
0
        def thread():
            """
            Run the shell in a normal synchronous thread.
            """
            # Set stdin/out pair for this thread.
            sys.stdout.set_handler(self.pty.stdout)
            sys.stdin.set_handler(self.pty.stdin)

            # Authentication
            try:
                self.username = pty_based_auth(self.auth_backend, self.pty) if self.auth_backend else ''
                authenticated = True
            except NotAuthenticated:
                authenticated = False

            if authenticated:
                # Create loggers
                logger_interface = LoggerInterface()
                in_shell_logger = DefaultLogger(self.pty.stdout, print_group=False)

                # Create options.
                options = Options()

                # Run shell
                shell = WebShell(self.root_node, self.pty, options, logger_interface, username=self.username)

                shell.session = self # Assign session to shell
                self.shell = shell

                with logger_interface.attach_in_block(in_shell_logger):
                    with nested(* [logger_interface.attach_in_block(l) for l in self.extra_loggers]):
                        shell.cmdloop()

                # Remove references (shell and session had circular reference)
                self.shell = None
                shell.session = None

            # 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
            reactor.callFromThread(self.reader.stopReading)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
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 __init__(self, connection, clone_shell=None, cd_path=None):
        self.connection = connection

        # Create loggers
        self.logger_interface = LoggerInterface()

        # Run shell
        self.shell = SocketShell(
            connection.root_node,
            connection.pty,
            connection.runtime_options,
            self.logger_interface,
            clone_shell=clone_shell,
            connection=connection,
        )
        self.cd_path = cd_path
Esempio n. 9
0
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)
Esempio n. 10
0
class ConnectionShell(object):
    """
    Start an interactive shell for a connection.
    (using a separate thread.)
    """

    def __init__(self, connection, clone_shell=None, cd_path=None):
        self.connection = connection

        # Create loggers
        self.logger_interface = LoggerInterface()

        # Run shell
        self.shell = SocketShell(
            connection.root_node,
            connection.pty,
            connection.runtime_options,
            self.logger_interface,
            clone_shell=clone_shell,
            connection=connection,
        )
        self.cd_path = cd_path

    def openNewShellFromThread(self):
        """
        Open new interactive shell in a new window.
        (Clone location of current shell.)
        """
        # Ask the client to open a new connection
        self.connection.openNewConnection(focus=True)

        try:
            # Blocking call to wait for a new incoming connection
            new_connection = PtyManager.getNewConnectionFromThread()

            # Start a new shell-thread into this connection.
            ConnectionShell(new_connection, clone_shell=self.shell).startThread()
        except PtyManager.NoPtyConnection as e:
            print "ERROR: could not open new terminal window..."

    def openNewShellFromReactor(self):
        self.connection.openNewConnection(focus=True)
        d = PtyManager.getNewConnection()

        @d.addCallback
        def openShell(new_connection):
            new_connection.startShell(clone_shell=self.shell)

        @d.addErrback
        def failed(failure):
            # Opening a new shell failed.
            pass

    def startThread(self, *a, **kw):
        threads.deferToThread(lambda: self.thread(*a, **kw))

    def thread(self, action_name=None, parameters=None, open_scp_shell=False):
        parameters = parameters or []

        # Set stdin/out pair for this thread.
        sys.stdout.set_handler(self.connection.pty.stdout)
        sys.stdin.set_handler(self.connection.pty.stdin)

        self.shell.session = self  # Assign session to shell

        # in_shell_logger: Displaying of events in shell
        with self.logger_interface.attach_in_block(DefaultLogger(print_group=False)):
            # Attach the extra loggers.
            with nested(*[self.logger_interface.attach_in_block(l) for l in self.connection.extra_loggers]):
                # Start at correct location
                if self.cd_path:
                    self.shell.cd(self.cd_path)

                if action_name and open_scp_shell:
                    print "Don't provide 'action_name' and 'open_scp_shell' at the same time"
                    exit_status = 1

                elif open_scp_shell:
                    self.shell.open_scp_shell()
                    exit_status = 0

                # When an action_name is given, call this action immediately,
                # otherwise, run the interactive cmdloop.
                elif action_name:
                    try:
                        self.shell.run_action(action_name, *parameters)
                        exit_status = 0
                    except ActionException:
                        exit_status = 1
                    except Exception:
                        import traceback

                        traceback.print_exc()
                        exit_status = 1
                else:
                    self.shell.cmdloop()
                    exit_status = 0

        # Remove references (shell and session have circular reference)
        self.shell.session = None
        self.shell = None

        # Remove std handlers for this thread.
        sys.stdout.del_handler()
        sys.stdin.del_handler()

        # Close connection
        reactor.callFromThread(lambda: self.connection.finish(exit_status=exit_status, always_close=True))
Esempio n. 11
0
            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()
Esempio n. 12
0
            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()
Esempio n. 13
0
class ConnectionShell(object):
    """
    Start an interactive shell for a connection.
    (using a separate thread.)
    """
    def __init__(self, connection, clone_shell=None, cd_path=None):
        self.connection = connection

        # Create loggers
        self.logger_interface = LoggerInterface()

        # Run shell
        self.shell = SocketShell(connection.root_node, connection.pty, connection.runtime_options,
                                self.logger_interface, clone_shell=clone_shell, connection=connection)
        self.cd_path = cd_path

    def openNewShellFromThread(self):
        """
        Open new interactive shell in a new window.
        (Clone location of current shell.)
        """
        # Ask the client to open a new connection
        self.connection.openNewConnection(focus=True)

        try:
            # Blocking call to wait for a new incoming connection
            new_connection = PtyManager.getNewConnectionFromThread()

            # Start a new shell-thread into this connection.
            ConnectionShell(new_connection, clone_shell=self.shell).startThread()
        except PtyManager.NoPtyConnection as e:
            print 'ERROR: could not open new terminal window...'

    def openNewShellFromReactor(self):
        self.connection.openNewConnection(focus=True)
        d = PtyManager.getNewConnection()

        @d.addCallback
        def openShell(new_connection):
            new_connection.startShell(clone_shell=self.shell)

        @d.addErrback
        def failed(failure):
            # Opening a new shell failed.
            pass

    def startThread(self, *a, **kw):
        threads.deferToThread(lambda: self.thread(*a, **kw))

    def thread(self, action_name=None, parameters=None, open_scp_shell=False):
        parameters = parameters or []

        # Set stdin/out pair for this thread.
        sys.stdout.set_handler(self.connection.pty.stdout)
        sys.stdin.set_handler(self.connection.pty.stdin)

        self.shell.session = self # Assign session to shell

        # in_shell_logger: Displaying of events in shell
        with self.logger_interface.attach_in_block(DefaultLogger(print_group=False)):
            # Attach the extra loggers.
            with nested(* [ self.logger_interface.attach_in_block(l) for l in self.connection.extra_loggers]):
                # Start at correct location
                if self.cd_path:
                    self.shell.cd(self.cd_path)

                if action_name and open_scp_shell:
                    print "Don't provide 'action_name' and 'open_scp_shell' at the same time"
                    exit_status = 1

                elif open_scp_shell:
                    self.shell.open_scp_shell()
                    exit_status = 0

                # When an action_name is given, call this action immediately,
                # otherwise, run the interactive cmdloop.
                elif action_name:
                    try:
                        self.shell.run_action(action_name, *parameters)
                        exit_status = 0
                    except ActionException:
                        exit_status = 1
                    except Exception:
                        import traceback
                        traceback.print_exc()
                        exit_status = 1
                else:
                    self.shell.cmdloop()
                    exit_status = 0

        # Remove references (shell and session have circular reference)
        self.shell.session = None
        self.shell = None

        # Remove std handlers for this thread.
        sys.stdout.del_handler()
        sys.stdin.del_handler()

        # Close connection
        reactor.callFromThread(lambda: self.connection.finish(
                    exit_status=exit_status, always_close=True))
def start(root_node,
          interactive=True,
          cd_path=None,
          logfile=None,
          action_name=None,
          parameters=None,
          shell=StandaloneShell,
          extra_loggers=None,
          open_scp_shell=False):
    """
    Start the deployment shell in standalone modus. (No parrallel execution,
    no server/client. Just one interface, and everything sequential.)
    """
    parameters = parameters or []

    # Enable logging
    if logfile:
        logging.basicConfig(filename=logfile, level=logging.DEBUG)

    # 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,
              interactive=interactive,
              term_var=os.environ.get('TERM', ''))

    def sigwinch_handler(n, frame):
        pty.trigger_resize()

    signal.signal(signal.SIGWINCH, sigwinch_handler)

    # Create runtime options
    options = Options()

    # Initialize root node
    root_node = root_node()

    # Set process title
    setproctitle('deploy:%s run -s' % root_node.__class__.__name__)

    # Loggers
    in_shell_logger = DefaultLogger(print_group=False)

    logger_interface = LoggerInterface()
    extra_loggers = extra_loggers or []

    with logger_interface.attach_in_block(in_shell_logger):
        with nested(
                *[logger_interface.attach_in_block(l) for l in extra_loggers]):
            # Create shell
            print 'Running single threaded shell...'
            shell = shell(root_node, pty, options, logger_interface)
            if cd_path is not None:
                shell.cd(cd_path)

            if action_name and open_scp_shell:
                raise Exception(
                    "Don't provide 'action_name' and 'open_scp_shell' at the same time"
                )

            if open_scp_shell:
                shell.open_scp_shell()

            elif action_name:
                try:
                    return shell.run_action(action_name, *parameters)
                except ActionException as e:
                    sys.exit(1)
                except:
                    import traceback
                    traceback.print_exc()
                    sys.exit(1)

            else:
                shell.cmdloop()