예제 #1
0
def handle_gui_exception(e, msg, parent, formatMsg=True, logMsg=None):
    """
    Handles an exception for the gui by logging the stack trace and
    displaying a user-friendly internationalized message.

    msg = User friendly message to display in GUI.
    parent = Parent window where the error originates.
    logMsg = Optional message to be logged in addition to stack trace.
    formatMsg = if true, string sub the exception error in the msg
    """

    if logMsg:
        log.error(logMsg)
    log.exception(e)

    # If exception is of these types we ignore the given display msg:
    if isinstance(e, socket_error):
        errorWindow(_('Network error, unable to connect to server. Please see /var/log/rhsm/rhsm.log for more information.'),
                parent=parent)
    elif isinstance(e, SSL.SSLError):
        errorWindow(_('Unable to verify server\'s identity: %s') % str(e),
                parent=parent)
    elif isinstance(e, connection.NetworkException):
        # NOTE: yes this looks a lot like the socket error, but I think these
        # were actually intended to display slightly different messages:
        errorWindow(_("Network error. Please check the connection details, or see /var/log/rhsm/rhsm.log for more information."), parent=parent)
    elif isinstance(e, connection.RemoteServerException):
        # This is what happens when there's an issue with the server on the other side of the wire
        errorWindow(_("Remote server error. Please check the connection details, or see /var/log/rhsm/rhsm.log for more information."), parent=parent)
    elif isinstance(e, connection.RestlibException):
        # If this exception's code is in the 200 range (such as 202 ACCEPTED)
        # we're going to ignore the message we were given and just display
        # the message from the server as an info dialog. (not an error)
        if 200 < int(e.code) < 300:
            message = linkify(e.msg)
            messageWindow.InfoDialog(messageWindow.wrap_text(message))

        else:
            try:
                if formatMsg:
                    message = msg % linkify(e.msg)
                else:
                    message = linkify(e.msg)
            except:
                message = msg

            errorWindow(message, parent=parent)

    elif isinstance(e, connection.BadCertificateException):
        errorWindow(_("Bad CA certificate: %s") % e.cert_path, parent=parent)
    else:
        #catch-all, try to interpolate and if it doesn't work out, just display the message
        try:
            interpolatedStr = msg % e
            errorWindow(interpolatedStr, parent=parent)
        except:
            errorWindow(msg, parent=parent)
예제 #2
0
def handle_gui_exception(e, msg, parent, format_msg=True, log_msg=None):
    """
    Handles an exception for the gui by logging the stack trace and
    displaying a user-friendly internationalized message.

    e = either an exception or a tuple returned from sys.exc_info()
    msg = User friendly message to display in GUI.
    parent = Parent window where the error originates.
    log_msg = Optional message to be logged in addition to stack trace.
    format_msg = if true, string sub the exception error in the msg
    """
    if isinstance(e, tuple):
        if not log_msg:
            log_msg = str(e[1])

        log.error(log_msg, exc_info=e)
        # Get the class instance of the exception
        e = e[1]
    else:
        if log_msg:
            log.error(log_msg)
        log.exception(e)

    exception_mapper = ExceptionMapper()
    mapped_message = exception_mapper.get_message(e)
    if mapped_message:
        if isinstance(e, connection.RestlibException):
            # If this exception's code is in the 200 range (such as 202 ACCEPTED)
            # we're going to ignore the message we were given and just display
            # the message from the server as an info dialog. (not an error)
            if 200 < int(e.code) < 300:
                message = linkify(mapped_message)
                messageWindow.InfoDialog(messageWindow.wrap_text(message))

            else:
                try:
                    if format_msg:
                        message = msg % linkify(mapped_message)
                    else:
                        message = linkify(mapped_message)
                except Exception:
                    message = msg

                show_error_window(message, parent=parent)
        else:
            show_error_window(mapped_message, parent)
    else:
        #catch-all, try to interpolate and if it doesn't work out, just display the message
        try:
            interpolated_str = msg % e
            show_error_window(interpolated_str, parent=parent)
        except Exception:
            show_error_window(msg, parent=parent)
예제 #3
0
def show_info_window(message, parent=None):
    messageWindow.InfoDialog(messageWindow.wrap_text(message), parent)
예제 #4
0
class ImportSubDialog(object):
    """
    Dialog to manually import an entitlement certificate for this machine.
    Generally used for disconnected (unregistered) systems.
    """
    def __init__(self):
        self._parent = None

        self.dialog = gtk.FileChooserDialog(_("Import Certificates"),
                None, gtk.FILE_CHOOSER_ACTION_OPEN,
                (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                 _("Import"), gtk.RESPONSE_OK))
        self.dialog.set_default_response(gtk.RESPONSE_OK)
        self.dialog.set_modal(True)

        self.dialog.set_local_only(True)
        self.dialog.set_select_multiple(True)
        self.dialog.set_icon_name('subscription-manager')

        afilter = gtk.FileFilter()
        afilter.set_name(_("Certificates"))
        afilter.add_pattern("*.pem")
        self.dialog.add_filter(afilter)

        afilter = gtk.FileFilter()
        afilter.set_name(_("All files"))
        afilter.add_pattern("*")
        self.dialog.add_filter(afilter)

        self.dialog.connect("response", self._on_dialog_response)
        self.dialog.connect("delete-event", self._delete_event)

    def _on_dialog_response(self, dialog, response_id):
        if response_id == gtk.RESPONSE_CANCEL:
            return self._cancel_button_clicked()
        elif response_id == gtk.RESPONSE_OK:
            return self._import_button_clicked()
        # other response is on dialog destroy, we don't act on that.

    def _cancel_button_clicked(self):
        self.dialog.hide()
        return True

    def show(self):
        self.dialog.present()

    def _delete_event(self, event, data=None):
        return self._cancel_button_clicked()

    def _import_button_clicked(self):
        src_cert_files = self.dialog.get_filenames()

        invalid_certs = []
        error_certs = []
        good_certs = []
        imported_certs = []
        non_cert_files = []

        for cert_file in src_cert_files:
            if not os.path.exists(cert_file):
                non_cert_files.append(cert_file)
            else:
                # Check to see if we have a key included in the cert file
                try:
                    extractor = ImportFileExtractor(cert_file)

                    #Verify the entitlement data.
                    if not extractor.verify_valid_entitlement():
                        log.error("Invalid X509 entitlement certificate.")
                        log.error("Error parsing manually imported entitlement "
                            "certificate: %s" % cert_file)
                        invalid_certs.append(cert_file)
                    else:
                        extractor.write_to_disk()
                        good_certs.append(cert_file)
                        imported_certs.append(extractor.get_cert())
                except Exception, e:
                    # Should not get here unless something really bad happened.
                    log.exception(e)
                    error_certs.append(cert_file)

        if imported_certs:
            brands_installer = rhelentbranding.RHELBrandsInstaller()
            brands_installer.install()

        if len(error_certs) > 0 \
            or len(invalid_certs) > 0 \
            or len(non_cert_files) > 0:

            msg = ""
            if len(non_cert_files) > 0:
                msg += _("The following certificate files did not exist:")
                msg += "\n" + "\n".join(non_cert_files)
            if len(invalid_certs) > 0:
                msg += _("The following files are not valid certificates and were not imported:")
                msg += "\n" + "\n".join(invalid_certs)
            if len(error_certs) > 0:
                if len(invalid_certs) > 0:
                    msg += "\n\n"
                msg += _("An error occurred while importing the following certificates. Please check the log file for more information.")
                msg += "\n" + "\n".join(error_certs)
            if len(good_certs) > 0:
                msg += "\n\n"
                msg += _("The following certificates were successfully imported:")
                msg += "\n" + "\n".join(good_certs)
            show_error_window(msg, parent=self._parent)
        else:
            #if we get to this point, the import was successful
            messageWindow.InfoDialog(_("Certificate import was successful."),
                    parent=self._parent)
        self.dialog.hide()
        self.dialog.unselect_all()
    def __init__(self,
                 backend=None,
                 ent_dir=None,
                 prod_dir=None,
                 auto_launch_registration=False):
        super(MainWindow, self).__init__()

        # When proxy server is set in configuration and it is not
        # possible to connect to proxy server, then open dialog
        # for setting proxy server.
        if not utils.test_proxy_reachability():
            print_error(
                _("Proxy connection failed, please check your settings."))
            error_dialog = messageWindow.ContinueDialog(
                _("Proxy connection failed, please check your settings."),
                self._get_window())
            error_dialog.connect("response",
                                 self._on_proxy_error_dialog_response)
            self.network_config_dialog = networkConfig.NetworkConfigDialog()
            # Sub-man gui will be terminated after saving settings and it is
            # necessary to start it once again.
            self.network_config_dialog.saveButton.connect(
                "clicked", self._exit)
            self.network_config_dialog.cancelButton.connect(
                "clicked", self._exit)
            return

        self.backend = backend or Backend()
        self.identity = require(IDENTITY)

        log.debug("Client Versions: %s " % get_client_versions())
        # Log the server version asynchronously
        ga_GLib.idle_add(self.log_server_version,
                         self.backend.cp_provider.get_consumer_auth_cp())

        settings = self.main_window.get_settings()

        # prevent gtk from trying to save a list of recently used files, which
        # as root, causes gtk warning:
        #  "Attempting to set the permissions of `/root/.local/share/recently-used.xbel'
        # The __name__ use is just for the 'origin' value gtk uses to store
        # where a Gtk.Settings value was set.
        settings.set_long_property('gtk-recent-files-max-age', 0,
                                   "%s:%s" % (__name__, type(self).__name__))

        ga_Gtk.Window.set_default_icon_name("subscription-manager")

        self.product_dir = prod_dir or self.backend.product_dir
        self.entitlement_dir = ent_dir or self.backend.entitlement_dir

        self.system_facts_dialog = factsgui.SystemFactsDialog(
            update_callback=self._handle_facts_updated)

        self.preferences_dialog = PreferencesDialog(self.backend,
                                                    self._get_window())

        self.repos_dialog = RepositoriesDialog(self.backend,
                                               self._get_window())

        self.import_sub_dialog = ImportSubDialog()

        self.network_config_dialog = networkConfig.NetworkConfigDialog()
        self.network_config_dialog.saveButton.connect("clicked",
                                                      self._config_changed)

        self.redeem_dialog = redeem.RedeemDialog(self.backend)

        self.installed_tab_icon = ga_Gtk.Image()
        self.installed_tab_icon.set_from_stock(ga_Gtk.STOCK_YES,
                                               ga_Gtk.IconSize.MENU)

        self.installed_tab = InstalledProductsTab(self.backend,
                                                  self.installed_tab_icon,
                                                  self,
                                                  ent_dir=self.entitlement_dir,
                                                  prod_dir=self.product_dir)

        self.my_subs_tab = MySubscriptionsTab(self.backend,
                                              self.main_window,
                                              ent_dir=self.entitlement_dir,
                                              prod_dir=self.product_dir)

        self.all_subs_tab = AllSubscriptionsTab(self.backend, self.main_window)

        hbox = ga_Gtk.HBox(spacing=6)
        hbox.pack_start(self.installed_tab_icon, False, False, 0)
        hbox.pack_start(ga_Gtk.Label(self.installed_tab.get_label()), False,
                        False, 0)
        self.notebook.append_page(self.installed_tab.get_content(), hbox)
        hbox.show_all()

        self.notebook.append_page(self.my_subs_tab.get_content(),
                                  ga_Gtk.Label(self.my_subs_tab.get_label()))

        self.connect_signals({
            "on_register_menu_item_activate": self._register_item_clicked,
            "on_unregister_menu_item_activate": self._unregister_item_clicked,
            "on_import_cert_menu_item_activate":
            self._import_cert_item_clicked,
            "on_view_facts_menu_item_activate": self._facts_item_clicked,
            "on_proxy_config_menu_item_activate":
            self._proxy_config_item_clicked,
            "on_redeem_menu_item_activate": self._redeem_item_clicked,
            "on_preferences_menu_item_activate":
            self._preferences_item_clicked,
            "on_repos_menu_item_activate": self._repos_item_clicked,
            "on_about_menu_item_activate": self._about_item_clicked,
            "on_getting_started_menu_item_activate":
            self._getting_started_item_clicked,
            "on_online_docs_menu_item_activate":
            self._online_docs_item_clicked,
            "on_quit_menu_item_activate": ga_Gtk.main_quit,
        })

        # various state tracking for async operations
        self._show_overrides = False
        self._can_redeem = False

        self.backend.cs.add_callback(self.on_cert_sorter_cert_change)

        self.main_window.show_all()

        # Check to see if already registered to old RHN/Spacewalk
        # and show dialog if so
        self._check_rhn_classic()

        # Update everything with compliance data
        self.backend.cs.notify()

        # managergui needs cert_sort.cert_monitor.run_check() to run
        # on a timer to detect cert changes from outside the gui
        # (via rhsmdd for example, or manually provisioned).
        cert_monitor_thread = threading.Thread(target=self._cert_check_timer,
                                               name="CertMonitorThread")
        cert_monitor_thread.daemon = True
        cert_monitor_thread.start()

        if auto_launch_registration and not self.registered():
            self._register_item_clicked(None)

        enabled_yum_plugins = YumPluginManager.enable_yum_plugins()
        if len(enabled_yum_plugins) > 0:
            messageWindow.InfoDialog(
                YumPluginManager.warning_message(enabled_yum_plugins),
                self._get_window(),
                _("Warning - subscription-manager plugins were automatically enabled"
                  ))
예제 #6
0
    def _import_button_clicked(self):
        src_cert_files = self.dialog.get_filenames()

        invalid_certs = []
        error_certs = []
        good_certs = []
        imported_certs = []
        non_cert_files = []

        for cert_file in src_cert_files:
            if not os.path.exists(cert_file):
                non_cert_files.append(cert_file)
            else:
                # Check to see if we have a key included in the cert file
                try:
                    extractor = ImportFileExtractor(cert_file)

                    #Verify the entitlement data.
                    if not extractor.verify_valid_entitlement():
                        log.error("Invalid X509 entitlement certificate.")
                        log.error(
                            "Error parsing manually imported entitlement "
                            "certificate: %s" % cert_file)
                        invalid_certs.append(cert_file)
                    else:
                        extractor.write_to_disk()
                        good_certs.append(cert_file)
                        imported_certs.append(extractor.get_cert())
                except Exception as e:
                    # Should not get here unless something really bad happened.
                    log.exception(e)
                    error_certs.append(cert_file)

        if imported_certs:
            brands_installer = rhelentbranding.RHELBrandsInstaller()
            brands_installer.install()

        if len(error_certs) > 0 \
            or len(invalid_certs) > 0 \
            or len(non_cert_files) > 0:

            msg = ""
            if len(non_cert_files) > 0:
                msg += _("The following certificate files did not exist:")
                msg += "\n" + "\n".join(non_cert_files)
            if len(invalid_certs) > 0:
                msg += _(
                    "The following files are not valid certificates and were not imported:"
                )
                msg += "\n" + "\n".join(invalid_certs)
            if len(error_certs) > 0:
                if len(invalid_certs) > 0:
                    msg += "\n\n"
                msg += _(
                    "An error occurred while importing the following certificates. Please check the log file for more information."
                )
                msg += "\n" + "\n".join(error_certs)
            if len(good_certs) > 0:
                msg += "\n\n"
                msg += _(
                    "The following certificates were successfully imported:")
                msg += "\n" + "\n".join(good_certs)
            show_error_window(msg, parent=self._parent)
        else:
            #if we get to this point, the import was successful
            messageWindow.InfoDialog(_("Certificate import was successful."),
                                     parent=self._parent)
        self.dialog.hide()
        self.dialog.unselect_all()
예제 #7
0
    def __init__(self,
                 backend=None,
                 ent_dir=None,
                 prod_dir=None,
                 auto_launch_registration=False):
        super(MainWindow, self).__init__()

        rhsm_cfg = config.get_config_parser()
        proxy_server = rhsm_cfg.get("server", "proxy_hostname")
        proxy_port = int(
            rhsm_cfg.get("server", "proxy_port") or config.DEFAULT_PROXY_PORT)

        def show_proxy_error_dialog(proxy_auth_required=False):
            """
            When proxy server is set in configuration and it is not
            possible to connect to proxy server, then open dialog
            for setting proxy server.
            """
            if proxy_auth_required:
                proxy_user = rhsm_cfg.get("server", "proxy_user")
                proxy_password = rhsm_cfg.get("server", "proxy_password")
                if proxy_user or proxy_password:
                    err_msg = _(
                        "Wrong proxy username or password, please check your settings."
                    )
                else:
                    err_msg = _(
                        "Proxy authentication required, please check your settings."
                    )
            else:
                err_msg = _(
                    "Proxy connection failed, please check your settings.")
            print_error(err_msg)
            error_dialog = messageWindow.ContinueDialog(
                err_msg, self._get_window())
            error_dialog.connect("response",
                                 self._on_proxy_error_dialog_response)
            self.network_config_dialog = networkConfig.NetworkConfigDialog()
            # Sub-man gui will be terminated after saving settings and it is
            # necessary to start it once again.
            self.network_config_dialog.saveButton.connect(
                "clicked", self._exit)
            self.network_config_dialog.cancelButton.connect(
                "clicked", self._exit)

        self.backend = backend or Backend()
        cp = self.backend.cp_provider.get_consumer_auth_cp()

        # allow specifying no_proxy via api or config
        no_proxy = rhsm_cfg.get('server', 'no_proxy')
        if no_proxy:
            os.environ['no_proxy'] = no_proxy

        rhsm_utils.fix_no_proxy()
        log.debug('Environment variable NO_PROXY=%s will be used' % no_proxy)

        # Don't check the proxy server if the hostname we aim to connect to is covered by no_proxy
        if proxy_server and not urllib.request.proxy_bypass(
                rhsm_cfg.get('server', 'hostname')):
            if not utils.test_proxy_reachability(proxy_server, proxy_port):
                show_proxy_error_dialog()
                return

            try:
                # Try to send to the simplest Rest API call to Candlepin server.
                # This result will be used for getting version of Candlepin server.
                # See self.log_server_version.
                cp.supports_resource("status")
            except (socket.error, connection.ProxyException) as err:
                # See https://tools.ietf.org/html/rfc7235#section-4.3
                if "407 Proxy Authentication Required" in str(err.message):
                    show_proxy_error_dialog(proxy_auth_required=True)
                    return

        self.identity = require(IDENTITY)
        log.debug("Client Versions: %s " % get_client_versions())
        ga_GLib.idle_add(self.log_server_version, cp)

        settings = self.main_window.get_settings()

        # prevent gtk from trying to save a list of recently used files, which
        # as root, causes gtk warning:
        #  "Attempting to set the permissions of `/root/.local/share/recently-used.xbel'
        # The __name__ use is just for the 'origin' value gtk uses to store
        # where a Gtk.Settings value was set.
        settings.set_long_property('gtk-recent-files-max-age', 0,
                                   "%s:%s" % (__name__, type(self).__name__))

        ga_Gtk.Window.set_default_icon_name("subscription-manager")

        self.product_dir = prod_dir or self.backend.product_dir
        self.entitlement_dir = ent_dir or self.backend.entitlement_dir

        self.system_facts_dialog = factsgui.SystemFactsDialog(
            update_callback=self._handle_facts_updated)

        self.preferences_dialog = PreferencesDialog(self.backend,
                                                    self._get_window())

        self.repos_dialog = RepositoriesDialog(self.backend,
                                               self._get_window())

        self.import_sub_dialog = ImportSubDialog()

        self.network_config_dialog = networkConfig.NetworkConfigDialog()
        self.network_config_dialog.saveButton.connect("clicked",
                                                      self._config_changed)

        self.redeem_dialog = redeem.RedeemDialog(self.backend)

        self.installed_tab_icon = ga_Gtk.Image()
        self.installed_tab_icon.set_from_stock(ga_Gtk.STOCK_YES,
                                               ga_Gtk.IconSize.MENU)

        self.installed_tab = InstalledProductsTab(self.backend,
                                                  self.installed_tab_icon,
                                                  self,
                                                  ent_dir=self.entitlement_dir,
                                                  prod_dir=self.product_dir)

        self.my_subs_tab = MySubscriptionsTab(self.backend,
                                              self.main_window,
                                              ent_dir=self.entitlement_dir,
                                              prod_dir=self.product_dir)

        self.all_subs_tab = AllSubscriptionsTab(self.backend, self.main_window)

        hbox = ga_Gtk.HBox(spacing=6)
        hbox.pack_start(self.installed_tab_icon, False, False, 0)
        hbox.pack_start(ga_Gtk.Label(self.installed_tab.get_label()), False,
                        False, 0)
        self.notebook.append_page(self.installed_tab.get_content(), hbox)
        hbox.show_all()

        self.notebook.append_page(self.my_subs_tab.get_content(),
                                  ga_Gtk.Label(self.my_subs_tab.get_label()))

        self.connect_signals({
            "on_register_menu_item_activate": self._register_item_clicked,
            "on_unregister_menu_item_activate": self._unregister_item_clicked,
            "on_import_cert_menu_item_activate":
            self._import_cert_item_clicked,
            "on_view_facts_menu_item_activate": self._facts_item_clicked,
            "on_proxy_config_menu_item_activate":
            self._proxy_config_item_clicked,
            "on_redeem_menu_item_activate": self._redeem_item_clicked,
            "on_preferences_menu_item_activate":
            self._preferences_item_clicked,
            "on_repos_menu_item_activate": self._repos_item_clicked,
            "on_about_menu_item_activate": self._about_item_clicked,
            "on_getting_started_menu_item_activate":
            self._getting_started_item_clicked,
            "on_online_docs_menu_item_activate":
            self._online_docs_item_clicked,
            "on_quit_menu_item_activate": ga_Gtk.main_quit,
        })

        # various state tracking for async operations
        self._show_overrides = False
        self._can_redeem = False

        self.backend.cs.add_callback(self.on_cert_sorter_cert_change)

        self.main_window.show_all()

        # Check to see if already registered to old RHN/Spacewalk
        # and show dialog if so
        self._check_rhn_classic()

        # Update everything with compliance data
        self.backend.cs.notify()

        # managergui needs cert_sort.cert_monitor.run_check() to run
        # on a timer to detect cert changes from outside the gui
        # (via manual provisioning).
        cert_monitor_thread = threading.Thread(target=self._cert_check_timer,
                                               name="CertMonitorThread")
        cert_monitor_thread.daemon = True
        cert_monitor_thread.start()

        if auto_launch_registration and not self.registered():
            self._register_item_clicked(None)

        enabled_yum_plugins = YumPluginManager.enable_pkg_plugins()
        if len(enabled_yum_plugins) > 0:
            messageWindow.InfoDialog(
                YumPluginManager.warning_message(enabled_yum_plugins),
                self._get_window(),
                _("Warning - subscription-manager plugins were automatically enabled"
                  ))