[PATCH 1/3] Add an early kickstart processing pass.

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

 



This gets rid of the old several early passes for VNC and rescue, instead
replacing them with a single one that also looks for ignoredisks.  We need
to look for ignoredisks early on so that we have that list ready before
enabling storage.  Otherwise, ignoredisks won't really do what it's supposed
to.  The problem here is what to do about if the ignoredisks directive is
located in an include generated by a %pre script.
---
 anaconda     |  122 ++++++++++++++-------------------------------------------
 kickstart.py |   68 ++++++++++++++++++++++++++------
 2 files changed, 85 insertions(+), 105 deletions(-)

diff --git a/anaconda b/anaconda
index 487795f..f47f50a 100755
--- a/anaconda
+++ b/anaconda
@@ -254,83 +254,6 @@ def parseOptions():
 
     return op.parse_args()
 
-def setVNCFromKickstart(opts):
-    from kickstart import KickstartError, VNCHandler
-    from pykickstart.parser import KickstartParser, preprocessKickstart
-
-    global vncS
-
-    try:
-        opts.ksfile = preprocessKickstart(opts.ksfile)
-    except KickstartError, msg:
-        stdoutLog.critical(_("Error processing %%ksappend lines: %s") % msg)
-        sys.exit(1)
-    except Exception, e:
-        stdoutLog.critical(_("Unknown error processing %%ksappend lines: %s") % e)
-        sys.exit(1)
-
-    # now see if they enabled vnc via the kickstart file. Note that command
-    # line options for password, connect host and port override values in
-    # kickstart file
-    handler = VNCHandler()
-    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(opts.ksfile)
-    except KickstartError, e:
-        print _("The following error was found while parsing your "
-                "kickstart configuration:\n\n%s") % e
-        sys.exit(1)
-
-    if handler.vnc.enabled:
-        flags.usevnc = 1
-
-        if vncS.password == "":
-            vncS.password = handler.vnc.password
-
-        if vncS.vncconnecthost == "":
-            vncS.vncconnecthost = handler.vnc.host
-
-        if vncS.vncconnectport == "":
-            vncS.vncconnectport = handler.vnc.port
-
-    from pykickstart.constants import DISPLAY_MODE_GRAPHICAL
-    if handler.displaymode.displayMode!=None:
-            flags.vncquestion = False
-
-    return handler.vnc
-
-def setRescueModeFromKickstart(opts):
-    from kickstart import KickstartError, RescueHandler
-    from pykickstart.parser import KickstartParser, preprocessKickstart
-
-    try:
-        opts.ksfile = preprocessKickstart(opts.ksfile)
-    except KickstartError, msg:
-        stdoutLog.critical(_("Error processing %%ksappend lines: %s") % msg)
-        sys.exit(1)
-    except Exception, e:
-        stdoutLog.critical(_("Unknown error processing %%ksappend lines: %s") % e)
-        sys.exit(1)
-
-    # now see if they enabled rescue mode via the kickstart file. 
-    handler = RescueHandler()
-    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(opts.ksfile)
-    except KickstartError, e:
-        print _("The following error was found while parsing your "
-                "kickstart configuration:\n\n%s") % e
-        sys.exit(1)
-
-    # True or False
-    return handler.rescue.rescue
-
 def setupPythonPath():
     # For anaconda in test mode
     if (os.path.exists('isys')):
@@ -765,11 +688,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.
+    if opts.ksfile:
+        from kickstart import earlyProcessKickstartFile
+        anaconda.isKickstart = True
+        earlyKS = earlyProcessKickstartFile(anaconda, opts.ksfile)
+    else:
+        earlyKS = None
+
     #
     # must specify install, rescue mode
     #
-    if opts.ksfile and (not opts.rescue):
-        opts.rescue = setRescueModeFromKickstart(opts)
+    if earlyKS and not opts.rescue:
+        opts.rescue = earlyKS.rescue.rescue
 
     if opts.rescue:
         anaconda.rescue = True
@@ -779,7 +712,6 @@ if __name__ == "__main__":
         anaconda.id = instdata.InstallData(anaconda, [], opts.display_mode)
 
         if opts.ksfile:
-            anaconda.isKickstart = True
             instClass.setInstallData(anaconda)
 
             #we need waitWindow valid in processKickstartFile. because storage uses it
@@ -787,7 +719,7 @@ if __name__ == "__main__":
             screen = SnackScreen()
             anaconda.intf = rescue.RescueInterface(screen)
 
-            kickstart.processKickstartFile(anaconda, opts.ksfile)
+            kickstart.processKickstartFile(anaconda, opts.ksfile, earlyKS)
 
             anaconda.intf = None
             screen.finish()
@@ -800,17 +732,23 @@ if __name__ == "__main__":
         # shouldn't get back here
         sys.exit(1)
 
-    #
-    # Here we have a hook to pull in second half of kickstart file via https
-    # if desired.
-    #
     if opts.ksfile:
