def process_input(self, user_input):
        """Process input from the screens.

        :param user_input: User input string.
        :type user_input: String.

        :raises: ExitMainLoop or any other kind of exception from screen processing.
        """
        # process the input, if it wasn't processed (valid)
        # increment the error counter
        try:
            result = self._process_input(user_input)
        except ExitMainLoop:  # pylint: disable=try-except-raise
            raise
        except Exception:  # pylint: disable=broad-except
            App.get_event_loop().enqueue_signal(ExceptionSignal(self))
            return

        if result.was_successful():
            self._input_error_counter = 0
        else:
            self._input_error_counter += 1

        App.get_scheduler().process_input_result(
            result, self.input_error_threshold_exceeded)
    def __init__(self, callback=None, source=None):
        """Class to handle input from the terminal.

        This class is designed to be instantiated on place where it should be used.
        The main method is `get_input()` which is non-blocking asynchronous call. It can be used
        as synchronous call be calling the `wait_on_input` method.

        To get result from this class use the `value` property.

        :param callback: You can specify callback which will be called when user give input.
        :type callback: Callback function with one argument which will be user input.

        :param source: Source of this input. It will be helpful in case of debugging an issue.
        :type source: Class which will process an input from this InputHandler.
        """
        super().__init__()
        self._input = None
        self._input_callback = callback
        self._input_received = False
        self._input_successful = False
        self._skip_concurrency_check = False
        self._source = source

        App.get_event_loop().register_signal_handler(
            InputReadySignal, self._input_received_handler)
示例#3
0
    def redraw(self):
        """Emit signal to initiate draw.

        Add RenderScreenSignal to the event loop.
        """
        signal = self.create_signal(RenderScreenSignal)
        App.get_event_loop().enqueue_signal(signal)
示例#4
0
    def close(self):
        """Emit signal to close this screen.

        Add CloseScreenSignal to the event loop.
        """
        signal = self.create_signal(CloseScreenSignal)
        App.get_event_loop().enqueue_signal(signal)
示例#5
0
    def run(self):
        """Run the `run_input` method and propagate input outside.

        Do not call this method directly. It will be called by InputThreadManager.
        """
        data = self.get_input()

        App.get_event_loop().enqueue_signal(InputReceivedSignal(self, data))
    def test_emit(self):
        connect_screen = UIScreen()

        App.initialize(scheduler=MagicMock())
        connect_screen.connect(TestSignal, self._callback)
        connect_screen.emit(TestSignal(self))
        App.get_event_loop().process_signals()

        self.assertTrue(self.callback_called)
示例#7
0
    def emit(self, signal):
        """Emit the signal.

        This will add `signal` to the event loop.

        :param signal: signal to emit
        :type signal: instance of class based on `simpleline.event_loop.AbstractSignal`
        """
        App.get_event_loop().enqueue_signal(signal)
    def test_basic_connect(self):
        connect_screen = UIScreen()

        App.initialize(scheduler=MagicMock())
        connect_screen.connect(SignalMock, self._callback)
        App.get_event_loop().enqueue_signal(SignalMock(self))
        App.get_event_loop().process_signals()

        self.assertTrue(self.callback_called)
示例#9
0
    def emit_failed_input_ready_signal(self):
        """Emit the InputReadySignal with failed state."""
        handler_source = self.source
        signal_source = self._get_request_source()

        new_signal = InputReadySignal(source=signal_source,
                                      input_handler_source=handler_source,
                                      data="",
                                      success=False)
        App.get_event_loop().enqueue_signal(new_signal)
    def tearDown(self):
        super().tearDown()
        self._thread_event_wait_for_outer.set()

        for t in self._threads:
            t.join()

        # process InputReceivedSignal
        App.get_event_loop().process_signals()
        # process InputReadySignal
        App.get_event_loop().process_signals()
    def wait_on_input(self):
        """Blocks execution till the user input is received.

        Events will works as expected during this blocking.

        Please check the `input_successful` method to test the input.
        """
        # we already received input from user
        if self._input_received:
            return

        while not self._input_received:
            App.get_event_loop().process_signals(InputReadySignal)
