diff options
Diffstat (limited to 'scripts/lib/mic')
45 files changed, 0 insertions, 7873 deletions
diff --git a/scripts/lib/mic/3rdparty/pykickstart/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/__init__.py +++ /dev/null diff --git a/scripts/lib/mic/3rdparty/pykickstart/base.py b/scripts/lib/mic/3rdparty/pykickstart/base.py deleted file mode 100644 index e6c8f56f9d..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/base.py +++ /dev/null @@ -1,466 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/commands/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py deleted file mode 100644 index 2d94550935..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/commands/bootloader.py b/scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py deleted file mode 100644 index c2b552f689..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py +++ /dev/null @@ -1,216 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/commands/partition.py b/scripts/lib/mic/3rdparty/pykickstart/commands/partition.py deleted file mode 100644 index 56b91aa9d9..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/commands/partition.py +++ /dev/null @@ -1,314 +0,0 @@ -# -# 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=%s" % 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="int", - 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/mic/3rdparty/pykickstart/constants.py b/scripts/lib/mic/3rdparty/pykickstart/constants.py deleted file mode 100644 index 5e12fc80ec..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/constants.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/errors.py b/scripts/lib/mic/3rdparty/pykickstart/errors.py deleted file mode 100644 index a234d99d43..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/errors.py +++ /dev/null @@ -1,103 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/handlers/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py +++ /dev/null diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py deleted file mode 100644 index 8dc80d1ebe..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/handlers/f16.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py deleted file mode 100644 index 3c52f8d754..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/ko.py b/scripts/lib/mic/3rdparty/pykickstart/ko.py deleted file mode 100644 index 1350d19c70..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/ko.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/options.py b/scripts/lib/mic/3rdparty/pykickstart/options.py deleted file mode 100644 index 341c5d7298..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/options.py +++ /dev/null @@ -1,204 +0,0 @@ -# -# 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 - -# 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") - TYPE_CHECKER = copy(Option.TYPE_CHECKER) - TYPE_CHECKER["ksboolean"] = _check_ksboolean - TYPE_CHECKER["string"] = _check_string - - 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/mic/3rdparty/pykickstart/parser.py b/scripts/lib/mic/3rdparty/pykickstart/parser.py deleted file mode 100644 index 840a448673..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/parser.py +++ /dev/null @@ -1,702 +0,0 @@ -# -# 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 * -from urlgrabber import urlread -import urlgrabber.grabber as grabber - -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 - -def _preprocessStateMachine (lineIter): - l = None - lineno = 0 - - # Now open an output kickstart file that we are going to write to one - # line at a time. - (outF, outName) = tempfile.mkstemp("-ks.cfg", "", "/tmp") - - while True: - try: - l = lineIter.next() - except StopIteration: - break - - # At the end of the file? - if l == "": - break - - lineno += 1 - url = None - - ll = l.strip() - if not ll.startswith("%ksappend"): - os.write(outF, l) - continue - - # Try to pull down the remote file. - try: - ksurl = ll.split(' ')[1] - except: - raise KickstartParseError, formatErrorMsg(lineno, msg=_("Illegal url for %%ksappend: %s") % ll) - - try: - url = grabber.urlopen(ksurl) - except grabber.URLGrabError, e: - raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file: %s") % e.strerror) - else: - # Sanity check result. Sometimes FTP doesn't catch a file - # is missing. - try: - if url.size < 1: - raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file")) - except: - raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file")) - - # If that worked, write the remote file to the output kickstart - # file in one burst. Then close everything up to get ready to - # read ahead in the input file. This allows multiple %ksappend - # lines to exist. - if url is not None: - os.write(outF, url.read()) - url.close() - - # All done - close the temp file and return its location. - os.close(outF) - return outName - -def preprocessFromString (s): - """Preprocess the kickstart file, provided as the string str. This - method is currently only useful for handling %ksappend lines, - which need to be fetched before the real kickstart parser can be - run. Returns the location of the complete kickstart file. - """ - i = iter(s.splitlines(True) + [""]) - rc = _preprocessStateMachine (i.next) - return rc - -def preprocessKickstart (f): - """Preprocess the kickstart file, given by the filename file. This - method is currently only useful for handling %ksappend lines, - which need to be fetched before the real kickstart parser can be - run. Returns the location of the complete kickstart file. - """ - try: - fh = urlopen(f) - except grabber.URLGrabError, e: - raise KickstartError, formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % e.strerror) - - rc = _preprocessStateMachine (iter(fh.readlines())) - fh.close() - return rc - -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 = urlread(f) - except grabber.URLGrabError, 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/mic/3rdparty/pykickstart/sections.py b/scripts/lib/mic/3rdparty/pykickstart/sections.py deleted file mode 100644 index 44df856b8d..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/sections.py +++ /dev/null @@ -1,244 +0,0 @@ -# -# 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/mic/3rdparty/pykickstart/version.py b/scripts/lib/mic/3rdparty/pykickstart/version.py deleted file mode 100644 index 102cc37d80..0000000000 --- a/scripts/lib/mic/3rdparty/pykickstart/version.py +++ /dev/null @@ -1,197 +0,0 @@ -# -# 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 -from urlgrabber import urlopen - -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 versionFromFile(f): - """Given a file or URL, look for a line starting with #version= and - return the version number. If no version is found, return DEVEL. - """ - v = DEVEL - - fh = urlopen(f) - - while True: - try: - l = fh.readline() - except StopIteration: - break - - # At the end of the file? - if l == "": - break - - if l.isspace() or l.strip() == "": - continue - - if l[:9] == "#version=": - v = stringToVersion(l[9:].rstrip()) - break - - fh.close() - return v - -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() diff --git a/scripts/lib/mic/__init__.py b/scripts/lib/mic/__init__.py deleted file mode 100644 index 63c1d9c846..0000000000 --- a/scripts/lib/mic/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -import os, sys - -cur_path = os.path.dirname(__file__) or '.' -sys.path.insert(0, cur_path + '/3rdparty') diff --git a/scripts/lib/mic/__version__.py b/scripts/lib/mic/__version__.py deleted file mode 100644 index 60d7626cac..0000000000 --- a/scripts/lib/mic/__version__.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = "0.14" diff --git a/scripts/lib/mic/conf.py b/scripts/lib/mic/conf.py deleted file mode 100644 index a686e9caa7..0000000000 --- a/scripts/lib/mic/conf.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os, sys, re -import ConfigParser - -from mic import msger -from mic import kickstart -from mic.utils import misc, runner, errors - - -def get_siteconf(): - mic_path = os.path.dirname(__file__) - eos = mic_path.find('scripts') + len('scripts') - scripts_path = mic_path[:eos] - - return scripts_path + "/lib/image/config/wic.conf" - -class ConfigMgr(object): - DEFAULTS = {'common': { - "distro_name": "Default Distribution", - "plugin_dir": "/usr/lib/wic/plugins", # TODO use prefix also? - }, - 'create': { - "tmpdir": '/var/tmp/wic', - "outdir": './wic-output', - - "release": None, - "logfile": None, - "name_prefix": None, - "name_suffix": None, - }, - } - - # make the manager class as singleton - _instance = None - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super(ConfigMgr, cls).__new__(cls, *args, **kwargs) - - return cls._instance - - def __init__(self, ksconf=None, siteconf=None): - # reset config options - self.reset() - - if not siteconf: - siteconf = get_siteconf() - - # initial options from siteconf - self._siteconf = siteconf - - if ksconf: - self._ksconf = ksconf - - def reset(self): - self.__ksconf = None - self.__siteconf = None - - # initialize the values with defaults - for sec, vals in self.DEFAULTS.iteritems(): - setattr(self, sec, vals) - - def __set_ksconf(self, ksconf): - if not os.path.isfile(ksconf): - msger.error('Cannot find ks file: %s' % ksconf) - - self.__ksconf = ksconf - self._parse_kickstart(ksconf) - def __get_ksconf(self): - return self.__ksconf - _ksconf = property(__get_ksconf, __set_ksconf) - - def _parse_kickstart(self, ksconf=None): - if not ksconf: - return - - ks = kickstart.read_kickstart(ksconf) - - self.create['ks'] = ks - self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0] - - self.create['name'] = misc.build_name(ksconf, - self.create['release'], - self.create['name_prefix'], - self.create['name_suffix']) - -configmgr = ConfigMgr() diff --git a/scripts/lib/mic/creator.py b/scripts/lib/mic/creator.py deleted file mode 100644 index 7c9ca6f9dc..0000000000 --- a/scripts/lib/mic/creator.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os, sys, re -from optparse import SUPPRESS_HELP - -from mic import msger -from mic.utils import cmdln, errors -from mic.conf import configmgr -from mic.plugin import pluginmgr - - -class Creator(cmdln.Cmdln): - """${name}: create an image - - Usage: - ${name} SUBCOMMAND <ksfile> [OPTS] - - ${command_list} - ${option_list} - """ - - name = 'mic create(cr)' - - def __init__(self, *args, **kwargs): - cmdln.Cmdln.__init__(self, *args, **kwargs) - self._subcmds = [] - - # get cmds from pluginmgr - # mix-in do_subcmd interface - for subcmd, klass in pluginmgr.get_plugins('imager').iteritems(): - if not hasattr(klass, 'do_create'): - msger.warning("Unsupported subcmd: %s" % subcmd) - continue - - func = getattr(klass, 'do_create') - setattr(self.__class__, "do_"+subcmd, func) - self._subcmds.append(subcmd) - - def get_optparser(self): - optparser = cmdln.CmdlnOptionParser(self) - optparser.add_option('-d', '--debug', action='store_true', - dest='debug', - help=SUPPRESS_HELP) - optparser.add_option('-v', '--verbose', action='store_true', - dest='verbose', - help=SUPPRESS_HELP) - optparser.add_option('', '--logfile', type='string', dest='logfile', - default=None, - help='Path of logfile') - optparser.add_option('-c', '--config', type='string', dest='config', - default=None, - help='Specify config file for mic') - optparser.add_option('-o', '--outdir', type='string', action='store', - dest='outdir', default=None, - help='Output directory') - optparser.add_option('', '--tmpfs', action='store_true', dest='enabletmpfs', - help='Setup tmpdir as tmpfs to accelerate, experimental' - ' feature, use it if you have more than 4G memory') - return optparser - - def preoptparse(self, argv): - optparser = self.get_optparser() - - largs = [] - rargs = [] - while argv: - arg = argv.pop(0) - - if arg in ('-h', '--help'): - rargs.append(arg) - - elif optparser.has_option(arg): - largs.append(arg) - - if optparser.get_option(arg).takes_value(): - try: - largs.append(argv.pop(0)) - except IndexError: - raise errors.Usage("option %s requires arguments" % arg) - - else: - if arg.startswith("--"): - if "=" in arg: - opt = arg.split("=")[0] - else: - opt = None - elif arg.startswith("-") and len(arg) > 2: - opt = arg[0:2] - else: - opt = None - - if opt and optparser.has_option(opt): - largs.append(arg) - else: - rargs.append(arg) - - return largs + rargs - - def postoptparse(self): - abspath = lambda pth: os.path.abspath(os.path.expanduser(pth)) - - if self.options.verbose: - msger.set_loglevel('verbose') - if self.options.debug: - msger.set_loglevel('debug') - - if self.options.logfile: - logfile_abs_path = abspath(self.options.logfile) - if os.path.isdir(logfile_abs_path): - raise errors.Usage("logfile's path %s should be file" - % self.options.logfile) - if not os.path.exists(os.path.dirname(logfile_abs_path)): - os.makedirs(os.path.dirname(logfile_abs_path)) - msger.set_interactive(False) - msger.set_logfile(logfile_abs_path) - configmgr.create['logfile'] = self.options.logfile - - if self.options.config: - configmgr.reset() - configmgr._siteconf = self.options.config - - if self.options.outdir is not None: - configmgr.create['outdir'] = abspath(self.options.outdir) - - cdir = 'outdir' - if os.path.exists(configmgr.create[cdir]) \ - and not os.path.isdir(configmgr.create[cdir]): - msger.error('Invalid directory specified: %s' \ - % configmgr.create[cdir]) - - if self.options.enabletmpfs: - configmgr.create['enabletmpfs'] = self.options.enabletmpfs - - def main(self, argv=None): - if argv is None: - argv = sys.argv - else: - argv = argv[:] # don't modify caller's list - - self.optparser = self.get_optparser() - if self.optparser: - try: - argv = self.preoptparse(argv) - self.options, args = self.optparser.parse_args(argv) - - except cmdln.CmdlnUserError, ex: - msg = "%s: %s\nTry '%s help' for info.\n"\ - % (self.name, ex, self.name) - msger.error(msg) - - except cmdln.StopOptionProcessing, ex: - return 0 - else: - # optparser=None means no process for opts - self.options, args = None, argv[1:] - - if not args: - return self.emptyline() - - self.postoptparse() - - return self.cmd(args) - - def precmd(self, argv): # check help before cmd - - if '-h' in argv or '?' in argv or '--help' in argv or 'help' in argv: - return argv - - if len(argv) == 1: - return ['help', argv[0]] - - return argv diff --git a/scripts/lib/mic/imager/__init__.py b/scripts/lib/mic/imager/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/scripts/lib/mic/imager/__init__.py +++ /dev/null diff --git a/scripts/lib/mic/imager/baseimager.py b/scripts/lib/mic/imager/baseimager.py deleted file mode 100644 index 23919d4cfa..0000000000 --- a/scripts/lib/mic/imager/baseimager.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2007 Red Hat Inc. -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -from __future__ import with_statement -import os, sys -import tempfile -import shutil - -from mic import kickstart -from mic import msger -from mic.utils.errors import CreatorError -from mic.utils import misc, runner, fs_related as fs - -class BaseImageCreator(object): - """Base class for image creation. - - BaseImageCreator is the simplest creator class available; it will - create a system image according to the supplied kickstart file. - - e.g. - - import mic.imgcreate as imgcreate - ks = imgcreate.read_kickstart("foo.ks") - imgcreate.ImageCreator(ks, "foo").create() - """ - - def __del__(self): - self.cleanup() - - def __init__(self, createopts = None): - """Initialize an ImageCreator instance. - - ks -- a pykickstart.KickstartParser instance; this instance will be - used to drive the install by e.g. providing the list of packages - to be installed, the system configuration and %post scripts - - name -- a name for the image; used for e.g. image filenames or - filesystem labels - """ - - self.__builddir = None - - self.ks = None - self.name = "target" - self.tmpdir = "/var/tmp/wic" - self.workdir = "/var/tmp/wic/build" - - # setup tmpfs tmpdir when enabletmpfs is True - self.enabletmpfs = False - - if createopts: - # Mapping table for variables that have different names. - optmap = {"outdir" : "destdir", - } - - # update setting from createopts - for key in createopts.keys(): - if key in optmap: - option = optmap[key] - else: - option = key - setattr(self, option, createopts[key]) - - self.destdir = os.path.abspath(os.path.expanduser(self.destdir)) - - self._dep_checks = ["ls", "bash", "cp", "echo"] - - # Output image file names - self.outimage = [] - - # No ks provided when called by convertor, so skip the dependency check - if self.ks: - # If we have btrfs partition we need to check necessary tools - for part in self.ks.handler.partition.partitions: - if part.fstype and part.fstype == "btrfs": - self._dep_checks.append("mkfs.btrfs") - break - - # make sure the specified tmpdir and cachedir exist - if not os.path.exists(self.tmpdir): - os.makedirs(self.tmpdir) - - - # - # Hooks for subclasses - # - def _create(self): - """Create partitions for the disk image(s) - - This is the hook where subclasses may create the partitions - that will be assembled into disk image(s). - - There is no default implementation. - """ - pass - - def _cleanup(self): - """Undo anything performed in _create(). - - This is the hook where subclasses must undo anything which was - done in _create(). - - There is no default implementation. - - """ - pass - - # - # Actual implementation - # - def __ensure_builddir(self): - if not self.__builddir is None: - return - - try: - self.workdir = os.path.join(self.tmpdir, "build") - if not os.path.exists(self.workdir): - os.makedirs(self.workdir) - self.__builddir = tempfile.mkdtemp(dir = self.workdir, - prefix = "imgcreate-") - except OSError, (err, msg): - raise CreatorError("Failed create build directory in %s: %s" % - (self.tmpdir, msg)) - - def __setup_tmpdir(self): - if not self.enabletmpfs: - return - - runner.show('mount -t tmpfs -o size=4G tmpfs %s' % self.workdir) - - def __clean_tmpdir(self): - if not self.enabletmpfs: - return - - runner.show('umount -l %s' % self.workdir) - - def create(self): - """Create partitions for the disk image(s) - - Create the partitions that will be assembled into disk - image(s). - """ - self.__setup_tmpdir() - self.__ensure_builddir() - - self._create() - - def cleanup(self): - """Undo anything performed in create(). - - Note, make sure to call this method once finished with the creator - instance in order to ensure no stale files are left on the host e.g.: - - creator = ImageCreator(ks, name) - try: - creator.create() - finally: - creator.cleanup() - - """ - if not self.__builddir: - return - - self._cleanup() - - shutil.rmtree(self.__builddir, ignore_errors = True) - self.__builddir = None - - self.__clean_tmpdir() - - - def print_outimage_info(self): - msg = "The new image can be found here:\n" - self.outimage.sort() - for file in self.outimage: - msg += ' %s\n' % os.path.abspath(file) - - msger.info(msg) diff --git a/scripts/lib/mic/imager/direct.py b/scripts/lib/mic/imager/direct.py deleted file mode 100644 index 2f2bd4e072..0000000000 --- a/scripts/lib/mic/imager/direct.py +++ /dev/null @@ -1,363 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2013, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This implements the 'direct' image creator class for 'wic', based -# loosely on the raw image creator from 'mic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import os -import stat -import shutil - -from mic import kickstart, msger -from mic.utils import fs_related, runner, misc -from mic.utils.partitionedfs import Image -from mic.utils.errors import CreatorError, ImageError -from mic.imager.baseimager import BaseImageCreator -from mic.utils.oe.misc import * -from mic.plugin import pluginmgr - -disk_methods = { - "do_install_disk":None, -} - -class DirectImageCreator(BaseImageCreator): - """ - Installs a system into a file containing a partitioned disk image. - - DirectImageCreator is an advanced ImageCreator subclass; an image - file is formatted with a partition table, each partition created - from a rootfs or other OpenEmbedded build artifact and dd'ed into - the virtual disk. The disk image can subsequently be dd'ed onto - media and used on actual hardware. - """ - - def __init__(self, oe_builddir, image_output_dir, rootfs_dir, bootimg_dir, - kernel_dir, native_sysroot, hdddir, staging_data_dir, - creatoropts=None): - """ - Initialize a DirectImageCreator instance. - - This method takes the same arguments as ImageCreator.__init__() - """ - BaseImageCreator.__init__(self, creatoropts) - - self.__image = None - self.__disks = {} - self.__disk_format = "direct" - self._disk_names = [] - self._ptable_format = self.ks.handler.bootloader.ptable - - self.oe_builddir = oe_builddir - if image_output_dir: - self.tmpdir = image_output_dir - self.rootfs_dir = rootfs_dir - self.bootimg_dir = bootimg_dir - self.kernel_dir = kernel_dir - self.native_sysroot = native_sysroot - self.hdddir = hdddir - self.staging_data_dir = staging_data_dir - - def __write_fstab(self, image_rootfs): - """overriden to generate fstab (temporarily) in rootfs. This is called - from _create, make sure it doesn't get called from - BaseImage.create() - """ - if image_rootfs is None: - return None - - fstab = image_rootfs + "/etc/fstab" - if not os.path.isfile(fstab): - return None - - parts = self._get_parts() - - self._save_fstab(fstab) - fstab_lines = self._get_fstab(fstab, parts) - self._update_fstab(fstab_lines, parts) - self._write_fstab(fstab, fstab_lines) - - return fstab - - def _update_fstab(self, fstab_lines, parts): - """Assume partition order same as in wks""" - for num, p in enumerate(parts, 1): - if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot": - continue - if self._ptable_format == 'msdos' and num > 3: - device_name = "/dev/" + p.disk + str(num + 1) - else: - device_name = "/dev/" + p.disk + str(num) - - opts = "defaults" - if p.fsopts: - opts = p.fsopts - - fstab_entry = device_name + "\t" + \ - p.mountpoint + "\t" + \ - p.fstype + "\t" + \ - opts + "\t0\t0\n" - fstab_lines.append(fstab_entry) - - def _write_fstab(self, fstab, fstab_lines): - fstab = open(fstab, "w") - for line in fstab_lines: - fstab.write(line) - fstab.close() - - def _save_fstab(self, fstab): - """Save the current fstab in rootfs""" - shutil.copyfile(fstab, fstab + ".orig") - - def _restore_fstab(self, fstab): - """Restore the saved fstab in rootfs""" - if fstab is None: - return - shutil.move(fstab + ".orig", fstab) - - def _get_fstab(self, fstab, parts): - """Return the desired contents of /etc/fstab.""" - f = open(fstab, "r") - fstab_contents = f.readlines() - f.close() - - return fstab_contents - - def set_bootimg_dir(self, bootimg_dir): - """ - Accessor for bootimg_dir, the actual location used for the source - of the bootimg. Should be set by source plugins (only if they - change the default bootimg source) so the correct info gets - displayed for print_outimage_info(). - """ - self.bootimg_dir = bootimg_dir - - def _get_parts(self): - if not self.ks: - raise CreatorError("Failed to get partition info, " - "please check your kickstart setting.") - - # Set a default partition if no partition is given out - if not self.ks.handler.partition.partitions: - partstr = "part / --size 1900 --ondisk sda --fstype=ext3" - args = partstr.split() - pd = self.ks.handler.partition.parse(args[1:]) - if pd not in self.ks.handler.partition.partitions: - self.ks.handler.partition.partitions.append(pd) - - # partitions list from kickstart file - return kickstart.get_partitions(self.ks) - - def get_disk_names(self): - """ Returns a list of physical target disk names (e.g., 'sdb') which - will be created. """ - - if self._disk_names: - return self._disk_names - - #get partition info from ks handler - parts = self._get_parts() - - for i in range(len(parts)): - if parts[i].disk: - disk_name = parts[i].disk - else: - raise CreatorError("Failed to create disks, no --ondisk " - "specified in partition line of ks file") - - if parts[i].mountpoint and not parts[i].fstype: - raise CreatorError("Failed to create disks, no --fstype " - "specified for partition with mountpoint " - "'%s' in the ks file") - - self._disk_names.append(disk_name) - - return self._disk_names - - def _full_name(self, name, extention): - """ Construct full file name for a file we generate. """ - return "%s-%s.%s" % (self.name, name, extention) - - def _full_path(self, path, name, extention): - """ Construct full file path to a file we generate. """ - return os.path.join(path, self._full_name(name, extention)) - - def get_default_source_plugin(self): - """ - The default source plugin i.e. the plugin that's consulted for - overall image generation tasks outside of any particular - partition. For convenience, we just hang it off the - bootloader handler since it's the one non-partition object in - any setup. By default the default plugin is set to the same - plugin as the /boot partition; since we hang it off the - bootloader object, the default can be explicitly set using the - --source bootloader param. - """ - return self.ks.handler.bootloader.source - - # - # Actual implemention - # - def _create(self): - """ - For 'wic', we already have our build artifacts - we just create - filesystems from the artifacts directly and combine them into - a partitioned image. - """ - parts = self._get_parts() - - self.__image = Image() - - for p in parts: - # as a convenience, set source to the boot partition source - # instead of forcing it to be set via bootloader --source - if not self.ks.handler.bootloader.source and p.mountpoint == "/boot": - self.ks.handler.bootloader.source = p.source - - for p in parts: - # need to create the filesystems in order to get their - # sizes before we can add them and do the layout. - # Image.create() actually calls __format_disks() to create - # the disk images and carve out the partitions, then - # self.assemble() calls Image.assemble() which calls - # __write_partitition() for each partition to dd the fs - # into the partitions. - fstab = self.__write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) - - p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir, - self.bootimg_dir, self.kernel_dir, self.native_sysroot) - - self._restore_fstab(fstab) - - self.__image.add_partition(int(p.size), - p.disk, - p.mountpoint, - p.source_file, - p.fstype, - p.label, - fsopts = p.fsopts, - boot = p.active, - align = p.align, - part_type = p.part_type) - - self.__image.layout_partitions(self._ptable_format) - - self.__imgdir = self.workdir - for disk_name, disk in self.__image.disks.items(): - full_path = self._full_path(self.__imgdir, disk_name, "direct") - msger.debug("Adding disk %s as %s with size %s bytes" \ - % (disk_name, full_path, disk['min_size'])) - disk_obj = fs_related.DiskImage(full_path, disk['min_size']) - self.__disks[disk_name] = disk_obj - self.__image.add_disk(disk_name, disk_obj) - - self.__image.create() - - def assemble(self): - """ - Assemble partitions into disk image(s) - """ - for disk_name, disk in self.__image.disks.items(): - full_path = self._full_path(self.__imgdir, disk_name, "direct") - msger.debug("Assembling disk %s as %s with size %s bytes" \ - % (disk_name, full_path, disk['min_size'])) - self.__image.assemble(full_path) - - def finalize(self): - """ - Finalize the disk image. - - For example, prepare the image to be bootable by e.g. - creating and installing a bootloader configuration. - - """ - source_plugin = self.get_default_source_plugin() - if source_plugin: - self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods) - for disk_name, disk in self.__image.disks.items(): - self._source_methods["do_install_disk"](disk, disk_name, self, - self.workdir, - self.oe_builddir, - self.bootimg_dir, - self.kernel_dir, - self.native_sysroot) - - def print_outimage_info(self): - """ - Print the image(s) and artifacts used, for the user. - """ - msg = "The new image(s) can be found here:\n" - - parts = self._get_parts() - - for disk_name, disk in self.__image.disks.items(): - full_path = self._full_path(self.__imgdir, disk_name, "direct") - msg += ' %s\n\n' % full_path - - msg += 'The following build artifacts were used to create the image(s):\n' - for p in parts: - if p.get_rootfs() is None: - continue - if p.mountpoint == '/': - str = ':' - else: - str = '["%s"]:' % p.label - msg += ' ROOTFS_DIR%s%s\n' % (str.ljust(20), p.get_rootfs()) - - msg += ' BOOTIMG_DIR: %s\n' % self.bootimg_dir - msg += ' KERNEL_DIR: %s\n' % self.kernel_dir - msg += ' NATIVE_SYSROOT: %s\n' % self.native_sysroot - - msger.info(msg) - - def _get_boot_config(self): - """ - Return the rootdev/root_part_uuid (if specified by - --part-type) - - Assume partition order same as in wks - """ - rootdev = None - root_part_uuid = None - parts = self._get_parts() - for num, p in enumerate(parts, 1): - if p.mountpoint == "/": - part = '' - if p.disk.startswith('mmcblk'): - part = 'p' - - if self._ptable_format == 'msdos' and num > 3: - rootdev = "/dev/%s%s%-d" % (p.disk, part, num + 1) - else: - rootdev = "/dev/%s%s%-d" % (p.disk, part, num) - root_part_uuid = p.part_type - - return (rootdev, root_part_uuid) - - def _cleanup(self): - if not self.__image is None: - try: - self.__image.cleanup() - except ImageError, err: - msger.warning("%s" % err) - diff --git a/scripts/lib/mic/kickstart/__init__.py b/scripts/lib/mic/kickstart/__init__.py deleted file mode 100644 index 590bf4728f..0000000000 --- a/scripts/lib/mic/kickstart/__init__.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2007 Red Hat, Inc. -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os, sys, re -import shutil -import subprocess -import string - -import pykickstart.sections as kssections -import pykickstart.commands as kscommands -import pykickstart.constants as ksconstants -import pykickstart.errors as kserrors -import pykickstart.parser as ksparser -import pykickstart.version as ksversion -from pykickstart.handlers.control import commandMap -from pykickstart.handlers.control import dataMap - -from mic import msger -from mic.utils import errors, misc, runner, fs_related as fs -from custom_commands import wicboot, partition - -def read_kickstart(path): - """Parse a kickstart file and return a KickstartParser instance. - - This is a simple utility function which takes a path to a kickstart file, - parses it and returns a pykickstart KickstartParser instance which can - be then passed to an ImageCreator constructor. - - If an error occurs, a CreatorError exception is thrown. - """ - - #version = ksversion.makeVersion() - #ks = ksparser.KickstartParser(version) - - using_version = ksversion.DEVEL - commandMap[using_version]["bootloader"] = wicboot.Wic_Bootloader - commandMap[using_version]["part"] = partition.Wic_Partition - commandMap[using_version]["partition"] = partition.Wic_Partition - dataMap[using_version]["PartData"] = partition.Wic_PartData - superclass = ksversion.returnClassForVersion(version=using_version) - - class KSHandlers(superclass): - def __init__(self): - superclass.__init__(self, mapping=commandMap[using_version]) - - ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False) - - try: - ks.readKickstart(path) - except (kserrors.KickstartParseError, kserrors.KickstartError), err: - if msger.ask("Errors occured on kickstart file, skip and continue?"): - msger.warning("%s" % err) - pass - else: - raise errors.KsError("%s" % err) - - return ks - -def get_image_size(ks, default = None): - __size = 0 - for p in ks.handler.partition.partitions: - if p.mountpoint == "/" and p.size: - __size = p.size - if __size > 0: - return int(__size) * 1024L * 1024L - else: - return default - -def get_image_fstype(ks, default = None): - for p in ks.handler.partition.partitions: - if p.mountpoint == "/" and p.fstype: - return p.fstype - return default - -def get_image_fsopts(ks, default = None): - for p in ks.handler.partition.partitions: - if p.mountpoint == "/" and p.fsopts: - return p.fsopts - return default - -def get_timeout(ks, default = None): - if not hasattr(ks.handler.bootloader, "timeout"): - return default - if ks.handler.bootloader.timeout is None: - return default - return int(ks.handler.bootloader.timeout) - -def get_kernel_args(ks, default = "ro rd.live.image"): - if not hasattr(ks.handler.bootloader, "appendLine"): - return default - if ks.handler.bootloader.appendLine is None: - return default - return "%s %s" %(default, ks.handler.bootloader.appendLine) - -def get_menu_args(ks, default = ""): - if not hasattr(ks.handler.bootloader, "menus"): - return default - if ks.handler.bootloader.menus in (None, ""): - return default - return "%s" % ks.handler.bootloader.menus - -def get_default_kernel(ks, default = None): - if not hasattr(ks.handler.bootloader, "default"): - return default - if not ks.handler.bootloader.default: - return default - return ks.handler.bootloader.default - -def get_partitions(ks): - return ks.handler.partition.partitions diff --git a/scripts/lib/mic/kickstart/custom_commands/__init__.py b/scripts/lib/mic/kickstart/custom_commands/__init__.py deleted file mode 100644 index f84c6d9e00..0000000000 --- a/scripts/lib/mic/kickstart/custom_commands/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from micpartition import Mic_Partition -from micpartition import Mic_PartData -from partition import Wic_Partition - -__all__ = ( - "Mic_Partition", - "Mic_PartData", - "Wic_Partition", - "Wic_PartData", -) diff --git a/scripts/lib/mic/kickstart/custom_commands/micboot.py b/scripts/lib/mic/kickstart/custom_commands/micboot.py deleted file mode 100644 index 66d1678aa7..0000000000 --- a/scripts/lib/mic/kickstart/custom_commands/micboot.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2008, 2009, 2010 Intel, Inc. -# -# Anas Nashif -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -from pykickstart.base import * -from pykickstart.errors import * -from pykickstart.options import * -from pykickstart.commands.bootloader import * - -class Mic_Bootloader(F8_Bootloader): - def __init__(self, writePriority=10, appendLine="", driveorder=None, - forceLBA=False, location="", md5pass="", password="", - upgrade=False, menus=""): - F8_Bootloader.__init__(self, writePriority, appendLine, driveorder, - forceLBA, location, md5pass, password, upgrade) - - self.menus = "" - self.ptable = "msdos" - - def _getArgsAsStr(self): - ret = F8_Bootloader._getArgsAsStr(self) - - if self.menus == "": - ret += " --menus=%s" %(self.menus,) - if self.ptable: - ret += " --ptable=\"%s\"" %(self.ptable,) - return ret - - def _getParser(self): - op = F8_Bootloader._getParser(self) - op.add_option("--menus", dest="menus") - op.add_option("--ptable", dest="ptable", type="string") - return op - diff --git a/scripts/lib/mic/kickstart/custom_commands/micpartition.py b/scripts/lib/mic/kickstart/custom_commands/micpartition.py deleted file mode 100644 index 59a87fb486..0000000000 --- a/scripts/lib/mic/kickstart/custom_commands/micpartition.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -tt -# -# Marko Saukko <marko.saukko@cybercom.com> -# -# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -# -# 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. - -from pykickstart.commands.partition import * - -class Mic_PartData(FC4_PartData): - removedKeywords = FC4_PartData.removedKeywords - removedAttrs = FC4_PartData.removedAttrs - - def __init__(self, *args, **kwargs): - FC4_PartData.__init__(self, *args, **kwargs) - self.deleteRemovedAttrs() - self.align = kwargs.get("align", None) - self.extopts = kwargs.get("extopts", None) - self.part_type = kwargs.get("part_type", None) - - def _getArgsAsStr(self): - retval = FC4_PartData._getArgsAsStr(self) - - if self.align: - retval += " --align" - if self.extopts: - retval += " --extoptions=%s" % self.extopts - if self.part_type: - retval += " --part-type=%s" % self.part_type - - return retval - -class Mic_Partition(FC4_Partition): - removedKeywords = FC4_Partition.removedKeywords - removedAttrs = FC4_Partition.removedAttrs - - def _getParser(self): - op = FC4_Partition._getParser(self) - # The alignment value is given in kBytes. e.g., value 8 means that - # the partition is aligned to start from 8096 byte boundary. - op.add_option("--align", type="int", action="store", dest="align", - default=None) - op.add_option("--extoptions", type="string", action="store", dest="extopts", - default=None) - op.add_option("--part-type", type="string", action="store", dest="part_type", - default=None) - return op diff --git a/scripts/lib/mic/kickstart/custom_commands/partition.py b/scripts/lib/mic/kickstart/custom_commands/partition.py deleted file mode 100644 index 101b90ef10..0000000000 --- a/scripts/lib/mic/kickstart/custom_commands/partition.py +++ /dev/null @@ -1,496 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2013, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This module provides the OpenEmbedded partition object definitions. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import shutil -import os -import tempfile - -from pykickstart.commands.partition import * -from mic.utils.oe.misc import * -from mic.kickstart.custom_commands import * -from mic.plugin import pluginmgr - -partition_methods = { - "do_stage_partition":None, - "do_prepare_partition":None, - "do_configure_partition":None, -} - -class Wic_PartData(Mic_PartData): - removedKeywords = Mic_PartData.removedKeywords - removedAttrs = Mic_PartData.removedAttrs - - def __init__(self, *args, **kwargs): - Mic_PartData.__init__(self, *args, **kwargs) - self.deleteRemovedAttrs() - self.source = kwargs.get("source", None) - self.rootfs = kwargs.get("rootfs-dir", None) - self.source_file = "" - self.size = 0 - - def _getArgsAsStr(self): - retval = Mic_PartData._getArgsAsStr(self) - - if self.source: - retval += " --source=%s" % self.source - if self.rootfs: - retval += " --rootfs-dir=%s" % self.rootfs - - return retval - - def get_rootfs(self): - """ - Acessor for rootfs dir - """ - return self.rootfs - - def set_rootfs(self, rootfs): - """ - Acessor for actual rootfs dir, which must be set by source - plugins. - """ - self.rootfs = rootfs - - def get_size(self): - """ - Accessor for partition size, 0 or --size before set_size(). - """ - return self.size - - def set_size(self, size): - """ - Accessor for actual partition size, which must be set by source - plugins. - """ - self.size = size - - def set_source_file(self, source_file): - """ - Accessor for source_file, the location of the generated partition - image, which must be set by source plugins. - """ - self.source_file = source_file - - def get_extra_block_count(self, current_blocks): - """ - The --size param is reflected in self.size (in MB), and we already - have current_blocks (1k) blocks, calculate and return the - number of (1k) blocks we need to add to get to --size, 0 if - we're already there or beyond. - """ - msger.debug("Requested partition size for %s: %d" % \ - (self.mountpoint, self.size)) - - if not self.size: - return 0 - - requested_blocks = self.size * 1024 - - msger.debug("Requested blocks %d, current_blocks %d" % \ - (requested_blocks, current_blocks)) - - if requested_blocks > current_blocks: - return requested_blocks - current_blocks - else: - return 0 - - def prepare(self, cr, cr_workdir, oe_builddir, rootfs_dir, bootimg_dir, - kernel_dir, native_sysroot): - """ - Prepare content for individual partitions, depending on - partition command parameters. - """ - if not self.source: - if not self.size: - msger.error("The %s partition has a size of zero. Please specify a non-zero --size for that partition." % self.mountpoint) - if self.fstype and self.fstype == "swap": - self.prepare_swap_partition(cr_workdir, oe_builddir, - native_sysroot) - elif self.fstype: - self.prepare_empty_partition(cr_workdir, oe_builddir, - native_sysroot) - return - - plugins = pluginmgr.get_source_plugins() - - if self.source not in plugins: - msger.error("The '%s' --source specified for %s doesn't exist.\n\tSee 'wic list source-plugins' for a list of available --sources.\n\tSee 'wic help source-plugins' for details on adding a new source plugin." % (self.source, self.mountpoint)) - - self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods) - self._source_methods["do_configure_partition"](self, cr, cr_workdir, - oe_builddir, - bootimg_dir, - kernel_dir, - native_sysroot) - self._source_methods["do_stage_partition"](self, cr, cr_workdir, - oe_builddir, - bootimg_dir, kernel_dir, - native_sysroot) - self._source_methods["do_prepare_partition"](self, cr, cr_workdir, - oe_builddir, - bootimg_dir, kernel_dir, rootfs_dir, - native_sysroot) - - def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir, - rootfs_dir): - """ - Handle an already-created partition e.g. xxx.ext3 - """ - rootfs = oe_builddir - du_cmd = "du -Lbms %s" % rootfs - out = exec_cmd(du_cmd) - rootfs_size = out.split()[0] - - self.size = rootfs_size - self.source_file = rootfs - - def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot): - """ - Prepare content for a rootfs partition i.e. create a partition - and fill it from a /rootfs dir. - - Currently handles ext2/3/4 and btrfs. - """ - pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot - pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir - pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir - pseudo += "export PSEUDO_NOSYMLINKEXP=1;" - pseudo += "%s/usr/bin/pseudo " % native_sysroot - - if self.fstype.startswith("ext"): - return self.prepare_rootfs_ext(cr_workdir, oe_builddir, - rootfs_dir, native_sysroot, - pseudo) - elif self.fstype.startswith("btrfs"): - return self.prepare_rootfs_btrfs(cr_workdir, oe_builddir, - rootfs_dir, native_sysroot, - pseudo) - - elif self.fstype.startswith("vfat"): - return self.prepare_rootfs_vfat(cr_workdir, oe_builddir, - rootfs_dir, native_sysroot, - pseudo) - elif self.fstype.startswith("squashfs"): - return self.prepare_rootfs_squashfs(cr_workdir, oe_builddir, - rootfs_dir, native_sysroot, - pseudo) - - def prepare_rootfs_ext(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for an ext2/3/4 rootfs partition. - """ - - image_rootfs = rootfs_dir - rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype) - - du_cmd = "du -ks %s" % image_rootfs - out = exec_cmd(du_cmd) - actual_rootfs_size = int(out.split()[0]) - - extra_blocks = self.get_extra_block_count(actual_rootfs_size) - - if extra_blocks < IMAGE_EXTRA_SPACE: - extra_blocks = IMAGE_EXTRA_SPACE - - rootfs_size = actual_rootfs_size + extra_blocks - - msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ - (extra_blocks, self.mountpoint, rootfs_size)) - - dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \ - (rootfs, rootfs_size) - exec_cmd(dd_cmd) - - extra_imagecmd = "-i 8192" - - mkfs_cmd = "mkfs.%s -F %s %s -d %s" % \ - (self.fstype, extra_imagecmd, rootfs, image_rootfs) - exec_native_cmd(pseudo + mkfs_cmd, native_sysroot) - - - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs - out = exec_cmd(du_cmd) - rootfs_size = out.split()[0] - - self.size = rootfs_size - self.source_file = rootfs - - return 0 - - def prepare_rootfs_btrfs(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a btrfs rootfs partition. - - Currently handles ext2/3/4 and btrfs. - """ - image_rootfs = rootfs_dir - rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype) - - du_cmd = "du -ks %s" % image_rootfs - out = exec_cmd(du_cmd) - actual_rootfs_size = int(out.split()[0]) - - extra_blocks = self.get_extra_block_count(actual_rootfs_size) - - if extra_blocks < IMAGE_EXTRA_SPACE: - extra_blocks = IMAGE_EXTRA_SPACE - - rootfs_size = actual_rootfs_size + extra_blocks - - msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ - (extra_blocks, self.mountpoint, rootfs_size)) - - dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \ - (rootfs, rootfs_size) - exec_cmd(dd_cmd) - - mkfs_cmd = "mkfs.%s -b %d -r %s %s" % \ - (self.fstype, rootfs_size * 1024, image_rootfs, rootfs) - exec_native_cmd(pseudo + mkfs_cmd, native_sysroot) - - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs - out = exec_cmd(du_cmd) - rootfs_size = out.split()[0] - - self.size = rootfs_size - self.source_file = rootfs - - def prepare_rootfs_vfat(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a vfat rootfs partition. - """ - image_rootfs = rootfs_dir - rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype) - - du_cmd = "du -bks %s" % image_rootfs - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - extra_blocks = self.get_extra_block_count(blocks) - - if extra_blocks < BOOTDD_EXTRA_SPACE: - extra_blocks = BOOTDD_EXTRA_SPACE - - blocks += extra_blocks - - msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ - (extra_blocks, self.mountpoint, blocks)) - - # Ensure total sectors is an integral number of sectors per - # track or mcopy will complain. Sectors are 512 bytes, and we - # generate images with 32 sectors per track. This calculation is - # done in blocks, thus the mod by 16 instead of 32. - blocks += (16 - (blocks % 16)) - - dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (rootfs, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, image_rootfs) - rc, out = exec_native_cmd(mcopy_cmd, native_sysroot) - if rc: - msger.error("ERROR: mcopy returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % rc) - - chmod_cmd = "chmod 644 %s" % rootfs - exec_cmd(chmod_cmd) - - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs - out = exec_cmd(du_cmd) - rootfs_size = out.split()[0] - - self.set_size(rootfs_size) - self.set_source_file(rootfs) - - def prepare_rootfs_squashfs(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a squashfs rootfs partition. - """ - image_rootfs = rootfs_dir - rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype) - - squashfs_cmd = "mksquashfs %s %s -noappend" % \ - (image_rootfs, rootfs) - exec_native_cmd(pseudo + squashfs_cmd, native_sysroot) - - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs - out = exec_cmd(du_cmd) - rootfs_size = out.split()[0] - - self.size = rootfs_size - self.source_file = rootfs - - return 0 - - def prepare_empty_partition(self, cr_workdir, oe_builddir, native_sysroot): - """ - Prepare an empty partition. - """ - if self.fstype.startswith("ext"): - return self.prepare_empty_partition_ext(cr_workdir, oe_builddir, - native_sysroot) - elif self.fstype.startswith("btrfs"): - return self.prepare_empty_partition_btrfs(cr_workdir, oe_builddir, - native_sysroot) - elif self.fstype.startswith("vfat"): - return self.prepare_empty_partition_vfat(cr_workdir, oe_builddir, - native_sysroot) - elif self.fstype.startswith("squashfs"): - return self.prepare_empty_partition_squashfs(cr_workdir, oe_builddir, - native_sysroot) - - def prepare_empty_partition_ext(self, cr_workdir, oe_builddir, - native_sysroot): - """ - Prepare an empty ext2/3/4 partition. - """ - fs = "%s/fs.%s" % (cr_workdir, self.fstype) - - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ - (fs, self.size) - exec_cmd(dd_cmd) - - extra_imagecmd = "-i 8192" - - mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs) - exec_native_cmd(mkfs_cmd, native_sysroot) - - self.source_file = fs - - return 0 - - def prepare_empty_partition_btrfs(self, cr_workdir, oe_builddir, - native_sysroot): - """ - Prepare an empty btrfs partition. - """ - fs = "%s/fs.%s" % (cr_workdir, self.fstype) - - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ - (fs, self.size) - exec_cmd(dd_cmd) - - mkfs_cmd = "mkfs.%s -b %d %s" % (self.fstype, self.size * 1024, rootfs) - exec_native_cmd(mkfs_cmd, native_sysroot) - - mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs) - exec_native_cmd(mkfs_cmd, native_sysroot) - - self.source_file = fs - - return 0 - - def prepare_empty_partition_vfat(self, cr_workdir, oe_builddir, - native_sysroot): - """ - Prepare an empty vfat partition. - """ - fs = "%s/fs.%s" % (cr_workdir, self.fstype) - - blocks = self.size * 1024 - - dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (fs, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % fs - exec_cmd(chmod_cmd) - - self.source_file = fs - - return 0 - - def prepare_empty_partition_squashfs(self, cr_workdir, oe_builddir, - native_sysroot): - """ - Prepare an empty squashfs partition. - """ - msger.warning("Creating of an empty squashfs %s partition was attempted. " \ - "Proceeding as requested." % self.mountpoint) - - fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype) - - # it is not possible to create a squashfs without source data, - # thus prepare an empty temp dir that is used as source - tmpdir = tempfile.mkdtemp() - - squashfs_cmd = "mksquashfs %s %s -noappend" % \ - (tmpdir, fs) - exec_native_cmd(squashfs_cmd, native_sysroot) - - os.rmdir(tmpdir) - - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % fs - out = exec_cmd(du_cmd) - fs_size = out.split()[0] - - self.size = fs_size - self.source_file = fs - - return 0 - - def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot): - """ - Prepare a swap partition. - """ - fs = "%s/fs.%s" % (cr_workdir, self.fstype) - - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ - (fs, self.size) - exec_cmd(dd_cmd) - - import uuid - label_str = "" - if self.label: - label_str = "-L %s" % self.label - mkswap_cmd = "mkswap %s -U %s %s" % (label_str, str(uuid.uuid1()), fs) - exec_native_cmd(mkswap_cmd, native_sysroot) - - self.source_file = fs - - return 0 - -class Wic_Partition(Mic_Partition): - removedKeywords = Mic_Partition.removedKeywords - removedAttrs = Mic_Partition.removedAttrs - - def _getParser(self): - op = Mic_Partition._getParser(self) - # use specified source file to fill the partition - # and calculate partition size - op.add_option("--source", type="string", action="store", - dest="source", default=None) - # use specified rootfs path to fill the partition - op.add_option("--rootfs-dir", type="string", action="store", - dest="rootfs", default=None) - return op diff --git a/scripts/lib/mic/kickstart/custom_commands/wicboot.py b/scripts/lib/mic/kickstart/custom_commands/wicboot.py deleted file mode 100644 index ab8871de4e..0000000000 --- a/scripts/lib/mic/kickstart/custom_commands/wicboot.py +++ /dev/null @@ -1,57 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This module provides the OpenEmbedded bootloader object definitions. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -from pykickstart.base import * -from pykickstart.errors import * -from pykickstart.options import * -from pykickstart.commands.bootloader import * - -from mic.kickstart.custom_commands.micboot import * - -class Wic_Bootloader(Mic_Bootloader): - def __init__(self, writePriority=10, appendLine="", driveorder=None, - forceLBA=False, location="", md5pass="", password="", - upgrade=False, menus=""): - Mic_Bootloader.__init__(self, writePriority, appendLine, driveorder, - forceLBA, location, md5pass, password, upgrade) - - self.source = "" - - def _getArgsAsStr(self): - retval = Mic_Bootloader._getArgsAsStr(self) - - if self.source: - retval += " --source=%s" % self.source - - return retval - - def _getParser(self): - op = Mic_Bootloader._getParser(self) - # use specified source plugin to implement bootloader-specific methods - op.add_option("--source", type="string", action="store", - dest="source", default=None) - return op - diff --git a/scripts/lib/mic/msger.py b/scripts/lib/mic/msger.py deleted file mode 100644 index 9afc85be93..0000000000 --- a/scripts/lib/mic/msger.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/python -tt -# vim: ai ts=4 sts=4 et sw=4 -# -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os,sys -import re -import time - -__ALL__ = ['set_mode', - 'get_loglevel', - 'set_loglevel', - 'set_logfile', - 'raw', - 'debug', - 'verbose', - 'info', - 'warning', - 'error', - 'ask', - 'pause', - ] - -# COLORs in ANSI -INFO_COLOR = 32 # green -WARN_COLOR = 33 # yellow -ERR_COLOR = 31 # red -ASK_COLOR = 34 # blue -NO_COLOR = 0 - -PREFIX_RE = re.compile('^<(.*?)>\s*(.*)', re.S) - -INTERACTIVE = True - -LOG_LEVEL = 1 -LOG_LEVELS = { - 'quiet': 0, - 'normal': 1, - 'verbose': 2, - 'debug': 3, - 'never': 4, - } - -LOG_FILE_FP = None -LOG_CONTENT = '' -CATCHERR_BUFFILE_FD = -1 -CATCHERR_BUFFILE_PATH = None -CATCHERR_SAVED_2 = -1 - -def _general_print(head, color, msg = None, stream = None, level = 'normal'): - global LOG_CONTENT - if not stream: - stream = sys.stdout - - if LOG_LEVELS[level] > LOG_LEVEL: - # skip - return - - # encode raw 'unicode' str to utf8 encoded str - if msg and isinstance(msg, unicode): - msg = msg.encode('utf-8', 'ignore') - - errormsg = '' - if CATCHERR_BUFFILE_FD > 0: - size = os.lseek(CATCHERR_BUFFILE_FD , 0, os.SEEK_END) - os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_SET) - errormsg = os.read(CATCHERR_BUFFILE_FD, size) - os.ftruncate(CATCHERR_BUFFILE_FD, 0) - - # append error msg to LOG - if errormsg: - LOG_CONTENT += errormsg - - # append normal msg to LOG - save_msg = msg.strip() if msg else None - if save_msg: - timestr = time.strftime("[%m/%d %H:%M:%S %Z] ", time.localtime()) - LOG_CONTENT += timestr + save_msg + '\n' - - if errormsg: - _color_print('', NO_COLOR, errormsg, stream, level) - - _color_print(head, color, msg, stream, level) - -def _color_print(head, color, msg, stream, level): - colored = True - if color == NO_COLOR or \ - not stream.isatty() or \ - os.getenv('ANSI_COLORS_DISABLED') is not None: - colored = False - - if head.startswith('\r'): - # need not \n at last - newline = False - else: - newline = True - - if colored: - head = '\033[%dm%s:\033[0m ' %(color, head) - if not newline: - # ESC cmd to clear line - head = '\033[2K' + head - else: - if head: - head += ': ' - if head.startswith('\r'): - head = head.lstrip() - newline = True - - if msg is not None: - if isinstance(msg, unicode): - msg = msg.encode('utf8', 'ignore') - - stream.write('%s%s' % (head, msg)) - if newline: - stream.write('\n') - - stream.flush() - -def _color_perror(head, color, msg, level = 'normal'): - if CATCHERR_BUFFILE_FD > 0: - _general_print(head, color, msg, sys.stdout, level) - else: - _general_print(head, color, msg, sys.stderr, level) - -def _split_msg(head, msg): - if isinstance(msg, list): - msg = '\n'.join(map(str, msg)) - - if msg.startswith('\n'): - # means print \n at first - msg = msg.lstrip() - head = '\n' + head - - elif msg.startswith('\r'): - # means print \r at first - msg = msg.lstrip() - head = '\r' + head - - m = PREFIX_RE.match(msg) - if m: - head += ' <%s>' % m.group(1) - msg = m.group(2) - - return head, msg - -def get_loglevel(): - return (k for k,v in LOG_LEVELS.items() if v==LOG_LEVEL).next() - -def set_loglevel(level): - global LOG_LEVEL - if level not in LOG_LEVELS: - # no effect - return - - LOG_LEVEL = LOG_LEVELS[level] - -def set_interactive(mode=True): - global INTERACTIVE - if mode: - INTERACTIVE = True - else: - INTERACTIVE = False - -def log(msg=''): - # log msg to LOG_CONTENT then save to logfile - global LOG_CONTENT - if msg: - LOG_CONTENT += msg - -def raw(msg=''): - _general_print('', NO_COLOR, msg) - -def info(msg): - head, msg = _split_msg('Info', msg) - _general_print(head, INFO_COLOR, msg) - -def verbose(msg): - head, msg = _split_msg('Verbose', msg) - _general_print(head, INFO_COLOR, msg, level = 'verbose') - -def warning(msg): - head, msg = _split_msg('Warning', msg) - _color_perror(head, WARN_COLOR, msg) - -def debug(msg): - head, msg = _split_msg('Debug', msg) - _color_perror(head, ERR_COLOR, msg, level = 'debug') - -def error(msg): - head, msg = _split_msg('Error', msg) - _color_perror(head, ERR_COLOR, msg) - sys.exit(1) - -def ask(msg, default=True): - _general_print('\rQ', ASK_COLOR, '') - try: - if default: - msg += '(Y/n) ' - else: - msg += '(y/N) ' - if INTERACTIVE: - while True: - repl = raw_input(msg) - if repl.lower() == 'y': - return True - elif repl.lower() == 'n': - return False - elif not repl.strip(): - # <Enter> - return default - - # else loop - else: - if default: - msg += ' Y' - else: - msg += ' N' - _general_print('', NO_COLOR, msg) - - return default - except KeyboardInterrupt: - sys.stdout.write('\n') - sys.exit(2) - -def choice(msg, choices, default=0): - if default >= len(choices): - return None - _general_print('\rQ', ASK_COLOR, '') - try: - msg += " [%s] " % '/'.join(choices) - if INTERACTIVE: - while True: - repl = raw_input(msg) - if repl in choices: - return repl - elif not repl.strip(): - return choices[default] - else: - msg += choices[default] - _general_print('', NO_COLOR, msg) - - return choices[default] - except KeyboardInterrupt: - sys.stdout.write('\n') - sys.exit(2) - -def pause(msg=None): - if INTERACTIVE: - _general_print('\rQ', ASK_COLOR, '') - if msg is None: - msg = 'press <ENTER> to continue ...' - raw_input(msg) - -def set_logfile(fpath): - global LOG_FILE_FP - - def _savelogf(): - if LOG_FILE_FP: - fp = open(LOG_FILE_FP, 'w') - fp.write(LOG_CONTENT) - fp.close() - - if LOG_FILE_FP is not None: - warning('duplicate log file configuration') - - LOG_FILE_FP = fpath - - import atexit - atexit.register(_savelogf) - -def enable_logstderr(fpath): - global CATCHERR_BUFFILE_FD - global CATCHERR_BUFFILE_PATH - global CATCHERR_SAVED_2 - - if os.path.exists(fpath): - os.remove(fpath) - CATCHERR_BUFFILE_PATH = fpath - CATCHERR_BUFFILE_FD = os.open(CATCHERR_BUFFILE_PATH, os.O_RDWR|os.O_CREAT) - CATCHERR_SAVED_2 = os.dup(2) - os.dup2(CATCHERR_BUFFILE_FD, 2) - -def disable_logstderr(): - global CATCHERR_BUFFILE_FD - global CATCHERR_BUFFILE_PATH - global CATCHERR_SAVED_2 - - raw(msg = None) # flush message buffer and print it. - os.dup2(CATCHERR_SAVED_2, 2) - os.close(CATCHERR_SAVED_2) - os.close(CATCHERR_BUFFILE_FD) - os.unlink(CATCHERR_BUFFILE_PATH) - CATCHERR_BUFFILE_FD = -1 - CATCHERR_BUFFILE_PATH = None - CATCHERR_SAVED_2 = -1 diff --git a/scripts/lib/mic/plugin.py b/scripts/lib/mic/plugin.py deleted file mode 100644 index 43afdbc2f2..0000000000 --- a/scripts/lib/mic/plugin.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os, sys - -from mic import msger -from mic import pluginbase -from mic.utils import errors -from mic.utils.oe.misc import * - -__ALL__ = ['PluginMgr', 'pluginmgr'] - -PLUGIN_TYPES = ["imager", "source"] - -PLUGIN_DIR = "/lib/mic/plugins" # relative to scripts -SCRIPTS_PLUGIN_DIR = "scripts" + PLUGIN_DIR - -class PluginMgr(object): - plugin_dirs = {} - - # make the manager class as singleton - _instance = None - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super(PluginMgr, cls).__new__(cls, *args, **kwargs) - - return cls._instance - - def __init__(self): - mic_path = os.path.dirname(__file__) - eos = mic_path.find('scripts') + len('scripts') - scripts_path = mic_path[:eos] - self.scripts_path = scripts_path - self.plugin_dir = scripts_path + PLUGIN_DIR - self.layers_path = None - - def _build_plugin_dir_list(self, dl, ptype): - if self.layers_path is None: - self.layers_path = get_bitbake_var("BBLAYERS") - layer_dirs = [] - - if self.layers_path is not None: - for layer_path in self.layers_path.split(): - path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype) - layer_dirs.append(path) - - path = os.path.join(dl, ptype) - layer_dirs.append(path) - - return layer_dirs - - def append_dirs(self, dirs): - for path in dirs: - self._add_plugindir(path) - - # load all the plugins AGAIN - self._load_all() - - def _add_plugindir(self, path): - path = os.path.abspath(os.path.expanduser(path)) - - if not os.path.isdir(path): - msger.debug("Plugin dir is not a directory or does not exist: %s"\ - % path) - return - - if path not in self.plugin_dirs: - self.plugin_dirs[path] = False - # the value True/False means "loaded" - - def _load_all(self): - for (pdir, loaded) in self.plugin_dirs.iteritems(): - if loaded: continue - - sys.path.insert(0, pdir) - for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]: - if mod and mod != '__init__': - if mod in sys.modules: - #self.plugin_dirs[pdir] = True - msger.warning("Module %s already exists, skip" % mod) - else: - try: - pymod = __import__(mod) - self.plugin_dirs[pdir] = True - msger.debug("Plugin module %s:%s imported"\ - % (mod, pymod.__file__)) - except ImportError, err: - msg = 'Failed to load plugin %s/%s: %s' \ - % (os.path.basename(pdir), mod, err) - msger.warning(msg) - - del(sys.path[0]) - - def get_plugins(self, ptype): - """ the return value is dict of name:class pairs """ - - if ptype not in PLUGIN_TYPES: - raise errors.CreatorError('%s is not valid plugin type' % ptype) - - plugins_dir = self._build_plugin_dir_list(self.plugin_dir, ptype) - - self.append_dirs(plugins_dir) - - return pluginbase.get_plugins(ptype) - - def get_source_plugins(self): - """ - Return list of available source plugins. - """ - plugins_dir = self._build_plugin_dir_list(self.plugin_dir, 'source') - - self.append_dirs(plugins_dir) - - plugins = [] - - for _source_name, klass in self.get_plugins('source').iteritems(): - plugins.append(_source_name) - - return plugins - - - def get_source_plugin_methods(self, source_name, methods): - """ - The methods param is a dict with the method names to find. On - return, the dict values will be filled in with pointers to the - corresponding methods. If one or more methods are not found, - None is returned. - """ - return_methods = None - for _source_name, klass in self.get_plugins('source').iteritems(): - if _source_name == source_name: - for _method_name in methods.keys(): - if not hasattr(klass, _method_name): - msger.warning("Unimplemented %s source interface for: %s"\ - % (_method_name, _source_name)) - return None - func = getattr(klass, _method_name) - methods[_method_name] = func - return_methods = methods - return return_methods - -pluginmgr = PluginMgr() diff --git a/scripts/lib/mic/pluginbase.py b/scripts/lib/mic/pluginbase.py deleted file mode 100644 index 46a4f4a6b6..0000000000 --- a/scripts/lib/mic/pluginbase.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os -import shutil -from mic import msger -from mic.utils import errors - -class _Plugin(object): - class __metaclass__(type): - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'plugins'): - cls.plugins = {} - - elif 'mic_plugin_type' in attrs: - if attrs['mic_plugin_type'] not in cls.plugins: - cls.plugins[attrs['mic_plugin_type']] = {} - - elif hasattr(cls, 'mic_plugin_type') and 'name' in attrs: - cls.plugins[cls.mic_plugin_type][attrs['name']] = cls - - def show_plugins(cls): - for cls in cls.plugins[cls.mic_plugin_type]: - print cls - - def get_plugins(cls): - return cls.plugins - - -class ImagerPlugin(_Plugin): - mic_plugin_type = "imager" - - -class SourcePlugin(_Plugin): - mic_plugin_type = "source" - """ - The methods that can be implemented by --source plugins. - - Any methods not implemented in a subclass inherit these. - """ - - @classmethod - def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called after all partitions have been prepared and assembled into a - disk image. This provides a hook to allow finalization of a - disk image e.g. to write an MBR to it. - """ - msger.debug("SourcePlugin: do_install_disk: disk: %s" % disk_name) - - @classmethod - def do_stage_partition(self, part, cr, workdir, oe_builddir, bootimg_dir, - kernel_dir, native_sysroot): - """ - Special content staging hook called before do_prepare_partition(), - normally empty. - - Typically, a partition will just use the passed-in parame e.g - straight bootimg_dir, etc, but in some cases, things need to - be more tailored e.g. to use a deploy dir + /boot, etc. This - hook allows those files to be staged in a customized fashion. - Not that get_bitbake_var() allows you to acces non-standard - variables that you might want to use for this. - """ - msger.debug("SourcePlugin: do_stage_partition: part: %s" % part) - - @classmethod - def do_configure_partition(self, part, cr, cr_workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called before do_prepare_partition(), typically used to create - custom configuration files for a partition, for example - syslinux or grub config files. - """ - msger.debug("SourcePlugin: do_configure_partition: part: %s" % part) - - @classmethod - def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, rootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - """ - msger.debug("SourcePlugin: do_prepare_partition: part: %s" % part) - -def get_plugins(typen): - ps = ImagerPlugin.get_plugins() - if typen in ps: - return ps[typen] - else: - return None - -__all__ = ['ImagerPlugin', 'SourcePlugin', 'get_plugins'] diff --git a/scripts/lib/mic/plugins/imager/direct_plugin.py b/scripts/lib/mic/plugins/imager/direct_plugin.py deleted file mode 100644 index c05a400768..0000000000 --- a/scripts/lib/mic/plugins/imager/direct_plugin.py +++ /dev/null @@ -1,103 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2013, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This implements the 'direct' imager plugin class for 'wic', based -# loosely on the raw imager plugin from 'mic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import os -import shutil -import re -import tempfile - -from mic import msger -from mic.utils import misc, fs_related, errors, runner, cmdln -from mic.conf import configmgr -from mic.plugin import pluginmgr - -import mic.imager.direct as direct -from mic.pluginbase import ImagerPlugin - -class DirectPlugin(ImagerPlugin): - name = 'direct' - - @classmethod - def __rootfs_dir_to_dict(self, rootfs_dirs): - """ - Gets a string that contain 'connection=dir' splitted by - space and return a dict - """ - krootfs_dir = {} - for rootfs_dir in rootfs_dirs.split(' '): - k, v = rootfs_dir.split('=') - krootfs_dir[k] = v - - return krootfs_dir - - @classmethod - def do_create(self, subcmd, opts, *args): - """ - Create direct image, called from creator as 'direct' cmd - """ - if len(args) != 9: - raise errors.Usage("Extra arguments given") - - staging_data_dir = args[0] - hdddir = args[1] - native_sysroot = args[2] - kernel_dir = args[3] - bootimg_dir = args[4] - rootfs_dir = args[5] - - creatoropts = configmgr.create - ksconf = args[6] - - image_output_dir = args[7] - oe_builddir = args[8] - - krootfs_dir = self.__rootfs_dir_to_dict(rootfs_dir) - - configmgr._ksconf = ksconf - - creator = direct.DirectImageCreator(oe_builddir, - image_output_dir, - krootfs_dir, - bootimg_dir, - kernel_dir, - native_sysroot, - hdddir, - staging_data_dir, - creatoropts) - - try: - creator.create() - creator.assemble() - creator.finalize() - creator.print_outimage_info() - - except errors.CreatorError: - raise - finally: - creator.cleanup() - - return 0 diff --git a/scripts/lib/mic/plugins/source/bootimg-efi.py b/scripts/lib/mic/plugins/source/bootimg-efi.py deleted file mode 100644 index 5b1a5332c4..0000000000 --- a/scripts/lib/mic/plugins/source/bootimg-efi.py +++ /dev/null @@ -1,166 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This implements the 'bootimg-efi' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import os -import shutil -import re -import tempfile - -from mic import kickstart, msger -from mic.utils import misc, fs_related, errors, runner, cmdln -from mic.conf import configmgr -from mic.plugin import pluginmgr -import mic.imager.direct as direct -from mic.pluginbase import SourcePlugin -from mic.utils.oe.misc import * -from mic.imager.direct import DirectImageCreator - -class BootimgEFIPlugin(SourcePlugin): - name = 'bootimg-efi' - - @classmethod - def do_configure_partition(self, part, cr, cr_workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called before do_prepare_partition(), creates grubefi config - """ - hdddir = "%s/hdd/boot" % cr_workdir - rm_cmd = "rm -rf %s" % cr_workdir - exec_cmd(rm_cmd) - - install_cmd = "install -d %s/EFI/BOOT" % hdddir - exec_cmd(install_cmd) - - splash = os.path.join(cr_workdir, "/EFI/boot/splash.jpg") - if os.path.exists(splash): - splashline = "menu background splash.jpg" - else: - splashline = "" - - (rootdev, root_part_uuid) = cr._get_boot_config() - options = cr.ks.handler.bootloader.appendLine - - grubefi_conf = "" - grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" - grubefi_conf += "default=boot\n" - timeout = kickstart.get_timeout(cr.ks) - if not timeout: - timeout = 0 - grubefi_conf += "timeout=%s\n" % timeout - grubefi_conf += "menuentry 'boot'{\n" - - kernel = "/vmlinuz" - - if cr._ptable_format == 'msdos': - rootstr = rootdev - else: - raise ImageError("Unsupported partition table format found") - - grubefi_conf += "linux %s root=%s rootwait %s\n" \ - % (kernel, rootstr, options) - grubefi_conf += "}\n" - if splashline: - syslinux_conf += "%s\n" % splashline - - msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \ - % cr_workdir) - cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") - cfg.write(grubefi_conf) - cfg.close() - - @classmethod - def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, rootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for an EFI (grub) boot partition. - """ - if not bootimg_dir: - bootimg_dir = get_bitbake_var("HDDDIR") - if not bootimg_dir: - msger.error("Couldn't find HDDDIR, exiting\n") - # just so the result notes display it - cr.set_bootimg_dir(bootimg_dir) - - staging_kernel_dir = kernel_dir - staging_data_dir = bootimg_dir - - hdddir = "%s/hdd/boot" % cr_workdir - - install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ - (staging_kernel_dir, hdddir) - exec_cmd(install_cmd) - - shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, - "%s/grub.cfg" % cr_workdir) - - cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (staging_data_dir, hdddir) - exec_cmd(cp_cmd, True) - - shutil.move("%s/grub.cfg" % cr_workdir, - "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir) - - du_cmd = "du -bks %s" % hdddir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - extra_blocks = part.get_extra_block_count(blocks) - - if extra_blocks < BOOTDD_EXTRA_SPACE: - extra_blocks = BOOTDD_EXTRA_SPACE - - blocks += extra_blocks - - msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ - (extra_blocks, part.mountpoint, blocks)) - - # Ensure total sectors is an integral number of sectors per - # track or mcopy will complain. Sectors are 512 bytes, and we - # generate images with 32 sectors per track. This calculation is - # done in blocks, thus the mod by 16 instead of 32. - blocks += (16 - (blocks % 16)) - - # dosfs image, created by mkdosfs - bootimg = "%s/boot.img" % cr_workdir - - dosfs_cmd = "mkdosfs -n efi -C %s %d" % (bootimg, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % bootimg - exec_cmd(chmod_cmd) - - du_cmd = "du -Lbms %s" % bootimg - out = exec_cmd(du_cmd) - bootimg_size = out.split()[0] - - part.set_size(bootimg_size) - part.set_source_file(bootimg) - - diff --git a/scripts/lib/mic/plugins/source/bootimg-pcbios.py b/scripts/lib/mic/plugins/source/bootimg-pcbios.py deleted file mode 100644 index 959cf411bf..0000000000 --- a/scripts/lib/mic/plugins/source/bootimg-pcbios.py +++ /dev/null @@ -1,190 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This implements the 'bootimg-pcbios' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import os -import shutil -import re -import tempfile - -from mic import kickstart, msger -from mic.utils import misc, fs_related, errors, runner, cmdln -from mic.conf import configmgr -from mic.plugin import pluginmgr -import mic.imager.direct as direct -from mic.pluginbase import SourcePlugin -from mic.utils.oe.misc import * -from mic.imager.direct import DirectImageCreator - -class BootimgPcbiosPlugin(SourcePlugin): - name = 'bootimg-pcbios' - - @classmethod - def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called after all partitions have been prepared and assembled into a - disk image. In this case, we install the MBR. - """ - mbrfile = "%s/syslinux/" % bootimg_dir - if cr._ptable_format == 'msdos': - mbrfile += "mbr.bin" - - if not os.path.exists(mbrfile): - msger.error("Couldn't find %s. If using the -e option, do you have the right MACHINE set in local.conf? If not, is the bootimg_dir path correct?" % mbrfile) - - full_path = cr._full_path(workdir, disk_name, "direct") - msger.debug("Installing MBR on disk %s as %s with size %s bytes" \ - % (disk_name, full_path, disk['min_size'])) - - rc = runner.show(['dd', 'if=%s' % mbrfile, - 'of=%s' % full_path, 'conv=notrunc']) - if rc != 0: - raise ImageError("Unable to set MBR to %s" % full_path) - - @classmethod - def do_configure_partition(self, part, cr, cr_workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called before do_prepare_partition(), creates syslinux config - """ - hdddir = "%s/hdd/boot" % cr_workdir - rm_cmd = "rm -rf " + cr_workdir - exec_cmd(rm_cmd) - - install_cmd = "install -d %s" % hdddir - exec_cmd(install_cmd) - - splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") - if os.path.exists(splash): - splashline = "menu background splash.jpg" - else: - splashline = "" - - (rootdev, root_part_uuid) = cr._get_boot_config() - options = cr.ks.handler.bootloader.appendLine - - syslinux_conf = "" - syslinux_conf += "PROMPT 0\n" - timeout = kickstart.get_timeout(cr.ks) - if not timeout: - timeout = 0 - syslinux_conf += "TIMEOUT " + str(timeout) + "\n" - syslinux_conf += "\n" - syslinux_conf += "ALLOWOPTIONS 1\n" - syslinux_conf += "SERIAL 0 115200\n" - syslinux_conf += "\n" - if splashline: - syslinux_conf += "%s\n" % splashline - syslinux_conf += "DEFAULT boot\n" - syslinux_conf += "LABEL boot\n" - - kernel = "/vmlinuz" - syslinux_conf += "KERNEL " + kernel + "\n" - - if cr._ptable_format == 'msdos': - rootstr = rootdev - else: - raise ImageError("Unsupported partition table format found") - - syslinux_conf += "APPEND label=boot root=%s %s\n" % (rootstr, options) - - msger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg" \ - % cr_workdir) - cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") - cfg.write(syslinux_conf) - cfg.close() - - @classmethod - def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, rootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for legacy bios boot partition. - """ - if not bootimg_dir: - bootimg_dir = get_bitbake_var("STAGING_DATADIR") - if not bootimg_dir: - msger.error("Couldn't find STAGING_DATADIR, exiting\n") - # just so the result notes display it - cr.set_bootimg_dir(bootimg_dir) - - staging_kernel_dir = kernel_dir - staging_data_dir = bootimg_dir - - hdddir = "%s/hdd/boot" % cr_workdir - - install_cmd = "install -m 0644 %s/bzImage %s/vmlinuz" \ - % (staging_kernel_dir, hdddir) - exec_cmd(install_cmd) - - install_cmd = "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" \ - % (staging_data_dir, hdddir) - exec_cmd(install_cmd) - - du_cmd = "du -bks %s" % hdddir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - extra_blocks = part.get_extra_block_count(blocks) - - if extra_blocks < BOOTDD_EXTRA_SPACE: - extra_blocks = BOOTDD_EXTRA_SPACE - - blocks += extra_blocks - - msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ - (extra_blocks, part.mountpoint, blocks)) - - # Ensure total sectors is an integral number of sectors per - # track or mcopy will complain. Sectors are 512 bytes, and we - # generate images with 32 sectors per track. This calculation is - # done in blocks, thus the mod by 16 instead of 32. - blocks += (16 - (blocks % 16)) - - # dosfs image, created by mkdosfs - bootimg = "%s/boot.img" % cr_workdir - - dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (bootimg, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - syslinux_cmd = "syslinux %s" % bootimg - exec_native_cmd(syslinux_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % bootimg - exec_cmd(chmod_cmd) - - du_cmd = "du -Lbms %s" % bootimg - out = exec_cmd(du_cmd) - bootimg_size = out.split()[0] - - part.set_size(bootimg_size) - part.set_source_file(bootimg) - - diff --git a/scripts/lib/mic/plugins/source/rootfs.py b/scripts/lib/mic/plugins/source/rootfs.py deleted file mode 100644 index 8ebf62c10b..0000000000 --- a/scripts/lib/mic/plugins/source/rootfs.py +++ /dev/null @@ -1,91 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This implements the 'rootfs' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com> -# - -import os -import shutil -import re -import tempfile - -from mic import kickstart, msger -from mic.utils import misc, fs_related, errors, runner, cmdln -from mic.conf import configmgr -from mic.plugin import pluginmgr -import mic.imager.direct as direct -from mic.pluginbase import SourcePlugin -from mic.utils.oe.misc import * -from mic.imager.direct import DirectImageCreator - -class RootfsPlugin(SourcePlugin): - name = 'rootfs' - - @staticmethod - def __get_rootfs_dir(rootfs_dir): - if os.path.isdir(rootfs_dir): - return rootfs_dir - - bitbake_env_lines = find_bitbake_env_lines(rootfs_dir) - if not bitbake_env_lines: - msg = "Couldn't get bitbake environment, exiting." - msger.error(msg) - - image_rootfs_dir = find_artifact(bitbake_env_lines, "IMAGE_ROOTFS") - if not os.path.isdir(image_rootfs_dir): - msg = "No valid artifact IMAGE_ROOTFS from image named" - msg += " %s has been found at %s, exiting.\n" % \ - (rootfs_dir, image_rootfs_dir) - msger.error(msg) - - return image_rootfs_dir - - @classmethod - def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, krootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for legacy bios boot partition. - """ - if part.rootfs is None: - if not 'ROOTFS_DIR' in krootfs_dir: - msg = "Couldn't find --rootfs-dir, exiting" - msger.error(msg) - rootfs_dir = krootfs_dir['ROOTFS_DIR'] - else: - if part.rootfs in krootfs_dir: - rootfs_dir = krootfs_dir[part.rootfs] - elif part.rootfs: - rootfs_dir = part.rootfs - else: - msg = "Couldn't find --rootfs-dir=%s connection" - msg += " or it is not a valid path, exiting" - msger.error(msg % part.rootfs) - - real_rootfs_dir = self.__get_rootfs_dir(rootfs_dir) - - part.set_rootfs(real_rootfs_dir) - part.prepare_rootfs(cr_workdir, oe_builddir, real_rootfs_dir, native_sysroot) - diff --git a/scripts/lib/mic/test b/scripts/lib/mic/test deleted file mode 100644 index 9daeafb986..0000000000 --- a/scripts/lib/mic/test +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/scripts/lib/mic/utils/__init__.py b/scripts/lib/mic/utils/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/scripts/lib/mic/utils/__init__.py +++ /dev/null diff --git a/scripts/lib/mic/utils/cmdln.py b/scripts/lib/mic/utils/cmdln.py deleted file mode 100644 index b099473ee4..0000000000 --- a/scripts/lib/mic/utils/cmdln.py +++ /dev/null @@ -1,1586 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2002-2007 ActiveState Software Inc. -# License: MIT (see LICENSE.txt for license details) -# Author: Trent Mick -# Home: http://trentm.com/projects/cmdln/ - -"""An improvement on Python's standard cmd.py module. - -As with cmd.py, this module provides "a simple framework for writing -line-oriented command intepreters." This module provides a 'RawCmdln' -class that fixes some design flaws in cmd.Cmd, making it more scalable -and nicer to use for good 'cvs'- or 'svn'-style command line interfaces -or simple shells. And it provides a 'Cmdln' class that add -optparse-based option processing. Basically you use it like this: - - import cmdln - - class MySVN(cmdln.Cmdln): - name = "svn" - - @cmdln.alias('stat', 'st') - @cmdln.option('-v', '--verbose', action='store_true' - help='print verbose information') - def do_status(self, subcmd, opts, *paths): - print "handle 'svn status' command" - - #... - - if __name__ == "__main__": - shell = MySVN() - retval = shell.main() - sys.exit(retval) - -See the README.txt or <http://trentm.com/projects/cmdln/> for more -details. -""" - -__version_info__ = (1, 1, 2) -__version__ = '.'.join(map(str, __version_info__)) - -import os -import sys -import re -import cmd -import optparse -from pprint import pprint -import sys - - - - -#---- globals - -LOOP_ALWAYS, LOOP_NEVER, LOOP_IF_EMPTY = range(3) - -# An unspecified optional argument when None is a meaningful value. -_NOT_SPECIFIED = ("Not", "Specified") - -# Pattern to match a TypeError message from a call that -# failed because of incorrect number of arguments (see -# Python/getargs.c). -_INCORRECT_NUM_ARGS_RE = re.compile( - r"(takes [\w ]+ )(\d+)( arguments? \()(\d+)( given\))") - - - -#---- exceptions - -class CmdlnError(Exception): - """A cmdln.py usage error.""" - def __init__(self, msg): - self.msg = msg - def __str__(self): - return self.msg - -class CmdlnUserError(Exception): - """An error by a user of a cmdln-based tool/shell.""" - pass - - - -#---- public methods and classes - -def alias(*aliases): - """Decorator to add aliases for Cmdln.do_* command handlers. - - Example: - class MyShell(cmdln.Cmdln): - @cmdln.alias("!", "sh") - def do_shell(self, argv): - #...implement 'shell' command - """ - def decorate(f): - if not hasattr(f, "aliases"): - f.aliases = [] - f.aliases += aliases - return f - return decorate - - -class RawCmdln(cmd.Cmd): - """An improved (on cmd.Cmd) framework for building multi-subcommand - scripts (think "svn" & "cvs") and simple shells (think "pdb" and - "gdb"). - - A simple example: - - import cmdln - - class MySVN(cmdln.RawCmdln): - name = "svn" - - @cmdln.aliases('stat', 'st') - def do_status(self, argv): - print "handle 'svn status' command" - - if __name__ == "__main__": - shell = MySVN() - retval = shell.main() - sys.exit(retval) - - See <http://trentm.com/projects/cmdln> for more information. - """ - name = None # if unset, defaults basename(sys.argv[0]) - prompt = None # if unset, defaults to self.name+"> " - version = None # if set, default top-level options include --version - - # Default messages for some 'help' command error cases. - # They are interpolated with one arg: the command. - nohelp = "no help on '%s'" - unknowncmd = "unknown command: '%s'" - - helpindent = '' # string with which to indent help output - - def __init__(self, completekey='tab', - stdin=None, stdout=None, stderr=None): - """Cmdln(completekey='tab', stdin=None, stdout=None, stderr=None) - - The optional argument 'completekey' is the readline name of a - completion key; it defaults to the Tab key. If completekey is - not None and the readline module is available, command completion - is done automatically. - - The optional arguments 'stdin', 'stdout' and 'stderr' specify - alternate input, output and error output file objects; if not - specified, sys.* are used. - - If 'stdout' but not 'stderr' is specified, stdout is used for - error output. This is to provide least surprise for users used - to only the 'stdin' and 'stdout' options with cmd.Cmd. - """ - import sys - if self.name is None: - self.name = os.path.basename(sys.argv[0]) - if self.prompt is None: - self.prompt = self.name+"> " - self._name_str = self._str(self.name) - self._prompt_str = self._str(self.prompt) - if stdin is not None: - self.stdin = stdin - else: - self.stdin = sys.stdin - if stdout is not None: - self.stdout = stdout - else: - self.stdout = sys.stdout - if stderr is not None: - self.stderr = stderr - elif stdout is not None: - self.stderr = stdout - else: - self.stderr = sys.stderr - self.cmdqueue = [] - self.completekey = completekey - self.cmdlooping = False - - def get_optparser(self): - """Hook for subclasses to set the option parser for the - top-level command/shell. - - This option parser is used retrieved and used by `.main()' to - handle top-level options. - - The default implements a single '-h|--help' option. Sub-classes - can return None to have no options at the top-level. Typically - an instance of CmdlnOptionParser should be returned. - """ - version = (self.version is not None - and "%s %s" % (self._name_str, self.version) - or None) - return CmdlnOptionParser(self, version=version) - - def postoptparse(self): - """Hook method executed just after `.main()' parses top-level - options. - - When called `self.options' holds the results of the option parse. - """ - pass - - def main(self, argv=None, loop=LOOP_NEVER): - """A possible mainline handler for a script, like so: - - import cmdln - class MyCmd(cmdln.Cmdln): - name = "mycmd" - ... - - if __name__ == "__main__": - MyCmd().main() - - By default this will use sys.argv to issue a single command to - 'MyCmd', then exit. The 'loop' argument can be use to control - interactive shell behaviour. - - Arguments: - "argv" (optional, default sys.argv) is the command to run. - It must be a sequence, where the first element is the - command name and subsequent elements the args for that - command. - "loop" (optional, default LOOP_NEVER) is a constant - indicating if a command loop should be started (i.e. an - interactive shell). Valid values (constants on this module): - LOOP_ALWAYS start loop and run "argv", if any - LOOP_NEVER run "argv" (or .emptyline()) and exit - LOOP_IF_EMPTY run "argv", if given, and exit; - otherwise, start loop - """ - if argv is None: - import sys - argv = sys.argv - else: - argv = argv[:] # don't modify caller's list - - self.optparser = self.get_optparser() - if self.optparser: # i.e. optparser=None means don't process for opts - try: - self.options, args = self.optparser.parse_args(argv[1:]) - except CmdlnUserError, ex: - msg = "%s: %s\nTry '%s help' for info.\n"\ - % (self.name, ex, self.name) - self.stderr.write(self._str(msg)) - self.stderr.flush() - return 1 - except StopOptionProcessing, ex: - return 0 - else: - self.options, args = None, argv[1:] - self.postoptparse() - - if loop == LOOP_ALWAYS: - if args: - self.cmdqueue.append(args) - return self.cmdloop() - elif loop == LOOP_NEVER: - if args: - return self.cmd(args) - else: - return self.emptyline() - elif loop == LOOP_IF_EMPTY: - if args: - return self.cmd(args) - else: - return self.cmdloop() - - def cmd(self, argv): - """Run one command and exit. - - "argv" is the arglist for the command to run. argv[0] is the - command to run. If argv is an empty list then the - 'emptyline' handler is run. - - Returns the return value from the command handler. - """ - assert isinstance(argv, (list, tuple)), \ - "'argv' is not a sequence: %r" % argv - retval = None - try: - argv = self.precmd(argv) - retval = self.onecmd(argv) - self.postcmd(argv) - except: - if not self.cmdexc(argv): - raise - retval = 1 - return retval - - def _str(self, s): - """Safely convert the given str/unicode to a string for printing.""" - try: - return str(s) - except UnicodeError: - #XXX What is the proper encoding to use here? 'utf-8' seems - # to work better than "getdefaultencoding" (usually - # 'ascii'), on OS X at least. - #import sys - #return s.encode(sys.getdefaultencoding(), "replace") - return s.encode("utf-8", "replace") - - def cmdloop(self, intro=None): - """Repeatedly issue a prompt, accept input, parse into an argv, and - dispatch (via .precmd(), .onecmd() and .postcmd()), passing them - the argv. In other words, start a shell. - - "intro" (optional) is a introductory message to print when - starting the command loop. This overrides the class - "intro" attribute, if any. - """ - self.cmdlooping = True - self.preloop() - if self.use_rawinput and self.completekey: - try: - import readline - self.old_completer = readline.get_completer() - readline.set_completer(self.complete) - readline.parse_and_bind(self.completekey+": complete") - except ImportError: - pass - try: - if intro is None: - intro = self.intro - if intro: - intro_str = self._str(intro) - self.stdout.write(intro_str+'\n') - self.stop = False - retval = None - while not self.stop: - if self.cmdqueue: - argv = self.cmdqueue.pop(0) - assert isinstance(argv, (list, tuple)), \ - "item on 'cmdqueue' is not a sequence: %r" % argv - else: - if self.use_rawinput: - try: - line = raw_input(self._prompt_str) - except EOFError: - line = 'EOF' - else: - self.stdout.write(self._prompt_str) - self.stdout.flush() - line = self.stdin.readline() - if not len(line): - line = 'EOF' - else: - line = line[:-1] # chop '\n' - argv = line2argv(line) - try: - argv = self.precmd(argv) - retval = self.onecmd(argv) - self.postcmd(argv) - except: - if not self.cmdexc(argv): - raise - retval = 1 - self.lastretval = retval - self.postloop() - finally: - if self.use_rawinput and self.completekey: - try: - import readline - readline.set_completer(self.old_completer) - except ImportError: - pass - self.cmdlooping = False - return retval - - def precmd(self, argv): - """Hook method executed just before the command argv is - interpreted, but after the input prompt is generated and issued. - - "argv" is the cmd to run. - - Returns an argv to run (i.e. this method can modify the command - to run). - """ - return argv - - def postcmd(self, argv): - """Hook method executed just after a command dispatch is finished. - - "argv" is the command that was run. - """ - pass - - def cmdexc(self, argv): - """Called if an exception is raised in any of precmd(), onecmd(), - or postcmd(). If True is returned, the exception is deemed to have - been dealt with. Otherwise, the exception is re-raised. - - The default implementation handles CmdlnUserError's, which - typically correspond to user error in calling commands (as - opposed to programmer error in the design of the script using - cmdln.py). - """ - import sys - type, exc, traceback = sys.exc_info() - if isinstance(exc, CmdlnUserError): - msg = "%s %s: %s\nTry '%s help %s' for info.\n"\ - % (self.name, argv[0], exc, self.name, argv[0]) - self.stderr.write(self._str(msg)) - self.stderr.flush() - return True - - def onecmd(self, argv): - if not argv: - return self.emptyline() - self.lastcmd = argv - cmdname = self._get_canonical_cmd_name(argv[0]) - if cmdname: - handler = self._get_cmd_handler(cmdname) - if handler: - return self._dispatch_cmd(handler, argv) - return self.default(argv) - - def _dispatch_cmd(self, handler, argv): - return handler(argv) - - def default(self, argv): - """Hook called to handle a command for which there is no handler. - - "argv" is the command and arguments to run. - - The default implementation writes and error message to stderr - and returns an error exit status. - - Returns a numeric command exit status. - """ - errmsg = self._str(self.unknowncmd % (argv[0],)) - if self.cmdlooping: - self.stderr.write(errmsg+"\n") - else: - self.stderr.write("%s: %s\nTry '%s help' for info.\n" - % (self._name_str, errmsg, self._name_str)) - self.stderr.flush() - return 1 - - def parseline(self, line): - # This is used by Cmd.complete (readline completer function) to - # massage the current line buffer before completion processing. - # We override to drop special '!' handling. - line = line.strip() - if not line: - return None, None, line - elif line[0] == '?': - line = 'help ' + line[1:] - i, n = 0, len(line) - while i < n and line[i] in self.identchars: i = i+1 - cmd, arg = line[:i], line[i:].strip() - return cmd, arg, line - - def helpdefault(self, cmd, known): - """Hook called to handle help on a command for which there is no - help handler. - - "cmd" is the command name on which help was requested. - "known" is a boolean indicating if this command is known - (i.e. if there is a handler for it). - - Returns a return code. - """ - if known: - msg = self._str(self.nohelp % (cmd,)) - if self.cmdlooping: - self.stderr.write(msg + '\n') - else: - self.stderr.write("%s: %s\n" % (self.name, msg)) - else: - msg = self.unknowncmd % (cmd,) - if self.cmdlooping: - self.stderr.write(msg + '\n') - else: - self.stderr.write("%s: %s\n" - "Try '%s help' for info.\n" - % (self.name, msg, self.name)) - self.stderr.flush() - return 1 - - def do_help(self, argv): - """${cmd_name}: give detailed help on a specific sub-command - - Usage: - ${name} help [COMMAND] - """ - if len(argv) > 1: # asking for help on a particular command - doc = None - cmdname = self._get_canonical_cmd_name(argv[1]) or argv[1] - if not cmdname: - return self.helpdefault(argv[1], False) - else: - helpfunc = getattr(self, "help_"+cmdname, None) - if helpfunc: - doc = helpfunc() - else: - handler = self._get_cmd_handler(cmdname) - if handler: - doc = handler.__doc__ - if doc is None: - return self.helpdefault(argv[1], handler != None) - else: # bare "help" command - doc = self.__class__.__doc__ # try class docstring - if doc is None: - # Try to provide some reasonable useful default help. - if self.cmdlooping: prefix = "" - else: prefix = self.name+' ' - doc = """Usage: - %sCOMMAND [ARGS...] - %shelp [COMMAND] - - ${option_list} - ${command_list} - ${help_list} - """ % (prefix, prefix) - cmdname = None - - if doc: # *do* have help content, massage and print that - doc = self._help_reindent(doc) - doc = self._help_preprocess(doc, cmdname) - doc = doc.rstrip() + '\n' # trim down trailing space - self.stdout.write(self._str(doc)) - self.stdout.flush() - do_help.aliases = ["?"] - - def _help_reindent(self, help, indent=None): - """Hook to re-indent help strings before writing to stdout. - - "help" is the help content to re-indent - "indent" is a string with which to indent each line of the - help content after normalizing. If unspecified or None - then the default is use: the 'self.helpindent' class - attribute. By default this is the empty string, i.e. - no indentation. - - By default, all common leading whitespace is removed and then - the lot is indented by 'self.helpindent'. When calculating the - common leading whitespace the first line is ignored -- hence - help content for Conan can be written as follows and have the - expected indentation: - - def do_crush(self, ...): - '''${cmd_name}: crush your enemies, see them driven before you... - - c.f. Conan the Barbarian''' - """ - if indent is None: - indent = self.helpindent - lines = help.splitlines(0) - _dedentlines(lines, skip_first_line=True) - lines = [(indent+line).rstrip() for line in lines] - return '\n'.join(lines) - - def _help_preprocess(self, help, cmdname): - """Hook to preprocess a help string before writing to stdout. - - "help" is the help string to process. - "cmdname" is the canonical sub-command name for which help - is being given, or None if the help is not specific to a - command. - - By default the following template variables are interpolated in - help content. (Note: these are similar to Python 2.4's - string.Template interpolation but not quite.) - - ${name} - The tool's/shell's name, i.e. 'self.name'. - ${option_list} - A formatted table of options for this shell/tool. - ${command_list} - A formatted table of available sub-commands. - ${help_list} - A formatted table of additional help topics (i.e. 'help_*' - methods with no matching 'do_*' method). - ${cmd_name} - The name (and aliases) for this sub-command formatted as: - "NAME (ALIAS1, ALIAS2, ...)". - ${cmd_usage} - A formatted usage block inferred from the command function - signature. - ${cmd_option_list} - A formatted table of options for this sub-command. (This is - only available for commands using the optparse integration, - i.e. using @cmdln.option decorators or manually setting the - 'optparser' attribute on the 'do_*' method.) - - Returns the processed help. - """ - preprocessors = { - "${name}": self._help_preprocess_name, - "${option_list}": self._help_preprocess_option_list, - "${command_list}": self._help_preprocess_command_list, - "${help_list}": self._help_preprocess_help_list, - "${cmd_name}": self._help_preprocess_cmd_name, - "${cmd_usage}": self._help_preprocess_cmd_usage, - "${cmd_option_list}": self._help_preprocess_cmd_option_list, - } - - for marker, preprocessor in preprocessors.items(): - if marker in help: - help = preprocessor(help, cmdname) - return help - - def _help_preprocess_name(self, help, cmdname=None): - return help.replace("${name}", self.name) - - def _help_preprocess_option_list(self, help, cmdname=None): - marker = "${option_list}" - indent, indent_width = _get_indent(marker, help) - suffix = _get_trailing_whitespace(marker, help) - - if self.optparser: - # Setup formatting options and format. - # - Indentation of 4 is better than optparse default of 2. - # C.f. Damian Conway's discussion of this in Perl Best - # Practices. - self.optparser.formatter.indent_increment = 4 - self.optparser.formatter.current_indent = indent_width - block = self.optparser.format_option_help() + '\n' - else: - block = "" - - help = help.replace(indent+marker+suffix, block, 1) - return help - - - def _help_preprocess_command_list(self, help, cmdname=None): - marker = "${command_list}" - indent, indent_width = _get_indent(marker, help) - suffix = _get_trailing_whitespace(marker, help) - - # Find any aliases for commands. - token2canonical = self._get_canonical_map() - aliases = {} - for token, cmdname in token2canonical.items(): - if token == cmdname: continue - aliases.setdefault(cmdname, []).append(token) - - # Get the list of (non-hidden) commands and their - # documentation, if any. - cmdnames = {} # use a dict to strip duplicates - for attr in self.get_names(): - if attr.startswith("do_"): - cmdnames[attr[3:]] = True - cmdnames = cmdnames.keys() - cmdnames.sort() - linedata = [] - for cmdname in cmdnames: - if aliases.get(cmdname): - a = aliases[cmdname] - a.sort() - cmdstr = "%s (%s)" % (cmdname, ", ".join(a)) - else: - cmdstr = cmdname - doc = None - try: - helpfunc = getattr(self, 'help_'+cmdname) - except AttributeError: - handler = self._get_cmd_handler(cmdname) - if handler: - doc = handler.__doc__ - else: - doc = helpfunc() - - # Strip "${cmd_name}: " from the start of a command's doc. Best - # practice dictates that command help strings begin with this, but - # it isn't at all wanted for the command list. - to_strip = "${cmd_name}:" - if doc and doc.startswith(to_strip): - #log.debug("stripping %r from start of %s's help string", - # to_strip, cmdname) - doc = doc[len(to_strip):].lstrip() - linedata.append( (cmdstr, doc) ) - - if linedata: - subindent = indent + ' '*4 - lines = _format_linedata(linedata, subindent, indent_width+4) - block = indent + "Commands:\n" \ - + '\n'.join(lines) + "\n\n" - help = help.replace(indent+marker+suffix, block, 1) - return help - - def _gen_names_and_attrs(self): - # Inheritance says we have to look in class and - # base classes; order is not important. - names = [] - classes = [self.__class__] - while classes: - aclass = classes.pop(0) - if aclass.__bases__: - classes = classes + list(aclass.__bases__) - for name in dir(aclass): - yield (name, getattr(aclass, name)) - - def _help_preprocess_help_list(self, help, cmdname=None): - marker = "${help_list}" - indent, indent_width = _get_indent(marker, help) - suffix = _get_trailing_whitespace(marker, help) - - # Determine the additional help topics, if any. - helpnames = {} - token2cmdname = self._get_canonical_map() - for attrname, attr in self._gen_names_and_attrs(): - if not attrname.startswith("help_"): continue - helpname = attrname[5:] - if helpname not in token2cmdname: - helpnames[helpname] = attr - - if helpnames: - linedata = [(n, a.__doc__ or "") for n, a in helpnames.items()] - linedata.sort() - - subindent = indent + ' '*4 - lines = _format_linedata(linedata, subindent, indent_width+4) - block = (indent - + "Additional help topics (run `%s help TOPIC'):\n" % self.name - + '\n'.join(lines) - + "\n\n") - else: - block = '' - help = help.replace(indent+marker+suffix, block, 1) - return help - - def _help_preprocess_cmd_name(self, help, cmdname=None): - marker = "${cmd_name}" - handler = self._get_cmd_handler(cmdname) - if not handler: - raise CmdlnError("cannot preprocess '%s' into help string: " - "could not find command handler for %r" - % (marker, cmdname)) - s = cmdname - if hasattr(handler, "aliases"): - s += " (%s)" % (", ".join(handler.aliases)) - help = help.replace(marker, s) - return help - - #TODO: this only makes sense as part of the Cmdln class. - # Add hooks to add help preprocessing template vars and put - # this one on that class. - def _help_preprocess_cmd_usage(self, help, cmdname=None): - marker = "${cmd_usage}" - handler = self._get_cmd_handler(cmdname) - if not handler: - raise CmdlnError("cannot preprocess '%s' into help string: " - "could not find command handler for %r" - % (marker, cmdname)) - indent, indent_width = _get_indent(marker, help) - suffix = _get_trailing_whitespace(marker, help) - - # Extract the introspection bits we need. - func = handler.im_func - if func.func_defaults: - func_defaults = list(func.func_defaults) - else: - func_defaults = [] - co_argcount = func.func_code.co_argcount - co_varnames = func.func_code.co_varnames - co_flags = func.func_code.co_flags - CO_FLAGS_ARGS = 4 - CO_FLAGS_KWARGS = 8 - - # Adjust argcount for possible *args and **kwargs arguments. - argcount = co_argcount - if co_flags & CO_FLAGS_ARGS: argcount += 1 - if co_flags & CO_FLAGS_KWARGS: argcount += 1 - - # Determine the usage string. - usage = "%s %s" % (self.name, cmdname) - if argcount <= 2: # handler ::= do_FOO(self, argv) - usage += " [ARGS...]" - elif argcount >= 3: # handler ::= do_FOO(self, subcmd, opts, ...) - argnames = list(co_varnames[3:argcount]) - tail = "" - if co_flags & CO_FLAGS_KWARGS: - name = argnames.pop(-1) - import warnings - # There is no generally accepted mechanism for passing - # keyword arguments from the command line. Could - # *perhaps* consider: arg=value arg2=value2 ... - warnings.warn("argument '**%s' on '%s.%s' command " - "handler will never get values" - % (name, self.__class__.__name__, - func.func_name)) - if co_flags & CO_FLAGS_ARGS: - name = argnames.pop(-1) - tail = "[%s...]" % name.upper() - while func_defaults: - func_defaults.pop(-1) - name = argnames.pop(-1) - tail = "[%s%s%s]" % (name.upper(), (tail and ' ' or ''), tail) - while argnames: - name = argnames.pop(-1) - tail = "%s %s" % (name.upper(), tail) - usage += ' ' + tail - - block_lines = [ - self.helpindent + "Usage:", - self.helpindent + ' '*4 + usage - ] - block = '\n'.join(block_lines) + '\n\n' - - help = help.replace(indent+marker+suffix, block, 1) - return help - - #TODO: this only makes sense as part of the Cmdln class. - # Add hooks to add help preprocessing template vars and put - # this one on that class. - def _help_preprocess_cmd_option_list(self, help, cmdname=None): - marker = "${cmd_option_list}" - handler = self._get_cmd_handler(cmdname) - if not handler: - raise CmdlnError("cannot preprocess '%s' into help string: " - "could not find command handler for %r" - % (marker, cmdname)) - indent, indent_width = _get_indent(marker, help) - suffix = _get_trailing_whitespace(marker, help) - if hasattr(handler, "optparser"): - # Setup formatting options and format. - # - Indentation of 4 is better than optparse default of 2. - # C.f. Damian Conway's discussion of this in Perl Best - # Practices. - handler.optparser.formatter.indent_increment = 4 - handler.optparser.formatter.current_indent = indent_width - block = handler.optparser.format_option_help() + '\n' - else: - block = "" - - help = help.replace(indent+marker+suffix, block, 1) - return help - - def _get_canonical_cmd_name(self, token): - map = self._get_canonical_map() - return map.get(token, None) - - def _get_canonical_map(self): - """Return a mapping of available command names and aliases to - their canonical command name. - """ - cacheattr = "_token2canonical" - if not hasattr(self, cacheattr): - # Get the list of commands and their aliases, if any. - token2canonical = {} - cmd2funcname = {} # use a dict to strip duplicates - for attr in self.get_names(): - if attr.startswith("do_"): cmdname = attr[3:] - elif attr.startswith("_do_"): cmdname = attr[4:] - else: - continue - cmd2funcname[cmdname] = attr - token2canonical[cmdname] = cmdname - for cmdname, funcname in cmd2funcname.items(): # add aliases - func = getattr(self, funcname) - aliases = getattr(func, "aliases", []) - for alias in aliases: - if alias in cmd2funcname: - import warnings - warnings.warn("'%s' alias for '%s' command conflicts " - "with '%s' handler" - % (alias, cmdname, cmd2funcname[alias])) - continue - token2canonical[alias] = cmdname - setattr(self, cacheattr, token2canonical) - return getattr(self, cacheattr) - - def _get_cmd_handler(self, cmdname): - handler = None - try: - handler = getattr(self, 'do_' + cmdname) - except AttributeError: - try: - # Private command handlers begin with "_do_". - handler = getattr(self, '_do_' + cmdname) - except AttributeError: - pass - return handler - - def _do_EOF(self, argv): - # Default EOF handler - # Note: an actual EOF is redirected to this command. - #TODO: separate name for this. Currently it is available from - # command-line. Is that okay? - self.stdout.write('\n') - self.stdout.flush() - self.stop = True - - def emptyline(self): - # Different from cmd.Cmd: don't repeat the last command for an - # emptyline. - if self.cmdlooping: - pass - else: - return self.do_help(["help"]) - - -#---- optparse.py extension to fix (IMO) some deficiencies -# -# See the class _OptionParserEx docstring for details. -# - -class StopOptionProcessing(Exception): - """Indicate that option *and argument* processing should stop - cleanly. This is not an error condition. It is similar in spirit to - StopIteration. This is raised by _OptionParserEx's default "help" - and "version" option actions and can be raised by custom option - callbacks too. - - Hence the typical CmdlnOptionParser (a subclass of _OptionParserEx) - usage is: - - parser = CmdlnOptionParser(mycmd) - parser.add_option("-f", "--force", dest="force") - ... - try: - opts, args = parser.parse_args() - except StopOptionProcessing: - # normal termination, "--help" was probably given - sys.exit(0) - """ - -class _OptionParserEx(optparse.OptionParser): - """An optparse.OptionParser that uses exceptions instead of sys.exit. - - This class is an extension of optparse.OptionParser that differs - as follows: - - Correct (IMO) the default OptionParser error handling to never - sys.exit(). Instead OptParseError exceptions are passed through. - - Add the StopOptionProcessing exception (a la StopIteration) to - indicate normal termination of option processing. - See StopOptionProcessing's docstring for details. - - I'd also like to see the following in the core optparse.py, perhaps - as a RawOptionParser which would serve as a base class for the more - generally used OptionParser (that works as current): - - Remove the implicit addition of the -h|--help and --version - options. They can get in the way (e.g. if want '-?' and '-V' for - these as well) and it is not hard to do: - optparser.add_option("-h", "--help", action="help") - optparser.add_option("--version", action="version") - These are good practices, just not valid defaults if they can - get in the way. - """ - def error(self, msg): - raise optparse.OptParseError(msg) - - def exit(self, status=0, msg=None): - if status == 0: - raise StopOptionProcessing(msg) - else: - #TODO: don't lose status info here - raise optparse.OptParseError(msg) - - - -#---- optparse.py-based option processing support - -class CmdlnOptionParser(_OptionParserEx): - """An optparse.OptionParser class more appropriate for top-level - Cmdln options. For parsing of sub-command options, see - SubCmdOptionParser. - - Changes: - - disable_interspersed_args() by default, because a Cmdln instance - has sub-commands which may themselves have options. - - Redirect print_help() to the Cmdln.do_help() which is better - equiped to handle the "help" action. - - error() will raise a CmdlnUserError: OptionParse.error() is meant - to be called for user errors. Raising a well-known error here can - make error handling clearer. - - Also see the changes in _OptionParserEx. - """ - def __init__(self, cmdln, **kwargs): - self.cmdln = cmdln - kwargs["prog"] = self.cmdln.name - _OptionParserEx.__init__(self, **kwargs) - self.disable_interspersed_args() - - def print_help(self, file=None): - self.cmdln.onecmd(["help"]) - - def error(self, msg): - raise CmdlnUserError(msg) - - -class SubCmdOptionParser(_OptionParserEx): - def set_cmdln_info(self, cmdln, subcmd): - """Called by Cmdln to pass relevant info about itself needed - for print_help(). - """ - self.cmdln = cmdln - self.subcmd = subcmd - - def print_help(self, file=None): - self.cmdln.onecmd(["help", self.subcmd]) - - def error(self, msg): - raise CmdlnUserError(msg) - - -def option(*args, **kwargs): - """Decorator to add an option to the optparser argument of a Cmdln - subcommand. - - Example: - class MyShell(cmdln.Cmdln): - @cmdln.option("-f", "--force", help="force removal") - def do_remove(self, subcmd, opts, *args): - #... - """ - #XXX Is there a possible optimization for many options to not have a - # large stack depth here? - def decorate(f): - if not hasattr(f, "optparser"): - f.optparser = SubCmdOptionParser() - f.optparser.add_option(*args, **kwargs) - return f - return decorate - - -class Cmdln(RawCmdln): - """An improved (on cmd.Cmd) framework for building multi-subcommand - scripts (think "svn" & "cvs") and simple shells (think "pdb" and - "gdb"). - - A simple example: - - import cmdln - - class MySVN(cmdln.Cmdln): - name = "svn" - - @cmdln.aliases('stat', 'st') - @cmdln.option('-v', '--verbose', action='store_true' - help='print verbose information') - def do_status(self, subcmd, opts, *paths): - print "handle 'svn status' command" - - #... - - if __name__ == "__main__": - shell = MySVN() - retval = shell.main() - sys.exit(retval) - - 'Cmdln' extends 'RawCmdln' by providing optparse option processing - integration. See this class' _dispatch_cmd() docstring and - <http://trentm.com/projects/cmdln> for more information. - """ - def _dispatch_cmd(self, handler, argv): - """Introspect sub-command handler signature to determine how to - dispatch the command. The raw handler provided by the base - 'RawCmdln' class is still supported: - - def do_foo(self, argv): - # 'argv' is the vector of command line args, argv[0] is - # the command name itself (i.e. "foo" or an alias) - pass - - In addition, if the handler has more than 2 arguments option - processing is automatically done (using optparse): - - @cmdln.option('-v', '--verbose', action='store_true') - def do_bar(self, subcmd, opts, *args): - # subcmd = <"bar" or an alias> - # opts = <an optparse.Values instance> - if opts.verbose: - print "lots of debugging output..." - # args = <tuple of arguments> - for arg in args: - bar(arg) - - TODO: explain that "*args" can be other signatures as well. - - The `cmdln.option` decorator corresponds to an `add_option()` - method call on an `optparse.OptionParser` instance. - - You can declare a specific number of arguments: - - @cmdln.option('-v', '--verbose', action='store_true') - def do_bar2(self, subcmd, opts, bar_one, bar_two): - #... - - and an appropriate error message will be raised/printed if the - command is called with a different number of args. - """ - co_argcount = handler.im_func.func_code.co_argcount - if co_argcount == 2: # handler ::= do_foo(self, argv) - return handler(argv) - elif co_argcount >= 3: # handler ::= do_foo(self, subcmd, opts, ...) - try: - optparser = handler.optparser - except AttributeError: - optparser = handler.im_func.optparser = SubCmdOptionParser() - assert isinstance(optparser, SubCmdOptionParser) - optparser.set_cmdln_info(self, argv[0]) - try: - opts, args = optparser.parse_args(argv[1:]) - except StopOptionProcessing: - #TODO: this doesn't really fly for a replacement of - # optparse.py behaviour, does it? - return 0 # Normal command termination - - try: - return handler(argv[0], opts, *args) - except TypeError, ex: - # Some TypeError's are user errors: - # do_foo() takes at least 4 arguments (3 given) - # do_foo() takes at most 5 arguments (6 given) - # do_foo() takes exactly 5 arguments (6 given) - # Raise CmdlnUserError for these with a suitably - # massaged error message. - import sys - tb = sys.exc_info()[2] # the traceback object - if tb.tb_next is not None: - # If the traceback is more than one level deep, then the - # TypeError do *not* happen on the "handler(...)" call - # above. In that we don't want to handle it specially - # here: it would falsely mask deeper code errors. - raise - msg = ex.args[0] - match = _INCORRECT_NUM_ARGS_RE.search(msg) - if match: - msg = list(match.groups()) - msg[1] = int(msg[1]) - 3 - if msg[1] == 1: - msg[2] = msg[2].replace("arguments", "argument") - msg[3] = int(msg[3]) - 3 - msg = ''.join(map(str, msg)) - raise CmdlnUserError(msg) - else: - raise - else: - raise CmdlnError("incorrect argcount for %s(): takes %d, must " - "take 2 for 'argv' signature or 3+ for 'opts' " - "signature" % (handler.__name__, co_argcount)) - - - -#---- internal support functions - -def _format_linedata(linedata, indent, indent_width): - """Format specific linedata into a pleasant layout. - - "linedata" is a list of 2-tuples of the form: - (<item-display-string>, <item-docstring>) - "indent" is a string to use for one level of indentation - "indent_width" is a number of columns by which the - formatted data will be indented when printed. - - The <item-display-string> column is held to 15 columns. - """ - lines = [] - WIDTH = 78 - indent_width - SPACING = 2 - NAME_WIDTH_LOWER_BOUND = 13 - NAME_WIDTH_UPPER_BOUND = 16 - NAME_WIDTH = max([len(s) for s,d in linedata]) - if NAME_WIDTH < NAME_WIDTH_LOWER_BOUND: - NAME_WIDTH = NAME_WIDTH_LOWER_BOUND - else: - NAME_WIDTH = NAME_WIDTH_UPPER_BOUND - - DOC_WIDTH = WIDTH - NAME_WIDTH - SPACING - for namestr, doc in linedata: - line = indent + namestr - if len(namestr) <= NAME_WIDTH: - line += ' ' * (NAME_WIDTH + SPACING - len(namestr)) - else: - lines.append(line) - line = indent + ' ' * (NAME_WIDTH + SPACING) - line += _summarize_doc(doc, DOC_WIDTH) - lines.append(line.rstrip()) - return lines - -def _summarize_doc(doc, length=60): - r"""Parse out a short one line summary from the given doclines. - - "doc" is the doc string to summarize. - "length" is the max length for the summary - - >>> _summarize_doc("this function does this") - 'this function does this' - >>> _summarize_doc("this function does this", 10) - 'this fu...' - >>> _summarize_doc("this function does this\nand that") - 'this function does this and that' - >>> _summarize_doc("this function does this\n\nand that") - 'this function does this' - """ - import re - if doc is None: - return "" - assert length > 3, "length <= 3 is absurdly short for a doc summary" - doclines = doc.strip().splitlines(0) - if not doclines: - return "" - - summlines = [] - for i, line in enumerate(doclines): - stripped = line.strip() - if not stripped: - break - summlines.append(stripped) - if len(''.join(summlines)) >= length: - break - - summary = ' '.join(summlines) - if len(summary) > length: - summary = summary[:length-3] + "..." - return summary - - -def line2argv(line): - r"""Parse the given line into an argument vector. - - "line" is the line of input to parse. - - This may get niggly when dealing with quoting and escaping. The - current state of this parsing may not be completely thorough/correct - in this respect. - - >>> from cmdln import line2argv - >>> line2argv("foo") - ['foo'] - >>> line2argv("foo bar") - ['foo', 'bar'] - >>> line2argv("foo bar ") - ['foo', 'bar'] - >>> line2argv(" foo bar") - ['foo', 'bar'] - - Quote handling: - - >>> line2argv("'foo bar'") - ['foo bar'] - >>> line2argv('"foo bar"') - ['foo bar'] - >>> line2argv(r'"foo\"bar"') - ['foo"bar'] - >>> line2argv("'foo bar' spam") - ['foo bar', 'spam'] - >>> line2argv("'foo 'bar spam") - ['foo bar', 'spam'] - - >>> line2argv('some\tsimple\ttests') - ['some', 'simple', 'tests'] - >>> line2argv('a "more complex" test') - ['a', 'more complex', 'test'] - >>> line2argv('a more="complex test of " quotes') - ['a', 'more=complex test of ', 'quotes'] - >>> line2argv('a more" complex test of " quotes') - ['a', 'more complex test of ', 'quotes'] - >>> line2argv('an "embedded \\"quote\\""') - ['an', 'embedded "quote"'] - - # Komodo bug 48027 - >>> line2argv('foo bar C:\\') - ['foo', 'bar', 'C:\\'] - - # Komodo change 127581 - >>> line2argv(r'"\test\slash" "foo bar" "foo\"bar"') - ['\\test\\slash', 'foo bar', 'foo"bar'] - - # Komodo change 127629 - >>> if sys.platform == "win32": - ... line2argv(r'\foo\bar') == ['\\foo\\bar'] - ... line2argv(r'\\foo\\bar') == ['\\\\foo\\\\bar'] - ... line2argv('"foo') == ['foo'] - ... else: - ... line2argv(r'\foo\bar') == ['foobar'] - ... line2argv(r'\\foo\\bar') == ['\\foo\\bar'] - ... try: - ... line2argv('"foo') - ... except ValueError, ex: - ... "not terminated" in str(ex) - True - True - True - """ - import string - line = line.strip() - argv = [] - state = "default" - arg = None # the current argument being parsed - i = -1 - while 1: - i += 1 - if i >= len(line): break - ch = line[i] - - if ch == "\\" and i+1 < len(line): - # escaped char always added to arg, regardless of state - if arg is None: arg = "" - if (sys.platform == "win32" - or state in ("double-quoted", "single-quoted") - ) and line[i+1] not in tuple('"\''): - arg += ch - i += 1 - arg += line[i] - continue - - if state == "single-quoted": - if ch == "'": - state = "default" - else: - arg += ch - elif state == "double-quoted": - if ch == '"': - state = "default" - else: - arg += ch - elif state == "default": - if ch == '"': - if arg is None: arg = "" - state = "double-quoted" - elif ch == "'": - if arg is None: arg = "" - state = "single-quoted" - elif ch in string.whitespace: - if arg is not None: - argv.append(arg) - arg = None - else: - if arg is None: arg = "" - arg += ch - if arg is not None: - argv.append(arg) - if not sys.platform == "win32" and state != "default": - raise ValueError("command line is not terminated: unfinished %s " - "segment" % state) - return argv - - -def argv2line(argv): - r"""Put together the given argument vector into a command line. - - "argv" is the argument vector to process. - - >>> from cmdln import argv2line - >>> argv2line(['foo']) - 'foo' - >>> argv2line(['foo', 'bar']) - 'foo bar' - >>> argv2line(['foo', 'bar baz']) - 'foo "bar baz"' - >>> argv2line(['foo"bar']) - 'foo"bar' - >>> print argv2line(['foo" bar']) - 'foo" bar' - >>> print argv2line(["foo' bar"]) - "foo' bar" - >>> argv2line(["foo'bar"]) - "foo'bar" - """ - escapedArgs = [] - for arg in argv: - if ' ' in arg and '"' not in arg: - arg = '"'+arg+'"' - elif ' ' in arg and "'" not in arg: - arg = "'"+arg+"'" - elif ' ' in arg: - arg = arg.replace('"', r'\"') - arg = '"'+arg+'"' - escapedArgs.append(arg) - return ' '.join(escapedArgs) - - -# Recipe: dedent (0.1) in /Users/trentm/tm/recipes/cookbook -def _dedentlines(lines, tabsize=8, skip_first_line=False): - """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines - - "lines" is a list of lines to dedent. - "tabsize" is the tab width to use for indent width calculations. - "skip_first_line" is a boolean indicating if the first line should - be skipped for calculating the indent width and for dedenting. - This is sometimes useful for docstrings and similar. - - Same as dedent() except operates on a sequence of lines. Note: the - lines list is modified **in-place**. - """ - DEBUG = False - if DEBUG: - print "dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\ - % (tabsize, skip_first_line) - indents = [] - margin = None - for i, line in enumerate(lines): - if i == 0 and skip_first_line: continue - indent = 0 - for ch in line: - if ch == ' ': - indent += 1 - elif ch == '\t': - indent += tabsize - (indent % tabsize) - elif ch in '\r\n': - continue # skip all-whitespace lines - else: - break - else: - continue # skip all-whitespace lines - if DEBUG: print "dedent: indent=%d: %r" % (indent, line) - if margin is None: - margin = indent - else: - margin = min(margin, indent) - if DEBUG: print "dedent: margin=%r" % margin - - if margin is not None and margin > 0: - for i, line in enumerate(lines): - if i == 0 and skip_first_line: continue - removed = 0 - for j, ch in enumerate(line): - if ch == ' ': - removed += 1 - elif ch == '\t': - removed += tabsize - (removed % tabsize) - elif ch in '\r\n': - if DEBUG: print "dedent: %r: EOL -> strip up to EOL" % line - lines[i] = lines[i][j:] - break - else: - raise ValueError("unexpected non-whitespace char %r in " - "line %r while removing %d-space margin" - % (ch, line, margin)) - if DEBUG: - print "dedent: %r: %r -> removed %d/%d"\ - % (line, ch, removed, margin) - if removed == margin: - lines[i] = lines[i][j+1:] - break - elif removed > margin: - lines[i] = ' '*(removed-margin) + lines[i][j+1:] - break - return lines - -def _dedent(text, tabsize=8, skip_first_line=False): - """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text - - "text" is the text to dedent. - "tabsize" is the tab width to use for indent width calculations. - "skip_first_line" is a boolean indicating if the first line should - be skipped for calculating the indent width and for dedenting. - This is sometimes useful for docstrings and similar. - - textwrap.dedent(s), but don't expand tabs to spaces - """ - lines = text.splitlines(1) - _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line) - return ''.join(lines) - - -def _get_indent(marker, s, tab_width=8): - """_get_indent(marker, s, tab_width=8) -> - (<indentation-of-'marker'>, <indentation-width>)""" - # Figure out how much the marker is indented. - INDENT_CHARS = tuple(' \t') - start = s.index(marker) - i = start - while i > 0: - if s[i-1] not in INDENT_CHARS: - break - i -= 1 - indent = s[i:start] - indent_width = 0 - for ch in indent: - if ch == ' ': - indent_width += 1 - elif ch == '\t': - indent_width += tab_width - (indent_width % tab_width) - return indent, indent_width - -def _get_trailing_whitespace(marker, s): - """Return the whitespace content trailing the given 'marker' in string 's', - up to and including a newline. - """ - suffix = '' - start = s.index(marker) + len(marker) - i = start - while i < len(s): - if s[i] in ' \t': - suffix += s[i] - elif s[i] in '\r\n': - suffix += s[i] - if s[i] == '\r' and i+1 < len(s) and s[i+1] == '\n': - suffix += s[i+1] - break - else: - break - i += 1 - return suffix - - - -#---- bash completion support -# Note: This is still experimental. I expect to change this -# significantly. -# -# To get Bash completion for a cmdln.Cmdln class, run the following -# bash command: -# $ complete -C 'python -m cmdln /path/to/script.py CmdlnClass' cmdname -# For example: -# $ complete -C 'python -m cmdln ~/bin/svn.py SVN' svn -# -#TODO: Simplify the above so don't have to given path to script (try to -# find it on PATH, if possible). Could also make class name -# optional if there is only one in the module (common case). - -if __name__ == "__main__" and len(sys.argv) == 6: - def _log(s): - return # no-op, comment out for debugging - from os.path import expanduser - fout = open(expanduser("~/tmp/bashcpln.log"), 'a') - fout.write(str(s) + '\n') - fout.close() - - # Recipe: module_from_path (1.0.1+) - def _module_from_path(path): - import imp, os, sys - path = os.path.expanduser(path) - dir = os.path.dirname(path) or os.curdir - name = os.path.splitext(os.path.basename(path))[0] - sys.path.insert(0, dir) - try: - iinfo = imp.find_module(name, [dir]) - return imp.load_module(name, *iinfo) - finally: - sys.path.remove(dir) - - def _get_bash_cplns(script_path, class_name, cmd_name, - token, preceding_token): - _log('--') - _log('get_cplns(%r, %r, %r, %r, %r)' - % (script_path, class_name, cmd_name, token, preceding_token)) - comp_line = os.environ["COMP_LINE"] - comp_point = int(os.environ["COMP_POINT"]) - _log("COMP_LINE: %r" % comp_line) - _log("COMP_POINT: %r" % comp_point) - - try: - script = _module_from_path(script_path) - except ImportError, ex: - _log("error importing `%s': %s" % (script_path, ex)) - return [] - shell = getattr(script, class_name)() - cmd_map = shell._get_canonical_map() - del cmd_map["EOF"] - - # Determine if completing the sub-command name. - parts = comp_line[:comp_point].split(None, 1) - _log(parts) - if len(parts) == 1 or not (' ' in parts[1] or '\t' in parts[1]): - #TODO: if parts[1].startswith('-'): handle top-level opts - _log("complete sub-command names") - matches = {} - for name, canon_name in cmd_map.items(): - if name.startswith(token): - matches[name] = canon_name - if not matches: - return [] - elif len(matches) == 1: - return matches.keys() - elif len(set(matches.values())) == 1: - return [matches.values()[0]] - else: - return matches.keys() - - # Otherwise, complete options for the given sub-command. - #TODO: refine this so it does the right thing with option args - if token.startswith('-'): - cmd_name = comp_line.split(None, 2)[1] - try: - cmd_canon_name = cmd_map[cmd_name] - except KeyError: - return [] - handler = shell._get_cmd_handler(cmd_canon_name) - optparser = getattr(handler, "optparser", None) - if optparser is None: - optparser = SubCmdOptionParser() - opt_strs = [] - for option in optparser.option_list: - for opt_str in option._short_opts + option._long_opts: - if opt_str.startswith(token): - opt_strs.append(opt_str) - return opt_strs - - return [] - - for cpln in _get_bash_cplns(*sys.argv[1:]): - print cpln - diff --git a/scripts/lib/mic/utils/errors.py b/scripts/lib/mic/utils/errors.py deleted file mode 100644 index 86e230ac19..0000000000 --- a/scripts/lib/mic/utils/errors.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2007 Red Hat, Inc. -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -class CreatorError(Exception): - """An exception base class for all imgcreate errors.""" - keyword = '<creator>' - - def __init__(self, msg): - self.msg = msg - - def __str__(self): - if isinstance(self.msg, unicode): - self.msg = self.msg.encode('utf-8', 'ignore') - else: - self.msg = str(self.msg) - return self.keyword + self.msg - -class Usage(CreatorError): - keyword = '<usage>' - - def __str__(self): - if isinstance(self.msg, unicode): - self.msg = self.msg.encode('utf-8', 'ignore') - else: - self.msg = str(self.msg) - return self.keyword + self.msg + ', please use "--help" for more info' - -class KsError(CreatorError): - keyword = '<kickstart>' - -class ImageError(CreatorError): - keyword = '<mount>' diff --git a/scripts/lib/mic/utils/fs_related.py b/scripts/lib/mic/utils/fs_related.py deleted file mode 100644 index cf2a759a06..0000000000 --- a/scripts/lib/mic/utils/fs_related.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2007, Red Hat, Inc. -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -from __future__ import with_statement -import os -import sys -import errno -import stat -import random -import string -import time -import uuid - -from mic import msger -from mic.utils import runner -from mic.utils.errors import * -from mic.utils.oe.misc import * - -def find_binary_path(binary): - if os.environ.has_key("PATH"): - paths = os.environ["PATH"].split(":") - else: - paths = [] - if os.environ.has_key("HOME"): - paths += [os.environ["HOME"] + "/bin"] - paths += ["/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin"] - - for path in paths: - bin_path = "%s/%s" % (path, binary) - if os.path.exists(bin_path): - return bin_path - - print "External command '%s' not found, exiting." % binary - print " (Please install '%s' on your host system)" % binary - sys.exit(1) - -def makedirs(dirname): - """A version of os.makedirs() that doesn't throw an - exception if the leaf directory already exists. - """ - try: - os.makedirs(dirname) - except OSError, err: - if err.errno != errno.EEXIST: - raise - -class Disk: - """ - Generic base object for a disk. - """ - def __init__(self, size, device = None): - self._device = device - self._size = size - - def create(self): - pass - - def cleanup(self): - pass - - def get_device(self): - return self._device - def set_device(self, path): - self._device = path - device = property(get_device, set_device) - - def get_size(self): - return self._size - size = property(get_size) - - -class DiskImage(Disk): - """ - A Disk backed by a file. - """ - def __init__(self, image_file, size): - Disk.__init__(self, size) - self.image_file = image_file - - def exists(self): - return os.path.exists(self.image_file) - - def create(self): - if self.device is not None: - return - - blocks = self.size / 1024 - if self.size - blocks * 1024: - blocks += 1 - - # create disk image - dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=1" % \ - (self.image_file, blocks) - exec_cmd(dd_cmd) - - self.device = self.image_file diff --git a/scripts/lib/mic/utils/misc.py b/scripts/lib/mic/utils/misc.py deleted file mode 100644 index 194b88f691..0000000000 --- a/scripts/lib/mic/utils/misc.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2010, 2011 Intel Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os -import sys -import time - -def build_name(kscfg, release=None, prefix = None, suffix = None): - """Construct and return an image name string. - - This is a utility function to help create sensible name and fslabel - strings. The name is constructed using the sans-prefix-and-extension - kickstart filename and the supplied prefix and suffix. - - kscfg -- a path to a kickstart file - release -- a replacement to suffix for image release - prefix -- a prefix to prepend to the name; defaults to None, which causes - no prefix to be used - suffix -- a suffix to append to the name; defaults to None, which causes - a YYYYMMDDHHMM suffix to be used - - Note, if maxlen is less then the len(suffix), you get to keep both pieces. - - """ - name = os.path.basename(kscfg) - idx = name.rfind('.') - if idx >= 0: - name = name[:idx] - - if release is not None: - suffix = "" - if prefix is None: - prefix = "" - if suffix is None: - suffix = time.strftime("%Y%m%d%H%M") - - if name.startswith(prefix): - name = name[len(prefix):] - - prefix = "%s-" % prefix if prefix else "" - suffix = "-%s" % suffix if suffix else "" - - ret = prefix + name + suffix - - return ret diff --git a/scripts/lib/mic/utils/oe/__init__.py b/scripts/lib/mic/utils/oe/__init__.py deleted file mode 100644 index d10e802116..0000000000 --- a/scripts/lib/mic/utils/oe/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -# OpenEmbedded mic utils library -# -# Copyright (c) 2013, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# diff --git a/scripts/lib/mic/utils/oe/misc.py b/scripts/lib/mic/utils/oe/misc.py deleted file mode 100644 index bed275090d..0000000000 --- a/scripts/lib/mic/utils/oe/misc.py +++ /dev/null @@ -1,181 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2013, Intel Corporation. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty 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. -# -# DESCRIPTION -# This module provides a place to collect various mic-related utils -# for the OpenEmbedded Image Tools. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -from mic import msger -from mic.utils import runner - -def __exec_cmd(cmd_and_args, as_shell = False, catch = 3): - """ - Execute command, catching stderr, stdout - - Need to execute as_shell if the command uses wildcards - """ - msger.debug("__exec_cmd: %s" % cmd_and_args) - args = cmd_and_args.split() - msger.debug(args) - - if (as_shell): - rc, out = runner.runtool(cmd_and_args, catch) - else: - rc, out = runner.runtool(args, catch) - out = out.strip() - msger.debug("__exec_cmd: output for %s (rc = %d): %s" % \ - (cmd_and_args, rc, out)) - - return (rc, out) - - -def exec_cmd(cmd_and_args, as_shell = False, catch = 3): - """ - Execute command, catching stderr, stdout - - Exits if rc non-zero - """ - rc, out = __exec_cmd(cmd_and_args, as_shell, catch) - - if rc != 0: - msger.error("exec_cmd: %s returned '%s' instead of 0" % (cmd_and_args, rc)) - - return out - - -def exec_cmd_quiet(cmd_and_args, as_shell = False): - """ - Execute command, catching nothing in the output - - Exits if rc non-zero - """ - return exec_cmd(cmd_and_args, as_shell, 0) - - -def exec_native_cmd(cmd_and_args, native_sysroot, catch = 3): - """ - Execute native command, catching stderr, stdout - - Need to execute as_shell if the command uses wildcards - - Always need to execute native commands as_shell - """ - native_paths = \ - "export PATH=%s/sbin:%s/usr/sbin:%s/usr/bin:$PATH" % \ - (native_sysroot, native_sysroot, native_sysroot) - native_cmd_and_args = "%s;%s" % (native_paths, cmd_and_args) - msger.debug("exec_native_cmd: %s" % cmd_and_args) - - args = cmd_and_args.split() - msger.debug(args) - - rc, out = __exec_cmd(native_cmd_and_args, True, catch) - - if rc == 127: # shell command-not-found - msger.error("A native (host) program required to build the image " - "was not found (see details above). Please make sure " - "it's installed and try again.") - - return (rc, out) - - -def exec_native_cmd_quiet(cmd_and_args, native_sysroot): - """ - Execute native command, catching nothing in the output - - Need to execute as_shell if the command uses wildcards - - Always need to execute native commands as_shell - """ - return exec_native_cmd(cmd_and_args, native_sysroot, 0) - - -# kickstart doesn't support variable substution in commands, so this -# is our current simplistic scheme for supporting that - -wks_vars = dict() - -def get_wks_var(key): - return wks_vars[key] - -def add_wks_var(key, val): - wks_vars[key] = val - -BOOTDD_EXTRA_SPACE = 16384 -IMAGE_EXTRA_SPACE = 10240 - -__bitbake_env_lines = "" - -def set_bitbake_env_lines(bitbake_env_lines): - global __bitbake_env_lines - __bitbake_env_lines = bitbake_env_lines - -def get_bitbake_env_lines(): - return __bitbake_env_lines - -def find_bitbake_env_lines(image_name): - """ - If image_name is empty, plugins might still be able to use the - environment, so set it regardless. - """ - if image_name: - bitbake_env_cmd = "bitbake -e %s" % image_name - else: - bitbake_env_cmd = "bitbake -e" - rc, bitbake_env_lines = __exec_cmd(bitbake_env_cmd) - if rc != 0: - print "Couldn't get '%s' output." % bitbake_env_cmd - return None - - return bitbake_env_lines - -def find_artifact(bitbake_env_lines, variable): - """ - Gather the build artifact for the current image (the image_name - e.g. core-image-minimal) for the current MACHINE set in local.conf - """ - retval = "" - - for line in bitbake_env_lines.split('\n'): - if (get_line_val(line, variable)): - retval = get_line_val(line, variable) - break - - return retval - -def get_line_val(line, key): - """ - Extract the value from the VAR="val" string - """ - if line.startswith(key + "="): - stripped_line = line.split('=')[1] - stripped_line = stripped_line.replace('\"', '') - return stripped_line - return None - -def get_bitbake_var(key): - for line in __bitbake_env_lines.split('\n'): - if (get_line_val(line, key)): - val = get_line_val(line, key) - return val - return None diff --git a/scripts/lib/mic/utils/partitionedfs.py b/scripts/lib/mic/utils/partitionedfs.py deleted file mode 100644 index 68e4cabbe0..0000000000 --- a/scripts/lib/mic/utils/partitionedfs.py +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# Copyright (c) 2007, 2008 Red Hat, Inc. -# Copyright (c) 2008 Daniel P. Berrange -# Copyright (c) 2008 David P. Huff -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os - -from mic import msger -from mic.utils import runner -from mic.utils.errors import ImageError -from mic.utils.fs_related import * -from mic.utils.oe.misc import * - -# Overhead of the MBR partitioning scheme (just one sector) -MBR_OVERHEAD = 1 - -# Size of a sector in bytes -SECTOR_SIZE = 512 - -class Image: - """ - Generic base object for an image. - - An Image is a container for a set of DiskImages and associated - partitions. - """ - def __init__(self): - self.disks = {} - self.partitions = [] - self.parted = find_binary_path("parted") - # Size of a sector used in calculations - self.sector_size = SECTOR_SIZE - self._partitions_layed_out = False - - def __add_disk(self, disk_name): - """ Add a disk 'disk_name' to the internal list of disks. Note, - 'disk_name' is the name of the disk in the target system - (e.g., sdb). """ - - if disk_name in self.disks: - # We already have this disk - return - - assert not self._partitions_layed_out - - self.disks[disk_name] = \ - { 'disk': None, # Disk object - 'numpart': 0, # Number of allocate partitions - 'partitions': [], # Indexes to self.partitions - 'offset': 0, # Offset of next partition (in sectors) - # Minimum required disk size to fit all partitions (in bytes) - 'min_size': 0, - 'ptable_format': "msdos" } # Partition table format - - def add_disk(self, disk_name, disk_obj): - """ Add a disk object which have to be partitioned. More than one disk - can be added. In case of multiple disks, disk partitions have to be - added for each disk separately with 'add_partition()". """ - - self.__add_disk(disk_name) - self.disks[disk_name]['disk'] = disk_obj - - def __add_partition(self, part): - """ This is a helper function for 'add_partition()' which adds a - partition to the internal list of partitions. """ - - assert not self._partitions_layed_out - - self.partitions.append(part) - self.__add_disk(part['disk_name']) - - def add_partition(self, size, disk_name, mountpoint, source_file = None, fstype = None, - label=None, fsopts = None, boot = False, align = None, - part_type = None): - """ Add the next partition. Prtitions have to be added in the - first-to-last order. """ - - ks_pnum = len(self.partitions) - - # Converting MB to sectors for parted - size = size * 1024 * 1024 / self.sector_size - - # We still need partition for "/" or non-subvolume - if mountpoint == "/" or not fsopts: - part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file - 'size': size, # In sectors - 'mountpoint': mountpoint, # Mount relative to chroot - 'source_file': source_file, # partition contents - 'fstype': fstype, # Filesystem type - 'fsopts': fsopts, # Filesystem mount options - 'label': label, # Partition label - 'disk_name': disk_name, # physical disk name holding partition - 'device': None, # kpartx device node for partition - 'num': None, # Partition number - 'boot': boot, # Bootable flag - 'align': align, # Partition alignment - 'part_type' : part_type } # Partition type - - self.__add_partition(part) - - def layout_partitions(self, ptable_format = "msdos"): - """ Layout the partitions, meaning calculate the position of every - partition on the disk. The 'ptable_format' parameter defines the - partition table format and may be "msdos". """ - - msger.debug("Assigning %s partitions to disks" % ptable_format) - - if ptable_format not in ('msdos'): - raise ImageError("Unknown partition table format '%s', supported " \ - "formats are: 'msdos'" % ptable_format) - - if self._partitions_layed_out: - return - - self._partitions_layed_out = True - - # Go through partitions in the order they are added in .ks file - for n in range(len(self.partitions)): - p = self.partitions[n] - - if not self.disks.has_key(p['disk_name']): - raise ImageError("No disk %s for partition %s" \ - % (p['disk_name'], p['mountpoint'])) - - if p['part_type']: - # The --part-type can also be implemented for MBR partitions, - # in which case it would map to the 1-byte "partition type" - # filed at offset 3 of the partition entry. - raise ImageError("setting custom partition type is not " \ - "implemented for msdos partitions") - - # Get the disk where the partition is located - d = self.disks[p['disk_name']] - d['numpart'] += 1 - d['ptable_format'] = ptable_format - - if d['numpart'] == 1: - if ptable_format == "msdos": - overhead = MBR_OVERHEAD - - # Skip one sector required for the partitioning scheme overhead - d['offset'] += overhead - # Steal few sectors from the first partition to offset for the - # partitioning overhead - p['size'] -= overhead - - if p['align']: - # If not first partition and we do have alignment set we need - # to align the partition. - # FIXME: This leaves a empty spaces to the disk. To fill the - # gaps we could enlargea the previous partition? - - # Calc how much the alignment is off. - align_sectors = d['offset'] % (p['align'] * 1024 / self.sector_size) - # We need to move forward to the next alignment point - align_sectors = (p['align'] * 1024 / self.sector_size) - align_sectors - - msger.debug("Realignment for %s%s with %s sectors, original" - " offset %s, target alignment is %sK." % - (p['disk_name'], d['numpart'], align_sectors, - d['offset'], p['align'])) - - # increase the offset so we actually start the partition on right alignment - d['offset'] += align_sectors - - p['start'] = d['offset'] - d['offset'] += p['size'] - - p['type'] = 'primary' - p['num'] = d['numpart'] - - if d['ptable_format'] == "msdos": - if d['numpart'] > 2: - # Every logical partition requires an additional sector for - # the EBR, so steal the last sector from the end of each - # partition starting from the 3rd one for the EBR. This - # will make sure the logical partitions are aligned - # correctly. - p['size'] -= 1 - - if d['numpart'] > 3: - p['type'] = 'logical' - p['num'] = d['numpart'] + 1 - - d['partitions'].append(n) - msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " - "sectors (%d bytes)." \ - % (p['mountpoint'], p['disk_name'], p['num'], - p['start'], p['start'] + p['size'] - 1, - p['size'], p['size'] * self.sector_size)) - - # Once all the partitions have been layed out, we can calculate the - # minumim disk sizes. - for disk_name, d in self.disks.items(): - d['min_size'] = d['offset'] - - d['min_size'] *= self.sector_size - - def __run_parted(self, args): - """ Run parted with arguments specified in the 'args' list. """ - - args.insert(0, self.parted) - msger.debug(args) - - rc, out = runner.runtool(args, catch = 3) - out = out.strip() - if out: - msger.debug('"parted" output: %s' % out) - - if rc != 0: - # We don't throw exception when return code is not 0, because - # parted always fails to reload part table with loop devices. This - # prevents us from distinguishing real errors based on return - # code. - msger.error("WARNING: parted returned '%s' instead of 0 (use --debug for details)" % rc) - - def __create_partition(self, device, parttype, fstype, start, size): - """ Create a partition on an image described by the 'device' object. """ - - # Start is included to the size so we need to substract one from the end. - end = start + size - 1 - msger.debug("Added '%s' partition, sectors %d-%d, size %d sectors" % - (parttype, start, end, size)) - - args = ["-s", device, "unit", "s", "mkpart", parttype] - if fstype: - args.extend([fstype]) - args.extend(["%d" % start, "%d" % end]) - - return self.__run_parted(args) - - def __format_disks(self): - self.layout_partitions() - - for dev in self.disks.keys(): - d = self.disks[dev] - msger.debug("Initializing partition table for %s" % \ - (d['disk'].device)) - self.__run_parted(["-s", d['disk'].device, "mklabel", - d['ptable_format']]) - - msger.debug("Creating partitions") - - for p in self.partitions: - d = self.disks[p['disk_name']] - if d['ptable_format'] == "msdos" and p['num'] == 5: - # The last sector of the 3rd partition was reserved for the EBR - # of the first _logical_ partition. This is why the extended - # partition should start one sector before the first logical - # partition. - self.__create_partition(d['disk'].device, "extended", - None, p['start'] - 1, - d['offset'] - p['start']) - - if p['fstype'] == "swap": - parted_fs_type = "linux-swap" - elif p['fstype'] == "vfat": - parted_fs_type = "fat32" - elif p['fstype'] == "msdos": - parted_fs_type = "fat16" - else: - # Type for ext2/ext3/ext4/btrfs - parted_fs_type = "ext2" - - # Boot ROM of OMAP boards require vfat boot partition to have an - # even number of sectors. - if p['mountpoint'] == "/boot" and p['fstype'] in ["vfat", "msdos"] \ - and p['size'] % 2: - msger.debug("Substracting one sector from '%s' partition to " \ - "get even number of sectors for the partition" % \ - p['mountpoint']) - p['size'] -= 1 - - self.__create_partition(d['disk'].device, p['type'], - parted_fs_type, p['start'], p['size']) - - if p['boot']: - flag_name = "boot" - msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \ - (flag_name, p['num'], d['disk'].device)) - self.__run_parted(["-s", d['disk'].device, "set", - "%d" % p['num'], flag_name, "on"]) - - # Parted defaults to enabling the lba flag for fat16 partitions, - # which causes compatibility issues with some firmware (and really - # isn't necessary). - if parted_fs_type == "fat16": - if d['ptable_format'] == 'msdos': - msger.debug("Disable 'lba' flag for partition '%s' on disk '%s'" % \ - (p['num'], d['disk'].device)) - self.__run_parted(["-s", d['disk'].device, "set", - "%d" % p['num'], "lba", "off"]) - - def cleanup(self): - if self.disks: - for dev in self.disks.keys(): - d = self.disks[dev] - try: - d['disk'].cleanup() - except: - pass - - def __write_partition(self, num, source_file, start, size): - """ - Install source_file contents into a partition. - """ - if not source_file: # nothing to write - return - - # Start is included in the size so need to substract one from the end. - end = start + size - 1 - msger.debug("Installed %s in partition %d, sectors %d-%d, size %d sectors" % (source_file, num, start, end, size)) - - dd_cmd = "dd if=%s of=%s bs=%d seek=%d count=%d conv=notrunc" % \ - (source_file, self.image_file, self.sector_size, start, size) - exec_cmd(dd_cmd) - - - def assemble(self, image_file): - msger.debug("Installing partitions") - - self.image_file = image_file - - for p in self.partitions: - d = self.disks[p['disk_name']] - if d['ptable_format'] == "msdos" and p['num'] == 5: - # The last sector of the 3rd partition was reserved for the EBR - # of the first _logical_ partition. This is why the extended - # partition should start one sector before the first logical - # partition. - self.__write_partition(p['num'], p['source_file'], - p['start'] - 1, - d['offset'] - p['start']) - - self.__write_partition(p['num'], p['source_file'], - p['start'], p['size']) - - def create(self): - for dev in self.disks.keys(): - d = self.disks[dev] - d['disk'].create() - - self.__format_disks() - - return diff --git a/scripts/lib/mic/utils/runner.py b/scripts/lib/mic/utils/runner.py deleted file mode 100644 index fded3c93fa..0000000000 --- a/scripts/lib/mic/utils/runner.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os -import subprocess - -from mic import msger - -def runtool(cmdln_or_args, catch=1): - """ wrapper for most of the subprocess calls - input: - cmdln_or_args: can be both args and cmdln str (shell=True) - catch: 0, quitely run - 1, only STDOUT - 2, only STDERR - 3, both STDOUT and STDERR - return: - (rc, output) - if catch==0: the output will always None - """ - - if catch not in (0, 1, 2, 3): - # invalid catch selection, will cause exception, that's good - return None - - if isinstance(cmdln_or_args, list): - cmd = cmdln_or_args[0] - shell = False - else: - import shlex - cmd = shlex.split(cmdln_or_args)[0] - shell = True - - if catch != 3: - dev_null = os.open("/dev/null", os.O_WRONLY) - - if catch == 0: - sout = dev_null - serr = dev_null - elif catch == 1: - sout = subprocess.PIPE - serr = dev_null - elif catch == 2: - sout = dev_null - serr = subprocess.PIPE - elif catch == 3: - sout = subprocess.PIPE - serr = subprocess.STDOUT - - try: - p = subprocess.Popen(cmdln_or_args, stdout=sout, - stderr=serr, shell=shell) - (sout, serr) = p.communicate() - # combine stdout and stderr, filter None out - out = ''.join(filter(None, [sout, serr])) - except OSError, e: - if e.errno == 2: - # [Errno 2] No such file or directory - msger.error('Cannot run command: %s, lost dependency?' % cmd) - else: - raise # relay - finally: - if catch != 3: - os.close(dev_null) - - return (p.returncode, out) - -def show(cmdln_or_args): - # show all the message using msger.verbose - - rc, out = runtool(cmdln_or_args, catch=3) - - if isinstance(cmdln_or_args, list): - cmd = ' '.join(cmdln_or_args) - else: - cmd = cmdln_or_args - - msg = 'running command: "%s"' % cmd - if out: out = out.strip() - if out: - msg += ', with output::' - msg += '\n +----------------' - for line in out.splitlines(): - msg += '\n | %s' % line - msg += '\n +----------------' - - msger.verbose(msg) - return rc - -def outs(cmdln_or_args, catch=1): - # get the outputs of tools - return runtool(cmdln_or_args, catch)[1].strip() - -def quiet(cmdln_or_args): - return runtool(cmdln_or_args, catch=0)[0] |