Пример #1
0
    def testPositional(self):
        """
        Tests positional arguments
        """
        def command(io_handler, arg1, arg2):
            """
            Sample command
            """
            return arg1, arg2

        # Register the command
        self.shell.register_command('test', 'command', command)

        # Valid execution
        session = beans.ShellSession(beans.IOHandler(sys.stdin, sys.stdout))
        self.assertTrue(self.shell.execute('test.command a 2', session))
        result = session.last_result
        self.assertEqual(result, ('a', '2'))

        # Invalid call
        for invalid in ([1], (1, 2, 3)):
            args = ' '.join(str(arg) for arg in invalid)
            self.assertFalse(
                self.shell.execute('test.command {0}'.format(args)),
                "Invalid call passed")
Пример #2
0
    def _make_session(self):
        """
        Prepares a ShellSession object for _run_command
        """
        # String output
        str_output = StringIO()

        # Session bean
        session = beans.ShellSession(beans.IOHandler(None, str_output))
        return session, str_output
Пример #3
0
    def _run_local_command(self, command, *args):
        """
        Runs the given command and returns the output stream
        """
        # String output
        str_output = StringIO()

        # Format command
        if args:
            command = command.format(*args)

        # Run command
        session = beans.ShellSession(beans.IOHandler(None, str_output))
        self.shell.execute(command, session)
        return str_output.getvalue().strip()
Пример #4
0
    def testKeywords(self):
        """
        Tests positional arguments
        """
        def command(io_handler, arg1='15', **kwargs):
            """
            Sample command
            """
            return arg1, kwargs

        # Register the command
        self.shell.register_command('test', 'command', command)

        # Prepare the session
        session = beans.ShellSession(beans.IOHandler(sys.stdin, sys.stdout))

        # Valid execution
        self.shell.execute('test.command arg1=12 a=2 b=abc', session)
        result = session.last_result
        self.assertEqual(result, ('12', {
            'a': '2',
            'b': 'abc'
        }), "Invalid result: {0}".format(result))

        self.shell.execute('test.command 12', session)
        result = session.last_result
        self.assertEqual(result, ('12', {}),
                         "Invalid result: {0}".format(result))

        self.shell.execute('test.command a=12', session)
        result = session.last_result
        self.assertEqual(result, ('15', {
            'a': '12'
        }), "Invalid result: {0}".format(result))

        # First '=' sign is the assignment  one,
        # shlex.split removes slashes
        self.shell.execute('test.command a=a=b b\=a=b', session)
        result = session.last_result
        self.assertEqual(result, ('15', {
            'a': 'a=b',
            'b': 'a=b'
        }), "Invalid result: {0}".format(result))

        # Invalid call (2 arguments)
        self.assertFalse(self.shell.execute('test.command 1 2'),
                         "Invalid call passed")
Пример #5
0
    def _run_command(self, command, *args):
        """
        Runs the given shell command
        """
        # String output
        str_output = StringIO()

        # Format command
        if args:
            command = command.format(*args)

        # Add the namespace prefix
        command = 'config.{0}'.format(command)

        # Run command
        session = beans.ShellSession(beans.IOHandler(None, str_output))
        self.shell.execute(command, session)
        return str_output.getvalue()
Пример #6
0
    def test_run_file(self):
        """
        Tests the run shell command
        """
        # Check bad file error
        self.assertFalse(self.shell.execute("run __fake_file__"))

        # Compute test file name
        filename = os.path.join(os.path.dirname(__file__),
                                "rshell_starter.pelix")

        # Install iPOPO
        self.context.install_bundle('pelix.ipopo.core').start()
        self.context.install_bundle('pelix.shell.ipopo').start()

        # Prepare a session
        port = 9001
        session = beans.ShellSession(beans.IOHandler(sys.stdin, sys.stdout),
                                     {"port": port})

        # Run the file a first time
        self.assertTrue(
            self.shell.execute("run '{0}'".format(filename), session))

        # Check the result
        self.assertEqual(session.get("rshell.name"), "rshell")

        # Check the bundle
        rshell_bundle = int(session.get("rshell.bundle"))
        bundle = self.context.get_bundle(rshell_bundle)
        self.assertEqual(bundle.get_symbolic_name(), "pelix.shell.remote")

        # Check the instance properties
        with use_ipopo(self.context) as ipopo:
            details = ipopo.get_instance_details(session.get("rshell.name"))
            self.assertEqual(int(details["properties"]["pelix.shell.port"]),
                             port)

        # Run the file a second time: it must fail
        self.assertFalse(
            self.shell.execute("run '{0}'".format(filename), session))
Пример #7
0
    def handle_message(self, source_jid, content):
        """
        Handles an XMPP message and reply to the source

        :param source_jid: JID of the message sender
        :param content: Content of the message
        """
        try:
            # Use the existing session
            session = self.__sessions[source_jid]
        except KeyError:
            # Subscribe to presence messages
            self.__bot.sendPresence(pto=source_jid, ptype='subscribe')

            # Create and store the session
            session = self.__sessions[source_jid] = beans.ShellSession(
                beans.IOHandler(_XmppInStream(self, source_jid),
                                _XmppOutStream(self.__bot, source_jid)),
                {"xmpp.jid": source_jid})

        self._shell.execute(content, session)
