[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 6/6] Remove the early kickstart processing pass (#532453).



Among other problems, this means that all the partitioning commands can be
in a file generated from a %pre script again.
---
 anaconda     |   75 +++++++++++++++++++++++++++--------------------
 kickstart.py |   92 +++++++++++++--------------------------------------------
 2 files changed, 64 insertions(+), 103 deletions(-)

diff --git a/anaconda b/anaconda
index 0dc5238..63cc35f 100755
--- a/anaconda
+++ b/anaconda
@@ -762,28 +762,21 @@ if __name__ == "__main__":
         except:
             pass
 
-    # If we were given a kickstart file, do a first processing run looking
-    # for a couple specific commands that'll be useful in setting up the
-    # interface.
+    # This is the one place we do all kickstart file parsing.
     if opts.ksfile:
         anaconda.isKickstart = True
-        earlyKS = kickstart.earlyCommandPass(anaconda, opts.ksfile)
-    else:
-        earlyKS = None
 
-    #
-    # must specify install, rescue mode
-    #
-    if earlyKS and not opts.rescue:
-        opts.rescue = earlyKS.rescue.rescue
+        kickstart.preScriptPass(anaconda, opts.ksfile)
+        ksdata = kickstart.parseKickstart(anaconda, opts.ksfile)
+        opts.rescue = ksdata.rescue.rescue
 
-    # we need to have a libuser.conf that points to the installer root for
-    # sshpw, but after that we start sshd, we need one that points to the
-    # install target.
-    luserConf = users.createLuserConf(instPath="")
-    handleSshPw(earlyKS)
-    startSsh()
-    del(os.environ["LIBUSER_CONF"])
+        # we need to have a libuser.conf that points to the installer root for
+        # sshpw, but after that we start sshd, we need one that points to the
+        # install target.
+        luserConf = users.createLuserConf(instPath="")
+        handleSshPw(ksdata)
+        startSsh()
+        del(os.environ["LIBUSER_CONF"])
 
     users.createLuserConf(anaconda.rootPath)
 
@@ -794,16 +787,17 @@ if __name__ == "__main__":
 
         anaconda.id = instdata.InstallData(anaconda, [], opts.display_mode)
 
-        if opts.ksfile:
+        if anaconda.isKickstart:
             instClass.setInstallData(anaconda)
+            anaconda.id.setKsdata(ksdata)
 
-            #we need waitWindow valid in processKickstartFile. because storage uses it
+            # We need an interface before running kickstart apply methods for
+            # storage.
             from snack import *
             screen = SnackScreen()
             anaconda.intf = rescue.RescueInterface(screen)
 
-            kickstart.preScriptPass(anaconda, opts.ksfile)
-            kickstart.fullCommandPass(anaconda, opts.ksfile, earlyKS)
+            ksdata.handler.apply()
 
             anaconda.intf = None
             screen.finish()
@@ -816,19 +810,19 @@ if __name__ == "__main__":
         # shouldn't get back here
         sys.exit(1)
 
-    if opts.ksfile:
-        if earlyKS.vnc.enabled:
+    if anaconda.isKickstart:
+        if ksdata.vnc.enabled:
             flags.usevnc = 1
             opts.display_mode = 'g'
 
             if vncS.password == "":
-                vncS.password = earlyKS.vnc.password
+                vncS.password = ksdata.earlyKS.vnc.password
 
             if vncS.vncconnecthost == "":
-                vncS.vncconnecthost = earlyKS.vnc.host
+                vncS.vncconnecthost = ksdata.vnc.host
 
             if vncS.vncconnectport == "":
-                vncS.vncconnectport = earlyKS.vnc.port
+                vncS.vncconnectport = ksdata.vnc.port
 
         flags.vncquestion = False
 
@@ -1021,11 +1015,28 @@ if __name__ == "__main__":
         anaconda.id.keyboard.activate()
 
     if anaconda.isKickstart:
-        kickstart.preScriptPass(anaconda, opts.ksfile)
-        kickstart.fullCommandPass(anaconda, opts.ksfile, earlyKS)
-        # We need to copy the VNC-related kickstart stuff into the new ksdata
-        anaconda.id.ksdata.vnc(enabled=earlyKS.vnc.enabled, host=earlyKS.vnc.host,
-                               password=earlyKS.vnc.password, port=earlyKS.vnc.port)
+        import storage
+
+        anaconda.id.setKsdata(ksdata)
+
+        # Before we set up the storage system, we need to know which disks to
+        # ignore, etc.  Luckily that's all in the kickstart data.
+        anaconda.id.storage.zeroMbr = ksdata.zerombr.zerombr
+        anaconda.id.storage.ignoredDisks = ksdata.ignoredisk.ignoredisk
+        anaconda.id.storage.exclusiveDisks = ksdata.ignoredisk.onlyuse
+
+        if ksdata.clearpart.type is not None:
+            anaconda.id.storage.clearPartType = ksdata.clearpart.type
+            anaconda.id.storage.clearPartDisks = ksdata.clearpart.drives
+            if ksdata.clearpart.initAll:
+                anaconda.id.storage.reinitializeDisks = ksdata.clearpart.initAll
+
+        storage.storageInitialize(anaconda)
+
+        # Now having initialized storage, we can apply all the other kickstart
+        # commands.  This gives us the ability to check that storage commands
+        # are correctly formed and refer to actual devices.
+        ksdata.handler.apply()
 
     # Skip the disk options in rootpath mode
     if flags.rootpath:
diff --git a/kickstart.py b/kickstart.py
index f1d7dcc..4078f79 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -996,8 +996,6 @@ dataMap = {
 superclass = returnClassForVersion()
 
 class AnacondaKSHandler(superclass):
-    # This handler class processes all kickstart commands.  It is used in the
-    # second parsing pass - when we do all the real work.
     def __init__ (self, anaconda):
         superclass.__init__(self, commandUpdates=commandMap, dataUpdates=dataMap)
         self.packages = AnacondaKSPackages()
@@ -1050,21 +1048,6 @@ class AnacondaKSHandler(superclass):
         for obj in filter(lambda o: hasattr(o, "execute"), self._dataObjs):
             obj.execute(self.anaconda)
 
-class EarlyKSHandler(superclass):
-    # This handler class only processes a couple kickstart commands.  It is
-    # used very early on in anaconda, when we don't yet have an interface
-    # and are looking for (1) what sort of interface we need to set up, and
-    # (2) what to ignore when we initialize storage.
-    def __init__(self, anaconda):
-        superclass.__init__(self, mapping=commandMap, dataMapping=dataMap)
-
-        self.anaconda = anaconda
-        self.id = self.anaconda.id
-
-        self.maskAllExcept(["vnc", "displaymode", "text", "cmdline",
-                            "graphical", "rescue", "ignoredisk", "clearpart",
-                            "zerombr", "sshpw"])
-
 class AnacondaPreParser(KickstartParser):
     # A subclass of KickstartParser that only looks for %pre scripts and
     # sets them up to be run.  All other scripts and commands are ignored.
@@ -1104,12 +1087,6 @@ class AnacondaKSParser(KickstartParser):
                   missingIncludeIsFatal=True):
         KickstartParser.__init__(self, handler)
 
-        # All the KickstartCommand and KickstartData objects that
-        # handleCommand returns, so we can later iterate over them and run
-        # the apply methods.  These really should be stored in the order
-        # they're seen in the kickstart file.
-        self._dataObjs = []
-
     def addScript (self):
         if string.join(self._script["body"]).strip() == "":
             return
@@ -1135,7 +1112,7 @@ class AnacondaKSParser(KickstartParser):
         return retval
 
 def preScriptPass(anaconda, file):
-    # The second pass through kickstart file processing - look for %pre scripts
+    # The first pass through kickstart file processing - look for %pre scripts
     # and run them.  This must come in a separate pass in case a script
     # generates an included file that has commands for later.
     ksparser = AnacondaPreParser(AnacondaKSHandler(anaconda))
@@ -1145,24 +1122,24 @@ def preScriptPass(anaconda, file):
     except IOError, e:
         if anaconda.intf:
             anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
-            sys.exit(0)
+            sys.exit(1)
         else:
-            raise
+            print _("The following error was found while parsing the kickstart "
+                    "configuration file:\n\n%s") % e
+            sys.exit(1)
     except KickstartError, e:
        if anaconda.intf:
            anaconda.intf.kickstartErrorWindow(e.__str__())
-           sys.exit(0)
+           sys.exit(1)
        else:
-           raise
+            print _("The following error was found while parsing the kickstart "
+                    "configuration file:\n\n%s") % e
+            sys.exit(1)
 
     # run %pre scripts
     runPreScripts(anaconda, ksparser.handler.scripts)
 
-def earlyCommandPass(anaconda, file):
-    # The first pass through kickstart file processing - look for the subset
-    # of commands listed in EarlyKSHandler and set attributes based on those.
-    # This has to be a separate pass because it needs to take place before
-    # anaconda even knows what interface to run.
+def parseKickstart(anaconda, file):
     try:
         file = preprocessKickstart(file)
     except KickstartError, msg:
@@ -1172,58 +1149,31 @@ def earlyCommandPass(anaconda, file):
         stdoutLog.critical(_("Unknown error processing %%ksappend lines: %s") % e)
         sys.exit(1)
 
-    handler = EarlyKSHandler(anaconda)
-    ksparser = KickstartParser(handler, missingIncludeIsFatal=False)
-
-    # We don't have an intf by now, so the best we can do is just print the
-    # exception out.
-    try:
-        ksparser.readKickstart(file)
-    except KickstartError, e:
-        print _("The following error was found while parsing the "
-                "kickstart configuration file:\n\n%s") % e
-        sys.exit(1)
-
-    # And return the handler object so we can get information out of it.
-    return handler
-
-def fullCommandPass(anaconda, file, earlyKS):
-    # We need to make sure storage is active before the rest of the kickstart
-    # file is processed.  But before we initialize storage, we have to tell it
-    # which disks to avoid, and we only get that information from the earlier
-    # processing of the kickstart file.
-    import storage
-    anaconda.id.storage.zeroMbr = earlyKS.zerombr.zerombr
-    anaconda.id.storage.ignoredDisks = earlyKS.ignoredisk.ignoredisk
-    anaconda.id.storage.exclusiveDisks = earlyKS.ignoredisk.onlyuse
-
-    if earlyKS.clearpart.type is not None:
-        anaconda.id.storage.clearPartType = earlyKS.clearpart.type
-        anaconda.id.storage.clearPartDisks = earlyKS.clearpart.drives
-        if earlyKS.clearpart.initAll:
-            anaconda.id.storage.reinitializeDisks = earlyKS.clearpart.initAll
-
-    storage.storageInitialize(anaconda)
-
     handler = AnacondaKSHandler(anaconda)
     ksparser = AnacondaKSParser(handler)
 
     try:
         ksparser.readKickstart(file)
     except IOError, e:
+        # We may not have an intf now, but we can do better than just raising
+        # the exception.
         if anaconda.intf:
             anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
-            sys.exit(0)
+            sys.exit(1)
         else:
-            raise
+            print _("The following error was found while parsing the kickstart "
+                    "configuration file:\n\n%s") % e
+            sys.exit(1)
     except KickstartError, e:
         if anaconda.intf:
             anaconda.intf.kickstartErrorWindow(e.__str__())
-            sys.exit(0)
+            sys.exit(1)
         else:
-            raise
+            print _("The following error was found while parsing the kickstart "
+                    "configuration file:\n\n%s") % e
+            sys.exit(1)
 
-    anaconda.id.setKsdata(handler)
+    return handler
 
 def runPostScripts(anaconda):
     if not anaconda.id.ksdata:
-- 
1.6.5.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]