示例#12
0
    def connect(self, signal, callback, data=None):
        """Connect this class method with given signal.

        :param signal: signal class which you want to connect
        :type signal: class based on `simpleline.event_loop.AbstractSignal`

        :param callback: the callback function
        :type callback: func(event_message, data)

        :param data: Data you want to pass to the callback
        :type data: Anything
        """
        App.get_event_loop().register_signal_handler(signal, callback, data)
示例#13
0
    def setup(self, args):
        """Do additional setup right before this screen is used.

        It is mandatory to call this ancestor method in the child class to set ready status.

        :param args: arguments for the setup
        :type args: array of values
        :return: whether this screen should be scheduled or not
        :rtype: bool
        """
        self._screen_ready = True
        App.get_event_loop().register_signal_source(self)
        return True
示例#14
0
    def emit_input_ready_signal(self, input_data):
        """Emit the InputReadySignal signal with collected input data.

        :param input_data: Input data received.
        :type input_data: str
        """
        handler_source = self.source
        signal_source = self._get_request_source()

        new_signal = InputReadySignal(source=signal_source,
                                      input_handler_source=handler_source,
                                      data=input_data,
                                      success=True)
        App.get_event_loop().enqueue_signal(new_signal)
示例#15
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)
示例#16
0
def start_rescue_mode_ui(anaconda):
    """Start the rescue mode UI."""

    ksdata_rescue = None
    if anaconda.ksdata.rescue.seen:
        ksdata_rescue = anaconda.ksdata.rescue
    scripts = anaconda.ksdata.scripts
    storage = anaconda.storage
    reboot = True
    if conf.target.is_image:
        reboot = False
    if flags.automatedInstall and anaconda.ksdata.reboot.action not in [
            KS_REBOOT, KS_SHUTDOWN
    ]:
        reboot = False

    rescue = Rescue(storage, ksdata_rescue, reboot, scripts)
    rescue.initialize()

    # We still want to choose from multiple roots, or unlock encrypted devices
    # if needed, so we run UI even for kickstarts (automated install).
    App.initialize()
    loop = App.get_event_loop()
    loop.set_quit_callback(tui_quit_callback)
    spoke = RescueModeSpoke(rescue)
    ScreenHandler.schedule_screen(spoke)
    App.run()
示例#17
0
def start_rescue_mode_ui(anaconda):
    """Start the rescue mode UI."""

    ksdata_rescue = None
    if anaconda.ksdata.rescue.seen:
        ksdata_rescue = anaconda.ksdata.rescue
    scripts = anaconda.ksdata.scripts
    storage = anaconda.storage
    reboot = True
    if conf.target.is_image:
        reboot = False
    if flags.automatedInstall and anaconda.ksdata.reboot.action not in [KS_REBOOT, KS_SHUTDOWN]:
        reboot = False

    rescue = Rescue(storage, ksdata_rescue, reboot, scripts)
    rescue.initialize()

    # We still want to choose from multiple roots, or unlock encrypted devices
    # if needed, so we run UI even for kickstarts (automated install).
    App.initialize()
    loop = App.get_event_loop()
    loop.set_quit_callback(tui_quit_callback)
    spoke = RescueModeSpoke(rescue)
    ScreenHandler.schedule_screen(spoke)
    App.run()
示例#18
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)
示例#19
0
    def test_create_instance_with_custom_everything(self):
        event_loop = CustomEventLoop()
        App.initialize(event_loop=event_loop,
                       scheduler=CustomScreenScheduler(event_loop),
                       global_configuration=CustomGlobalConfiguration())

        self.assertTrue(isinstance(App.get_event_loop(), CustomEventLoop))
        self.assertTrue(isinstance(App.get_scheduler(), CustomScreenScheduler))
        self.assertTrue(isinstance(App.get_configuration(), CustomGlobalConfiguration))
