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)
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)
def show_info_window(message, parent=None): messageWindow.InfoDialog(messageWindow.wrap_text(message), parent)
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" ))
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()
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" ))