Blob Blame History Raw
diff --git a/Makefile b/Makefile
index 12b891e..fb0d2eb 100644
--- a/Makefile
+++ b/Makefile
@@ -307,6 +307,7 @@ install-ui:
 install-gui: install-glade install-ui
 
 install-files: set-versions dbus-service-install desktop-files install-plugins install-post-boot install-ga install-gui
+	install -d $(PYTHON_INST_DIR)/api
 	install -d $(PYTHON_INST_DIR)/gui
 	install -d $(PYTHON_INST_DIR)/gui/data/icons
 	install -d $(PYTHON_INST_DIR)/branding
@@ -356,6 +357,7 @@ install-files: set-versions dbus-service-install desktop-files install-plugins i
 
 
 	install -m 644 -p $(SRC_DIR)/*.py $(PYTHON_INST_DIR)/
+	install -m 644 -p $(SRC_DIR)/api/*.py $(PYTHON_INST_DIR)/api
 	install -m 644 -p $(SRC_DIR)/gui/*.py $(PYTHON_INST_DIR)/gui
 	install -m 644 -p $(SRC_DIR)/migrate/*.py $(PYTHON_INST_DIR)/migrate
 	install -m 644 -p $(SRC_DIR)/branding/*.py $(PYTHON_INST_DIR)/branding
diff --git a/rel-eng/packages/subscription-manager b/rel-eng/packages/subscription-manager
index c569df4..b7ea50a 100644
--- a/rel-eng/packages/subscription-manager
+++ b/rel-eng/packages/subscription-manager
@@ -1 +1 @@
-1.15.9-3 ./
+1.15.9-4 ./
diff --git a/setup.py b/setup.py
index ebac808..b27670b 100644
--- a/setup.py
+++ b/setup.py
@@ -23,6 +23,7 @@ setup(name="subscription-manager",
       author="Adrian Likins",
       author_email="alikins@redhat.com",
       packages=['src/subscription_manager',
+                'src/subscription_manager/api',
                 'src/subscription_manager/gui',
                 'src/subscription_manager/plugin',
                 'src/subscription_manager/plugin/ostree',
diff --git a/src/initial-setup/com_redhat_subscription_manager/gui/spokes/rhsm_gui.py b/src/initial-setup/com_redhat_subscription_manager/gui/spokes/rhsm_gui.py
index 73cb2ca..09ca0b6 100644
--- a/src/initial-setup/com_redhat_subscription_manager/gui/spokes/rhsm_gui.py
+++ b/src/initial-setup/com_redhat_subscription_manager/gui/spokes/rhsm_gui.py
@@ -22,7 +22,6 @@ import sys
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
 from pyanaconda.ui.categories.system import SystemCategory
-from pyanaconda.ui.gui import GUIObject
 
 log = logging.getLogger(__name__)
 
@@ -81,6 +80,8 @@ class RHSMSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
         # each attaching different handlers.
         self._registergui.close_window_callback = self._close_window_callback
 
+        self._registergui._error_screen = registergui.CHOOSE_SERVER_PAGE
+
         # we have a ref to _register_box, but need to remove it from
         # the regustergui.window (a GtkDialog), and add it to the main
         # box in the action area of our initial-setup screen.
@@ -91,10 +92,12 @@ class RHSMSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
         self._registergui.initialize()
 
     def _close_window_callback(self):
-        pass
+        self._registergui.goto_error_screen()
 
     def finished(self):
         self._registergui.done()
+        self._registergui.cancel_button.hide()
+        self._registergui.register_button.hide()
         self._done = True
 
     # Update gui widgets to reflect state of self.data
diff --git a/src/subscription_manager/async.py b/src/subscription_manager/async.py
index 05433f9..41a9aab 100644
--- a/src/subscription_manager/async.py
+++ b/src/subscription_manager/async.py
@@ -61,7 +61,7 @@ class AsyncPool(object):
         Run pool stash refresh asynchronously.
         """
         ga_GObject.idle_add(self._watch_thread)
-        threading.Thread(target=self._run_refresh,
+        threading.Thread(target=self._run_refresh, name="AsyncPoolRefreshThread",
                 args=(active_on, callback, data)).start()
 
 
@@ -105,11 +105,11 @@ class AsyncBind(object):
             ga_GObject.idle_add(except_callback, e, selection)
 
     def bind(self, pool, quantity, except_callback, bind_callback=None, cert_callback=None):
-        threading.Thread(target=self._run_bind,
+        threading.Thread(target=self._run_bind, name="AsyncBindBindThread",
                 args=(pool, quantity, bind_callback, cert_callback, except_callback)).start()
 
     def unbind(self, serial, selection, callback, except_callback):
-        threading.Thread(target=self._run_unbind,
+        threading.Thread(target=self._run_unbind, name="AsyncBindUnbindThread",
                 args=(serial, selection, callback, except_callback)).start()
 
 
@@ -177,10 +177,13 @@ class AsyncRepoOverridesUpdate(object):
         ga_GObject.idle_add(callback, *args)
 
     def load_data(self, success_callback, failure_callback):
-        threading.Thread(target=self._load_data, args=(success_callback, failure_callback)).start()
+        threading.Thread(target=self._load_data, name="AsyncRepoOverridesUpdateLoadDataThread",
+                         args=(success_callback, failure_callback)).start()
 
     def update_overrides(self, to_add, to_remove, success_callback, except_callback):
-        threading.Thread(target=self._update, args=(to_add, to_remove, success_callback, except_callback)).start()
+        threading.Thread(target=self._update, name="AsyncRepoOverridesUpdateUpdateOverridesThread",
+                         args=(to_add, to_remove, success_callback, except_callback)).start()
 
     def remove_all_overrides(self, repo_ids, success_callback, except_callback):
-        threading.Thread(target=self._remove_all, args=(repo_ids, success_callback, except_callback)).start()
+        threading.Thread(target=self._remove_all, name="AsyncRepoOverridesUpdateRemoveAllOverridesThread",
+                         args=(repo_ids, success_callback, except_callback)).start()
diff --git a/src/subscription_manager/ga_loader.py b/src/subscription_manager/ga_loader.py
index 59a00f6..1d7912e 100644
--- a/src/subscription_manager/ga_loader.py
+++ b/src/subscription_manager/ga_loader.py
@@ -94,9 +94,6 @@ class GaImporter(object):
         return None
 
     def load_module(self, fullname):
-        log.debug("ga_loader class %s loading virtual module %s from %s",
-                  self.__class__.__name__,
-                  fullname, self.virtual_modules[fullname])
         if fullname in sys.modules:
             return sys.modules[fullname]
 
@@ -150,14 +147,6 @@ class GaImporter(object):
         """
         return self._new_module(self.namespace)
 
-    def _dirprint(self, module):
-        return
-        print "module ", module, type(module)
-        for i in dir(module):
-            if i == "__builtins__":
-                continue
-            print "\t%s = %s" % (i, getattr(module, i))
-
 
 class GaImporterGtk3(GaImporter):
     virtual_modules = {'subscription_manager.ga': None,
diff --git a/src/subscription_manager/gui/allsubs.py b/src/subscription_manager/gui/allsubs.py
index fe27082..5d6d7af 100644
--- a/src/subscription_manager/gui/allsubs.py
+++ b/src/subscription_manager/gui/allsubs.py
@@ -363,9 +363,7 @@ class AllSubscriptionsTab(widgets.SubscriptionManagerTab):
                 # show pulsating progress bar while we wait for results
                 self.pb = progress.Progress(pb_title, pb_label)
                 self.timer = ga_GObject.timeout_add(100, self.pb.pulse)
-                tl = self.content.get_toplevel()
-                if tl.is_toplevel():
-                    self.pb.set_parent_window(tl)
+                self.pb.set_transient_for(self.parent_win)
 
             # fire off async refresh
             async_stash = async.AsyncPool(self.pool_stash)
@@ -410,11 +408,7 @@ class AllSubscriptionsTab(widgets.SubscriptionManagerTab):
         self.pb = progress.Progress(_("Attaching"),
                 _("Attaching subscription. Please wait."))
         self.timer = ga_GObject.timeout_add(100, self.pb.pulse)
-        content_toplevel = self.content.get_toplevel()
-        # get_toplevel() can return a GtkWindow that is within another
-        # GtkWindow. See the get_toplevel() gtk docs
-        if content_toplevel.is_toplevel():
-            self.pb.set_parent_window(content_toplevel)
+        self.pb.set_transient_for(self.parent_win)
         # Spin off a thread to handle binding the selected pool.
         # After it has completed the actual bind call, available
         # subs will be refreshed, but we won't re-run compliance
@@ -451,10 +445,7 @@ class AllSubscriptionsTab(widgets.SubscriptionManagerTab):
         self.contract_selection = ContractSelectionWindow(
                 self._contract_selected, self._contract_selection_cancelled)
 
-        content_toplevel = self.content.get_toplevel()
-        self.log.debug("content_toplevel %s", content_toplevel)
-        if content_toplevel.is_toplevel():
-            self.contract_selection.set_parent_window(content_toplevel)
+        self.contract_selection.set_parent_window(self.parent_win)
         #self.log.debug("user_data %s", pw.get_user_data())
         merged_pools.sort_virt_to_top()
 
diff --git a/src/subscription_manager/gui/contract_selection.py b/src/subscription_manager/gui/contract_selection.py
index 70233d2..9c5572e 100644
--- a/src/subscription_manager/gui/contract_selection.py
+++ b/src/subscription_manager/gui/contract_selection.py
@@ -168,14 +168,6 @@ class ContractSelectionWindow(widgets.SubmanBaseWidget):
             'quantity_increment': quantity_increment,
             })
 
-    def toplevel(self):
-        tl = self.get_toplevel()
-        if tl.is_toplevel():
-            return tl
-        else:
-            self.log.debug("no toplevel window?")
-            return None
-
     def set_parent_window(self, window):
         self.log.debug('window %s', window)
         self.contract_selection_window.set_transient_for(window)
diff --git a/src/subscription_manager/gui/firstboot/rhsm_login.py b/src/subscription_manager/gui/firstboot/rhsm_login.py
index 791607d..7c06f19 100644
--- a/src/subscription_manager/gui/firstboot/rhsm_login.py
+++ b/src/subscription_manager/gui/firstboot/rhsm_login.py
@@ -255,6 +255,7 @@ class moduleClass(RhsmFirstbootModule, registergui.RegisterScreen):
         else:
             return registergui.CHOOSE_SERVER_PAGE
 
+    @property
     def error_screen(self):
         return self._get_initial_screen()
 
diff --git a/src/subscription_manager/gui/mysubstab.py b/src/subscription_manager/gui/mysubstab.py
index 4c5922d..adc471c 100644
--- a/src/subscription_manager/gui/mysubstab.py
+++ b/src/subscription_manager/gui/mysubstab.py
@@ -146,9 +146,7 @@ class MySubscriptionsTab(widgets.SubscriptionManagerTab):
             self.pb = progress.Progress(_("Removing"),
                     _("Removing subscription. Please wait."))
             self.timer = ga_GObject.timeout_add(100, self.pb.pulse)
-            content_toplevel = self.content.get_toplevel()
-            if content_toplevel.is_toplevel():
-                self.pb.set_parent_window(content_toplevel)
+            self.pb.set_transient_for(self.parent_win)
             self.async_bind.unbind(serial, selection, self._unsubscribe_callback, self._handle_unbind_exception)
         else:
             # unregistered, just delete the certs directly
diff --git a/src/subscription_manager/gui/networkConfig.py b/src/subscription_manager/gui/networkConfig.py
index 503839b..7efd0b1 100644
--- a/src/subscription_manager/gui/networkConfig.py
+++ b/src/subscription_manager/gui/networkConfig.py
@@ -264,7 +264,7 @@ class NetworkConfigDialog(widgets.SubmanBaseWidget):
         self._display_progress_bar()
         threading.Thread(target=self.test_connection_wrapper,
                          args=(proxy_host, proxy_port, proxy_user, proxy_password),
-                         name='test_connection_thread').start()
+                         name='TestNetworkConnectionThread').start()
 
     def deleted(self, event, data):
         self.write_values()
@@ -279,7 +279,7 @@ class NetworkConfigDialog(widgets.SubmanBaseWidget):
         else:
             self.progress_bar = progress.Progress(_("Testing Connection"), _("Please wait"))
             self.timer = ga_GObject.timeout_add(100, self.progress_bar.pulse)
-            self.progress_bar.set_parent_window(self.networkConfigDialog)
+            self.progress_bar.set_transient_for(self.networkConfigDialog)
 
     def _clear_progress_bar(self):
         if not self.progress_bar:  # progress bar could be none iff self.test_connection is called directly
diff --git a/src/subscription_manager/gui/progress.py b/src/subscription_manager/gui/progress.py
index 61b2b2d..5aa938e 100644
--- a/src/subscription_manager/gui/progress.py
+++ b/src/subscription_manager/gui/progress.py
@@ -75,7 +75,7 @@ class Progress(widgets.SubmanBaseWidget):
     def set_status_label(self, text):
         self.statusLabel.set_text(text)
 
-    def set_parent_window(self, window):
+    def set_transient_for(self, window):
         self.progressWindow.set_transient_for(window)
 
     def _on_delete_event(self, widget, event):
diff --git a/src/subscription_manager/gui/registergui.py b/src/subscription_manager/gui/registergui.py
index c56ec5b..123c783 100644
--- a/src/subscription_manager/gui/registergui.py
+++ b/src/subscription_manager/gui/registergui.py
@@ -294,6 +294,7 @@ class RegisterScreen(widgets.SubmanBaseWidget):
                         screen.container, tab_label=None)
 
         self._current_screen = CHOOSE_SERVER_PAGE
+        self._error_screen = DONT_CHANGE
 
         # values that will be set by the screens
         self.username = None
@@ -337,15 +338,24 @@ class RegisterScreen(widgets.SubmanBaseWidget):
     # for subman gui, we don't need to switch screens on error
     # but for firstboot, we will go back to the info screen if
     # we have it.
+    @property
     def error_screen(self):
-        return DONT_CHANGE
+        return self._error_screen
+
+    def goto_error_screen(self):
+        self._set_navigation_sensitive(True)
+        self._set_screen(self.error_screen)
 
     # FIXME: This exists because standalone gui needs to update the nav
     #        buttons in it's own top level window, while firstboot needs to
     #        update the buttons in the main firstboot window. Firstboot version
     #        has additional logic for rhel5/rhel6 differences.
+    # FIXME: just split this into a registerWidget and a registerDialog
     def _set_navigation_sensitive(self, sensitive):
-        self.cancel_button.set_sensitive(sensitive)
+        # We could unsens the cancel button here, but since we use it as
+        # a 'do over' button that sends the dialog back to the start, just
+        # leave it enabled, to avoid leaving un unsens after an async error
+        # handler.
         self.register_button.set_sensitive(sensitive)
 
     def _set_screen(self, screen):
@@ -421,6 +431,10 @@ class RegisterScreen(widgets.SubmanBaseWidget):
         # XXX it would be cool here to do some async spinning while the
         # main window gui refreshes itself
 
+        if failed:
+            self.goto_error_screen()
+            return
+
         # FIXME: subman-gui needs this but initial-setup doesnt
         self.close_window_callback()
 
@@ -1151,16 +1165,16 @@ class ChooseServerScreen(Screen):
                     show_error_window(_("Unable to reach the server at %s:%s%s") %
                                       (hostname, port, prefix),
                                       self._parent.window)
-                    return self._parent.error_screen()
+                    return self._parent.error_screen
             except MissingCaCertException:
                 show_error_window(_("CA certificate for subscription service has not been installed."),
                                   self._parent.window)
-                return self._parent.error_screen()
+                return self._parent.error_screen
 
         except ServerUrlParseError:
             show_error_window(_("Please provide a hostname with optional port and/or prefix: hostname[:port][/prefix]"),
                               self._parent.window)
-            return self._parent.error_screen()
+            return self._parent.error_screen
 
         log.debug("Writing server data to rhsm.conf")
         CFG.save()
diff --git a/src/subscription_manager/gui/reposgui.py b/src/subscription_manager/gui/reposgui.py
index 2b6a391..4c00ead 100644
--- a/src/subscription_manager/gui/reposgui.py
+++ b/src/subscription_manager/gui/reposgui.py
@@ -250,7 +250,7 @@ class RepositoriesDialog(widgets.SubmanBaseWidget, HasSortableWidget):
     def _show_progress_bar(self, title, label, progress_parent=None):
         self.pb = progress.Progress(title, label, True)
         self.timer = ga_GObject.timeout_add(100, self.pb.pulse)
-        self.pb.set_parent_window(progress_parent or self._get_dialog_widget())
+        self.pb.set_transient_for(progress_parent or self._get_dialog_widget())
 
     def _clear_progress_bar(self):
         if self.pb:
diff --git a/src/subscription_manager/gui/utils.py b/src/subscription_manager/gui/utils.py
index 6535c7d..6c77ff7 100644
--- a/src/subscription_manager/gui/utils.py
+++ b/src/subscription_manager/gui/utils.py
@@ -264,5 +264,6 @@ class AsyncWidgetUpdater(object):
             ga_GObject.idle_add(widget_update.finished)
 
     def update(self, widget_update, backend_method, args=None, kwargs=None, exception_msg=None, callback=None):
-        threading.Thread(target=self.worker, args=(widget_update,
-            backend_method, args, kwargs, exception_msg, callback)).start()
+        threading.Thread(target=self.worker, name="AsyncWidgetUpdaterThread",
+                         args=(widget_update, backend_method, args,
+                               kwargs, exception_msg, callback)).start()
diff --git a/subscription-manager.spec b/subscription-manager.spec
index a44c4db..c762947 100644
--- a/subscription-manager.spec
+++ b/subscription-manager.spec
@@ -3,10 +3,22 @@
 # For optional building of ostree-plugin sub package. Unrelated to systemd
 # but the same versions apply at the moment.
 %global has_ostree %use_systemd
-%global use_old_firstboot (0%{?rhel} && 0%{?rhel} <= 6)
+%global use_firstboot 0
+%global use_initial_setup 1
 %global rhsm_plugins_dir  /usr/share/rhsm-plugins
 %global use_gtk3 %use_systemd
-%global use_initial_setup %use_systemd
+%global rhel7_minor %(%{__grep} -o "7.[0-9]*" /etc/redhat-release |%{__sed} -s 's/7.//')
+
+%if 0%{?rhel} == 7
+%global use_initial_setup 1
+%global use_firstboot 0
+%endif
+
+# 6 < rhel < 7
+%if 0%{?rhel} == 6
+%global use_initial_setup 0
+%global use_firstboot 1
+%endif
 
 %global _hardened_build 1
 %{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro -Wl,-z,now}
@@ -37,7 +49,7 @@
 
 Name: subscription-manager
 Version: 1.15.9
-Release: 3%{?dist}
+Release: 4%{?dist}
 Summary: Tools and libraries for subscription and repository management
 Group:   System Environment/Base
 License: GPLv2
@@ -178,28 +190,26 @@ This package contains a GTK+ graphical interface for configuring and
 registering a system with a Red Hat Entitlement platform and manage
 subscriptions.
 
+%if %use_firstboot
 %package -n subscription-manager-firstboot
 Summary: Firstboot screens for subscription manager
 Group: System Environment/Base
 Requires: %{name}-gui = %{version}-%{release}
-
-# Required for firstboot before RHEL 7:
-%if %use_old_firstboot
 Requires: rhn-setup-gnome
-%endif
 
 # Fedora can figure this out automatically, but RHEL cannot:
 Requires: librsvg2
 
 %description -n subscription-manager-firstboot
 This package contains the firstboot screens for subscription-manager.
+%endif
 
 %if %use_initial_setup
 %package -n subscription-manager-initial-setup-addon
 Summary: initial-setup screens for subscription-manager
 Group: System Environment/Base
 Requires: %{name}-gui = %{version}-%{release}
-Requires: initial-setup-gui
+Requires: initial-setup-gui >= 0.3.9.24-1
 Obsoletes: subscription-manager-firstboot < 1.15.3-1
 
 %description -n subscription-manager-initial-setup-addon
@@ -354,6 +364,7 @@ rm -rf %{buildroot}
 # python package dirs
 %dir %{_datadir}/rhsm
 %dir %{_datadir}/rhsm/subscription_manager
+%dir %{_datadir}/rhsm/subscription_manager/api
 %dir %{_datadir}/rhsm/subscription_manager/branding
 %dir %{_datadir}/rhsm/subscription_manager/model
 %dir %{_datadir}/rhsm/subscription_manager/plugin
@@ -361,6 +372,7 @@ rm -rf %{buildroot}
 # code, python modules and packages
 %{_datadir}/rhsm/subscription_manager/*.py*
 
+%{_datadir}/rhsm/subscription_manager/api/*.py*
 %{_datadir}/rhsm/subscription_manager/branding/*.py*
 
 # our gtk2/gtk3 compat modules
@@ -469,8 +481,9 @@ rm -rf %{buildroot}
 %{_datadir}/anaconda/addons/com_redhat_subscription_manager/gui/spokes/*.py*
 %{_datadir}/anaconda/addons/com_redhat_subscription_manager/categories/*.py*
 %{_datadir}/anaconda/addons/com_redhat_subscription_manager/ks/*.py*
-%else
+%endif
 
+%if %use_firstboot
 %files -n subscription-manager-firstboot
 %defattr(-,root,root,-)
 %{_datadir}/rhn/up2date_client/firstboot/rhsm_login.py*
@@ -529,6 +542,16 @@ fi
 %endif
 
 %changelog
+* Thu Aug 06 2015 Chris Rog <crog@redhat.com> 1.15.9-4
+- Fix spec file build errors (alikins@redhat.com)
+- Require initial-setup >= 0.3.9.24, no fb on el7 (alikins@redhat.com)
+- Remove use of Widget.is_toplevel() (alikins@redhat.com)
+- Only build initial-setup rpm on rhel > 7.1 (alikins@redhat.com)
+- 1243704: Goto error screen on 'cancel' (alikins@redhat.com)
+- Add new api package to RPM. (awood@redhat.com)
+- Turn off ga loading debug messages. (alikins@redhat.com)
+- Specify a thread name for any threads we start. (alikins@redhat.com)
+
 * Fri Jul 31 2015 Chris Rog <crog@redhat.com> 1.15.9-3
 - 1248746: Fix layout of contract dialog (GTK3) (mstead@redhat.com)
 - 1248821: Add Gtk.Window to ga_gtk2.Gtk (alikins@redhat.com)