예제 #1
0
def exception_msg_handler(signal, data):
    """
    Handler for the ExceptionSignal signal.

    :param signal: event data
    :type signal: (event_type, message_data)
    :param data: additional data
    :type data: any
    """
    global exception_processed
    if exception_processed:
        # get data from the event data structure
        exception_info = signal.exception_info

        stack_trace = "\n" + App.get_scheduler().dump_stack()
        log.error(stack_trace)
        # exception_info is a list
        sys.excepthook(*exception_info)
    else:
        # show only the first exception do not spam user with others
        exception_processed = True
        loop = App.get_event_loop()
        # start new loop for handling the exception
        # this will stop processing all the old signals and prevent raising new exceptions
        loop.execute_new_loop(signal)
예제 #2
0
    def setup(self, data):
        """Construct all the objects required to implement this interface.

        This method must be provided by all subclasses.
        """
        # Use GLib event loop for the Simpleline TUI
        loop = GLibEventLoop()
        App.initialize(event_loop=loop)

        loop.set_quit_callback(tui_quit_callback)
        scheduler = App.get_scheduler()
        scheduler.quit_screen = YesNoDialog(self.quitMessage)

        # tell python-meh it should use our raw_input
        meh_io_handler = meh.ui.text.IOHandler(in_func=self._get_meh_input_func)
        self._meh_interface.set_io_handler(meh_io_handler)

        # register handlers for various messages
        loop = App.get_event_loop()
        loop.register_signal_handler(ExceptionSignal, exception_msg_handler)
        loop.register_signal_handler(SendMessageSignal, self._handle_show_message)

        _hubs = self._list_hubs()

        # First, grab a list of all the standalone spokes.
        spokes = self._collectActionClasses(self.paths["spokes"], StandaloneSpoke)
        actionClasses = self._orderActionClasses(spokes, _hubs)

        for klass in actionClasses:
            obj = klass(data, self.storage, self.payload, self.instclass)

            # If we are doing a kickstart install, some standalone spokes
            # could already be filled out.  In that case, we do not want
            # to display them.
            if self._is_standalone(obj) and obj.completed:
                del(obj)
                continue

            if hasattr(obj, "set_path"):
                obj.set_path("spokes", self.paths["spokes"])
                obj.set_path("categories", self.paths["categories"])

            should_schedule = obj.setup(self.ENVIRONMENT)

            if should_schedule:
                scheduler.schedule_screen(obj)
예제 #3
0
    def handleException(self, dump_info):
        """
        Our own handleException method doing some additional stuff before
        calling the original python-meh's one.

        :type dump_info: an instance of the meh.DumpInfo class
        :see: python-meh's ExceptionHandler.handleException

        """

        log.debug("running handleException")
        exception_lines = traceback.format_exception(*dump_info.exc_info)
        log.critical("\n".join(exception_lines))

        ty = dump_info.exc_info.type
        value = dump_info.exc_info.value

        try:
            gi.require_version("Gtk", "3.0")

            from gi.repository import Gtk

            # XXX: Gtk stopped raising RuntimeError if it fails to
            # initialize. Horay! But will it stay like this? Let's be
            # cautious and raise the exception on our own to work in both
            # cases
            initialized = Gtk.init_check(None)[0]
            if not initialized:
                raise RuntimeError()

            # Attempt to grab the GUI initializing lock, do not block
            if not self._gui_lock.acquire(False):
                # the graphical interface is running, don't crash it by
                # running another one potentially from a different thread
                log.debug("Gtk running, queuing exception handler to the main loop")
                run_in_loop(self._main_loop_handleException, dump_info)
            else:
                log.debug("Gtk not running, starting Gtk and running exception handler in it")
                self._main_loop_handleException(dump_info)

        except (RuntimeError, ImportError, ValueError):
            log.debug("Gtk cannot be initialized")
            # X not running (Gtk cannot be initialized)
            if threadMgr.in_main_thread():
                log.debug("In the main thread, running exception handler")
                if issubclass(ty, NonInteractiveError) or not self._interactive:
                    if issubclass(ty, NonInteractiveError):
                        cmdline_error_msg = _("\nThe installation was stopped due to an "
                                              "error which occurred while running in "
                                              "non-interactive cmdline mode. Since there "
                                              "cannot be any questions in cmdline mode, edit "
                                              "your kickstart file and retry installation. "
                                              "\nThe exact error message is: \n\n%s. \n\nThe "
                                              "installer will now terminate.") % str(value)
                    else:
                        cmdline_error_msg = _("\nRunning in cmdline mode, no interactive "
                                              "debugging allowed.\nThe exact error message is: "
                                              "\n\n%s.\n\nThe installer will now terminate."
                                              ) % str(value)

                    # since there is no UI in cmdline mode and it is completely
                    # non-interactive, we can't show a message window asking the user
                    # to acknowledge the error; instead, print the error out and sleep
                    # for a few seconds before exiting the installer
                    print(cmdline_error_msg)
                    time.sleep(180)
                    sys.exit(1)
                else:
                    print("\nAn unknown error has occured, look at the "
                          "/tmp/anaconda-tb* file(s) for more details")
                    # in the main thread, run exception handler
                    self._main_loop_handleException(dump_info)
            else:
                log.debug("In a non-main thread, sending a message with exception data")
                # not in the main thread, just send message with exception
                # data and let message handler run the exception handler in
                # the main thread
                exc_info = dump_info.exc_info
                # new Simpleline package is now used in TUI. Look if Simpleline is
                # initialized or if this is some fallback from GTK or other stuff.
                if App.is_initialized():
                    # if Simpleline is initialized enqueue exception there
                    loop = App.get_event_loop()
                    loop.enqueue_signal(ExceptionSignal(App.get_scheduler(), exception_info=exc_info))
                else:
                    hubQ.send_exception((exc_info.type,
                                         exc_info.value,
                                         exc_info.stack))
예제 #4
0
 def test_close_screen_closed_from_other_source_error(self):
     App.initialize()
     App.get_scheduler().schedule_screen(UIScreen())
     with self.assertRaises(RenderUnexpectedError):
         App.get_scheduler().close_screen(closed_from=mock.MagicMock())
예제 #5
0
 def _check_app_settings(self, event_loop, scheduler, configuration):
     self.assertEqual(App.get_event_loop(), event_loop)
     self.assertEqual(App.get_scheduler(), scheduler)
     self.assertEqual(App.get_configuration(), configuration)
예제 #6
0
    def test_failed_screen_setup(self):
        screen = FailedSetupScreen()

        App.initialize()
        App.get_scheduler().schedule_screen(screen)
        App.run()
예제 #7
0
    def test_quit_input(self, mock_stdin, mock_stdout):
        mock_stdin.return_value = "q"
        screen = UIScreen()

        App.get_scheduler().schedule_screen(screen)
        App.run()
예제 #8
0
    def handleException(self, dump_info):
        """
        Our own handleException method doing some additional stuff before
        calling the original python-meh's one.

        :type dump_info: an instance of the meh.DumpInfo class
        :see: python-meh's ExceptionHandler.handleException

        """

        log.debug("running handleException")
        exception_lines = traceback.format_exception(*dump_info.exc_info)
        log.critical("\n".join(exception_lines))

        ty = dump_info.exc_info.type
        value = dump_info.exc_info.value

        try:
            gi.require_version("Gtk", "3.0")

            from gi.repository import Gtk

            # XXX: Gtk stopped raising RuntimeError if it fails to
            # initialize. Horay! But will it stay like this? Let's be
            # cautious and raise the exception on our own to work in both
            # cases
            initialized = Gtk.init_check(None)[0]
            if not initialized:
                raise RuntimeError()

            # Attempt to grab the GUI initializing lock, do not block
            if not self._gui_lock.acquire(False):
                # the graphical interface is running, don't crash it by
                # running another one potentially from a different thread
                log.debug("Gtk running, queuing exception handler to the main loop")
                run_in_loop(self._main_loop_handleException, dump_info)
            else:
                log.debug("Gtk not running, starting Gtk and running exception handler in it")
                self._main_loop_handleException(dump_info)

        except (RuntimeError, ImportError, ValueError):
            log.debug("Gtk cannot be initialized")
            # X not running (Gtk cannot be initialized)
            if threadMgr.in_main_thread():
                log.debug("In the main thread, running exception handler")
                if issubclass(ty, NonInteractiveError) or not self._interactive:
                    if issubclass(ty, NonInteractiveError):
                        cmdline_error_msg = _("\nThe installation was stopped due to an "
                                              "error which occurred while running in "
                                              "non-interactive cmdline mode. Since there "
                                              "cannot be any questions in cmdline mode, edit "
                                              "your kickstart file and retry installation. "
                                              "\nThe exact error message is: \n\n%s. \n\nThe "
                                              "installer will now terminate.") % str(value)
                    else:
                        cmdline_error_msg = _("\nRunning in cmdline mode, no interactive "
                                              "debugging allowed.\nThe exact error message is: "
                                              "\n\n%s.\n\nThe installer will now terminate."
                                              ) % str(value)

                    # since there is no UI in cmdline mode and it is completely
                    # non-interactive, we can't show a message window asking the user
                    # to acknowledge the error; instead, print the error out and sleep
                    # for a few seconds before exiting the installer
                    print(cmdline_error_msg)
                    time.sleep(180)
                    sys.exit(1)
                else:
                    print("\nAn unknown error has occured, look at the "
                          "/tmp/anaconda-tb* file(s) for more details")
                    # in the main thread, run exception handler
                    self._main_loop_handleException(dump_info)
            else:
                log.debug("In a non-main thread, sending a message with exception data")
                # not in the main thread, just send message with exception
                # data and let message handler run the exception handler in
                # the main thread
                exc_info = dump_info.exc_info
                # new Simpleline package is now used in TUI. Look if Simpleline is
                # initialized or if this is some fallback from GTK or other stuff.
                if App.is_initialized():
                    # if Simpleline is initialized enqueue exception there
                    loop = App.get_event_loop()
                    loop.enqueue_signal(ExceptionSignal(App.get_scheduler(), exception_info=exc_info))
                else:
                    hubQ.send_exception((exc_info.type,
                                         exc_info.value,
                                         exc_info.stack))
예제 #9
0
 def schedule_screen_and_run(screen):
     App.initialize()
     App.get_scheduler().schedule_screen(screen)
     App.run()
예제 #10
0
 def test_create_instance_with_custom_scheduler(self):
     App.initialize(scheduler=CustomScreenScheduler(CustomEventLoop()))
     self.assertTrue(isinstance(App.get_scheduler(), CustomScreenScheduler))
예제 #11
0
 def test_create_instance(self):
     App.initialize()
     self.assertTrue(isinstance(App.get_scheduler(), ScreenScheduler))
     self.assertTrue(isinstance(App.get_event_loop(), MainLoop))
     self.assertTrue(
         isinstance(App.get_configuration(), GlobalConfiguration))
예제 #12
0
    def schedule_screen_and_run_with_glib(self, screen):
        self.setup_glib()

        App.get_scheduler().schedule_screen(screen)
        App.run()
    def push_screen_modal(cls, ui_screen, args=None):
        """Schedule screen to the active scheduler.

        See: `simpleline.render.screen_scheduler.push_screen_modal()`.
        """
        App.get_scheduler().push_screen_modal(ui_screen=ui_screen, args=args)
    def replace_screen(cls, ui_screen, args=None):
        """Schedule screen to the active scheduler.

        See: `simpleline.render.screen_scheduler.replace_screen()`.
        """
        App.get_scheduler().replace_screen(ui_screen=ui_screen, args=args)