示例#20
0
    def _update_progress(self):
        """Handle progress updates from install thread."""

        from pyanaconda.progress import progressQ
        import queue

        q = progressQ.q

        # Grab all messages may have appeared since last time this method ran.
        while True:
            # Attempt to get a message out of the queue for how we should update
            # the progress bar.  If there's no message, don't error out.
            # Also flush the communication Queue at least once a second and
            # process it's events so we can react to async evens (like a thread
            # throwing an exception)
            while True:
                try:
                    (code, args) = q.get(timeout=1)
                    break
                except queue.Empty:
                    pass
                finally:
                    loop = App.get_event_loop()
                    loop.process_signals()

            if code == progressQ.PROGRESS_CODE_INIT:
                # Text mode doesn't have a finite progress bar
                pass
            elif code == progressQ.PROGRESS_CODE_STEP:
                # Instead of updating a progress bar, we just print a pip
                # but print it without a new line.
                sys.stdout.write('.')
                sys.stdout.flush()
                # Use _stepped as an indication to if we need a newline before
                # the next message
                self._stepped = True
            elif code == progressQ.PROGRESS_CODE_MESSAGE:
                # This should already be translated
                if self._stepped:
                    # Get a new line in case we've done a step before
                    self._stepped = False
                    print('')
                print(args[0])
            elif code == progressQ.PROGRESS_CODE_COMPLETE:
                # There shouldn't be any more progress updates, so return
                q.task_done()

                if self._stepped:
                    print('')
                return True
            elif code == progressQ.PROGRESS_CODE_QUIT:
                sys.exit(args[0])

            q.task_done()
        return True
    def _update_progress(self):
        """Handle progress updates from install thread."""

        from pyanaconda.progress import progressQ
        import queue

        q = progressQ.q

        # Grab all messages may have appeared since last time this method ran.
        while True:
            # Attempt to get a message out of the queue for how we should update
            # the progress bar.  If there's no message, don't error out.
            # Also flush the communication Queue at least once a second and
            # process it's events so we can react to async evens (like a thread
            # throwing an exception)
            while True:
                try:
                    (code, args) = q.get(timeout=1)
                    break
                except queue.Empty:
                    pass
                finally:
                    loop = App.get_event_loop()
                    loop.process_signals()

            if code == progressQ.PROGRESS_CODE_INIT:
                # Text mode doesn't have a finite progress bar
                pass
            elif code == progressQ.PROGRESS_CODE_STEP:
                # Instead of updating a progress bar, we just print a pip
                # but print it without a new line.
                sys.stdout.write('.')
                sys.stdout.flush()
                # Use _stepped as an indication to if we need a newline before
                # the next message
                self._stepped = True
            elif code == progressQ.PROGRESS_CODE_MESSAGE:
                # This should already be translated
                if self._stepped:
                    # Get a new line in case we've done a step before
                    self._stepped = False
                    print('')
                print(args[0])
            elif code == progressQ.PROGRESS_CODE_COMPLETE:
                # There shouldn't be any more progress updates, so return
                q.task_done()

                if self._stepped:
                    print('')
                return True
            elif code == progressQ.PROGRESS_CODE_QUIT:
                sys.exit(args[0])

            q.task_done()
        return True
示例#22
0
    def __init__(self, data, storage=None, payload=None, instclass=None, message=""):
        super().__init__(data, storage, payload, instclass)
        self.input_required = True
        self.initialize_start()
        self._container = None

        # The TUI hasn't been initialized with the message handlers yet. Add an
        # exception message handler so that the TUI exits if anything goes wrong
        # at this stage.
        loop = App.get_event_loop()
        loop.register_signal_handler(ExceptionSignal, exception_msg_handler_and_exit)
        self._message = message
        self._usevnc = False
        self.initialize_done()
示例#23
0
    def __init__(self, data, storage=None, payload=None, instclass=None, message=""):
        super().__init__(data, storage, payload, instclass)
        self.input_required = True
        self.initialize_start()
        self._container = None

        # The TUI hasn't been initialized with the message handlers yet. Add an
        # exception message handler so that the TUI exits if anything goes wrong
        # at this stage.
        loop = App.get_event_loop()
        loop.register_signal_handler(ExceptionSignal, exception_msg_handler_and_exit)
        self._message = message
        self._usevnc = False
        self.initialize_done()
示例#24
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)

            # 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)