-        anaconda.isKickstart = True
-        vncksdata = setVNCFromKickstart(opts)
-
-        if vncksdata.enabled:
+        if earlyKS.vnc.enabled:
+            flags.usevnc = 1
             opts.display_mode = 'g'
 
+            if vncS.password == "":
+                vncS.password = earlyKS.vnc.password
+
+            if vncS.vncconnecthost == "":
+                vncS.vncconnecthost = earlyKS.vnc.host
+
+            if vncS.vncconnectport == "":
+                vncS.vncconnectport = earlyKS.vnc.port
+
+        if earlyKS.displaymode.displayMode != None:
+            flags.vncquestion = False
+
     #
     # Determine install method - GUI or TUI
     #
@@ -993,10 +931,10 @@ if __name__ == "__main__":
         anaconda.id.keyboard.activate()
 
     if anaconda.isKickstart:
-        kickstart.processKickstartFile(anaconda, opts.ksfile)
+        kickstart.processKickstartFile(anaconda, opts.ksfile, earlyKS)
         # We need to copy the VNC-related kickstart stuff into the new ksdata
-        anaconda.id.ksdata.vnc(enabled=vncksdata.enabled, host=vncksdata.host,
-                               password=vncksdata.password, port=vncksdata.port)
+        anaconda.id.ksdata.vnc(enabled=earlyKS.vnc.enabled, host=earlyKS.vnc.host,
+                               password=earlyKS.vnc.password, port=earlyKS.vnc.port)
 
     # Skip the disk options in rootpath mode
     if flags.rootpath:
diff --git a/kickstart.py b/kickstart.py
index 802cb43..cd2985a 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -277,6 +277,12 @@ class IgnoreDisk(commands.ignoredisk.F8_IgnoreDisk):
     def parse(self, args):
         retval = commands.ignoredisk.F8_IgnoreDisk.parse(self, args)
 
+        # If doing the early kickstart processing, we will not yet have
+        # an instdata attribute.  That's okay because we pull the lists
+        # right out of this class instead of the instdata.
+        if not self.handler.id:
+            return retval
+
         for drive in self.ignoredisk:
             if not drive in self.handler.id.storage.ignoredDisks:
                 self.handler.id.storage.ignoredDisks.append(drive)
@@ -1007,6 +1013,8 @@ commandMap = {
 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, mapping=commandMap)
         self.packages = AnacondaKSPackages()
@@ -1017,19 +1025,23 @@ class AnacondaKSHandler(superclass):
         self.anaconda = anaconda
         self.id = self.anaconda.id
 
-class VNCHandler(superclass):
-    # We're only interested in the handler for the VNC command and display modes.
-    def __init__(self, anaconda=None):
+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)
-        self.maskAllExcept(["vnc", "displaymode", "text", "cmdline", "graphical"])
 
-class RescueHandler(superclass):
-    # We're only interested in the handler for the rescue command
-    def __init__(self, anaconda=None):
-        superclass.__init__(self, mapping=commandMap)
-        self.maskAllExcept(["rescue"])
+        self.anaconda = anaconda
+        self.id = self.anaconda.id
+
+        self.maskAllExcept(["vnc", "displaymode", "text", "cmdline",
+                            "graphical", "rescue", "ignoredisk"])
 
 class KickstartPreParser(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.
     def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
                   missingIncludeIsFatal=True):
         KickstartParser.__init__(self, handler, missingIncludeIsFatal=False)
@@ -1088,11 +1100,32 @@ class AnacondaKSParser(KickstartParser):
 
         KickstartParser.handleCommand(self, lineno, args)
 
-def processKickstartFile(anaconda, file):
-    # We need to make sure storage is active before the kickstart file is read.
-    import storage
-    storage.storageInitialize(anaconda)
+def earlyProcessKickstartFile(anaconda, file):
+    try:
+        file = preprocessKickstart(file)
+    except KickstartError, msg:
+        stdoutLog.critical(_("Error processing %%ksappend lines: %s") % msg)
+        sys.exit(1)
+    except Exception, e:
+        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 your "
+                "kickstart configuration:\n\n%s") % e
+        sys.exit(1)
 
+    # And return the handler object so we can get information out of it.
+    return handler
+
+def processKickstartFile(anaconda, file, earlyKS):
     # parse the %pre
     ksparser = KickstartPreParser(AnacondaKSHandler(anaconda))
 
@@ -1114,6 +1147,15 @@ def processKickstartFile(anaconda, file):
     # run %pre scripts
     runPreScripts(anaconda, ksparser.handler.scripts)
 
+    # 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.ignoredDisks = earlyKS.ignoredisk.ignoredisk
+    anaconda.id.storage.exclusiveDisks = earlyKS.ignoredisk.onlyuse
+    storage.storageInitialize(anaconda)
+
     # now read the kickstart file for real
     handler = AnacondaKSHandler(anaconda)
     ksparser = AnacondaKSParser(handler)
-- 
1.6.1.3

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux