Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/scripts/lib/wic/3rdparty/pykickstart/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/__init__.py
diff --git a/scripts/lib/wic/3rdparty/pykickstart/base.py b/scripts/lib/wic/3rdparty/pykickstart/base.py
new file mode 100644
index 0000000..e6c8f56
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/base.py
@@ -0,0 +1,466 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2006, 2007, 2008 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Base classes for creating commands and syntax version object.
+
+This module exports several important base classes:
+
+    BaseData - The base abstract class for all data objects.  Data objects
+               are contained within a BaseHandler object.
+
+    BaseHandler - The base abstract class from which versioned kickstart
+                  handler are derived.  Subclasses of BaseHandler hold
+                  BaseData and KickstartCommand objects.
+
+    DeprecatedCommand - An abstract subclass of KickstartCommand that should
+                        be further subclassed by users of this module.  When
+                        a subclass is used, a warning message will be
+                        printed.
+
+    KickstartCommand - The base abstract class for all kickstart commands.
+                       Command objects are contained within a BaseHandler
+                       object.
+"""
+import gettext
+gettext.textdomain("pykickstart")
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+import types
+import warnings
+from pykickstart.errors import *
+from pykickstart.ko import *
+from pykickstart.parser import Packages
+from pykickstart.version import versionToString
+
+###
+### COMMANDS
+###
+class KickstartCommand(KickstartObject):
+    """The base class for all kickstart commands.  This is an abstract class."""
+    removedKeywords = []
+    removedAttrs = []
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        """Create a new KickstartCommand instance.  This method must be
+           provided by all subclasses, but subclasses must call
+           KickstartCommand.__init__ first.  Instance attributes:
+
+           currentCmd    -- The name of the command in the input file that
+                            caused this handler to be run.
+           currentLine   -- The current unprocessed line from the input file
+                            that caused this handler to be run.
+           handler       -- A reference to the BaseHandler subclass this
+                            command is contained withing.  This is needed to
+                            allow referencing of Data objects.
+           lineno        -- The current line number in the input file.
+           writePriority -- An integer specifying when this command should be
+                            printed when iterating over all commands' __str__
+                            methods.  The higher the number, the later this
+                            command will be written.  All commands with the
+                            same priority will be written alphabetically.
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is KickstartCommand:
+            raise TypeError, "KickstartCommand is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        self.writePriority = writePriority
+
+        # These will be set by the dispatcher.
+        self.currentCmd = ""
+        self.currentLine = ""
+        self.handler = None
+        self.lineno = 0
+
+        # If a subclass provides a removedKeywords list, remove all the
+        # members from the kwargs list before we start processing it.  This
+        # ensures that subclasses don't continue to recognize arguments that
+        # were removed.
+        for arg in filter(kwargs.has_key, self.removedKeywords):
+            kwargs.pop(arg)
+
+    def __call__(self, *args, **kwargs):
+        """Set multiple attributes on a subclass of KickstartCommand at once
+           via keyword arguments.  Valid attributes are anything specified in
+           a subclass, but unknown attributes will be ignored.
+        """
+        for (key, val) in kwargs.items():
+            # Ignore setting attributes that were removed in a subclass, as
+            # if they were unknown attributes.
+            if key in self.removedAttrs:
+                continue
+
+            if hasattr(self, key):
+                setattr(self, key, val)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file.  This
+           method must be provided by all subclasses.
+        """
+        return KickstartObject.__str__(self)
+
+    def parse(self, args):
+        """Parse the list of args and set data on the KickstartCommand object.
+           This method must be provided by all subclasses.
+        """
+        raise TypeError, "parse() not implemented for KickstartCommand"
+
+    def apply(self, instroot="/"):
+        """Write out the configuration related to the KickstartCommand object.
+           Subclasses which do not provide this method will not have their
+           configuration written out.
+        """
+        return
+
+    def dataList(self):
+        """For commands that can occur multiple times in a single kickstart
+           file (like network, part, etc.), return the list that we should
+           append more data objects to.
+        """
+        return None
+
+    def deleteRemovedAttrs(self):
+        """Remove all attributes from self that are given in the removedAttrs
+           list.  This method should be called from __init__ in a subclass,
+           but only after the superclass's __init__ method has been called.
+        """
+        for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
+            delattr(self, attr)
+
+    # Set the contents of the opts object (an instance of optparse.Values
+    # returned by parse_args) as attributes on the KickstartCommand object.
+    # It's useful to call this from KickstartCommand subclasses after parsing
+    # the arguments.
+    def _setToSelf(self, optParser, opts):
+        self._setToObj(optParser, opts, self)
+
+    # Sets the contents of the opts object (an instance of optparse.Values
+    # returned by parse_args) as attributes on the provided object obj.  It's
+    # useful to call this from KickstartCommand subclasses that handle lists
+    # of objects (like partitions, network devices, etc.) and need to populate
+    # a Data object.
+    def _setToObj(self, optParser, opts, obj):
+        for key in filter (lambda k: getattr(opts, k) != None, optParser.keys()):
+            setattr(obj, key, getattr(opts, key))
+
+class DeprecatedCommand(KickstartCommand):
+    """Specify that a command is deprecated and no longer has any function.
+       Any command that is deprecated should be subclassed from this class,
+       only specifying an __init__ method that calls the superclass's __init__.
+       This is an abstract class.
+    """
+    def __init__(self, writePriority=None, *args, **kwargs):
+        # We don't want people using this class by itself.
+        if self.__class__ is KickstartCommand:
+            raise TypeError, "DeprecatedCommand is an abstract class."
+
+        # Create a new DeprecatedCommand instance.
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+
+    def __str__(self):
+        """Placeholder since DeprecatedCommands don't work anymore."""
+        return ""
+
+    def parse(self, args):
+        """Print a warning message if the command is seen in the input file."""
+        mapping = {"lineno": self.lineno, "cmd": self.currentCmd}
+        warnings.warn(_("Ignoring deprecated command on line %(lineno)s:  The %(cmd)s command has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this command.") % mapping, DeprecationWarning)
+
+
+###
+### HANDLERS
+###
+class BaseHandler(KickstartObject):
+    """Each version of kickstart syntax is provided by a subclass of this
+       class.  These subclasses are what users will interact with for parsing,
+       extracting data, and writing out kickstart files.  This is an abstract
+       class.
+
+       version -- The version this syntax handler supports.  This is set by
+                  a class attribute of a BaseHandler subclass and is used to
+                  set up the command dict.  It is for read-only use.
+    """
+    version = None
+
+    def __init__(self, mapping=None, dataMapping=None, commandUpdates=None,
+                 dataUpdates=None, *args, **kwargs):
+        """Create a new BaseHandler instance.  This method must be provided by
+           all subclasses, but subclasses must call BaseHandler.__init__ first.
+
+           mapping          -- A custom map from command strings to classes,
+                               useful when creating your own handler with
+                               special command objects.  It is otherwise unused
+                               and rarely needed.  If you give this argument,
+                               the mapping takes the place of the default one
+                               and so must include all commands you want
+                               recognized.
+           dataMapping      -- This is the same as mapping, but for data
+                               objects.  All the same comments apply.
+           commandUpdates   -- This is similar to mapping, but does not take
+                               the place of the defaults entirely.  Instead,
+                               this mapping is applied after the defaults and
+                               updates it with just the commands you want to
+                               modify.
+           dataUpdates      -- This is the same as commandUpdates, but for
+                               data objects.
+
+
+           Instance attributes:
+
+           commands -- A mapping from a string command to a KickstartCommand
+                       subclass object that handles it.  Multiple strings can
+                       map to the same object, but only one instance of the
+                       command object should ever exist.  Most users should
+                       never have to deal with this directly, as it is
+                       manipulated internally and called through dispatcher.
+           currentLine -- The current unprocessed line from the input file
+                          that caused this handler to be run.
+           packages -- An instance of pykickstart.parser.Packages which
+                       describes the packages section of the input file.
+           platform -- A string describing the hardware platform, which is
+                       needed only by system-config-kickstart.
+           scripts  -- A list of pykickstart.parser.Script instances, which is
+                       populated by KickstartParser.addScript and describes the
+                       %pre/%post/%traceback script section of the input file.
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is BaseHandler:
+            raise TypeError, "BaseHandler is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        # This isn't really a good place for these, but it's better than
+        # everything else I can think of.
+        self.scripts = []
+        self.packages = Packages()
+        self.platform = ""
+
+        # These will be set by the dispatcher.
+        self.commands = {}
+        self.currentLine = 0
+
+        # A dict keyed by an integer priority number, with each value being a
+        # list of KickstartCommand subclasses.  This dict is maintained by
+        # registerCommand and used in __str__.  No one else should be touching
+        # it.
+        self._writeOrder = {}
+
+        self._registerCommands(mapping, dataMapping, commandUpdates, dataUpdates)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        retval = ""
+
+        if self.platform != "":
+            retval += "#platform=%s\n" % self.platform
+
+        retval += "#version=%s\n" % versionToString(self.version)
+
+        lst = self._writeOrder.keys()
+        lst.sort()
+
+        for prio in lst:
+            for obj in self._writeOrder[prio]:
+                retval += obj.__str__()
+
+        for script in self.scripts:
+            retval += script.__str__()
+
+        retval += self.packages.__str__()
+
+        return retval
+
+    def _insertSorted(self, lst, obj):
+        length = len(lst)
+        i = 0
+
+        while i < length:
+            # If the two classes have the same name, it's because we are
+            # overriding an existing class with one from a later kickstart
+            # version, so remove the old one in favor of the new one.
+            if obj.__class__.__name__ > lst[i].__class__.__name__:
+                i += 1
+            elif obj.__class__.__name__ == lst[i].__class__.__name__:
+                lst[i] = obj
+                return
+            elif obj.__class__.__name__ < lst[i].__class__.__name__:
+                break
+
+        if i >= length:
+            lst.append(obj)
+        else:
+            lst.insert(i, obj)
+
+    def _setCommand(self, cmdObj):
+        # Add an attribute on this version object.  We need this to provide a
+        # way for clients to access the command objects.  We also need to strip
+        # off the version part from the front of the name.
+        if cmdObj.__class__.__name__.find("_") != -1:
+            name = unicode(cmdObj.__class__.__name__.split("_", 1)[1])
+        else:
+            name = unicode(cmdObj.__class__.__name__).lower()
+
+        setattr(self, name.lower(), cmdObj)
+
+        # Also, add the object into the _writeOrder dict in the right place.
+        if cmdObj.writePriority is not None:
+            if self._writeOrder.has_key(cmdObj.writePriority):
+                self._insertSorted(self._writeOrder[cmdObj.writePriority], cmdObj)
+            else:
+                self._writeOrder[cmdObj.writePriority] = [cmdObj]
+
+    def _registerCommands(self, mapping=None, dataMapping=None, commandUpdates=None,
+                          dataUpdates=None):
+        if mapping == {} or mapping == None:
+            from pykickstart.handlers.control import commandMap
+            cMap = commandMap[self.version]
+        else:
+            cMap = mapping
+
+        if dataMapping == {} or dataMapping == None:
+            from pykickstart.handlers.control import dataMap
+            dMap = dataMap[self.version]
+        else:
+            dMap = dataMapping
+
+        if type(commandUpdates) == types.DictType:
+            cMap.update(commandUpdates)
+
+        if type(dataUpdates) == types.DictType:
+            dMap.update(dataUpdates)
+
+        for (cmdName, cmdClass) in cMap.iteritems():
+            # First make sure we haven't instantiated this command handler
+            # already.  If we have, we just need to make another mapping to
+            # it in self.commands.
+            cmdObj = None
+
+            for (key, val) in self.commands.iteritems():
+                if val.__class__.__name__ == cmdClass.__name__:
+                    cmdObj = val
+                    break
+
+            # If we didn't find an instance in self.commands, create one now.
+            if cmdObj == None:
+                cmdObj = cmdClass()
+                self._setCommand(cmdObj)
+
+            # Finally, add the mapping to the commands dict.
+            self.commands[cmdName] = cmdObj
+            self.commands[cmdName].handler = self
+
+        # We also need to create attributes for the various data objects.
+        # No checks here because dMap is a bijection.  At least, that's what
+        # the comment says.  Hope no one screws that up.
+        for (dataName, dataClass) in dMap.iteritems():
+            setattr(self, dataName, dataClass)
+
+    def dispatcher(self, args, lineno):
+        """Call the appropriate KickstartCommand handler for the current line
+           in the kickstart file.  A handler for the current command should
+           be registered, though a handler of None is not an error.  Returns
+           the data object returned by KickstartCommand.parse.
+
+           args    -- A list of arguments to the current command
+           lineno  -- The line number in the file, for error reporting
+        """
+        cmd = args[0]
+
+        if not self.commands.has_key(cmd):
+            raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown command: %s" % cmd))
+        elif self.commands[cmd] != None:
+            self.commands[cmd].currentCmd = cmd
+            self.commands[cmd].currentLine = self.currentLine
+            self.commands[cmd].lineno = lineno
+
+            # The parser returns the data object that was modified.  This could
+            # be a BaseData subclass that should be put into a list, or it
+            # could be the command handler object itself.
+            obj = self.commands[cmd].parse(args[1:])
+            lst = self.commands[cmd].dataList()
+            if lst is not None:
+                lst.append(obj)
+
+            return obj
+
+    def maskAllExcept(self, lst):
+        """Set all entries in the commands dict to None, except the ones in
+           the lst.  All other commands will not be processed.
+        """
+        self._writeOrder = {}
+
+        for (key, val) in self.commands.iteritems():
+            if not key in lst:
+                self.commands[key] = None
+
+    def hasCommand(self, cmd):
+        """Return true if there is a handler for the string cmd."""
+        return hasattr(self, cmd)
+
+
+###
+### DATA
+###
+class BaseData(KickstartObject):
+    """The base class for all data objects.  This is an abstract class."""
+    removedKeywords = []
+    removedAttrs = []
+
+    def __init__(self, *args, **kwargs):
+        """Create a new BaseData instance.
+        
+           lineno -- Line number in the ks-file where this object was defined
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is BaseData:
+            raise TypeError, "BaseData is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+        self.lineno = 0
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        return ""
+
+    def __call__(self, *args, **kwargs):
+        """Set multiple attributes on a subclass of BaseData at once via
+           keyword arguments.  Valid attributes are anything specified in a
+           subclass, but unknown attributes will be ignored.
+        """
+        for (key, val) in kwargs.items():
+            # Ignore setting attributes that were removed in a subclass, as
+            # if they were unknown attributes.
+            if key in self.removedAttrs:
+                continue
+
+            if hasattr(self, key):
+                setattr(self, key, val)
+
+    def deleteRemovedAttrs(self):
+        """Remove all attributes from self that are given in the removedAttrs
+           list.  This method should be called from __init__ in a subclass,
+           but only after the superclass's __init__ method has been called.
+        """
+        for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
+            delattr(self, attr)
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py
new file mode 100644
index 0000000..2d94550
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py
@@ -0,0 +1,20 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+import bootloader, partition
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py b/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py
new file mode 100644
index 0000000..c2b552f
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py
@@ -0,0 +1,216 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+class FC3_Bootloader(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.driveorder = kwargs.get("driveorder", [])
+        self.appendLine = kwargs.get("appendLine", "")
+        self.forceLBA = kwargs.get("forceLBA", False)
+        self.linear = kwargs.get("linear", True)
+        self.location = kwargs.get("location", "")
+        self.md5pass = kwargs.get("md5pass", "")
+        self.password = kwargs.get("password", "")
+        self.upgrade = kwargs.get("upgrade", False)
+        self.useLilo = kwargs.get("useLilo", False)
+
+        self.deleteRemovedAttrs()
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.appendLine != "":
+            retval += " --append=\"%s\"" % self.appendLine
+        if self.linear:
+            retval += " --linear"
+        if self.location:
+            retval += " --location=%s" % self.location
+        if hasattr(self, "forceLBA") and self.forceLBA:
+            retval += " --lba32"
+        if self.password != "":
+            retval += " --password=\"%s\"" % self.password
+        if self.md5pass != "":
+            retval += " --md5pass=\"%s\"" % self.md5pass
+        if self.upgrade:
+            retval += " --upgrade"
+        if self.useLilo:
+            retval += " --useLilo"
+        if len(self.driveorder) > 0:
+            retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
+
+        return retval
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.location != "":
+            retval += "# System bootloader configuration\nbootloader"
+            retval += self._getArgsAsStr() + "\n"
+
+        return retval
+
+    def _getParser(self):
+        def driveorder_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser()
+        op.add_option("--append", dest="appendLine")
+        op.add_option("--linear", dest="linear", action="store_true",
+                      default=True)
+        op.add_option("--nolinear", dest="linear", action="store_false")
+        op.add_option("--location", dest="location", type="choice",
+                      default="mbr",
+                      choices=["mbr", "partition", "none", "boot"])
+        op.add_option("--lba32", dest="forceLBA", action="store_true",
+                      default=False)
+        op.add_option("--password", dest="password", default="")
+        op.add_option("--md5pass", dest="md5pass", default="")
+        op.add_option("--upgrade", dest="upgrade", action="store_true",
+                      default=False)
+        op.add_option("--useLilo", dest="useLilo", action="store_true",
+                      default=False)
+        op.add_option("--driveorder", dest="driveorder", action="callback",
+                      callback=driveorder_cb, nargs=1, type="string")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if self.currentCmd == "lilo":
+            self.useLilo = True
+
+        return self
+
+class FC4_Bootloader(FC3_Bootloader):
+    removedKeywords = FC3_Bootloader.removedKeywords + ["linear", "useLilo"]
+    removedAttrs = FC3_Bootloader.removedAttrs + ["linear", "useLilo"]
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        FC3_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+    def _getArgsAsStr(self):
+        retval = ""
+        if self.appendLine != "":
+            retval += " --append=\"%s\"" % self.appendLine
+        if self.location:
+            retval += " --location=%s" % self.location
+        if hasattr(self, "forceLBA") and self.forceLBA:
+            retval += " --lba32"
+        if self.password != "":
+            retval += " --password=\"%s\"" % self.password
+        if self.md5pass != "":
+            retval += " --md5pass=\"%s\"" % self.md5pass
+        if self.upgrade:
+            retval += " --upgrade"
+        if len(self.driveorder) > 0:
+            retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
+        return retval
+
+    def _getParser(self):
+        op = FC3_Bootloader._getParser(self)
+        op.remove_option("--linear")
+        op.remove_option("--nolinear")
+        op.remove_option("--useLilo")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
+
+class F8_Bootloader(FC4_Bootloader):
+    removedKeywords = FC4_Bootloader.removedKeywords
+    removedAttrs = FC4_Bootloader.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        FC4_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+        self.timeout = kwargs.get("timeout", None)
+        self.default = kwargs.get("default", "")
+
+    def _getArgsAsStr(self):
+        ret = FC4_Bootloader._getArgsAsStr(self)
+
+        if self.timeout is not None:
+            ret += " --timeout=%d" %(self.timeout,)
+        if self.default:
+            ret += " --default=%s" %(self.default,)
+
+        return ret
+
+    def _getParser(self):
+        op = FC4_Bootloader._getParser(self)
+        op.add_option("--timeout", dest="timeout", type="int")
+        op.add_option("--default", dest="default")
+        return op
+
+class F12_Bootloader(F8_Bootloader):
+    removedKeywords = F8_Bootloader.removedKeywords
+    removedAttrs = F8_Bootloader.removedAttrs
+
+    def _getParser(self):
+        op = F8_Bootloader._getParser(self)
+        op.add_option("--lba32", dest="forceLBA", deprecated=1, action="store_true")
+        return op
+
+class F14_Bootloader(F12_Bootloader):
+    removedKeywords = F12_Bootloader.removedKeywords + ["forceLBA"]
+    removedAttrs = F12_Bootloader.removedKeywords + ["forceLBA"]
+
+    def _getParser(self):
+        op = F12_Bootloader._getParser(self)
+        op.remove_option("--lba32")
+        return op
+
+class F15_Bootloader(F14_Bootloader):
+    removedKeywords = F14_Bootloader.removedKeywords
+    removedAttrs = F14_Bootloader.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        F14_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+        self.isCrypted = kwargs.get("isCrypted", False)
+
+    def _getArgsAsStr(self):
+        ret = F14_Bootloader._getArgsAsStr(self)
+
+        if self.isCrypted:
+            ret += " --iscrypted"
+
+        return ret
+
+    def _getParser(self):
+        def password_cb(option, opt_str, value, parser):
+            parser.values.isCrypted = True
+            parser.values.password = value
+
+        op = F14_Bootloader._getParser(self)
+        op.add_option("--iscrypted", dest="isCrypted", action="store_true", default=False)
+        op.add_option("--md5pass", action="callback", callback=password_cb, nargs=1, type="string")
+        return op
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py
new file mode 100644
index 0000000..b564b1a
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py
@@ -0,0 +1,314 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_PartData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.active = kwargs.get("active", False)
+        self.primOnly = kwargs.get("primOnly", False)
+        self.end = kwargs.get("end", 0)
+        self.fstype = kwargs.get("fstype", "")
+        self.grow = kwargs.get("grow", False)
+        self.maxSizeMB = kwargs.get("maxSizeMB", 0)
+        self.format = kwargs.get("format", True)
+        self.onbiosdisk = kwargs.get("onbiosdisk", "")
+        self.disk = kwargs.get("disk", "")
+        self.onPart = kwargs.get("onPart", "")
+        self.recommended = kwargs.get("recommended", False)
+        self.size = kwargs.get("size", None)
+        self.start = kwargs.get("start", 0)
+        self.mountpoint = kwargs.get("mountpoint", "")
+
+    def __eq__(self, y):
+        if self.mountpoint:
+            return self.mountpoint == y.mountpoint
+        else:
+            return False
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.active:
+            retval += " --active"
+        if self.primOnly:
+            retval += " --asprimary"
+        if hasattr(self, "end") and self.end != 0:
+            retval += " --end=%s" % self.end
+        if self.fstype != "":
+            retval += " --fstype=\"%s\"" % self.fstype
+        if self.grow:
+            retval += " --grow"
+        if self.maxSizeMB > 0:
+            retval += " --maxsize=%d" % self.maxSizeMB
+        if not self.format:
+            retval += " --noformat"
+        if self.onbiosdisk != "":
+            retval += " --onbiosdisk=%s" % self.onbiosdisk
+        if self.disk != "":
+            retval += " --ondisk=%s" % self.disk
+        if self.onPart != "":
+            retval += " --onpart=%s" % self.onPart
+        if self.recommended:
+            retval += " --recommended"
+        if self.size and self.size != 0:
+            retval += " --size=%sk" % self.size
+        if hasattr(self, "start") and self.start != 0:
+            retval += " --start=%s" % self.start
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        if self.mountpoint:
+            mountpoint_str = "%s" % self.mountpoint
+        else:
+            mountpoint_str = "(No mount point)"
+        retval += "part %s%s\n" % (mountpoint_str, self._getArgsAsStr())
+        return retval
+
+class FC4_PartData(FC3_PartData):
+    removedKeywords = FC3_PartData.removedKeywords
+    removedAttrs = FC3_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_PartData.__init__(self, *args, **kwargs)
+        self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
+        self.fsopts = kwargs.get("fsopts", "")
+        self.label = kwargs.get("label", "")
+
+    def _getArgsAsStr(self):
+        retval = FC3_PartData._getArgsAsStr(self)
+
+        if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
+            retval += " --bytes-per-inode=%d" % self.bytesPerInode
+        if self.fsopts != "":
+            retval += " --fsoptions=\"%s\"" % self.fsopts
+        if self.label != "":
+            retval += " --label=%s" % self.label
+
+        return retval
+
+class F9_PartData(FC4_PartData):
+    removedKeywords = FC4_PartData.removedKeywords + ["bytesPerInode"]
+    removedAttrs = FC4_PartData.removedAttrs + ["bytesPerInode"]
+
+    def __init__(self, *args, **kwargs):
+        FC4_PartData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.fsopts = kwargs.get("fsopts", "")
+        self.label = kwargs.get("label", "")
+        self.fsprofile = kwargs.get("fsprofile", "")
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC4_PartData._getArgsAsStr(self)
+
+        if self.fsprofile != "":
+            retval += " --fsprofile=\"%s\"" % self.fsprofile
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\"" % self.passphrase
+
+        return retval
+
+class F11_PartData(F9_PartData):
+    removedKeywords = F9_PartData.removedKeywords + ["start", "end"]
+    removedAttrs = F9_PartData.removedAttrs + ["start", "end"]
+
+class F12_PartData(F11_PartData):
+    removedKeywords = F11_PartData.removedKeywords
+    removedAttrs = F11_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F11_PartData.__init__(self, *args, **kwargs)
+
+        self.escrowcert = kwargs.get("escrowcert", "")
+        self.backuppassphrase = kwargs.get("backuppassphrase", False)
+
+    def _getArgsAsStr(self):
+        retval = F11_PartData._getArgsAsStr(self)
+
+        if self.encrypted and self.escrowcert != "":
+            retval += " --escrowcert=\"%s\"" % self.escrowcert
+
+            if self.backuppassphrase:
+                retval += " --backuppassphrase"
+
+        return retval
+
+F14_PartData = F12_PartData
+
+class FC3_Partition(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.partitions = kwargs.get("partitions", [])
+
+    def __str__(self):
+        retval = ""
+
+        for part in self.partitions:
+            retval += part.__str__()
+
+        if retval != "":
+            return "# Disk partitioning information\n" + retval
+        else:
+            return ""
+
+    def _getParser(self):
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+        op = KSOptionParser()
+        op.add_option("--active", dest="active", action="store_true",
+                      default=False)
+        op.add_option("--asprimary", dest="primOnly", action="store_true",
+                      default=False)
+        op.add_option("--end", dest="end", action="store", type="int",
+                      nargs=1)
+        op.add_option("--fstype", "--type", dest="fstype")
+        op.add_option("--grow", dest="grow", action="store_true", default=False)
+        op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
+                      nargs=1)
+        op.add_option("--noformat", dest="format", action="store_false",
+                      default=True)
+        op.add_option("--onbiosdisk", dest="onbiosdisk")
+        op.add_option("--ondisk", "--ondrive", dest="disk")
+        op.add_option("--onpart", "--usepart", dest="onPart", action="callback",
+                      callback=part_cb, nargs=1, type="string")
+        op.add_option("--recommended", dest="recommended", action="store_true",
+                      default=False)
+        op.add_option("--size", dest="size", action="store", type="size",
+                      nargs=1)
+        op.add_option("--start", dest="start", action="store", type="int",
+                      nargs=1)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        pd = self.handler.PartData()
+        self._setToObj(self.op, opts, pd)
+        pd.lineno = self.lineno
+        if extra:
+            pd.mountpoint = extra[0]
+            if pd in self.dataList():
+                warnings.warn(_("A partition with the mountpoint %s has already been defined.") % pd.mountpoint)
+        else:
+            pd.mountpoint = None
+
+        return pd
+
+    def dataList(self):
+        return self.partitions
+
+class FC4_Partition(FC3_Partition):
+    removedKeywords = FC3_Partition.removedKeywords
+    removedAttrs = FC3_Partition.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        FC3_Partition.__init__(self, writePriority, *args, **kwargs)
+
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+    def _getParser(self):
+        op = FC3_Partition._getParser(self)
+        op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
+                      type="int", nargs=1)
+        op.add_option("--fsoptions", dest="fsopts")
+        op.add_option("--label", dest="label")
+        return op
+
+class F9_Partition(FC4_Partition):
+    removedKeywords = FC4_Partition.removedKeywords
+    removedAttrs = FC4_Partition.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        FC4_Partition.__init__(self, writePriority, *args, **kwargs)
+
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+    def _getParser(self):
+        op = FC4_Partition._getParser(self)
+        op.add_option("--bytes-per-inode", deprecated=1)
+        op.add_option("--fsprofile")
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+class F11_Partition(F9_Partition):
+    removedKeywords = F9_Partition.removedKeywords
+    removedAttrs = F9_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F9_Partition._getParser(self)
+        op.add_option("--start", deprecated=1)
+        op.add_option("--end", deprecated=1)
+        return op
+
+class F12_Partition(F11_Partition):
+    removedKeywords = F11_Partition.removedKeywords
+    removedAttrs = F11_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F11_Partition._getParser(self)
+        op.add_option("--escrowcert")
+        op.add_option("--backuppassphrase", action="store_true", default=False)
+        return op
+
+class F14_Partition(F12_Partition):
+    removedKeywords = F12_Partition.removedKeywords
+    removedAttrs = F12_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F12_Partition._getParser(self)
+        op.remove_option("--bytes-per-inode")
+        op.remove_option("--start")
+        op.remove_option("--end")
+        return op
diff --git a/scripts/lib/wic/3rdparty/pykickstart/constants.py b/scripts/lib/wic/3rdparty/pykickstart/constants.py
new file mode 100644
index 0000000..5e12fc8
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/constants.py
@@ -0,0 +1,57 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005-2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+CLEARPART_TYPE_LINUX = 0
+CLEARPART_TYPE_ALL = 1
+CLEARPART_TYPE_NONE = 2
+
+DISPLAY_MODE_CMDLINE = 0
+DISPLAY_MODE_GRAPHICAL = 1
+DISPLAY_MODE_TEXT = 2
+
+FIRSTBOOT_DEFAULT = 0
+FIRSTBOOT_SKIP = 1
+FIRSTBOOT_RECONFIG = 2
+
+KS_MISSING_PROMPT = 0
+KS_MISSING_IGNORE = 1
+
+SELINUX_DISABLED = 0
+SELINUX_ENFORCING = 1
+SELINUX_PERMISSIVE = 2
+
+KS_SCRIPT_PRE = 0
+KS_SCRIPT_POST = 1
+KS_SCRIPT_TRACEBACK = 2
+
+KS_WAIT = 0
+KS_REBOOT = 1
+KS_SHUTDOWN = 2
+
+KS_INSTKEY_SKIP = -99
+
+BOOTPROTO_DHCP = "dhcp"
+BOOTPROTO_BOOTP = "bootp"
+BOOTPROTO_STATIC = "static"
+BOOTPROTO_QUERY = "query"
+BOOTPROTO_IBFT = "ibft"
+
+GROUP_REQUIRED = 0
+GROUP_DEFAULT = 1
+GROUP_ALL = 2
diff --git a/scripts/lib/wic/3rdparty/pykickstart/errors.py b/scripts/lib/wic/3rdparty/pykickstart/errors.py
new file mode 100644
index 0000000..a234d99
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/errors.py
@@ -0,0 +1,103 @@
+#
+# errors.py:  Kickstart error handling.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Error handling classes and functions.
+
+This module exports a single function:
+
+    formatErrorMsg - Properly formats an error message.
+
+It also exports several exception classes:
+
+    KickstartError - A generic exception class.
+
+    KickstartParseError - An exception for errors relating to parsing.
+
+    KickstartValueError - An exception for errors relating to option
+                          processing.
+
+    KickstartVersionError - An exception for errors relating to unsupported
+                            syntax versions.
+"""
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+def formatErrorMsg(lineno, msg=""):
+    """Properly format the error message msg for inclusion in an exception."""
+    if msg != "":
+        mapping = {"lineno": lineno, "msg": msg}
+        return _("The following problem occurred on line %(lineno)s of the kickstart file:\n\n%(msg)s\n") % mapping
+    else:
+        return _("There was a problem reading from line %s of the kickstart file") % lineno
+
+class KickstartError(Exception):
+    """A generic exception class for unspecific error conditions."""
+    def __init__(self, val = ""):
+        """Create a new KickstartError exception instance with the descriptive
+           message val.  val should be the return value of formatErrorMsg.
+        """
+        Exception.__init__(self)
+        self.value = val
+
+    def __str__ (self):
+        return self.value
+
+class KickstartParseError(KickstartError):
+    """An exception class for errors when processing the input file, such as
+       unknown options, commands, or sections.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartParseError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__(self):
+        return self.value
+
+class KickstartValueError(KickstartError):
+    """An exception class for errors when processing arguments to commands,
+       such as too many arguments, too few arguments, or missing required
+       arguments.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartValueError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
+
+class KickstartVersionError(KickstartError):
+    """An exception class for errors related to using an incorrect version of
+       kickstart syntax.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartVersionError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py
new file mode 100644
index 0000000..8dc80d1
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py
@@ -0,0 +1,46 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.version import *
+from pykickstart.commands import *
+
+# This map is keyed on kickstart syntax version as provided by
+# pykickstart.version.  Within each sub-dict is a mapping from command name
+# to the class that handles it.  This is an onto mapping - that is, multiple
+# command names can map to the same class.  However, the Handler will ensure
+# that only one instance of each class ever exists.
+commandMap = {
+    # based on f15
+    F16: {
+        "bootloader": bootloader.F15_Bootloader,
+        "part": partition.F14_Partition,
+        "partition": partition.F14_Partition,
+    },
+}
+
+# This map is keyed on kickstart syntax version as provided by
+# pykickstart.version.  Within each sub-dict is a mapping from a data object
+# name to the class that provides it.  This is a bijective mapping - that is,
+# each name maps to exactly one data class and all data classes have a name.
+# More than one instance of each class is allowed to exist, however.
+dataMap = {
+    F16: {
+        "PartData": partition.F14_PartData,
+    },
+}
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py
new file mode 100644
index 0000000..3c52f8d
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class F16Handler(BaseHandler):
+    version = F16
diff --git a/scripts/lib/wic/3rdparty/pykickstart/ko.py b/scripts/lib/wic/3rdparty/pykickstart/ko.py
new file mode 100644
index 0000000..1350d19
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/ko.py
@@ -0,0 +1,37 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Base classes for internal pykickstart use.
+
+The module exports the following important classes:
+
+    KickstartObject - The base class for all classes in pykickstart
+"""
+
+class KickstartObject(object):
+    """The base class for all other classes in pykickstart."""
+    def __init__(self, *args, **kwargs):
+        """Create a new KickstartObject instance.  All other classes in
+           pykickstart should be derived from this one.  Instance attributes:
+        """
+        pass
+
+    def __str__(self):
+        return ""
diff --git a/scripts/lib/wic/3rdparty/pykickstart/options.py b/scripts/lib/wic/3rdparty/pykickstart/options.py
new file mode 100644
index 0000000..ebc23ed
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/options.py
@@ -0,0 +1,223 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Specialized option handling.
+
+This module exports two classes:
+
+    KSOptionParser - A specialized subclass of OptionParser to be used
+                     in BaseHandler subclasses.
+
+    KSOption - A specialized subclass of Option.
+"""
+import warnings
+from copy import copy
+from optparse import *
+
+from constants import *
+from errors import *
+from version import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class KSOptionParser(OptionParser):
+    """A specialized subclass of optparse.OptionParser to handle extra option
+       attribute checking, work error reporting into the KickstartParseError
+       framework, and to turn off the default help.
+    """
+    def exit(self, status=0, msg=None):
+        pass
+
+    def error(self, msg):
+        if self.lineno != None:
+            raise KickstartParseError, formatErrorMsg(self.lineno, msg=msg)
+        else:
+            raise KickstartParseError, msg
+
+    def keys(self):
+        retval = []
+
+        for opt in self.option_list:
+            if opt not in retval:
+                retval.append(opt.dest)
+
+        return retval
+
+    def _init_parsing_state (self):
+        OptionParser._init_parsing_state(self)
+        self.option_seen = {}
+
+    def check_values (self, values, args):
+        def seen(self, option):
+            return self.option_seen.has_key(option)
+
+        def usedTooNew(self, option):
+            return option.introduced and option.introduced > self.version
+
+        def usedDeprecated(self, option):
+            return option.deprecated
+
+        def usedRemoved(self, option):
+            return option.removed and option.removed <= self.version
+
+        for option in filter(lambda o: isinstance(o, Option), self.option_list):
+            if option.required and not seen(self, option):
+                raise KickstartValueError, formatErrorMsg(self.lineno, _("Option %s is required") % option)
+            elif seen(self, option) and usedTooNew(self, option):
+                mapping = {"option": option, "intro": versionToString(option.introduced),
+                           "version": versionToString(self.version)}
+                self.error(_("The %(option)s option was introduced in version %(intro)s, but you are using kickstart syntax version %(version)s.") % mapping)
+            elif seen(self, option) and usedRemoved(self, option):
+                mapping = {"option": option, "removed": versionToString(option.removed),
+                           "version": versionToString(self.version)}
+
+                if option.removed == self.version:
+                    self.error(_("The %(option)s option is no longer supported.") % mapping)
+                else:
+                    self.error(_("The %(option)s option was removed in version %(removed)s, but you are using kickstart syntax version %(version)s.") % mapping)
+            elif seen(self, option) and usedDeprecated(self, option):
+                mapping = {"lineno": self.lineno, "option": option}
+                warnings.warn(_("Ignoring deprecated option on line %(lineno)s:  The %(option)s option has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this option.") % mapping, DeprecationWarning)
+
+        return (values, args)
+
+    def parse_args(self, *args, **kwargs):
+        if kwargs.has_key("lineno"):
+            self.lineno = kwargs.pop("lineno")
+
+        return OptionParser.parse_args(self, **kwargs)
+
+    def __init__(self, mapping=None, version=None):
+        """Create a new KSOptionParser instance.  Each KickstartCommand
+           subclass should create one instance of KSOptionParser, providing
+           at least the lineno attribute.  mapping and version are not required.
+           Instance attributes:
+
+           mapping -- A mapping from option strings to different values.
+           version -- The version of the kickstart syntax we are checking
+                      against.
+        """
+        OptionParser.__init__(self, option_class=KSOption,
+                              add_help_option=False,
+                              conflict_handler="resolve")
+        if mapping is None:
+            self.map = {}
+        else:
+            self.map = mapping
+
+        self.lineno = None
+        self.option_seen = {}
+        self.version = version
+
+def _check_ksboolean(option, opt, value):
+    if value.lower() in ("on", "yes", "true", "1"):
+        return True
+    elif value.lower() in ("off", "no", "false", "0"):
+        return False
+    else:
+        mapping = {"opt": opt, "value": value}
+        raise OptionValueError(_("Option %(opt)s: invalid boolean value: %(value)r") % mapping)
+
+def _check_string(option, opt, value):
+    if len(value) > 2 and value.startswith("--"):
+        mapping = {"opt": opt, "value": value}
+        raise OptionValueError(_("Option %(opt)s: invalid string value: %(value)r") % mapping)
+    else:
+        return value
+
+def _check_size(option, opt, value):
+    # Former default was MB
+    if value.isdigit():
+        return int(value) * 1024L
+
+    mapping = {"opt": opt, "value": value}
+    if not value[:-1].isdigit():
+        raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping)
+
+    size = int(value[:-1])
+    if value.endswith("k") or value.endswith("K"):
+        return size
+    if value.endswith("M"):
+        return size * 1024L
+    if value.endswith("G"):
+        return size * 1024L * 1024L
+    raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping)
+
+# Creates a new Option class that supports several new attributes:
+# - required:  any option with this attribute must be supplied or an exception
+#              is thrown
+# - introduced:  the kickstart syntax version that this option first appeared
+#                in - an exception will be raised if the option is used and
+#                the specified syntax version is less than the value of this
+#                attribute
+# - deprecated:  the kickstart syntax version that this option was deprecated
+#                in - a DeprecationWarning will be thrown if the option is
+#                used and the specified syntax version is greater than the
+#                value of this attribute
+# - removed:  the kickstart syntax version that this option was removed in - an
+#             exception will be raised if the option is used and the specified
+#             syntax version is greated than the value of this attribute
+# Also creates a new type:
+# - ksboolean:  support various kinds of boolean values on an option
+# And two new actions:
+# - map :  allows you to define an opt -> val mapping such that dest gets val
+#          when opt is seen
+# - map_extend:  allows you to define an opt -> [val1, ... valn] mapping such
+#                that dest gets a list of vals built up when opt is seen
+class KSOption (Option):
+    ATTRS = Option.ATTRS + ['introduced', 'deprecated', 'removed', 'required']
+    ACTIONS = Option.ACTIONS + ("map", "map_extend",)
+    STORE_ACTIONS = Option.STORE_ACTIONS + ("map", "map_extend",)
+
+    TYPES = Option.TYPES + ("ksboolean", "string", "size")
+    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER["ksboolean"] = _check_ksboolean
+    TYPE_CHECKER["string"] = _check_string
+    TYPE_CHECKER["size"] = _check_size
+
+    def _check_required(self):
+        if self.required and not self.takes_value():
+            raise OptionError(_("Required flag set for option that doesn't take a value"), self)
+
+    # Make sure _check_required() is called from the constructor!
+    CHECK_METHODS = Option.CHECK_METHODS + [_check_required]
+
+    def process (self, opt, value, values, parser):
+        Option.process(self, opt, value, values, parser)
+        parser.option_seen[self] = 1
+
+    # Override default take_action method to handle our custom actions.
+    def take_action(self, action, dest, opt, value, values, parser):
+        if action == "map":
+            values.ensure_value(dest, parser.map[opt.lstrip('-')])
+        elif action == "map_extend":
+            values.ensure_value(dest, []).extend(parser.map[opt.lstrip('-')])
+        else:
+            Option.take_action(self, action, dest, opt, value, values, parser)
+
+    def takes_value(self):
+        # Deprecated options don't take a value.
+        return Option.takes_value(self) and not self.deprecated
+
+    def __init__(self, *args, **kwargs):
+        self.deprecated = False
+        self.required = False
+        Option.__init__(self, *args, **kwargs)
diff --git a/scripts/lib/wic/3rdparty/pykickstart/parser.py b/scripts/lib/wic/3rdparty/pykickstart/parser.py
new file mode 100644
index 0000000..9c9674b
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/parser.py
@@ -0,0 +1,619 @@
+#
+# parser.py:  Kickstart file parser.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007, 2008, 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Main kickstart file processing module.
+
+This module exports several important classes:
+
+    Script - Representation of a single %pre, %post, or %traceback script.
+
+    Packages - Representation of the %packages section.
+
+    KickstartParser - The kickstart file parser state machine.
+"""
+
+from collections import Iterator
+import os
+import shlex
+import sys
+import tempfile
+from copy import copy
+from optparse import *
+
+import constants
+from errors import KickstartError, KickstartParseError, KickstartValueError, formatErrorMsg
+from ko import KickstartObject
+from sections import *
+import version
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+STATE_END = "end"
+STATE_COMMANDS = "commands"
+
+ver = version.DEVEL
+
+
+class PutBackIterator(Iterator):
+    def __init__(self, iterable):
+        self._iterable = iter(iterable)
+        self._buf = None
+
+    def __iter__(self):
+        return self
+
+    def put(self, s):
+        self._buf = s
+
+    def next(self):
+        if self._buf:
+            retval = self._buf
+            self._buf = None
+            return retval
+        else:
+            return self._iterable.next()
+
+###
+### SCRIPT HANDLING
+###
+class Script(KickstartObject):
+    """A class representing a single kickstart script.  If functionality beyond
+       just a data representation is needed (for example, a run method in
+       anaconda), Script may be subclassed.  Although a run method is not
+       provided, most of the attributes of Script have to do with running the
+       script.  Instances of Script are held in a list by the Version object.
+    """
+    def __init__(self, script, *args , **kwargs):
+        """Create a new Script instance.  Instance attributes:
+
+           errorOnFail -- If execution of the script fails, should anaconda
+                          stop, display an error, and then reboot without
+                          running any other scripts?
+           inChroot    -- Does the script execute in anaconda's chroot
+                          environment or not?
+           interp      -- The program that should be used to interpret this
+                          script.
+           lineno      -- The line number this script starts on.
+           logfile     -- Where all messages from the script should be logged.
+           script      -- A string containing all the lines of the script.
+           type        -- The type of the script, which can be KS_SCRIPT_* from
+                          pykickstart.constants.
+        """
+        KickstartObject.__init__(self, *args, **kwargs)
+        self.script = "".join(script)
+
+        self.interp = kwargs.get("interp", "/bin/sh")
+        self.inChroot = kwargs.get("inChroot", False)
+        self.lineno = kwargs.get("lineno", None)
+        self.logfile = kwargs.get("logfile", None)
+        self.errorOnFail = kwargs.get("errorOnFail", False)
+        self.type = kwargs.get("type", constants.KS_SCRIPT_PRE)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        retval = ""
+
+        if self.type == constants.KS_SCRIPT_PRE:
+            retval += '\n%pre'
+        elif self.type == constants.KS_SCRIPT_POST:
+            retval += '\n%post'
+        elif self.type == constants.KS_SCRIPT_TRACEBACK:
+            retval += '\n%traceback'
+
+        if self.interp != "/bin/sh" and self.interp != "":
+            retval += " --interpreter=%s" % self.interp
+        if self.type == constants.KS_SCRIPT_POST and not self.inChroot:
+            retval += " --nochroot"
+        if self.logfile != None:
+            retval += " --logfile %s" % self.logfile
+        if self.errorOnFail:
+            retval += " --erroronfail"
+
+        if self.script.endswith("\n"):
+            if ver >= version.F8:
+                return retval + "\n%s%%end\n" % self.script
+            else:
+                return retval + "\n%s\n" % self.script
+        else:
+            if ver >= version.F8:
+                return retval + "\n%s\n%%end\n" % self.script
+            else:
+                return retval + "\n%s\n" % self.script
+
+
+##
+## PACKAGE HANDLING
+##
+class Group:
+    """A class representing a single group in the %packages section."""
+    def __init__(self, name="", include=constants.GROUP_DEFAULT):
+        """Create a new Group instance.  Instance attributes:
+
+           name    -- The group's identifier
+           include -- The level of how much of the group should be included.
+                      Values can be GROUP_* from pykickstart.constants.
+        """
+        self.name = name
+        self.include = include
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        if self.include == constants.GROUP_REQUIRED:
+            return "@%s --nodefaults" % self.name
+        elif self.include == constants.GROUP_ALL:
+            return "@%s --optional" % self.name
+        else:
+            return "@%s" % self.name
+
+    def __cmp__(self, other):
+        if self.name < other.name:
+            return -1
+        elif self.name > other.name:
+            return 1
+        return 0
+
+class Packages(KickstartObject):
+    """A class representing the %packages section of the kickstart file."""
+    def __init__(self, *args, **kwargs):
+        """Create a new Packages instance.  Instance attributes:
+
+           addBase       -- Should the Base group be installed even if it is
+                            not specified?
+           default       -- Should the default package set be selected?
+           excludedList  -- A list of all the packages marked for exclusion in
+                            the %packages section, without the leading minus
+                            symbol.
+           excludeDocs   -- Should documentation in each package be excluded?
+           groupList     -- A list of Group objects representing all the groups
+                            specified in the %packages section.  Names will be
+                            stripped of the leading @ symbol.
+           excludedGroupList -- A list of Group objects representing all the
+                                groups specified for removal in the %packages
+                                section.  Names will be stripped of the leading
+                                -@ symbols.
+           handleMissing -- If unknown packages are specified in the %packages
+                            section, should it be ignored or not?  Values can
+                            be KS_MISSING_* from pykickstart.constants.
+           packageList   -- A list of all the packages specified in the
+                            %packages section.
+           instLangs     -- A list of languages to install.
+        """
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        self.addBase = True
+        self.default = False
+        self.excludedList = []
+        self.excludedGroupList = []
+        self.excludeDocs = False
+        self.groupList = []
+        self.handleMissing = constants.KS_MISSING_PROMPT
+        self.packageList = []
+        self.instLangs = None
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        pkgs = ""
+
+        if not self.default:
+            grps = self.groupList
+            grps.sort()
+            for grp in grps:
+                pkgs += "%s\n" % grp.__str__()
+
+            p = self.packageList
+            p.sort()
+            for pkg in p:
+                pkgs += "%s\n" % pkg
+
+            grps = self.excludedGroupList
+            grps.sort()
+            for grp in grps:
+                pkgs += "-%s\n" % grp.__str__()
+
+            p = self.excludedList
+            p.sort()
+            for pkg in p:
+                pkgs += "-%s\n" % pkg
+
+            if pkgs == "":
+                return ""
+
+        retval = "\n%packages"
+
+        if self.default:
+            retval += " --default"
+        if self.excludeDocs:
+            retval += " --excludedocs"
+        if not self.addBase:
+            retval += " --nobase"
+        if self.handleMissing == constants.KS_MISSING_IGNORE:
+            retval += " --ignoremissing"
+        if self.instLangs:
+            retval += " --instLangs=%s" % self.instLangs
+
+        if ver >= version.F8:
+            return retval + "\n" + pkgs + "\n%end\n"
+        else:
+            return retval + "\n" + pkgs + "\n"
+
+    def _processGroup (self, line):
+        op = OptionParser()
+        op.add_option("--nodefaults", action="store_true", default=False)
+        op.add_option("--optional", action="store_true", default=False)
+
+        (opts, extra) = op.parse_args(args=line.split())
+
+        if opts.nodefaults and opts.optional:
+            raise KickstartValueError, _("Group cannot specify both --nodefaults and --optional")
+
+        # If the group name has spaces in it, we have to put it back together
+        # now.
+        grp = " ".join(extra)
+
+        if opts.nodefaults:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_REQUIRED))
+        elif opts.optional:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_ALL))
+        else:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_DEFAULT))
+
+    def add (self, pkgList):
+        """Given a list of lines from the input file, strip off any leading
+           symbols and add the result to the appropriate list.
+        """
+        existingExcludedSet = set(self.excludedList)
+        existingPackageSet = set(self.packageList)
+        newExcludedSet = set()
+        newPackageSet = set()
+
+        excludedGroupList = []
+
+        for pkg in pkgList:
+            stripped = pkg.strip()
+
+            if stripped[0] == "@":
+                self._processGroup(stripped[1:])
+            elif stripped[0] == "-":
+                if stripped[1] == "@":
+                    excludedGroupList.append(Group(name=stripped[2:]))
+                else:
+                    newExcludedSet.add(stripped[1:])
+            else:
+                newPackageSet.add(stripped)
+
+        # Groups have to be excluded in two different ways (note: can't use
+        # sets here because we have to store objects):
+        excludedGroupNames = map(lambda g: g.name, excludedGroupList)
+
+        # First, an excluded group may be cancelling out a previously given
+        # one.  This is often the case when using %include.  So there we should
+        # just remove the group from the list.
+        self.groupList = filter(lambda g: g.name not in excludedGroupNames, self.groupList)
+
+        # Second, the package list could have included globs which are not
+        # processed by pykickstart.  In that case we need to preserve a list of
+        # excluded groups so whatever tool doing package/group installation can
+        # take appropriate action.
+        self.excludedGroupList.extend(excludedGroupList)
+
+        existingPackageSet = (existingPackageSet - newExcludedSet) | newPackageSet
+        existingExcludedSet = (existingExcludedSet - existingPackageSet) | newExcludedSet
+
+        self.packageList = list(existingPackageSet)
+        self.excludedList = list(existingExcludedSet)
+
+
+###
+### PARSER
+###
+class KickstartParser:
+    """The kickstart file parser class as represented by a basic state
+       machine.  To create a specialized parser, make a subclass and override
+       any of the methods you care about.  Methods that don't need to do
+       anything may just pass.  However, _stateMachine should never be
+       overridden.
+    """
+    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
+                  missingIncludeIsFatal=True):
+        """Create a new KickstartParser instance.  Instance attributes:
+
+           errorsAreFatal        -- Should errors cause processing to halt, or
+                                    just print a message to the screen?  This
+                                    is most useful for writing syntax checkers
+                                    that may want to continue after an error is
+                                    encountered.
+           followIncludes        -- If %include is seen, should the included
+                                    file be checked as well or skipped?
+           handler               -- An instance of a BaseHandler subclass.  If
+                                    None, the input file will still be parsed
+                                    but no data will be saved and no commands
+                                    will be executed.
+           missingIncludeIsFatal -- Should missing include files be fatal, even
+                                    if errorsAreFatal is False?
+        """
+        self.errorsAreFatal = errorsAreFatal
+        self.followIncludes = followIncludes
+        self.handler = handler
+        self.currentdir = {}
+        self.missingIncludeIsFatal = missingIncludeIsFatal
+
+        self._state = STATE_COMMANDS
+        self._includeDepth = 0
+        self._line = ""
+
+        self.version = self.handler.version
+
+        global ver
+        ver = self.version
+
+        self._sections = {}
+        self.setupSections()
+
+    def _reset(self):
+        """Reset the internal variables of the state machine for a new kickstart file."""
+        self._state = STATE_COMMANDS
+        self._includeDepth = 0
+
+    def getSection(self, s):
+        """Return a reference to the requested section (s must start with '%'s),
+           or raise KeyError if not found.
+        """
+        return self._sections[s]
+
+    def handleCommand (self, lineno, args):
+        """Given the list of command and arguments, call the Version's
+           dispatcher method to handle the command.  Returns the command or
+           data object returned by the dispatcher.  This method may be
+           overridden in a subclass if necessary.
+        """
+        if self.handler:
+            self.handler.currentCmd = args[0]
+            self.handler.currentLine = self._line
+            retval = self.handler.dispatcher(args, lineno)
+
+            return retval
+
+    def registerSection(self, obj):
+        """Given an instance of a Section subclass, register the new section
+           with the parser.  Calling this method means the parser will
+           recognize your new section and dispatch into the given object to
+           handle it.
+        """
+        if not obj.sectionOpen:
+            raise TypeError, "no sectionOpen given for section %s" % obj
+
+        if not obj.sectionOpen.startswith("%"):
+            raise TypeError, "section %s tag does not start with a %%" % obj.sectionOpen
+
+        self._sections[obj.sectionOpen] = obj
+
+    def _finalize(self, obj):
+        """Called at the close of a kickstart section to take any required
+           actions.  Internally, this is used to add scripts once we have the
+           whole body read.
+        """
+        obj.finalize()
+        self._state = STATE_COMMANDS
+
+    def _handleSpecialComments(self, line):
+        """Kickstart recognizes a couple special comments."""
+        if self._state != STATE_COMMANDS:
+            return
+
+        # Save the platform for s-c-kickstart.
+        if line[:10] == "#platform=":
+            self.handler.platform = self._line[11:]
+
+    def _readSection(self, lineIter, lineno):
+        obj = self._sections[self._state]
+
+        while True:
+            try:
+                line = lineIter.next()
+                if line == "":
+                    # This section ends at the end of the file.
+                    if self.version >= version.F8:
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
+
+                    self._finalize(obj)
+            except StopIteration:
+                break
+
+            lineno += 1
+
+            # Throw away blank lines and comments, unless the section wants all
+            # lines.
+            if self._isBlankOrComment(line) and not obj.allLines:
+                continue
+
+            if line.startswith("%"):
+                args = shlex.split(line)
+
+                if args and args[0] == "%end":
+                    # This is a properly terminated section.
+                    self._finalize(obj)
+                    break
+                elif args and args[0] == "%ksappend":
+                    continue
+                elif args and (self._validState(args[0]) or args[0] in ["%include", "%ksappend"]):
+                    # This is an unterminated section.
+                    if self.version >= version.F8:
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
+
+                    # Finish up.  We do not process the header here because
+                    # kicking back out to STATE_COMMANDS will ensure that happens.
+                    lineIter.put(line)
+                    lineno -= 1
+                    self._finalize(obj)
+                    break
+            else:
+                # This is just a line within a section.  Pass it off to whatever
+                # section handles it.
+                obj.handleLine(line)
+
+        return lineno
+
+    def _validState(self, st):
+        """Is the given section tag one that has been registered with the parser?"""
+        return st in self._sections.keys()
+
+    def _tryFunc(self, fn):
+        """Call the provided function (which doesn't take any arguments) and
+           do the appropriate error handling.  If errorsAreFatal is False, this
+           function will just print the exception and keep going.
+        """
+        try:
+            fn()
+        except Exception, msg:
+            if self.errorsAreFatal:
+                raise
+            else:
+                print msg
+
+    def _isBlankOrComment(self, line):
+        return line.isspace() or line == "" or line.lstrip()[0] == '#'
+
+    def _stateMachine(self, lineIter):
+        # For error reporting.
+        lineno = 0
+
+        while True:
+            # Get the next line out of the file, quitting if this is the last line.
+            try:
+                self._line = lineIter.next()
+                if self._line == "":
+                    break
+            except StopIteration:
+                break
+
+            lineno += 1
+
+            # Eliminate blank lines, whitespace-only lines, and comments.
+            if self._isBlankOrComment(self._line):
+                self._handleSpecialComments(self._line)
+                continue
+
+            # Remove any end-of-line comments.
+            sanitized = self._line.split("#")[0]
+
+            # Then split the line.
+            args = shlex.split(sanitized.rstrip())
+
+            if args[0] == "%include":
+                # This case comes up primarily in ksvalidator.
+                if not self.followIncludes:
+                    continue
+
+                if len(args) == 1 or not args[1]:
+                    raise KickstartParseError, formatErrorMsg(lineno)
+
+                self._includeDepth += 1
+
+                try:
+                    self.readKickstart(args[1], reset=False)
+                except KickstartError:
+                    # Handle the include file being provided over the
+                    # network in a %pre script.  This case comes up in the
+                    # early parsing in anaconda.
+                    if self.missingIncludeIsFatal:
+                        raise
+
+                self._includeDepth -= 1
+                continue
+
+            # Now on to the main event.
+            if self._state == STATE_COMMANDS:
+                if args[0] == "%ksappend":
+                    # This is handled by the preprocess* functions, so continue.
+                    continue
+                elif args[0][0] == '%':
+                    # This is the beginning of a new section.  Handle its header
+                    # here.
+                    newSection = args[0]
+                    if not self._validState(newSection):
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown kickstart section: %s" % newSection))
+
+                    self._state = newSection
+                    obj = self._sections[self._state]
+                    self._tryFunc(lambda: obj.handleHeader(lineno, args))
+
+                    # This will handle all section processing, kicking us back
+                    # out to STATE_COMMANDS at the end with the current line
+                    # being the next section header, etc.
+                    lineno = self._readSection(lineIter, lineno)
+                else:
+                    # This is a command in the command section.  Dispatch to it.
+                    self._tryFunc(lambda: self.handleCommand(lineno, args))
+            elif self._state == STATE_END:
+                break
+
+    def readKickstartFromString (self, s, reset=True):
+        """Process a kickstart file, provided as the string str."""
+        if reset:
+            self._reset()
+
+        # Add a "" to the end of the list so the string reader acts like the
+        # file reader and we only get StopIteration when we're after the final
+        # line of input.
+        i = PutBackIterator(s.splitlines(True) + [""])
+        self._stateMachine (i)
+
+    def readKickstart(self, f, reset=True):
+        """Process a kickstart file, given by the filename f."""
+        if reset:
+            self._reset()
+
+        # an %include might not specify a full path.  if we don't try to figure
+        # out what the path should have been, then we're unable to find it
+        # requiring full path specification, though, sucks.  so let's make
+        # the reading "smart" by keeping track of what the path is at each
+        # include depth.
+        if not os.path.exists(f):
+            if self.currentdir.has_key(self._includeDepth - 1):
+                if os.path.exists(os.path.join(self.currentdir[self._includeDepth - 1], f)):
+                    f = os.path.join(self.currentdir[self._includeDepth - 1], f)
+
+        cd = os.path.dirname(f)
+        if not cd.startswith("/"):
+            cd = os.path.abspath(cd)
+        self.currentdir[self._includeDepth] = cd
+
+        try:
+            s = file(f).read()
+        except IOError, e:
+            raise KickstartError, formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % e.strerror)
+
+        self.readKickstartFromString(s, reset=False)
+
+    def setupSections(self):
+        """Install the sections all kickstart files support.  You may override
+           this method in a subclass, but should avoid doing so unless you know
+           what you're doing.
+        """
+        self._sections = {}
+
+        # Install the sections all kickstart files support.
+        self.registerSection(PreScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PostScriptSection(self.handler, dataObj=Script))
+        self.registerSection(TracebackScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PackageSection(self.handler))
diff --git a/scripts/lib/wic/3rdparty/pykickstart/sections.py b/scripts/lib/wic/3rdparty/pykickstart/sections.py
new file mode 100644
index 0000000..44df856
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/sections.py
@@ -0,0 +1,244 @@
+#
+# sections.py:  Kickstart file sections.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+This module exports the classes that define a section of a kickstart file.  A
+section is a chunk of the file starting with a %tag and ending with a %end.
+Examples of sections include %packages, %pre, and %post.
+
+You may use this module to define your own custom sections which will be
+treated just the same as a predefined one by the kickstart parser.  All that
+is necessary is to create a new subclass of Section and call
+parser.registerSection with an instance of your new class.
+"""
+from constants import *
+from options import KSOptionParser
+from version import *
+
+class Section(object):
+    """The base class for defining kickstart sections.  You are free to
+       subclass this as appropriate.
+
+       Class attributes:
+
+       allLines    -- Does this section require the parser to call handleLine
+                      for every line in the section, even blanks and comments?
+       sectionOpen -- The string that denotes the start of this section.  You
+                      must start your tag with a percent sign.
+       timesSeen   -- This attribute is for informational purposes only.  It is
+                      incremented every time handleHeader is called to keep
+                      track of the number of times a section of this type is
+                      seen.
+    """
+    allLines = False
+    sectionOpen = ""
+    timesSeen = 0
+
+    def __init__(self, handler, **kwargs):
+        """Create a new Script instance.  At the least, you must pass in an
+           instance of a baseHandler subclass.
+
+           Valid kwargs:
+
+           dataObj --
+        """
+        self.handler = handler
+
+        self.version = self.handler.version
+
+        self.dataObj = kwargs.get("dataObj", None)
+
+    def finalize(self):
+        """This method is called when the %end tag for a section is seen.  It
+           is not required to be provided.
+        """
+        pass
+
+    def handleLine(self, line):
+        """This method is called for every line of a section.  Take whatever
+           action is appropriate.  While this method is not required to be
+           provided, not providing it does not make a whole lot of sense.
+
+           Arguments:
+
+           line -- The complete line, with any trailing newline.
+        """
+        pass
+
+    def handleHeader(self, lineno, args):
+        """This method is called when the opening tag for a section is seen.
+           Not all sections will need this method, though all provided with
+           kickstart include one.
+
+           Arguments:
+
+           args -- A list of all strings passed as arguments to the section
+                   opening tag.
+        """
+        self.timesSeen += 1
+
+class NullSection(Section):
+    """This defines a section that pykickstart will recognize but do nothing
+       with.  If the parser runs across a %section that has no object registered,
+       it will raise an error.  Sometimes, you may want to simply ignore those
+       sections instead.  This class is useful for that purpose.
+    """
+    def __init__(self, *args, **kwargs):
+        """Create a new NullSection instance.  You must pass a sectionOpen
+           parameter (including a leading '%') for the section you wish to
+           ignore.
+        """
+        Section.__init__(self, *args, **kwargs)
+        self.sectionOpen = kwargs.get("sectionOpen")
+
+class ScriptSection(Section):
+    allLines = True
+
+    def __init__(self, *args, **kwargs):
+        Section.__init__(self, *args, **kwargs)
+        self._script = {}
+        self._resetScript()
+
+    def _getParser(self):
+        op = KSOptionParser(self.version)
+        op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
+                      default=False)
+        op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
+        op.add_option("--log", "--logfile", dest="log")
+        return op
+
+    def _resetScript(self):
+        self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
+                        "lineno": None, "chroot": False, "body": []}
+
+    def handleLine(self, line):
+        self._script["body"].append(line)
+
+    def finalize(self):
+        if " ".join(self._script["body"]).strip() == "":
+            return
+
+        kwargs = {"interp": self._script["interp"],
+                  "inChroot": self._script["chroot"],
+                  "lineno": self._script["lineno"],
+                  "logfile": self._script["log"],
+                  "errorOnFail": self._script["errorOnFail"],
+                  "type": self._script["type"]}
+
+        s = self.dataObj (self._script["body"], **kwargs)
+        self._resetScript()
+
+        if self.handler:
+            self.handler.scripts.append(s)
+
+    def handleHeader(self, lineno, args):
+        """Process the arguments to a %pre/%post/%traceback header for later
+           setting on a Script instance once the end of the script is found.
+           This method may be overridden in a subclass if necessary.
+        """
+        Section.handleHeader(self, lineno, args)
+        op = self._getParser()
+
+        (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
+
+        self._script["interp"] = opts.interpreter
+        self._script["lineno"] = lineno
+        self._script["log"] = opts.log
+        self._script["errorOnFail"] = opts.errorOnFail
+        if hasattr(opts, "nochroot"):
+            self._script["chroot"] = not opts.nochroot
+
+class PreScriptSection(ScriptSection):
+    sectionOpen = "%pre"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_PRE
+
+class PostScriptSection(ScriptSection):
+    sectionOpen = "%post"
+
+    def _getParser(self):
+        op = ScriptSection._getParser(self)
+        op.add_option("--nochroot", dest="nochroot", action="store_true",
+                      default=False)
+        return op
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["chroot"] = True
+        self._script["type"] = KS_SCRIPT_POST
+
+class TracebackScriptSection(ScriptSection):
+    sectionOpen = "%traceback"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_TRACEBACK
+
+class PackageSection(Section):
+    sectionOpen = "%packages"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+
+        self.handler.packages.add([line])
+
+    def handleHeader(self, lineno, args):
+        """Process the arguments to the %packages header and set attributes
+           on the Version's Packages instance appropriate.  This method may be
+           overridden in a subclass if necessary.
+        """
+        Section.handleHeader(self, lineno, args)
+        op = KSOptionParser(version=self.version)
+        op.add_option("--excludedocs", dest="excludedocs", action="store_true",
+                      default=False)
+        op.add_option("--ignoremissing", dest="ignoremissing",
+                      action="store_true", default=False)
+        op.add_option("--nobase", dest="nobase", action="store_true",
+                      default=False)
+        op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
+                      deprecated=FC4, removed=F9)
+        op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
+                      deprecated=FC4, removed=F9)
+        op.add_option("--default", dest="defaultPackages", action="store_true",
+                      default=False, introduced=F7)
+        op.add_option("--instLangs", dest="instLangs", type="string",
+                      default="", introduced=F9)
+
+        (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
+
+        self.handler.packages.excludeDocs = opts.excludedocs
+        self.handler.packages.addBase = not opts.nobase
+        if opts.ignoremissing:
+            self.handler.packages.handleMissing = KS_MISSING_IGNORE
+        else:
+            self.handler.packages.handleMissing = KS_MISSING_PROMPT
+
+        if opts.defaultPackages:
+            self.handler.packages.default = True
+
+        if opts.instLangs:
+            self.handler.packages.instLangs = opts.instLangs
diff --git a/scripts/lib/wic/3rdparty/pykickstart/version.py b/scripts/lib/wic/3rdparty/pykickstart/version.py
new file mode 100644
index 0000000..8a8e6aa
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/version.py
@@ -0,0 +1,168 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Methods for working with kickstart versions.
+
+This module defines several symbolic constants that specify kickstart syntax
+versions.  Each version corresponds roughly to one release of Red Hat Linux,
+Red Hat Enterprise Linux, or Fedora Core as these are where most syntax
+changes take place.
+
+This module also exports several functions:
+
+    makeVersion - Given a version number, return an instance of the
+                  matching handler class.
+
+    returnClassForVersion - Given a version number, return the matching
+                            handler class.  This does not return an
+                            instance of that class, however.
+
+    stringToVersion - Convert a string representation of a version number
+                      into the symbolic constant.
+
+    versionToString - Perform the reverse mapping.
+
+    versionFromFile - Read a kickstart file and determine the version of
+                      syntax it uses.  This requires the kickstart file to
+                      have a version= comment in it.
+"""
+import imputil, re, sys
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+from pykickstart.errors import KickstartVersionError
+
+# Symbolic names for internal version numbers.
+RHEL3 = 900
+FC3 = 1000
+RHEL4 = 1100
+FC4 = 2000
+FC5 = 3000
+FC6 = 4000
+RHEL5 = 4100
+F7  = 5000
+F8 = 6000
+F9 = 7000
+F10 = 8000
+F11 = 9000
+F12 = 10000
+F13 = 11000
+RHEL6 = 11100
+F14 = 12000
+F15 = 13000
+F16 = 14000
+
+# This always points at the latest version and is the default.
+DEVEL = F16
+
+# A one-to-one mapping from string representations to version numbers.
+versionMap = {
+        "DEVEL": DEVEL,
+        "FC3": FC3, "FC4": FC4, "FC5": FC5, "FC6": FC6, "F7": F7, "F8": F8,
+        "F9": F9, "F10": F10, "F11": F11, "F12": F12, "F13": F13,
+        "F14": F14, "F15": F15, "F16": F16,
+        "RHEL3": RHEL3, "RHEL4": RHEL4, "RHEL5": RHEL5, "RHEL6": RHEL6
+}
+
+def stringToVersion(s):
+    """Convert string into one of the provided version constants.  Raises
+       KickstartVersionError if string does not match anything.
+    """
+    # First try these short forms.
+    try:
+        return versionMap[s.upper()]
+    except KeyError:
+        pass
+
+    # Now try the Fedora versions.
+    m = re.match("^fedora.* (\d+)$", s, re.I)
+
+    if m and m.group(1):
+        if versionMap.has_key("FC" + m.group(1)):
+            return versionMap["FC" + m.group(1)]
+        elif versionMap.has_key("F" + m.group(1)):
+            return versionMap["F" + m.group(1)]
+        else:
+            raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+    # Now try the RHEL versions.
+    m = re.match("^red hat enterprise linux.* (\d+)([\.\d]*)$", s, re.I)
+
+    if m and m.group(1):
+        if versionMap.has_key("RHEL" + m.group(1)):
+            return versionMap["RHEL" + m.group(1)]
+        else:
+            raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+    # If nothing else worked, we're out of options.
+    raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+def versionToString(version, skipDevel=False):
+    """Convert version into a string representation of the version number.
+       This is the reverse operation of stringToVersion.  Raises
+       KickstartVersionError if version does not match anything.
+    """
+    if not skipDevel and version == versionMap["DEVEL"]:
+        return "DEVEL"
+
+    for (key, val) in versionMap.iteritems():
+        if key == "DEVEL":
+            continue
+        elif val == version:
+            return key
+
+    raise KickstartVersionError(_("Unsupported version specified: %s") % version)
+
+def returnClassForVersion(version=DEVEL):
+    """Return the class of the syntax handler for version.  version can be
+       either a string or the matching constant.  Raises KickstartValueError
+       if version does not match anything.
+    """
+    try:
+        version = int(version)
+        module = "%s" % versionToString(version, skipDevel=True)
+    except ValueError:
+        module = "%s" % version
+        version = stringToVersion(version)
+
+    module = module.lower()
+
+    try:
+        import pykickstart.handlers
+        sys.path.extend(pykickstart.handlers.__path__)
+        found = imputil.imp.find_module(module)
+        loaded = imputil.imp.load_module(module, found[0], found[1], found[2])
+
+        for (k, v) in loaded.__dict__.iteritems():
+            if k.lower().endswith("%shandler" % module):
+                return v
+    except:
+        raise KickstartVersionError(_("Unsupported version specified: %s") % version)
+
+def makeVersion(version=DEVEL):
+    """Return a new instance of the syntax handler for version.  version can be
+       either a string or the matching constant.  This function is useful for
+       standalone programs which just need to handle a specific version of
+       kickstart syntax (as provided by a command line argument, for example)
+       and need to instantiate the correct object.
+    """
+    cl = returnClassForVersion(version)
+    return cl()