示例#25
0
    def _send_show_message(self, msg_fn, args, ret_queue):
        """ Send message requesting to show some message dialog specified by the message function.

        :param msg_fn: message dialog function requested to be called
        :type msg_fn: a function taking the same number of arguments as is the
                      length of the args param
        :param args: arguments to be passed to the message dialog function
        :type args: any
        :param ret_queue: the queue which the return value of the message dialog
                          function should be put
        :type ret_queue: a queue.Queue instance
        """

        signal = SendMessageSignal(self, msg_fn=msg_fn, args=args, ret_queue=ret_queue)
        loop = App.get_event_loop()
        loop.enqueue_signal(signal)
示例#26
0
    def _send_show_message(self, msg_fn, args, ret_queue):
        """ Send message requesting to show some message dialog specified by the message function.

        :param msg_fn: message dialog function requested to be called
        :type msg_fn: a function taking the same number of arguments as is the
                      length of the args param
        :param args: arguments to be passed to the message dialog function
        :type args: any
        :param ret_queue: the queue which the return value of the message dialog
                          function should be put
        :type ret_queue: a queue.Queue instance
        """

        signal = SendMessageSignal(self, msg_fn=msg_fn, args=args, ret_queue=ret_queue)
        loop = App.get_event_loop()
        loop.enqueue_signal(signal)
示例#27
0
    def changeVNCPasswdWindow(self):
        """ Change the password to a sane parameter.

        We ask user to input a password that (len(password) > 6
        and len(password) <= 8) or password == ''.
        """

        message = _("VNC password must be six to eight characters long.\n"
                    "Please enter a new one, or leave blank for no password.")
        App.initialize()
        loop = App.get_event_loop()
        loop.set_quit_callback(tui_quit_callback)
        spoke = VNCPassSpoke(self.anaconda.ksdata, None, None, message)
        ScreenHandler.schedule_screen(spoke)
        App.run()

        self.password = self.anaconda.ksdata.vnc.password
示例#28
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)
示例#29
0
文件: vnc.py 项目: jaymzh/anaconda
    def changeVNCPasswdWindow(self):
        """ Change the password to a sane parameter.

        We ask user to input a password that (len(password) > 6
        and len(password) <= 8) or password == ''.
        """

        message = _("VNC password must be six to eight characters long.\n"
                    "Please enter a new one, or leave blank for no password.")
        App.initialize()
        loop = App.get_event_loop()
        loop.set_quit_callback(tui_quit_callback)
        spoke = VNCPassSpoke(self.anaconda.ksdata, None, None, None, message)
        ScreenHandler.schedule_screen(spoke)
        App.run()

        self.password = self.anaconda.ksdata.vnc.password
示例#30
0
    def test_reinitialize(self):
        event_loop1 = CustomEventLoop()
        event_loop2 = CustomEventLoop()
        scheduler1 = CustomScreenScheduler(event_loop1)
        scheduler2 = CustomScreenScheduler(event_loop2)
        configuration1 = CustomGlobalConfiguration()
        configuration2 = CustomGlobalConfiguration()

        App.initialize(event_loop=event_loop1, scheduler=scheduler1,
                       global_configuration=configuration1)
        self._check_app_settings(event_loop1, scheduler1, configuration1)

        App.initialize(event_loop=event_loop2, scheduler=scheduler2,
                       global_configuration=configuration2)
        self._check_app_settings(event_loop2, scheduler2, configuration2)

        App.initialize()
        self.assertNotEqual(App.get_event_loop(), event_loop2)
        self.assertNotEqual(App.get_scheduler(), scheduler2)
        self.assertNotEqual(App.get_configuration(), configuration2)
示例#31
0
def ask_vnc_question(anaconda, vnc_server, message):
    """ Ask the user if TUI or GUI-over-VNC should be started.

    :param anaconda: instance of the Anaconda class
    :param vnc_server: instance of the VNC server object
    :param str message: a message to show to the user together
                        with the question
    """
    App.initialize()
    loop = App.get_event_loop()
    loop.set_quit_callback(tui_quit_callback)
    spoke = AskVNCSpoke(anaconda.ksdata, message)
    ScreenHandler.schedule_screen(spoke)
    App.run()

    if anaconda.ksdata.vnc.enabled:
        if not anaconda.gui_mode:
            log.info("VNC requested via VNC question, switching Anaconda to GUI mode.")
        anaconda.display_mode = constants.DisplayModes.GUI
        flags.usevnc = True
        vnc_server.password = anaconda.ksdata.vnc.password
示例#32
0
def ask_vnc_question(anaconda, vnc_server, message):
    """ Ask the user if TUI or GUI-over-VNC should be started.

    :param anaconda: instance of the Anaconda class
    :param vnc_server: instance of the VNC server object
    :param str message: a message to show to the user together
                        with the question
    """
    App.initialize()
    loop = App.get_event_loop()
    loop.set_quit_callback(tui_quit_callback)
    spoke = AskVNCSpoke(anaconda.ksdata, message)
    ScreenHandler.schedule_screen(spoke)
    App.run()

    if anaconda.ksdata.vnc.enabled:
        if not anaconda.gui_mode:
            log.info("VNC requested via VNC question, switching Anaconda to GUI mode.")
        anaconda.display_mode = constants.DisplayModes.GUI
        flags.usevnc = True
        vnc_server.password = anaconda.ksdata.vnc.password
示例#33
0
    def setup(self, args="anaconda"):
        environment = args
        should_schedule = TUIHub.setup(self, environment)
        if not should_schedule:
            return False

        if flags.automatedInstall:
            sys.stdout.write(_("Starting automated install"))
            sys.stdout.flush()
            spokes = self._spokes.values()

            while not all(spoke.ready for spoke in spokes):
                # Catch any asynchronous events (like storage crashing)
                loop = App.get_event_loop()
                loop.process_signals()
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(1)

            print('')

        return True
示例#34
0
    def setup(self, args="anaconda"):
        environment = args
        should_schedule = TUIHub.setup(self, environment)
        if not should_schedule:
            return False

        if flags.automatedInstall:
            sys.stdout.write(_("Starting automated install"))
            sys.stdout.flush()
            spokes = self._spokes.values()
            while not all(spoke.ready for spoke in spokes):
                # Catch any asynchronous events (like storage crashing)
                loop = App.get_event_loop()
                loop.process_signals()
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(1)

            print('')
            for spoke in spokes:
                if spoke.changed:
                    spoke.execute()

        return True
    def show_all(self):
        super().show_all()
        from pyanaconda.installation import RunInstallationTask

        # Start the installation task.
        self._task = RunInstallationTask(payload=self.payload,
                                         ksdata=self.data)
        self._task.progress_changed_signal.connect(self._on_progress_changed)
        self._task.stopped_signal.connect(self._on_installation_done)
        self._task.start()

        log.debug("The installation has started.")

        # This will run until the task is finished.
        loop = App.get_event_loop()
        loop.process_signals(return_after=ScreenReadySignal)

        # kickstart install, continue automatically if reboot or shutdown selected
        if flags.automatedInstall and self.data.reboot.action in [
                KS_REBOOT, KS_SHUTDOWN
        ]:
            # Just pretend like we got input, and our input doesn't care
            # what it gets, it just quits.
            raise ExitMainLoop()
    def _on_installation_done(self):
        log.debug("The installation has finished.")

        # Print a new line after the last step.
        if self._stepped:
            print('')

        # Finish the installation task. Re-raise tracebacks if any.
        self._task.finish()

        util.ipmi_report(IPMI_FINISHED)

        if conf.license.eula:
            # Notify user about the EULA (if any).
            print(_("Installation complete"))
            print('')
            print(
                _("Use of this product is subject to the license agreement found at:"
                  ))
            print(conf.license.eula)
            print('')

        loop = App.get_event_loop()
        loop.enqueue_signal(ScreenReadySignal(self))
 def force_quit_mock(self, signal, data=None):
     self._force_quit_called = True
     loop = App.get_event_loop()
     loop.force_quit()
示例#38
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))
示例#39
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))
示例#40
0
 def _post_init_configuration(self):
     App.get_event_loop().register_signal_handler(
         InputReceivedSignal, self.__instance._input_received_handler)