Пример #8
0
    def _run_command(self, command, *args, **kwargs):
        """
        Runs the given command and returns the output stream. A keyword
        argument 'session' can be given to use a custom ShellSession.
        """
        # Format command
        if args:
            command = command.format(*args)

        try:
            # Get the given session
            session = kwargs['session']
            str_output = kwargs['output']
            str_output.truncate(0)
            str_output.seek(0)
        except KeyError:
            # No session given
            str_output = StringIO()
            session = beans.ShellSession(beans.IOHandler(None, str_output))

        # Run command
        self.shell.execute(command, session)
        return str_output.getvalue()
Пример #9
0
    def handle(self):
        """
        Handles a TCP client
        """
        _logger.info("RemoteConsole client connected: [%s]:%d",
                     self.client_address[0], self.client_address[1])

        # Prepare the session
        session = beans.ShellSession(
            beans.IOHandler(self.rfile, self.wfile),
            {"remote_client_ip": self.client_address[0]})

        # Print the banner
        def get_ps1():
            """
            Gets the prompt string from the session of the shell service

            :return: The prompt string
            """
            try:
                return session.get("PS1")
            except KeyError:
                return self._shell.get_ps1()

        self.send(self._shell.get_banner())
        self.send(get_ps1())

        try:
            while self._active.get_value():
                # Wait for data
                rlist = select([self.connection], [], [], .5)[0]
                if not rlist:
                    # Nothing to do (poll timed out)
                    continue

                data = self.rfile.readline()
                if not data:
                    # End of stream (client gone)
                    break

                # Strip the line
                line = data.strip()
                if not data:
                    # Empty line
                    continue

                # Execute it
                try:
                    self._shell.handle_line(line, session)
                except KeyboardInterrupt:
                    # Stop there on interruption
                    self.send("\nInterruption received.")
                    return
                except IOError as ex:
                    # I/O errors are fatal
                    _logger.exception(
                        "Error communicating with a client: %s", ex)
                    break
                except Exception as ex:
                    # Other exceptions are not important
                    import traceback
                    self.send("\nError during last command: {0}\n".format(ex))
                    self.send(traceback.format_exc())

                # Print the prompt
                self.send(get_ps1())
        finally:
            _logger.info("RemoteConsole client gone: [%s]:%d",
                         self.client_address[0], self.client_address[1])

            try:
                # Be polite
                self.send("\nSession closed. Good bye.\n")
                self.finish()
            except IOError as ex:
                _logger.warning("Error cleaning up connection: %s", ex)
Пример #10
0
    def execute(self, cmdline, session=None):
        """
        Executes the command corresponding to the given line

        :param cmdline: Command line to parse
        :param session: Current shell session
        :return: True if command succeeded, else False
        """
        if session is None:
            # Default session
            session = beans.ShellSession(
                beans.IOHandler(sys.stdin, sys.stdout), {})

        assert isinstance(session, beans.ShellSession)

        # Split the command line
        if not cmdline:
            return False

        # Convert the line into a string
        cmdline = to_str(cmdline)

        try:
            line_split = shlex.split(cmdline, True, True)
        except ValueError as ex:
            session.write_line("Error reading line: {0}", ex)
            return False

        if not line_split:
            return False

        try:
            # Extract command information
            namespace, command = self.get_ns_command(line_split[0])
        except ValueError as ex:
            # Unknown command
            session.write_line(str(ex))
            return False

        # Get the content of the name space
        space = self._commands.get(namespace, None)
        if not space:
            session.write_line("Unknown name space {0}", namespace)
            return False

        # Get the method object
        method = space.get(command, None)
        if method is None:
            session.write_line("Unknown command: {0}.{1}", namespace, command)
            return False

        # Make arguments and keyword arguments
        args, kwargs = _make_args(line_split[1:], session,
                                  self._framework.get_properties())
        try:
            # Execute it
            result = method(session, *args, **kwargs)

            # Store the result as $?
            if result is not None:
                session.set(beans.RESULT_VAR_NAME, result)

            # 0, None are considered as success, so don't use not nor bool
            return result is not False
        except TypeError as ex:
            # Invalid arguments...
            self._logger.error("Error calling %s.%s: %s", namespace, command,
                               ex)
            session.write_line("Invalid method call: {0}", ex)
            self.__print_namespace_help(session, namespace, command)
            return False
        except Exception as ex:
            # Error
            self._logger.exception("Error calling %s.%s: %s", namespace,
                                   command, ex)
            session.write_line("{0}: {1}", type(ex).__name__, str(ex))
            return False
        finally:
            # Try to flush in any case
            try:
                session.flush()
            except IOError:
                pass