[PATCH 2/2] Make Initial Setup compatible with rebased Anaconda (#1229747)

Martin Kolman mkolman at redhat.com
Tue Jun 16 16:23:10 UTC 2015


Adapt to the changed category handling and other less significant
changes such as root path handling. Also remove a couple unused
imports when we are at it.

Resolves: rhbz#1229747
Signed-off-by: Martin Kolman <mkolman at redhat.com>
---
 initial_setup/__main__.py                   | 24 +++------
 initial_setup/common.py                     | 63 ++++++++++++++++++++++++
 initial_setup/gui/gui.py                    |  6 +--
 initial_setup/gui/hubs/initial_setup.glade  | 27 +++++++----
 initial_setup/gui/hubs/initial_setup_hub.py | 75 ++---------------------------
 initial_setup/gui/spokes/eula.glade         |  2 -
 initial_setup/gui/spokes/eula.py            |  9 +++-
 initial_setup/post_installclass.py          |  2 +-
 initial_setup/tui/hubs/initial_setup_hub.py | 11 +++--
 initial_setup/tui/spokes/eula.py            |  3 +-
 initial_setup/tui/tui.py                    |  4 --
 11 files changed, 110 insertions(+), 116 deletions(-)
 create mode 100644 initial_setup/common.py

diff --git a/initial_setup/__main__.py b/initial_setup/__main__.py
index 642e93c..d9e411f 100644
--- a/initial_setup/__main__.py
+++ b/initial_setup/__main__.py
@@ -5,7 +5,7 @@ import signal
 import pykickstart
 import logging
 from pyanaconda.users import Users
-from initial_setup.post_installclass import InstallClass
+from initial_setup.post_installclass import PostInstallClass
 from initial_setup import initial_setup_log
 from pyanaconda import iutil
 
@@ -35,14 +35,6 @@ if mode == "gui":
         gi.overrides.__path__.insert(0, p)
     log.debug("GI overrides imported")
 
-# set the root path to / so the imported spokes
-# know where to apply their changes
-from pyanaconda import constants
-
-# this has to stay in the form constants.ROOT_PATH so it modifies
-# the scalar in anaconda, not the local copy here
-constants.ROOT_PATH = "/"
-
 from pyanaconda.addons import collect_addon_paths
 
 addon_paths = ["/usr/share/initial-setup/modules", "/usr/share/anaconda/addons"]
@@ -99,14 +91,14 @@ try:
     parser.readKickstart(INPUT_KICKSTART_PATH)
     log.info("kickstart parsing done")
 except pykickstart.errors.KickstartError as kserr:
-    log.exception("kickstart parsing failed")
+    log.exception("kickstart parsing failed: %s" % kserr)
     sys.exit(1)
 
 if mode == "gui":
     try:
         # Try to import IS gui specifics
         log.debug("trying to import GUI")
-        import gui
+        import initial_setup.gui
     except ImportError:
         log.exception("GUI import failed, falling back to TUI")
         mode = "tui"
@@ -115,21 +107,21 @@ if mode == "gui":
     # gui already imported (see above)
 
     # Add addons to search paths
-    gui.InitialSetupGraphicalUserInterface.update_paths(addon_module_paths)
+    initial_setup.gui.InitialSetupGraphicalUserInterface.update_paths(addon_module_paths)
 
     # Initialize the UI
     log.debug("initializing GUI")
-    ui = gui.InitialSetupGraphicalUserInterface(None, None, InstallClass())
+    ui = initial_setup.gui.InitialSetupGraphicalUserInterface(None, None, PostInstallClass())
 else:
     # Import IS gui specifics
-    import tui
+    import initial_setup.tui
 
     # Add addons to search paths
-    tui.InitialSetupTextUserInterface.update_paths(addon_module_paths)
+    initial_setup.tui.InitialSetupTextUserInterface.update_paths(addon_module_paths)
 
     # Initialize the UI
     log.debug("initializing TUI")
-    ui = tui.InitialSetupTextUserInterface(None, None, None)
+    ui = initial_setup.tui.InitialSetupTextUserInterface(None, None, None)
 
 # Pass the data object to user inteface
 log.debug("setting up the UI")
diff --git a/initial_setup/common.py b/initial_setup/common.py
new file mode 100644
index 0000000..ce8e5b1
--- /dev/null
+++ b/initial_setup/common.py
@@ -0,0 +1,63 @@
+"""Common methods for Initial Setup"""
+
+from pyanaconda.ui.common import collect
+from pyanaconda.constants import FIRSTBOOT_ENVIRON
+from pyanaconda.i18n import N_
+from pyanaconda.ui.categories import SpokeCategory
+
+
+def collect_spokes(mask_paths, spoke_parent_class):
+    """Return a list of all spoke subclasses that should appear for a given
+       category. Look for them in files imported as module_path % basename(f)
+
+       :param mask_paths: list of mask, path tuples to search for classes
+       :type mask_paths: list of (mask, path)
+
+       :param spoke_parent_class: Spoke parent class used for checking spoke compatibility
+       :type spoke_parent_class: GUI or TUI Spoke class
+
+       :return: list of Spoke classes belonging to category
+       :rtype: list of Spoke classes
+
+    """
+    spokes = []
+    for mask, path in mask_paths:
+
+        spokes.extend(collect(mask, path,
+                              lambda obj: issubclass(obj, spoke_parent_class) and obj.should_run("firstboot", None)))
+    return spokes
+
+
+def collectCategoriesAndSpokes(hub_instance, spoke_parent_class):
+    """Collects categories and spokes to be displayed on this Hub,
+       this method overrides the Anacondas implementation so that
+       spokes relevant to Initial setup are collected
+
+       :param hub_instance: an Initial Setup GUI or TUI Hub class instance
+       :type hub_instance: class instance
+
+       :param spoke_parent_class: Spoke parent class used for checking spoke compatibility
+       :type spoke_parent_class: GUI or TUI Spoke class
+
+       :return: dictionary mapping category class to list of spoke classes
+       :rtype: dictionary[category class] -> [ list of spoke classes ]
+    """
+    ret = {}
+
+    # Collect all the categories this hub displays, then collect all the
+    # spokes belonging to all those categories.
+    candidate_spokes = collect_spokes(hub_instance.paths["spokes"], spoke_parent_class)
+    spokes = [spoke for spoke in candidate_spokes
+              if spoke.should_run(FIRSTBOOT_ENVIRON, hub_instance.data)]
+
+    for spoke in spokes:
+        ret.setdefault(spoke.category, [])
+        ret[spoke.category].append(spoke)
+
+    return ret
+
+class LicensingCategory(SpokeCategory):
+    displayOnHubGUI = "ProgressHub"
+    displayOnHubTUI = "SummaryHub"
+    sortOrder = 100
+    title = N_("LICENSING")
diff --git a/initial_setup/gui/gui.py b/initial_setup/gui/gui.py
index d23a93a..b689492 100644
--- a/initial_setup/gui/gui.py
+++ b/initial_setup/gui/gui.py
@@ -1,12 +1,8 @@
-from pyanaconda.ui.gui import QuitDialog, GUIObject, GraphicalUserInterface
+from pyanaconda.ui.gui import QuitDialog, GraphicalUserInterface
 from initial_setup.product import product_title, is_final
 from .hubs import InitialSetupMainHub
-from pyanaconda.ui.gui.spokes import StandaloneSpoke
-import pyanaconda.ui.gui.spokes
-from pyanaconda.ui.common import collect, FirstbootSpokeMixIn
 import os
 from gi.repository import Gdk
-import logging
 import gettext
 from di import inject, usesclassinject
 
diff --git a/initial_setup/gui/hubs/initial_setup.glade b/initial_setup/gui/hubs/initial_setup.glade
index 3fc725d..b6a4ad2 100644
--- a/initial_setup/gui/hubs/initial_setup.glade
+++ b/initial_setup/gui/hubs/initial_setup.glade
@@ -1,24 +1,31 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
-  <!-- interface-requires AnacondaWidgets 1.0 -->
+  <requires lib="gtk+" version="3.0"/>
+  <requires lib="AnacondaWidgets" version="3.0"/>
   <object class="AnacondaHubWindow" id="summaryWindow">
-    <property name="startup_id">filler</property>
     <property name="can_focus">False</property>
-    <property name="startup_id">filler</property>
-    <property name="mnemonics_visible">False</property>
-    <property name="focus_visible">False</property>
     <property name="distribution" translatable="yes">DISTRIBUTION SETUP</property>
     <property name="window_name" translatable="yes">INITIAL SETUP</property>
+    <property name="quit_button">quitButton</property>
+    <property name="continue_button">continueButton</property>
     <child internal-child="main_box">
       <object class="GtkBox" id="AnacondaHubWindow-main_box1">
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
-        <child internal-child="nav_area">
-          <object class="GtkGrid" id="AnacondaHubWindow-nav_area1">
+        <child internal-child="nav_box">
+          <object class="GtkEventBox" id="AnacondaHubWindow-nav_box1">
             <property name="can_focus">False</property>
-            <child>
-              <placeholder/>
+            <child internal-child="nav_area">
+              <object class="GtkGrid" id="AnacondaHubWindow-nav_area1">
+                <property name="can_focus">False</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
             </child>
           </object>
           <packing>
diff --git a/initial_setup/gui/hubs/initial_setup_hub.py b/initial_setup/gui/hubs/initial_setup_hub.py
index 24b9edd..0fb6cb4 100644
--- a/initial_setup/gui/hubs/initial_setup_hub.py
+++ b/initial_setup/gui/hubs/initial_setup_hub.py
@@ -1,31 +1,11 @@
 from pyanaconda.constants import FIRSTBOOT_ENVIRON
 from pyanaconda.ui.gui.hubs import Hub
-from pyanaconda.ui.gui.spokes import Spoke
-from pyanaconda.ui.common import collect
+from pyanaconda.ui.gui.spokes import NormalSpoke as GUI_spoke_class
 from initial_setup import product
-import os
-import sys
+from initial_setup import common
 
 __all__ = ["InitialSetupMainHub"]
 
-def collect_spokes(mask_paths):
-    """Return a list of all spoke subclasses that should appear for a given
-       category. Look for them in files imported as module_path % basename(f)
-
-       :param mask_paths: list of mask, path tuples to search for classes
-       :type mask_paths: list of (mask, path)
-
-       :return: list of Spoke classes belonging to category
-       :rtype: list of Spoke classes
-
-    """
-    spokes = []
-    for mask, path in mask_paths:
-        spokes.extend(collect(mask, path,
-                              lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
-
-    return spokes
-
 
 class InitialSetupMainHub(Hub):
     uiFile = "initial_setup.glade"
@@ -39,25 +19,7 @@ class InitialSetupMainHub(Hub):
         self._environs = [FIRSTBOOT_ENVIRON]
 
     def _collectCategoriesAndSpokes(self):
-        """collects categories and spokes to be displayed on this Hub
-
-           :return: dictionary mapping category class to list of spoke classes
-           :rtype: dictionary[category class] -> [ list of spoke classes ]
-        """
-
-        ret = {}
-
-        # Collect all the categories this hub displays, then collect all the
-        # spokes belonging to all those categories.
-        candidate_spokes = collect_spokes(self.paths["spokes"])
-        spokes = [spoke for spoke in candidate_spokes \
-                        if spoke.should_run(FIRSTBOOT_ENVIRON, self.data)]
-
-        for spoke in spokes:
-            ret.setdefault(spoke.category, [])
-            ret[spoke.category].append(spoke)
-
-        return ret
+        return common.collectCategoriesAndSpokes(self, GUI_spoke_class)
 
     def _createBox(self):
         Hub._createBox(self)
@@ -66,34 +28,3 @@ class InitialSetupMainHub(Hub):
         for spoke in self._spokes.itervalues():
             spoke.window.set_property("distribution",
                                       product.product_title().upper())
-
-
-    @property
-    def continueButton(self):
-        return self.builder.get_object("continueButton")
-
-    @property
-    def quitButton(self):
-        return self.builder.get_object("quitButton")
-
-    def register_event_cb(self, event, cb, *args):
-        if event == "continue" and self.continueButton:
-            self.continueButton.connect("clicked", lambda *args: cb())
-        elif event == "quit" and self.quitButton:
-            self.quitButton.connect("clicked", lambda *args: self._on_quit_clicked(cb))
-        elif event == "help-button":
-            self.window.connect("help-button-clicked", cb, *args)
-
-    def _on_quit_clicked(self, cb):
-        try:
-            cb()
-        except SystemExit:
-            # user wants to exit, check if EULA is available and accepted and do
-            # proper action
-            license_file = product.get_license_file_name()
-            if not license_file or self.data.eula.agreed:
-                # agreed, just exit
-                sys.exit(0)
-            else:
-                # not agreed, reboot the system and leave Initial Setup enabled
-                os.system("reboot")
diff --git a/initial_setup/gui/spokes/eula.glade b/initial_setup/gui/spokes/eula.glade
index 384fd25..d361311 100644
--- a/initial_setup/gui/spokes/eula.glade
+++ b/initial_setup/gui/spokes/eula.glade
@@ -6,11 +6,9 @@
     <property name="text">The license will go here</property>
   </object>
   <object class="AnacondaSpokeWindow" id="eulaWindow">
-    <property name="startup_id">filler</property>
     <property name="can_focus">False</property>
     <property name="hexpand">True</property>
     <property name="vexpand">True</property>
-    <property name="startup_id">filler</property>
     <property name="window_name" translatable="yes">LICENSE INFORMATION</property>
     <signal name="button-clicked" handler="on_back_clicked" swapped="no"/>
     <child internal-child="main_box">
diff --git a/initial_setup/gui/spokes/eula.py b/initial_setup/gui/spokes/eula.py
index 0d568df..342910f 100644
--- a/initial_setup/gui/spokes/eula.py
+++ b/initial_setup/gui/spokes/eula.py
@@ -3,13 +3,12 @@
 import gettext
 import logging
 
-from gi.repository import Pango
 from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
 from pyanaconda.ui.gui.spokes import NormalSpoke
-from pyanaconda.ui.gui.categories.licensing import LicensingCategory
 from pyanaconda.constants import FIRSTBOOT_ENVIRON
 
 from initial_setup.product import get_license_file_name
+from initial_setup.common import LicensingCategory
 
 log = logging.getLogger("initial-setup")
 
@@ -95,6 +94,12 @@ class EULAspoke(FirstbootOnlySpokeMixIn, NormalSpoke):
 
         return _("License accepted") if self.data.eula.agreed else _("License not accepted")
 
+    @classmethod
+    def should_run(cls, environment, data):
+        # the EULA spoke should always run, but only in Initial Setup
+        if environment == FIRSTBOOT_ENVIRON:
+            return True
+
     def on_check_button_toggled(self, checkbutton, *args):
         if self._agree_check_button.get_active():
             log.debug("license is now accepted")
diff --git a/initial_setup/post_installclass.py b/initial_setup/post_installclass.py
index 8745dcc..81a7246 100644
--- a/initial_setup/post_installclass.py
+++ b/initial_setup/post_installclass.py
@@ -19,7 +19,7 @@
 
 from pyanaconda.installclass import BaseInstallClass
 
-class InstallClass(BaseInstallClass):
+class PostInstallClass(BaseInstallClass):
     help_placeholder = "RHEL7Placeholder.html"
     help_placeholder_with_links = "RHEL7PlaceholderWithLinks.html"
 
diff --git a/initial_setup/tui/hubs/initial_setup_hub.py b/initial_setup/tui/hubs/initial_setup_hub.py
index 021a48a..c87d528 100644
--- a/initial_setup/tui/hubs/initial_setup_hub.py
+++ b/initial_setup/tui/hubs/initial_setup_hub.py
@@ -1,6 +1,8 @@
 from pyanaconda.constants import FIRSTBOOT_ENVIRON
 from pyanaconda.ui.tui.hubs import TUIHub
+from pyanaconda.ui.tui.spokes import NormalSpoke as TUI_spoke_class
 from initial_setup import product
+from initial_setup import common
 import gettext
 
 __all__ = ["InitialSetupMainHub"]
@@ -10,14 +12,17 @@ _ = lambda x: gettext.ldgettext("initial-setup", x)
 N_ = lambda x: x
 
 class InitialSetupMainHub(TUIHub):
-    categories = ["password", "localization", "system"]
+    categories = ["user", "localization"]
 
     prod_title = product.product_title()
     if prod_title:
-        title = _("Initial setup of %(product)s") % {"product": prod_title}
+        title = N_("Initial setup of %(product)s") % {"product": prod_title}
     else:
-        title = _("Initial setup")
+        title = N_("Initial setup")
 
     def __init__(self, *args):
         TUIHub.__init__(self, *args)
         self._environs = [FIRSTBOOT_ENVIRON]
+
+    def _collectCategoriesAndSpokes(self):
+        return common.collectCategoriesAndSpokes(self, TUI_spoke_class)
diff --git a/initial_setup/tui/spokes/eula.py b/initial_setup/tui/spokes/eula.py
index bbc2bc1..fcadfec 100644
--- a/initial_setup/tui/spokes/eula.py
+++ b/initial_setup/tui/spokes/eula.py
@@ -9,6 +9,7 @@ from pyanaconda.ui.tui.simpleline.widgets import TextWidget, CheckboxWidget
 from pyanaconda.ui.tui.simpleline.base import UIScreen
 from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
 from initial_setup.product import get_license_file_name
+from initial_setup.common import LicensingCategory
 
 log = logging.getLogger("initial-setup")
 
@@ -21,7 +22,7 @@ class EULAspoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
     """The EULA spoke providing ways to read the license and agree/disagree with it."""
 
     title = _("License information")
-    category = "system"
+    category = LicensingCategory
 
     def __init__(self, *args, **kwargs):
         NormalTUISpoke.__init__(self, *args, **kwargs)
diff --git a/initial_setup/tui/tui.py b/initial_setup/tui/tui.py
index 2545a28..5b7b1f7 100644
--- a/initial_setup/tui/tui.py
+++ b/initial_setup/tui/tui.py
@@ -1,11 +1,7 @@
 from pyanaconda.ui.tui import TextUserInterface
 from initial_setup.product import product_title, is_final
 from .hubs import InitialSetupMainHub
-from pyanaconda.ui.tui.spokes import StandaloneSpoke
-import pyanaconda.ui.tui.spokes
-from pyanaconda.ui.common import collect, FirstbootSpokeMixIn
 import os
-import logging
 import gettext
 from di import inject, usesclassinject
 
-- 
2.4.2



More information about the anaconda-patches mailing list