Add prebuild mic py2 bin to mic 31/302431/3
authorwangbiao <biao716.wang@samsung.com>
Wed, 6 Dec 2023 10:02:11 +0000 (19:02 +0900)
committerwangbiao <biao716.wang@samsung.com>
Wed, 6 Dec 2023 10:15:17 +0000 (19:15 +0900)
Change-Id: I572a1e1154bcc50d0037eb2b3b1013fbb1ce1fcd
Signed-off-by: wangbiao <biao716.wang@samsung.com>
127 files changed:
debian/rules
mic_py2/etc/mic/mic.conf [new file with mode: 0644]
mic_py2/usr/bin/mic [new file with mode: 0755]
mic_py2/usr/lib/mic/plugins/backend/yumpkgmgr.py [new file with mode: 0644]
mic_py2/usr/lib/mic/plugins/backend/zypppkgmgr.py [new file with mode: 0644]
mic_py2/usr/lib/mic/plugins/imager/fs_plugin.py [new file with mode: 0755]
mic_py2/usr/lib/mic/plugins/imager/loop_plugin.py [new file with mode: 0755]
mic_py2/usr/lib/mic/plugins/imager/qcow_plugin.py [new file with mode: 0755]
mic_py2/usr/lib/mic/plugins/imager/raw_plugin.py [new file with mode: 0755]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/base.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/authconfig.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autopart.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autostep.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/bootloader.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/clearpart.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/device.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/deviceprobe.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/displaymode.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/dmraid.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/driverdisk.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/fcoe.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firewall.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firstboot.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/group.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/ignoredisk.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/interactive.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsi.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsiname.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/key.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/keyboard.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lang.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/langsupport.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lilocheck.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logging.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logvol.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mediacheck.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/method.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/monitor.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mouse.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/multipath.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/network.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/partition.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/raid.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/reboot.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/repo.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rescue.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rootpw.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/selinux.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/services.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/skipx.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/sshpw.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/timezone.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/updates.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/upgrade.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/user.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/vnc.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/volgroup.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/xconfig.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zerombr.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zfcp.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/constants.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/errors.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/control.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f10.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f11.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f12.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f13.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f14.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f15.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f16.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f7.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f8.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f9.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc3.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc4.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc5.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc6.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel3.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel4.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel5.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel6.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/ko.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/options.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/parser.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/sections.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/version.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/archive.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/bootstrap.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/chroot.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_chroot.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_create.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/conf.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/helpformat.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/baseimager.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/fs.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/loop.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/qcow.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/imager/raw.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/desktop.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/installerfw.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micboot.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micrepo.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/partition.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/msger.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/plugin.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/pluginbase.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/rt_util.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/__init__.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/errors.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/fs_related.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/gpt_parser.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/grabber.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/lock.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/misc.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/partitionedfs.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/proxy.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/rpmmisc.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/runner.py [new file with mode: 0644]
mic_py2/usr/lib/python2.7/dist-packages/mic/utils/safeurl.py [new file with mode: 0644]
packaging/mic.spec

index dd312e2dec386fe6d6c0629a8b712c80c07d3161..a1dc75adf60e9ea1d2c573f35296a997b714186c 100755 (executable)
@@ -15,7 +15,9 @@ override_dh_auto_install:
        install -m755 etc/bash_completion.d/mic.sh $(CURDIR)/debian/tmp/etc/bash_completion.d/
        install -m755 etc/zsh_completion.d/_mic $(CURDIR)/debian/tmp/etc/zsh_completion.d/_mic
        python3 setup.py install --root=$(CURDIR)/debian/tmp --prefix=/usr
-
+       # Installing mic py2 code
+       mkdir -p $(CURDIR)/debian/tmp/usr/lib/mic/mic_py2
+       cp -rp mic_py2/* $(CURDIR)/debian/tmp/usr/lib/mic/mic_py2
 override_dh_installchangelogs:
        dh_installchangelogs ChangeLog
 override_dh_auto_test:
diff --git a/mic_py2/etc/mic/mic.conf b/mic_py2/etc/mic/mic.conf
new file mode 100644 (file)
index 0000000..a544168
--- /dev/null
@@ -0,0 +1,36 @@
+[common]
+; general settings
+distro_name = Tizen
+
+plugin_dir = /usr/lib/mic/plugins
+
+[create]
+; settings for create subcommand
+tmpdir= /var/tmp/mic
+cachedir= /var/tmp/mic/cache
+outdir= ./mic-output
+runtime=bootstrap
+#use_mic_in_bootstrap = yes
+
+pkgmgr = auto
+
+# to set global proxy for repos
+#proxy = http://proxy.yourcompany.com:8080/
+#no_proxy = localhost,127.0.0.0/8,.yourcompany.com
+
+# prefix will be added in front of generated files
+#name_prefix = output
+
+# to skip all ssl verification for repos
+#ssl_verify = no
+
+[convert]
+; settings for convert subcommand
+
+[chroot]
+; settings for chroot subcommand
+
+[bootstrap]
+rootdir=/var/tmp/mic-bootstrap
+packages=mic-bootstrap-x86-arm
+
diff --git a/mic_py2/usr/bin/mic b/mic_py2/usr/bin/mic
new file mode 100755 (executable)
index 0000000..e40d3da
--- /dev/null
@@ -0,0 +1,317 @@
+#! /usr/bin/python2
+
+#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.
+#
+# pylint: disable-msg=E0611, E1101, R0201
+# E0611: no name in module, some attributes are set during running, so ignore it
+# E1101: %s %r has no %r member, some attributes are set during running,
+#        so ignore it
+# R0201: Method could be a function
+
+"""
+ This mudule is entry for mic.
+ It defines a class named MicCmd inheriting Cmdln, and supplies interfaces like
+ 'create, chroot, convert' and also some parameters for command 'mic'.
+"""
+import os
+import signal
+import sys
+import errno
+
+from argparse import ArgumentParser, SUPPRESS
+
+from mic import msger, __version__ as VERSION
+from mic.utils import misc, errors
+from mic.conf import configmgr
+from mic.plugin import pluginmgr
+from mic.helpformat import MICHelpFormatter, subparser
+    
+
+@subparser
+def chroot_parser(parser):
+    """chroot into an image
+
+    Examples:
+        mic chroot platform.img
+        mic chroot platform.img ls
+    """
+    parser.add_argument('imagefile', help='Path of image file')
+    parser.add_argument('-s', '--saveto', action = 'store', dest = 'saveto', default = None,
+                        help = "Save the unpacked image to specified dir")
+    parser.add_argument('-c', '--cmd', dest = 'cmd', default = None,
+                        help = "command which will be executed in chroot environment")
+    parser.set_defaults(alias="ch")
+    return parser
+
+@subparser
+def create_parser(parser):
+    """create an image
+    Examples:
+      $ mic -d -v create auto handset_blackbay.ks
+      $ mic -d -v cr loop handset_blackbay.ks --logfile=mic.log
+    """
+
+    parent_parser = ArgumentParser(add_help=False)
+    parent_parser.add_argument('ksfile', help='Path of ksfile')
+    parent_parser.add_argument('--logfile', dest='logfile', default=None,
+                               help='Path of logfile')
+    parent_parser.add_argument('-c', '--config', dest='config', default=None,
+                               help='Specify config file for mic')
+    parent_parser.add_argument('-k', '--cachedir', action='store',
+                               dest='cachedir', default=None,
+                               help='Cache directory to store the downloaded')
+    parent_parser.add_argument('-o', '--outdir', action='store', dest='outdir',
+                               default=None, help='Output directory')
+    parent_parser.add_argument('-A', '--arch', dest='arch', default=None,
+                               help='Specify repo architecture')
+    parent_parser.add_argument('--release', dest='release', default=None, metavar='RID',
+                               help='Generate a release of RID with all necessary'
+                               ' files, when @BUILD_ID@ is contained in '
+                               'kickstart file, it will be replaced by RID')
+    parent_parser.add_argument("--record-pkgs", dest="record_pkgs", default=None,
+                               help='Record the info of installed packages, '
+                               'multiple values can be specified which '
+                               'joined by ",", valid values: "name", '
+                               '"content", "license", "vcs"')
+    parent_parser.add_argument('--pkgmgr', dest='pkgmgr', default=None,
+                               help='Specify backend package manager')
+    parent_parser.add_argument('--local-pkgs-path', dest='local_pkgs_path', default=None,
+                               help='Path for local pkgs(rpms) to be installed')
+    parent_parser.add_argument('--runtime', dest='runtime', default=None,
+                               help='Specify runtime mode, avaiable: bootstrap')
+    # --taring-to is alias to --pack-to
+    parent_parser.add_argument('--taring-to', dest='pack_to', default=None,
+                               help=SUPPRESS)
+    parent_parser.add_argument('--pack-to', dest='pack_to', default=None,
+                               help='Pack the images together into the specified'
+                                    ' achive, extension supported: .zip, .tar, '
+                                    '.tar.gz, .tar.bz2, etc. by default, .tar '
+                                    'will be used')
+    parent_parser.add_argument('--copy-kernel', action='store_true', dest='copy_kernel',
+                               help='Copy kernel files from image /boot directory'
+                                    ' to the image output directory.')
+    parent_parser.add_argument('--install-pkgs', action='store', dest='install_pkgs', default=None,
+                               help='Specify what type of packages to be installed,'
+                                    ' valid: source, debuginfo, debugsource')
+    parent_parser.add_argument('--check-pkgs', action='store', dest='check_pkgs', default=[],
+                               help='Check if given packages would be installed, '
+                                    'packages should be separated by comma')
+    parent_parser.add_argument('--tmpfs', action='store_true', dest='enabletmpfs',
+                               help='Setup tmpdir as tmpfs to accelerate, experimental'
+                                    ' feature, use it if you have more than 4G memory')
+    parent_parser.add_argument('--repourl', action='append', dest='repourl', default=[],
+                               help=SUPPRESS)
+    parent_parser.add_argument('-R', '--repo', action='append',
+                               dest='repo', default=[],
+                               help=SUPPRESS)
+    parent_parser.add_argument('--ignore-ksrepo', action='store_true',
+                               dest='ignore_ksrepo', default=False,
+                               help=SUPPRESS)
+    parent_parser.add_argument('--strict-mode', action='store_true',
+                               dest='strict_mode', default=False,
+                               help='Abort creation of image, if there are some errors'
+                                    ' during rpm installation. ')
+    parent_parser.add_argument('--use-mic-in-bootstrap', action='store_true',
+                               dest='use_mic_in_bootstrap', default=False,
+                               help='This option works in bootstrap runtime mode,'
+                                    ' Use mic in bootstrap to create image.'
+                                    ' By default, copy host mic to bootstrap and use it.')
+
+    parent_parser.add_argument('-d', '--debug', action='store_true',
+                               help='debug output')
+    parent_parser.add_argument('-v', '--verbose', action='store_true',
+                                help='verbose output')
+    parent_parser.add_argument('-i', '--interactive', action='store_true',
+                                dest='interactive', default=True,
+                               help='interactive output')
+    parent_parser.add_argument('--run_script', action='store', dest='run_script',
+                                                   default=None, help='Run script on local PC after image created')
+    parent_parser.add_argument('--tpk_install', action='store', dest='tpk_install',
+                                                                       default=None, help='Copy tpk file to /usr/apps/.preload-tpk')
+    parent_parser.add_argument('--rpm-debug', action='store_true', dest='rpm_debug', help='Set debug mode for rpm install')
+    parent_parser.add_argument('--skip-set-hosts', action='store_true', dest='skip_set_hosts', default=False, help='choose to skip set hosts by mic')
+    parent_parser.add_argument('--postscripts-maxruntime', dest='postscripts_maxruntime', default=120, help='max run time for post scripts')
+    parent_parser.add_argument('--block-recommends', action='store_true', dest='block_recommends', default=False, help='Do not install recommended packages')
+
+    parser.set_defaults(alias="cr")
+
+    subparsers  = parser.add_subparsers(title='Subcommands', dest='subcommand')
+    auto_parser = subparsers.add_parser('auto', parents=[parent_parser], help='auto detect image type from magic header')
+
+    fs_parser   = subparsers.add_parser('fs', parents=[parent_parser],
+                                        help='create fs image')
+    fs_parser.add_argument("--include-src", dest = "include_src",action = "store_true",
+                           default = False, help = "Generate a image with source rpms included")
+
+    loop_parser = subparsers.add_parser('loop', parents=[parent_parser], help='create loop image')
+
+    loop_parser.add_argument("--compress-disk-image", dest="compress_image",
+                             choices=("gz", "bz2"), default=None,
+                             help="Same with --compress-image")
+    # alias to compress-image for compatibility
+    loop_parser.add_argument("--compress-image", dest="compress_image",
+                             choices=("gz", "bz2"), default=None,
+                             help="Compress all loop images with 'gz' or 'bz2'")
+    loop_parser.add_argument("--shrink", action='store_true', default=False,
+                  help="Whether to shrink loop images to minimal size")
+                  
+    qcow_parser = subparsers.add_parser('qcow', parents=[parent_parser], help='create qcow image')
+
+    raw_parser = subparsers.add_parser('raw', parents=[parent_parser], help='create raw image')
+
+    raw_parser.add_argument("--compress-disk-image", dest="compress_image",
+                            choices=("gz", "bz2"), default=None,
+                            help="Same with --compress-image")
+    raw_parser.add_argument("--compress-image", dest="compress_image",
+                            choices=("gz", "bz2"), default = None,
+                            help="Compress all raw images before package")
+    raw_parser.add_argument("--generate-bmap", action="store_true", default = None,
+                            help="also generate the block map file")
+    raw_parser.add_argument("--fstab-entry", dest="fstab_entry", choices=("name", "uuid"), default="uuid",
+                            help="Set fstab entry, 'name' means using device names, "
+                                 "'uuid' means using filesystem uuid")
+    return parser
+
+def main(argv):
+    """Script entry point."""
+    
+    def print_version():
+        """log name, verion, hostname"""
+        
+        name = 'mic'
+        msger.raw("%s %s (%s)" % (name,
+                                  VERSION,
+                                  misc.get_hostname_distro_str()))
+                                  
+    def has_parameter(arg, arglist):
+        """
+        Helper function.
+        Check if argument requires parameter by analyzing
+        its action. Parameter is required only for 'store' and 'append' actions
+        """
+        if arg.startswith('-'):
+            for args in arglist:
+                if arg in (args['short'], args['long']):
+                    if args.get('action') in (None, 'store', 'append'):
+                        return True
+                    return False
+
+    def sigterm_handler(signal, frame):
+        raise errors.Abort('\nSIGTERM catched, program aborted.')
+
+    # Add SIGTERM handler for exit gracefully
+    signal.signal(signal.SIGTERM, sigterm_handler)
+
+    # Create top level parser
+    epilog = "Try 'mic SUBCOMMAND --help' for help on a specific subcommand."
+    description = "mic - the Image Creation tool"
+    parser = ArgumentParser(description=description, epilog=epilog,
+                            formatter_class=MICHelpFormatter)
+
+    # List of global arguments
+    # The main purpose of this structure is to contain arguments
+    # of add_argument. This is used to do aliasing properly
+    # (see code under the comment 'replace aliases with real commands')
+    global_args = [{'short': '-V', 'long': '--version', 'action': 'version',
+                    'version': '%(prog)s ' + VERSION},
+                   {'short': '-d', 'long': '--debug', 'action': 'store_true',
+                    'help': 'debug output'},
+                   {'short': '-v', 'long': '--verbose', 'action': 'store_true',
+                    'help': 'verbose output'},
+                   {'short': '-i', 'long': '--interactive', 'action': 'store_true',
+                    'dest': 'interactive', 'default': 'True', 'help': 'interactive output'}, 
+                   {'short': '', 'long': '--non-interactive', 'action': 'store_false',
+                    'dest': 'interactive', 'default': 'True', 'help': 'non-interactive output'}, 
+                  ]
+
+    for args in global_args:
+        parser_kwargs = {}
+        for key in ('action', 'help', 'version', 'default', 'dest'):
+            if key in args:
+                parser_kwargs[key] = args[key]
+        
+        if args['short'] is '':
+            parser.add_argument(args['long'], **parser_kwargs)
+        else:
+            parser.add_argument(args['short'], args['long'], **parser_kwargs)
+
+    # hacked by the request of cmdln lovers
+    parser.format_usage = parser.format_help
+
+    # Create parsers for subcommands
+    subparsers = parser.add_subparsers(title='subcommands')
+
+    # collect aliases
+    aliases = {}
+    for name, obj in globals().iteritems():
+        if name.endswith('_parser') and callable(obj):
+            aliases[obj(subparsers).get_default('alias')] = name.split('_')[0]
+
+    # replace aliases with real commands
+    for i, arg in enumerate(argv[1:]):
+        if not arg.startswith('-'):
+            # argv[i] is previous argument to arg
+            if not has_parameter(argv[i], global_args) and arg in aliases:
+                argv[i+1] = aliases[arg]
+                break
+
+    # Parse arguments
+    args = parser.parse_args(argv[1:])
+
+    if args.interactive:
+        msger.enable_interactive()
+    else:
+        msger.disable_interactive()
+
+    if args.verbose:
+        msger.set_loglevel('VERBOSE')
+
+    if args.debug:
+        try:
+            import rpm
+            rpm.setVerbosity(rpm.RPMLOG_DEBUG)
+        except ImportError:
+            pass
+
+        msger.set_loglevel('DEBUG')
+
+    print_version()
+
+    # Import target module and call 'main' from it
+    module = __import__("mic.%s" % args.module, fromlist=[args.module])
+    return module.main(parser, args, argv[1:])
+
+    
+if __name__ == "__main__":
+    try:
+        sys.exit(main(sys.argv))
+    except KeyboardInterrupt:
+        msger.error('\n^C catched, program aborted.')
+    except IOError as ioerr:
+        # catch 'no space left' exception, etc
+        if ioerr.errno == errno.ENOSPC:
+            msger.error('\nNo space left on device')
+        raise
+    except errors.Usage as usage:
+        msger.error(str(usage))
+    except errors.Abort as  msg:
+        msger.info(str(msg))
+    except errors.CreatorError as err:
+        if msger.get_loglevel() == 'DEBUG':
+            import traceback
+            msger.error(traceback.format_exc())
+        else:
+            msger.error(str(err))
diff --git a/mic_py2/usr/lib/mic/plugins/backend/yumpkgmgr.py b/mic_py2/usr/lib/mic/plugins/backend/yumpkgmgr.py
new file mode 100644 (file)
index 0000000..d63c592
--- /dev/null
@@ -0,0 +1,509 @@
+#!/usr/bin/python -tt
+#
+# Copyright (c) 2007 Red Hat  Inc.
+# 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 tempfile
+import glob
+from string import Template
+
+import rpmUtils
+import yum
+
+from mic import msger
+from mic.kickstart import ksparser
+from mic.utils import misc, rpmmisc
+from mic.utils.grabber import TextProgress
+from mic.utils.proxy import get_proxy_for
+from mic.utils.errors import CreatorError
+from mic.utils.safeurl import SafeURL
+
+
+YUMCONF_TEMP = """[main]
+installroot=$installroot
+cachedir=/var/cache/yum
+persistdir=/var/lib/yum
+plugins=0
+reposdir=
+failovermethod=priority
+http_caching=packages
+sslverify=1
+"""
+
+class MyYumRepository(yum.yumRepo.YumRepository):
+    def __init__(self, repoid, nocache):
+        super(MyYumRepository, self).__init__(repoid)
+        self.nocache = nocache
+
+    def __del__(self):
+        pass
+
+    def dirSetup(self):
+        super(MyYumRepository, self).dirSetup()
+        # relocate package dir
+        pkgdir = os.path.join(self.basecachedir, 'packages', self.id)
+        self.setAttribute('_dir_setup_pkgdir', pkgdir)
+        self._dirSetupMkdir_p(self.pkgdir)
+
+    def _getFile(self, url=None,
+                       relative=None,
+                       local=None,
+                       start=None,
+                       end=None,
+                       copy_local=None,
+                       checkfunc=None,
+                       text=None,
+                       reget='simple',
+                       cache=True,
+                       size=None):
+
+        m2c_connection = None
+        if not self.sslverify:
+            try:
+                import M2Crypto
+                m2c_connection = M2Crypto.SSL.Connection.clientPostConnectionCheck
+                M2Crypto.SSL.Connection.clientPostConnectionCheck = None
+            except ImportError as err:
+                raise CreatorError("%s, please try to install python-m2crypto" % str(err))
+
+        proxy = None
+        if url:
+            proxy = get_proxy_for(url)
+        else:
+            proxy = get_proxy_for(self.urls[0])
+
+        if proxy:
+            self.proxy = str(proxy)
+
+        size = int(size) if size else None
+        rvalue = super(MyYumRepository, self)._getFile(url,
+                                                       relative,
+                                                       local,
+                                                       start,
+                                                       end,
+                                                       copy_local,
+                                                       checkfunc,
+                                                       text,
+                                                       reget,
+                                                       cache,
+                                                       size)
+
+        if m2c_connection and \
+           not M2Crypto.SSL.Connection.clientPostConnectionCheck:
+            M2Crypto.SSL.Connection.clientPostConnectionCheck = m2c_connection
+
+        return rvalue
+
+from mic.pluginbase import BackendPlugin
+class Yum(BackendPlugin, yum.YumBase):
+    name = 'yum'
+
+    def __init__(self, target_arch, instroot, cachedir, strict_mode = False):
+        yum.YumBase.__init__(self)
+
+        self.cachedir = cachedir
+        self.instroot  = instroot
+        self.target_arch = target_arch
+        self.strict_mode = strict_mode
+
+        if self.target_arch:
+            if not rpmUtils.arch.arches.has_key(self.target_arch):
+                rpmUtils.arch.arches["armv7hl"] = "noarch"
+                rpmUtils.arch.arches["armv7tnhl"] = "armv7nhl"
+                rpmUtils.arch.arches["armv7tnhl"] = "armv7thl"
+                rpmUtils.arch.arches["armv7thl"] = "armv7hl"
+                rpmUtils.arch.arches["armv7nhl"] = "armv7hl"
+            self.arch.setup_arch(self.target_arch)
+
+        self.__pkgs_license = {}
+        self.__pkgs_content = {}
+        self.__pkgs_vcsinfo = {}
+        self.check_pkgs = []
+
+        self.install_debuginfo = False
+
+    def doFileLogSetup(self, uid, logfile):
+        # don't do the file log for the livecd as it can lead to open fds
+        # being left and an inability to clean up after ourself
+        pass
+
+    def close(self):
+        try:
+            os.unlink(self.confpath)
+            os.unlink(self.conf.installroot + "/yum.conf")
+        except:
+            pass
+
+        if self.ts:
+            self.ts.close()
+        self._delRepos()
+        self._delSacks()
+        yum.YumBase.close(self)
+        self.closeRpmDB()
+
+    def __del__(self):
+        pass
+
+    def _writeConf(self, confpath, installroot):
+        conf = Template(YUMCONF_TEMP).safe_substitute(installroot=installroot)
+
+        f = file(confpath, "w+")
+        f.write(conf)
+        f.close()
+
+        os.chmod(confpath, 0o644)
+
+    def _cleanupRpmdbLocks(self, installroot):
+        # cleans up temporary files left by bdb so that differing
+        # versions of rpm don't cause problems
+        for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
+            os.unlink(f)
+
+    def setup(self):
+        # create yum.conf
+        (fn, self.confpath) = tempfile.mkstemp(dir=self.cachedir,
+                                               prefix='yum.conf-')
+        os.close(fn)
+        self._writeConf(self.confpath, self.instroot)
+        self._cleanupRpmdbLocks(self.instroot)
+        # do setup
+        self.doConfigSetup(fn = self.confpath, root = self.instroot)
+        self.conf.cache = 0
+        self.doTsSetup()
+        self.doRpmDBSetup()
+        self.doRepoSetup()
+        self.doSackSetup()
+
+    def preInstall(self, pkg):
+        # FIXME: handle pre-install package
+        return None
+
+    def checkPackage(self, pkg):
+        self.check_pkgs.append(pkg)
+
+    def selectPackage(self, pkg):
+        """Select a given package.
+        Can be specified with name.arch or name*
+        """
+
+        try:
+            self.install(pattern = pkg)
+            return None
+        except yum.Errors.InstallError:
+            return "No package(s) available to install"
+        except yum.Errors.RepoError as e:
+            raise CreatorError("Unable to download from repo : %s" % (e,))
+        except yum.Errors.YumBaseError as e:
+            raise CreatorError("Unable to install: %s" % (e,))
+
+    def deselectPackage(self, pkg):
+        """Deselect package.  Can be specified as name.arch or name*
+        """
+
+        sp = pkg.rsplit(".", 2)
+        txmbrs = []
+        if len(sp) == 2:
+            txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
+
+        if len(txmbrs) == 0:
+            exact, match, unmatch = yum.packages.parsePackages(
+                                            self.pkgSack.returnPackages(),
+                                            [pkg],
+                                            casematch=1)
+            for p in exact + match:
+                txmbrs.append(p)
+
+        if len(txmbrs) > 0:
+            for x in txmbrs:
+                self.tsInfo.remove(x.pkgtup)
+                # we also need to remove from the conditionals
+                # dict so that things don't get pulled back in as a result
+                # of them.  yes, this is ugly.  conditionals should die.
+                for req, pkgs in self.tsInfo.conditionals.iteritems():
+                    if x in pkgs:
+                        pkgs.remove(x)
+                        self.tsInfo.conditionals[req] = pkgs
+        else:
+            msger.warning("No such package %s to remove" %(pkg,))
+
+    def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
+        try:
+            yum.YumBase.selectGroup(self, grp)
+            if include == ksparser.GROUP_REQUIRED:
+                for p in grp.default_packages.keys():
+                    self.deselectPackage(p)
+
+            elif include == ksparser.GROUP_ALL:
+                for p in grp.optional_packages.keys():
+                    self.selectPackage(p)
+
+            return None
+        except (yum.Errors.InstallError, yum.Errors.GroupsError) as e:
+            return e
+        except yum.Errors.RepoError as e:
+            raise CreatorError("Unable to download from repo : %s" % (e,))
+        except yum.Errors.YumBaseError as e:
+            raise CreatorError("Unable to install: %s" % (e,))
+
+    def addRepository(self, name, url = None, mirrorlist = None, proxy = None,
+                      proxy_username = None, proxy_password = None,
+                      inc = None, exc = None, ssl_verify=True, nocache=False,
+                      cost = None, priority=None):
+        # TODO: Handle priority attribute for repos
+        def _varSubstitute(option):
+            # takes a variable and substitutes like yum configs do
+            option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
+            option = option.replace("$arch", rpmUtils.arch.getCanonArch())
+            return option
+        repo = MyYumRepository(name, nocache)
+
+        # Set proxy
+        repo.proxy = proxy
+        repo.proxy_username = proxy_username
+        repo.proxy_password = proxy_password
+
+        if url:
+            repo.baseurl.append(_varSubstitute(url.full))
+
+        if mirrorlist:
+            repo.mirrorlist = _varSubstitute(mirrorlist)
+
+        conf = yum.config.RepoConf()
+        for k, v in conf.iteritems():
+            if v or not hasattr(repo, k):
+                repo.setAttribute(k, v)
+
+        repo.sslverify = ssl_verify
+
+        repo.basecachedir = self.cachedir
+        repo.base_persistdir = self.conf.persistdir
+        repo.failovermethod = "priority"
+        repo.metadata_expire = 0
+        # Enable gpg check for verifying corrupt packages
+        repo.gpgcheck = 1
+        repo.enable()
+        repo.setup(0)
+        self.repos.add(repo)
+        if cost:
+            repo.cost = cost
+
+        msger.verbose('repo: %s was added' % name)
+        return repo
+
+    def installLocal(self, pkg, po=None, updateonly=False):
+        ts = rpmUtils.transaction.initReadOnlyTransaction()
+        try:
+            hdr = rpmUtils.miscutils.hdrFromPackage(ts, pkg)
+        except rpmUtils.RpmUtilsError as e:
+            raise yum.Errors.MiscError \
+                  ('Could not open local rpm file: %s: %s' % (pkg, e))
+
+        self.deselectPackage(hdr['name'])
+        yum.YumBase.installLocal(self, pkg, po, updateonly)
+
+    def installHasFile(self, file):
+        provides_pkg = self.whatProvides(file, None, None)
+        dlpkgs = map(
+                    lambda x: x.po,
+                    filter(
+                        lambda txmbr: txmbr.ts_state in ("i", "u"),
+                        self.tsInfo.getMembers()))
+
+        for p in dlpkgs:
+            for q in provides_pkg:
+                if (p == q):
+                    return True
+
+        return False
+
+    def runInstall(self, checksize = 0):
+        os.environ["HOME"] = "/"
+        os.environ["LD_PRELOAD"] = ""
+        try:
+            (res, resmsg) = self.buildTransaction()
+        except yum.Errors.RepoError as e:
+            raise CreatorError("Unable to download from repo : %s" %(e,))
+
+        if res != 2:
+            raise CreatorError("Failed to build transaction : %s" \
+                               % str.join("\n", resmsg))
+
+        dlpkgs = map(
+                    lambda x: x.po,
+                    filter(
+                        lambda txmbr: txmbr.ts_state in ("i", "u"),
+                        self.tsInfo.getMembers()))
+
+        # record all pkg and the content
+        for pkg in dlpkgs:
+            pkg_long_name = misc.RPM_FMT % {
+                                'name': pkg.name,
+                                'arch': pkg.arch,
+                                'version': pkg.version,
+                                'release': pkg.release
+                            }
+            self.__pkgs_content[pkg_long_name] = pkg.files
+            license = pkg.license
+            if license in self.__pkgs_license.keys():
+                self.__pkgs_license[license].append(pkg_long_name)
+            else:
+                self.__pkgs_license[license] = [pkg_long_name]
+
+            if pkg.name in self.check_pkgs:
+                self.check_pkgs.remove(pkg.name)
+
+        if self.check_pkgs:
+            raise CreatorError('Packages absent in image: %s' % ','.join(self.check_pkgs))
+
+        total_count = len(dlpkgs)
+        cached_count = 0
+        download_total_size = sum(map(lambda x: int(x.packagesize), dlpkgs))
+
+        msger.info("\nChecking packages cached ...")
+        for po in dlpkgs:
+            local = po.localPkg()
+            repo = filter(lambda r: r.id == po.repoid, self.repos.listEnabled())[0]
+            if repo.nocache and os.path.exists(local):
+                os.unlink(local)
+            if not os.path.exists(local):
+                continue
+            if not self.verifyPkg(local, po, False):
+                msger.warning("Package %s is damaged: %s" \
+                              % (os.path.basename(local), local))
+            else:
+                download_total_size -= int(po.packagesize)
+                cached_count += 1
+
+        cache_avail_size = misc.get_filesystem_avail(self.cachedir)
+        if cache_avail_size < download_total_size:
+            raise CreatorError("No enough space used for downloading.")
+
+        # record the total size of installed pkgs
+        pkgs_total_size = 0
+        for x in dlpkgs:
+            if hasattr(x, 'installedsize'):
+                pkgs_total_size += int(x.installedsize)
+            else:
+                pkgs_total_size += int(x.size)
+
+        # check needed size before actually download and install
+        if checksize and pkgs_total_size > checksize:
+            raise CreatorError("No enough space used for installing, "
+                               "please resize partition size in ks file")
+
+        msger.info("Packages: %d Total, %d Cached, %d Missed" \
+                   % (total_count, cached_count, total_count - cached_count))
+
+        try:
+            repos = self.repos.listEnabled()
+            for repo in repos:
+                repo.setCallback(TextProgress(total_count - cached_count))
+
+            self.downloadPkgs(dlpkgs)
+            # FIXME: sigcheck?
+
+            self.initActionTs()
+            self.populateTs(keepold=0)
+
+            deps = self.ts.check()
+            if len(deps) != 0:
+                # This isn't fatal, Ubuntu has this issue but it is ok.
+                msger.debug(deps)
+                msger.warning("Dependency check failed!")
+
+            rc = self.ts.order()
+            if rc != 0:
+                raise CreatorError("ordering packages for installation failed")
+
+            # FIXME: callback should be refactored a little in yum
+            cb = rpmmisc.RPMInstallCallback(self.ts)
+            cb.tsInfo = self.tsInfo
+            cb.filelog = False
+
+            msger.warning('\nCaution, do NOT interrupt the installation, '
+                          'else mic cannot finish the cleanup.')
+
+            installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
+            msger.enable_logstderr(installlogfile)
+            transactionResult = self.runTransaction(cb)
+            if transactionResult.return_code != 0 and self.strict_mode:
+                raise CreatorError("mic failes to install some packages")
+            self._cleanupRpmdbLocks(self.conf.installroot)
+
+        except rpmUtils.RpmUtilsError as e:
+            raise CreatorError("mic does NOT support delta rpm: %s" % e)
+        except yum.Errors.RepoError as e:
+            raise CreatorError("Unable to download from repo : %s" % e)
+        except yum.Errors.YumBaseError as e:
+            raise CreatorError("Unable to install: %s" % e)
+        finally:
+            msger.disable_logstderr()
+
+    def getVcsInfo(self):
+        if self.__pkgs_vcsinfo:
+            return self.__pkgs_vcsinfo
+        if not self.ts:
+            self.__initialize_transaction()
+        mi = self.ts.dbMatch()
+        for hdr in mi:
+            lname = misc.RPM_FMT % {
+                        'name': hdr['name'],
+                        'arch': hdr['arch'],
+                        'version': hdr['version'],
+                        'release': hdr['release']
+                    }
+            try:
+                self.__pkgs_vcsinfo[lname] = hdr['VCS']
+            except ValueError as KeyError:
+                self.__pkgs_vcsinfo[lname] = None
+
+        return self.__pkgs_vcsinfo
+
+    def getAllContent(self):
+        return self.__pkgs_content
+
+    def getPkgsLicense(self):
+        return self.__pkgs_license
+
+    def getFilelist(self, pkgname):
+        if not pkgname:
+            return None
+
+        pkg = filter(lambda txmbr: txmbr.po.name == pkgname, self.tsInfo.getMembers())
+        if not pkg:
+            return None
+        return pkg[0].po.filelist
+
+    def package_url(self, pkgname):
+        pkgs = self.pkgSack.searchNevra(name=pkgname)
+        if pkgs:
+            pkg = pkgs[0]
+
+            repo = pkg.repo
+            url = SafeURL(repo.baseurl[0]).join(pkg.remote_path)
+
+            proxy = repo.proxy
+            if not proxy:
+                proxy = get_proxy_for(url)
+            if proxy:
+                proxies = {str(url.split(':')[0]): str(proxy)}
+            else:
+                proxies = None
+
+            return (url, proxies)
+
+        return (None, None)
diff --git a/mic_py2/usr/lib/mic/plugins/backend/zypppkgmgr.py b/mic_py2/usr/lib/mic/plugins/backend/zypppkgmgr.py
new file mode 100644 (file)
index 0000000..950c1af
--- /dev/null
@@ -0,0 +1,1034 @@
+#!/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 shutil
+import urlparse
+import rpm
+import glob
+
+import zypp #pylint: disable=import-error
+if not hasattr(zypp, 'PoolQuery') or \
+   not hasattr(zypp.RepoManager, 'loadSolvFile'):
+    raise ImportError("python-zypp in host system cannot support PoolQuery or "
+                      "loadSolvFile interface, please update it to enhanced "
+                      "version which can be found in download.tizen.org/tools")
+
+from mic import msger
+from mic.kickstart import ksparser
+from mic.utils import misc, rpmmisc, runner, fs_related
+from mic.utils.grabber import myurlgrab, TextProgress
+from mic.utils.proxy import get_proxy_for
+from mic.utils.errors import CreatorError, RepoError, RpmError
+from mic.conf import configmgr
+
+class RepositoryStub:
+    def __init__(self):
+        self.name = None
+        self.baseurl = []
+        self.mirrorlist = None
+        self.proxy = None
+        self.proxy_username = None
+        self.proxy_password = None
+        self.nocache = False
+
+        self.enabled = True
+        self.autorefresh = True
+        self.keeppackages = True
+        self.priority = None
+
+from mic.pluginbase import BackendPlugin
+class Zypp(BackendPlugin):
+    name = 'zypp'
+
+    def __init__(self, target_arch, instroot, cachedir, strict_mode = False):
+        self.cachedir = cachedir
+        self.instroot  = instroot
+        self.target_arch = target_arch
+        self.strict_mode = strict_mode
+
+        self.__pkgs_license = {}
+        self.__pkgs_content = {}
+        self.__pkgs_vcsinfo = {}
+        self.repos = []
+        self.to_deselect = []
+        self.localpkgs = {}
+        self.repo_manager = None
+        self.repo_manager_options = None
+        self.Z = None
+        self.ts = None
+        self.ts_pre = None
+        self.pkgs_bak = []
+        self.incpkgs = {}
+        self.excpkgs = {}
+        self.pre_pkgs = []
+        self.check_pkgs = []
+        self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE,
+                                 rpm.RPMPROB_FILTER_REPLACEPKG ]
+
+        self.has_prov_query = True
+        self.install_debuginfo = False
+        # this can't be changed, it is used by zypp
+        self.tmp_file_path = '/var/tmp'
+
+    def doFileLogSetup(self, uid, logfile):
+        # don't do the file log for the livecd as it can lead to open fds
+        # being left and an inability to clean up after ourself
+        pass
+
+    def closeRpmDB(self):
+        pass
+
+    def close(self):
+        if self.ts:
+            self.ts.closeDB()
+            self.ts = None
+
+        if self.ts_pre:
+            self.ts_pre.closeDB()
+            self.ts_pre = None
+
+        self.pkgs_bak = []
+
+        self.closeRpmDB()
+
+    def __del__(self):
+        self.close()
+
+    def _cleanupRpmdbLocks(self, installroot):
+        # cleans up temporary files left by bdb so that differing
+        # versions of rpm don't cause problems
+        for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
+            os.unlink(f)
+
+    def _cleanupZyppJunk(self, installroot):
+        try:
+            shutil.rmtree(os.path.join(installroot, '.zypp'))
+        except:
+            pass
+
+    def setup(self):
+        self._cleanupRpmdbLocks(self.instroot)
+        # '/var/tmp' is used by zypp to build cache, so make sure
+        # if it exists
+        if not os.path.exists(self.tmp_file_path ):
+            os.makedirs(self.tmp_file_path)
+
+    def whatObsolete(self, pkg):
+        query = zypp.PoolQuery()
+        query.addKind(zypp.ResKind.package)
+        query.addDependency(zypp.SolvAttr.obsoletes, pkg.name(), pkg.edition())
+        query.setMatchExact()
+        for pi in query.queryResults(self.Z.pool()):
+            return pi
+        return None
+
+    def _zyppQueryPackage(self, pkg):
+        query = zypp.PoolQuery()
+        query.addKind(zypp.ResKind.package)
+        query.addAttribute(zypp.SolvAttr.name, pkg)
+        query.setMatchExact()
+        for pi in query.queryResults(self.Z.pool()):
+            return pi
+        return None
+
+    def _splitPkgString(self, pkg):
+        sp = pkg.rsplit(".", 1)
+        name = sp[0]
+        arch = None
+        if len(sp) == 2:
+            arch = sp[1]
+            sysarch = zypp.Arch(self.target_arch)
+            if not zypp.Arch(arch).compatible_with (sysarch):
+                arch = None
+                name = ".".join(sp)
+        return name, arch
+
+    def selectPackage(self, pkg):
+        """Select a given package or package pattern, can be specified
+        with name.arch or name* or *name
+        """
+
+        if not self.Z:
+            self.__initialize_zypp()
+
+        def markPoolItem(obs, pi):
+            if obs == None:
+                pi.status().setToBeInstalled (zypp.ResStatus.USER)
+            else:
+                obs.status().setToBeInstalled (zypp.ResStatus.USER)
+
+        def cmpEVR(p1, p2):
+            # compare criterion: arch compatibility first, then repo
+            # priority, and version last
+            a1 = p1.arch()
+            a2 = p2.arch()
+            if str(a1) != str(a2):
+                if a1.compatible_with(a2):
+                    return -1
+                else:
+                    return 1
+            # Priority of a repository is an integer value between 0 (the
+            # highest priority) and 99 (the lowest priority)
+            pr1 = int(p1.repoInfo().priority())
+            pr2 = int(p2.repoInfo().priority())
+            if pr1 > pr2:
+                return -1
+            elif pr1 < pr2:
+                return 1
+
+            ed1 = p1.edition()
+            ed2 = p2.edition()
+            (e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
+            (e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
+            return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
+
+        found = False
+        startx = pkg.startswith("*")
+        endx = pkg.endswith("*")
+        ispattern = startx or endx
+        name, arch = self._splitPkgString(pkg)
+
+        q = zypp.PoolQuery()
+        q.addKind(zypp.ResKind.package)
+
+        if ispattern:
+            if startx and not endx:
+                pattern = '%s$' % (pkg[1:])
+            if endx and not startx:
+                pattern = '^%s' % (pkg[0:-1])
+            if endx and startx:
+                pattern = '%s' % (pkg[1:-1])
+            q.setMatchRegex()
+            q.addAttribute(zypp.SolvAttr.name, pattern)
+
+        elif arch:
+            q.setMatchExact()
+            q.addAttribute(zypp.SolvAttr.name, name)
+
+        else:
+            q.setMatchExact()
+            q.addAttribute(zypp.SolvAttr.name, pkg)
+
+        for pitem in sorted(
+                        q.queryResults(self.Z.pool()),
+                        cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
+                        reverse=True):
+            item = zypp.asKindPackage(pitem)
+            if item.name() in self.excpkgs.keys() and \
+               self.excpkgs[item.name()] == item.repoInfo().name():
+                continue
+            if item.name() in self.incpkgs.keys() and \
+               self.incpkgs[item.name()] != item.repoInfo().name():
+                continue
+
+            found = True
+            obspkg = self.whatObsolete(item)
+            if arch:
+                if arch == str(item.arch()):
+                    pitem.status().setToBeInstalled (zypp.ResStatus.USER)
+            else:
+                markPoolItem(obspkg, pitem)
+            if not ispattern:
+                break
+
+        # Can't match using package name, then search from packge
+        # provides infomation
+        if found == False and not ispattern:
+            q.addAttribute(zypp.SolvAttr.provides, pkg)
+            q.addAttribute(zypp.SolvAttr.name,'')
+
+            for pitem in sorted(
+                            q.queryResults(self.Z.pool()),
+                            cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
+                            reverse=True):
+                item = zypp.asKindPackage(pitem)
+                if item.name() in self.excpkgs.keys() and \
+                   self.excpkgs[item.name()] == item.repoInfo().name():
+                    continue
+                if item.name() in self.incpkgs.keys() and \
+                   self.incpkgs[item.name()] != item.repoInfo().name():
+                    continue
+
+                found = True
+                obspkg = self.whatObsolete(item)
+                markPoolItem(obspkg, pitem)
+                break
+
+        if found:
+            return None
+        else:
+            raise CreatorError("Unable to find package: %s" % (pkg,))
+
+    def inDeselectPackages(self, pitem):
+        """check if specified pacakges are in the list of inDeselectPackages
+        """
+        item = zypp.asKindPackage(pitem)
+        name = item.name()
+        for pkg in self.to_deselect:
+            startx = pkg.startswith("*")
+            endx = pkg.endswith("*")
+            ispattern = startx or endx
+            pkgname, pkgarch = self._splitPkgString(pkg)
+            if not ispattern:
+                if pkgarch:
+                    if name == pkgname and str(item.arch()) == pkgarch:
+                        return True
+                else:
+                    if name == pkgname:
+                        return True
+            else:
+                if startx and name.endswith(pkg[1:]):
+                    return True
+                if endx and name.startswith(pkg[:-1]):
+                    return True
+
+        return False
+
+    def deselectPackage(self, pkg):
+        """collect packages should not be installed"""
+        self.to_deselect.append(pkg)
+
+    def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
+        def compareGroup(pitem):
+            item = zypp.asKindPattern(pitem)
+            return item.repoInfo().priority()
+        if not self.Z:
+            self.__initialize_zypp()
+        found = False
+        q = zypp.PoolQuery()
+        q.addKind(zypp.ResKind.pattern)
+        for pitem in sorted(q.queryResults(self.Z.pool()), key=compareGroup):
+            item = zypp.asKindPattern(pitem)
+            summary = "%s" % item.summary()
+            name = "%s" % item.name()
+            if name == grp or summary == grp:
+                found = True
+                pitem.status().setToBeInstalled (zypp.ResStatus.USER)
+                break
+
+        if found:
+            if include == ksparser.GROUP_REQUIRED:
+                map(
+                    lambda p: self.deselectPackage(p),
+                    grp.default_packages.keys())
+
+            return None
+        else:
+            raise CreatorError("Unable to find pattern: %s" % (grp,))
+
+    def addRepository(self, name,
+                            url = None,
+                            mirrorlist = None,
+                            proxy = None,
+                            proxy_username = None,
+                            proxy_password = None,
+                            inc = None,
+                            exc = None,
+                            ssl_verify = True,
+                            nocache = False,
+                            cost=None,
+                            priority=None):
+        # TODO: Handle cost attribute for repos
+
+        if not self.repo_manager:
+            self.__initialize_repo_manager()
+
+        if not proxy and url:
+            proxy = get_proxy_for(url)
+
+        repo = RepositoryStub()
+        repo.name = name
+        repo.id = name
+        repo.proxy = proxy
+        repo.proxy_username = proxy_username
+        repo.proxy_password = proxy_password
+        repo.ssl_verify = ssl_verify
+        repo.nocache = nocache
+        repo.baseurl.append(url)
+        if inc:
+            for pkg in inc:
+                self.incpkgs[pkg] = name
+        if exc:
+            for pkg in exc:
+                self.excpkgs[pkg] = name
+
+        if mirrorlist:
+            repo.mirrorlist = mirrorlist
+
+        # Enable gpg check for verifying corrupt packages
+        repo.gpgcheck = 1
+        if priority is not None:
+            # priority 0 has issue in RepoInfo.setPriority
+            repo.priority = priority + 1
+
+        try:
+            repo_info = zypp.RepoInfo()
+            repo_info.setAlias(repo.name)
+            repo_info.setName(repo.name)
+            repo_info.setEnabled(repo.enabled)
+            repo_info.setAutorefresh(repo.autorefresh)
+            repo_info.setKeepPackages(repo.keeppackages)
+            baseurl = zypp.Url(repo.baseurl[0].full)
+            if not ssl_verify:
+                baseurl.setQueryParam("ssl_verify", "no")
+            if proxy:
+                host = urlparse.urlparse(proxy)[1]
+                # scheme, host, path, parm, query, frag = urlparse.urlparse(proxy)
+
+                proxyinfo = host.rsplit(":", 1)
+                host = proxyinfo[0]
+
+                port = "80"
+                if len(proxyinfo) > 1:
+                    port = proxyinfo[1]
+
+                if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2:
+                    host = proxy.rsplit(':', 1)[0]
+                    port = proxy.rsplit(':', 1)[1]
+
+                # parse user/pass from proxy host
+                proxyinfo = host.rsplit("@", 1)
+                if len(proxyinfo) == 2:
+                    host = proxyinfo[1]
+                    # Known Issue: If password contains ":", which should be
+                    # quoted, for example, use '123%3Aabc' instead of 123:abc
+                    userpassinfo = proxyinfo[0].rsplit(":", 1)
+                    if len(userpassinfo) == 2:
+                        proxy_username = userpassinfo[0]
+                        proxy_password = userpassinfo[1]
+                    elif len(userpassinfo) == 1:
+                        proxy_username = userpassinfo[0]
+
+                baseurl.setQueryParam ("proxy", host)
+                baseurl.setQueryParam ("proxyport", port)
+                if proxy_username:
+                    baseurl.setQueryParam ("proxyuser", proxy_username)
+                if proxy_password:
+                    baseurl.setQueryParam ("proxypass", proxy_password)
+            else:
+                baseurl.setQueryParam ("proxy", "_none_")
+
+            self.repos.append(repo)
+
+            repo_info.addBaseUrl(baseurl)
+
+            if repo.priority is not None:
+                repo_info.setPriority(repo.priority)
+
+            # this hack is used to change zypp credential file location
+            # the default one is $HOME/.zypp, which cause conflicts when
+            # installing some basic packages, and the location doesn't
+            # have any interface actually, so use a tricky way anyway
+            homedir = None
+            if 'HOME' in os.environ:
+                homedir = os.environ['HOME']
+                os.environ['HOME'] = '/'
+            else:
+                os.environ['HOME'] = '/'
+
+            self.repo_manager.addRepository(repo_info)
+
+            # save back the $HOME env
+            if homedir:
+                os.environ['HOME'] = homedir
+            else:
+                del os.environ['HOME']
+
+            self.__build_repo_cache(name)
+
+        except RuntimeError as e:
+            raise CreatorError(str(e))
+
+        msger.verbose('repo: %s was added' % name)
+        return repo
+
+    def installHasFile(self, file):
+        return False
+
+    def preInstall(self, pkg):
+        self.pre_pkgs.append(pkg)
+
+    def checkPackage(self, pkg):
+        self.check_pkgs.append(pkg)
+
+    def _get_local_packages(self):
+        """Return a list of rpm path to be local installed.
+        This is the hook where subclasses may specify a set of rpms which
+        it requires to be installed locally.
+        This returns an empty list by default.
+        Note, subclasses should usually chain up to the base class
+        implementation of this hook.
+        """
+        cropts = configmgr.create
+        if cropts['local_pkgs_path']:
+            if os.path.isdir(cropts['local_pkgs_path']):
+                return glob.glob(
+                        os.path.join(cropts['local_pkgs_path'], '*.rpm'))
+            elif os.path.splitext(cropts['local_pkgs_path'])[-1] == '.rpm':
+                return [cropts['local_pkgs_path']]
+        return []
+    def __localinst_packages(self):
+        for rpm_path in self._get_local_packages():
+            self.installLocal(rpm_path)
+    def runInstall(self, checksize = 0):
+        os.environ["HOME"] = "/"
+        os.environ["LD_PRELOAD"] = ""
+        self.buildTransaction()
+        self.__localinst_packages()
+
+        todo = zypp.GetResolvablesToInsDel(self.Z.pool())
+        installed_pkgs = todo._toInstall
+        dlpkgs = []
+
+        for pitem in installed_pkgs:
+            if not zypp.isKindPattern(pitem) and \
+              not self.inDeselectPackages(pitem):
+                item = zypp.asKindPackage(pitem)
+                dlpkgs.append(item)
+
+                if item.name() in self.check_pkgs:
+                    self.check_pkgs.remove(item.name())
+
+                if not self.install_debuginfo or str(item.arch()) == "noarch":
+                    continue
+
+                dipkg = self._zyppQueryPackage("%s-debuginfo" % item.name())
+                if dipkg:
+                    ditem = zypp.asKindPackage(dipkg)
+                    dlpkgs.append(ditem)
+                else:
+                    msger.warning("No debuginfo rpm found for: %s" \
+                                  % item.name())
+
+        if self.check_pkgs:
+            raise CreatorError('Packages absent in image: %s' % ','.join(self.check_pkgs))
+
+        # record all pkg and the content
+        localpkgs = self.localpkgs.keys()
+        for pkg in dlpkgs:
+            license = ''
+            if pkg.name() in localpkgs:
+                hdr = rpmmisc.readRpmHeader(self.ts, self.localpkgs[pkg.name()])
+                pkg_long_name = misc.RPM_FMT % {
+                                    'name': hdr['name'],
+                                    'arch': hdr['arch'],
+                                    'version': hdr['version'],
+                                    'release': hdr['release']
+                                }
+                license = hdr['license']
+
+            else:
+                pkg_long_name = misc.RPM_FMT % {
+                                    'name': pkg.name(),
+                                    'arch': pkg.arch(),
+                                    'version': pkg.edition().version(),
+                                    'release': pkg.edition().release()
+                                }
+
+                license = pkg.license()
+
+            if license in self.__pkgs_license.keys():
+                self.__pkgs_license[license].append(pkg_long_name)
+            else:
+                self.__pkgs_license[license] = [pkg_long_name]
+
+        total_count = len(dlpkgs)
+        cached_count = 0
+        download_total_size = sum(map(lambda x: int(x.downloadSize()), dlpkgs))
+        localpkgs = self.localpkgs.keys()
+
+        msger.info("Checking packages cached ...")
+        for po in dlpkgs:
+            # Check if it is cached locally
+            if po.name() in localpkgs:
+                cached_count += 1
+            else:
+                local = self.getLocalPkgPath(po)
+                name = str(po.repoInfo().name())
+                try:
+                    repo = filter(lambda r: r.name == name, self.repos)[0]
+                except IndexError:
+                    repo = None
+                nocache = repo.nocache if repo else False
+
+                if os.path.exists(local):
+                    if nocache or self.checkPkg(local) !=0:
+                        os.unlink(local)
+                    else:
+                        download_total_size -= int(po.downloadSize())
+                        cached_count += 1
+        cache_avail_size = misc.get_filesystem_avail(self.cachedir)
+        if cache_avail_size < download_total_size:
+            raise CreatorError("No enough space used for downloading.")
+
+        # record the total size of installed pkgs
+        install_total_size = sum(map(lambda x: int(x.installSize()), dlpkgs))
+        # check needed size before actually download and install
+
+        # FIXME: for multiple partitions for loop type, check fails
+        #        skip the check temporarily
+        #if checksize and install_total_size > checksize:
+        #    raise CreatorError("No enough space used for installing, "
+        #                       "please resize partition size in ks file")
+
+        download_count =  total_count - cached_count
+        msger.info("Packages: %d Total, %d Cached, %d Missed" \
+                   % (total_count, cached_count, download_count))
+
+        try:
+            if download_count > 0:
+                msger.info("Downloading packages ...")
+            self.downloadPkgs(dlpkgs, download_count)
+        except CreatorError as e:
+            raise CreatorError("Package download failed: %s" %(e,))
+
+        try:
+            self.installPkgs(dlpkgs)
+        except (RepoError, RpmError):
+            raise
+        except Exception as e:
+            raise CreatorError("Package installation failed: %s" % (e,))
+
+    def getVcsInfo(self):
+        if self.__pkgs_vcsinfo:
+            return
+
+        if not self.ts:
+            self.__initialize_transaction()
+
+        mi = self.ts.dbMatch()
+        for hdr in mi:
+            lname = misc.RPM_FMT % {
+                        'name': hdr['name'],
+                        'arch': hdr['arch'],
+                        'version': hdr['version'],
+                        'release': hdr['release']
+                    }
+            try:
+                self.__pkgs_vcsinfo[lname] = hdr['VCS']
+            except ValueError:
+                # if rpm not support VCS, set to None
+                self.__pkgs_vcsinfo[lname] = None
+
+        return self.__pkgs_vcsinfo
+
+    def getAllContent(self):
+        if self.__pkgs_content:
+            return self.__pkgs_content
+
+        if not self.ts:
+            self.__initialize_transaction()
+
+        mi = self.ts.dbMatch()
+        for hdr in mi:
+            lname = misc.RPM_FMT % {
+                        'name': hdr['name'],
+                        'arch': hdr['arch'],
+                        'version': hdr['version'],
+                        'release': hdr['release']
+                    }
+            self.__pkgs_content[lname] = hdr['FILENAMES']
+
+        return self.__pkgs_content
+
+    def getPkgsLicense(self):
+        return self.__pkgs_license
+
+    def getFilelist(self, pkgname):
+        if not pkgname:
+            return None
+
+        if not self.ts:
+            self.__initialize_transaction()
+
+        mi = self.ts.dbMatch('name', pkgname)
+        for header in mi:
+            return header['FILENAMES']
+
+    def __initialize_repo_manager(self):
+        if self.repo_manager:
+            return
+
+        # Clean up repo metadata
+        shutil.rmtree(self.cachedir + "/etc", ignore_errors = True)
+        shutil.rmtree(self.cachedir + "/solv", ignore_errors = True)
+        shutil.rmtree(self.cachedir + "/raw", ignore_errors = True)
+
+        zypp.KeyRing.setDefaultAccept( zypp.KeyRing.ACCEPT_UNSIGNED_FILE
+                                     | zypp.KeyRing.ACCEPT_VERIFICATION_FAILED
+                                     | zypp.KeyRing.ACCEPT_UNKNOWNKEY
+                                     | zypp.KeyRing.TRUST_KEY_TEMPORARILY
+                                     )
+
+        self.repo_manager_options = \
+                zypp.RepoManagerOptions(zypp.Pathname(self.instroot))
+
+        self.repo_manager_options.knownReposPath = \
+                zypp.Pathname(self.cachedir + "/etc/zypp/repos.d")
+
+        self.repo_manager_options.repoCachePath = \
+                zypp.Pathname(self.cachedir)
+
+        self.repo_manager_options.repoRawCachePath = \
+                zypp.Pathname(self.cachedir + "/raw")
+
+        self.repo_manager_options.repoSolvCachePath = \
+                zypp.Pathname(self.cachedir + "/solv")
+
+        self.repo_manager_options.repoPackagesCachePath = \
+                zypp.Pathname(self.cachedir + "/packages")
+
+        self.repo_manager = zypp.RepoManager(self.repo_manager_options)
+
+    def __build_repo_cache(self, name):
+        repo = self.repo_manager.getRepositoryInfo(name)
+        if self.repo_manager.isCached(repo) or not repo.enabled():
+            return
+
+        msger.info('Refreshing repository: %s ...' % name)
+        self.repo_manager.buildCache(repo, zypp.RepoManager.BuildIfNeeded)
+
+    def __initialize_zypp(self):
+        if self.Z:
+            return
+
+        zconfig = zypp.ZConfig_instance()
+
+        # Set system architecture
+        if self.target_arch:
+            zconfig.setSystemArchitecture(zypp.Arch(self.target_arch))
+
+        msger.info("zypp architecture is <%s>" % zconfig.systemArchitecture())
+
+        # repoPackagesCachePath is corrected by this
+        self.repo_manager = zypp.RepoManager(self.repo_manager_options)
+        repos = self.repo_manager.knownRepositories()
+        for repo in repos:
+            if not repo.enabled():
+                continue
+            self.repo_manager.loadFromCache(repo)
+
+        self.Z = zypp.ZYppFactory_instance().getZYpp()
+        if configmgr.create['block_recommends']:
+            msger.info("zypp not install recommend packages")
+            self.Z.resolver().setOnlyRequires(True)
+        self.Z.initializeTarget(zypp.Pathname(self.instroot))
+        self.Z.target().load()
+
+    def buildTransaction(self):
+        if not self.Z.resolver().resolvePool():
+            probs = self.Z.resolver().problems()
+
+            for problem in probs:
+                msger.warning("repo problem: %s, %s" \
+                              % (problem.description().decode("utf-8"),
+                                 problem.details().decode("utf-8")))
+
+            raise RepoError("found %d resolver problem, abort!" \
+                            % len(probs))
+
+    def getLocalPkgPath(self, po):
+        repoinfo = po.repoInfo()
+        cacheroot = repoinfo.packagesPath()
+        location = po.location()
+        rpmpath = str(location.filename())
+        pkgpath = "%s/%s" % (cacheroot, os.path.basename(rpmpath))
+        return pkgpath
+
+    def installLocal(self, pkg, po=None, updateonly=False):
+        if not self.ts:
+            self.__initialize_transaction()
+
+        solvfile = "%s/.solv" % (self.cachedir)
+
+        rc, out = runner.runtool([fs_related.find_binary_path("rpms2solv"),
+                                  pkg])
+        if rc == 0:
+            f = open(solvfile, "w+")
+            f.write(out)
+            f.close()
+
+            warnmsg = self.repo_manager.loadSolvFile(solvfile,
+                                                     os.path.basename(pkg))
+            if warnmsg:
+                msger.warning(warnmsg)
+
+            os.unlink(solvfile)
+        else:
+            msger.warning('Can not get %s solv data.' % pkg)
+
+        hdr = rpmmisc.readRpmHeader(self.ts, pkg)
+        arch = zypp.Arch(hdr['arch'])
+        sysarch = zypp.Arch(self.target_arch)
+
+        if arch.compatible_with (sysarch):
+            pkgname = hdr['name']
+            self.localpkgs[pkgname] = pkg
+            self.selectPackage(pkgname)
+            msger.info("Marking %s to be installed" % (pkg))
+
+        else:
+            msger.warning("Cannot add package %s to transaction. "
+                          "Not a compatible architecture: %s" \
+                          % (pkg, hdr['arch']))
+
+    def downloadPkgs(self, package_objects, count):
+        localpkgs = self.localpkgs.keys()
+        progress_obj = TextProgress(count)
+
+        for po in package_objects:
+            if po.name() in localpkgs:
+                continue
+
+            filename = self.getLocalPkgPath(po)
+            if os.path.exists(filename):
+                if self.checkPkg(filename) == 0:
+                    continue
+
+            dirn = os.path.dirname(filename)
+            if not os.path.exists(dirn):
+                os.makedirs(dirn)
+
+            url = self.get_url(po)
+            proxies = self.get_proxies(po)
+
+            try:
+                filename = myurlgrab(url.full, filename, proxies, progress_obj)
+            except CreatorError:
+                self.close()
+                raise
+
+    def preinstallPkgs(self):
+        if not self.ts_pre:
+            self.__initialize_transaction()
+
+        self.ts_pre.order()
+        cb = rpmmisc.RPMInstallCallback(self.ts_pre)
+        cb.headmsg = "Preinstall"
+        installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
+
+        # start to catch stderr output from librpm
+        msger.enable_logstderr(installlogfile)
+
+        errors = self.ts_pre.run(cb.callback, '')
+        # stop catch
+        msger.disable_logstderr()
+        self.ts_pre.closeDB()
+        self.ts_pre = None
+
+        if errors is not None:
+            if len(errors) == 0:
+                msger.warning('scriptlet or other non-fatal errors occurred '
+                              'during transaction.')
+
+            else:
+                for e in errors:
+                    msger.warning(e[0])
+                raise RepoError('Could not run transaction.')
+    def show_unresolved_dependencies_msg(self, unresolved_dependencies):
+        for pkg, need, needflags, sense, key in unresolved_dependencies:
+
+            package = '-'.join(pkg)
+
+            if needflags == rpm.RPMSENSE_LESS:
+                deppkg = ' < '.join(need)
+            elif needflags == rpm.RPMSENSE_EQUAL:
+                deppkg = ' = '.join(need)
+            elif needflags == rpm.RPMSENSE_GREATER:
+                deppkg = ' > '.join(need)
+            else:
+                deppkg = '-'.join(need)
+
+            if sense == rpm.RPMDEP_SENSE_REQUIRES:
+                msger.warning("[%s] Requires [%s], which is not provided" \
+                              % (package, deppkg))
+
+            elif sense == rpm.RPMDEP_SENSE_CONFLICTS:
+                msger.warning("[%s] Conflicts with [%s]" % (package, deppkg))
+
+    def installPkgs(self, package_objects):
+        if not self.ts:
+            self.__initialize_transaction()
+
+        # clean rpm lock
+        self._cleanupRpmdbLocks(self.instroot)
+        self._cleanupZyppJunk(self.instroot)
+        # Set filters
+        probfilter = 0
+        for flag in self.probFilterFlags:
+            probfilter |= flag
+        self.ts.setProbFilter(probfilter)
+        self.ts_pre.setProbFilter(probfilter)
+
+        localpkgs = self.localpkgs.keys()
+
+        for po in package_objects:
+            pkgname = po.name()
+            if pkgname in localpkgs:
+                rpmpath = self.localpkgs[pkgname]
+            else:
+                rpmpath = self.getLocalPkgPath(po)
+
+            if not os.path.exists(rpmpath):
+                # Maybe it is a local repo
+                rpmuri = self.get_url(po)
+                if rpmuri.startswith("file:/"):
+                    rpmpath = rpmuri[5:]
+
+            if not os.path.exists(rpmpath):
+                raise RpmError("Error: %s doesn't exist" % rpmpath)
+
+            h = rpmmisc.readRpmHeader(self.ts, rpmpath)
+
+            if pkgname in self.pre_pkgs:
+                msger.verbose("pre-install package added: %s" % pkgname)
+                self.ts_pre.addInstall(h, rpmpath, 'u')
+
+            #for rpm4.14 vesion, need to split addInstall for these two transactionSet.
+            #addInstall for self.ts should be after self.ts_pre done.
+            self.pkgs_bak.append({"header": h, "rpmpath": rpmpath})
+
+        unresolved_dependencies = self.ts.check()
+        if not unresolved_dependencies:
+            if self.pre_pkgs:
+                self.preinstallPkgs()
+
+            for pkg_bak in self.pkgs_bak:
+                self.ts.addInstall(pkg_bak["header"], pkg_bak["rpmpath"], 'u')
+            self.ts.order()
+            cb = rpmmisc.RPMInstallCallback(self.ts)
+            installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
+
+            # start to catch stderr output from librpm
+            msger.enable_logstderr(installlogfile)
+
+            errors = self.ts.run(cb.callback, '')
+            # stop catch
+            msger.disable_logstderr()
+            self.ts.closeDB()
+            self.ts = None
+            self.pkgs_bak = []
+
+            if errors is not None:
+                if len(errors) == 0:
+                    msger.warning('scriptlet or other non-fatal errors occurred '
+                                  'during transaction.')
+                    if self.strict_mode:
+                        raise CreatorError("mic failes to install some packages")
+                else:
+                    for e in errors:
+                        msger.warning(e[0])
+                    raise RepoError('Could not run transaction.')
+
+        else:
+            self.show_unresolved_dependencies_msg(unresolved_dependencies)
+            raise RepoError("Unresolved dependencies, transaction failed.")
+
+    def __initialize_transaction(self):
+        if not self.ts:
+            self.ts = rpm.TransactionSet(self.instroot)
+            # Set to not verify DSA signatures.
+            self.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
+
+        if not self.ts_pre:
+            self.ts_pre = rpm.TransactionSet(self.instroot)
+            # Just unpack the files, don't run scripts
+            self.ts_pre.setFlags(rpm.RPMTRANS_FLAG_ALLFILES | rpm.RPMTRANS_FLAG_NOSCRIPTS)
+            # Set to not verify DSA signatures.
+            self.ts_pre.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
+
+    def checkPkg(self, pkg):
+        ret = 1
+        if not os.path.exists(pkg):
+            return ret
+        ret = rpmmisc.checkRpmIntegrity('rpm', pkg)
+        if ret != 0:
+            msger.warning("package %s is damaged: %s" \
+                          % (os.path.basename(pkg), pkg))
+
+        return ret
+
+    def _add_prob_flags(self, *flags):
+        for flag in flags:
+            if flag not in self.probFilterFlags:
+                self.probFilterFlags.append(flag)
+
+    def get_proxies(self, pobj):
+        if not pobj:
+            return None
+
+        proxy = None
+        proxies = None
+        repoinfo = pobj.repoInfo()
+        reponame = "%s" % repoinfo.name()
+        repos = filter(lambda r: r.name == reponame, self.repos)
+        repourl = str(repoinfo.baseUrls()[0])
+
+        if repos:
+            proxy = repos[0].proxy
+        if not proxy:
+            proxy = get_proxy_for(repourl)
+        if proxy:
+            proxies = {str(repourl.split(':')[0]): str(proxy)}
+
+        return proxies
+
+    def get_url(self, pobj):
+        if not pobj:
+            return None
+
+        name = str(pobj.repoInfo().name())
+        try:
+            repo = filter(lambda r: r.name == name, self.repos)[0]
+        except IndexError:
+            return None
+
+        location = pobj.location()
+        location = str(location.filename())
+        if location.startswith("./"):
+            location = location[2:]
+
+        return repo.baseurl[0].join(location)
+
+    def package_url(self, pkgname):
+
+        def cmpEVR(p1, p2):
+            ed1 = p1.edition()
+            ed2 = p2.edition()
+            (e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
+            (e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
+            return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
+
+        if not self.Z:
+            self.__initialize_zypp()
+
+        q = zypp.PoolQuery()
+        q.addKind(zypp.ResKind.package)
+        q.setMatchExact()
+        q.addAttribute(zypp.SolvAttr.name, pkgname)
+        items = sorted(q.queryResults(self.Z.pool()),
+                       cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
+                       reverse=True)
+
+        if items:
+            item = zypp.asKindPackage(items[0])
+            url = self.get_url(item)
+            proxies = self.get_proxies(item)
+            return (url, proxies)
+
+        return (None, None)
diff --git a/mic_py2/usr/lib/mic/plugins/imager/fs_plugin.py b/mic_py2/usr/lib/mic/plugins/imager/fs_plugin.py
new file mode 100755 (executable)
index 0000000..21bb544
--- /dev/null
@@ -0,0 +1,98 @@
+#! /usr/bin/python2
+#
+# 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 subprocess
+from mic import chroot, msger, rt_util
+from mic.utils import misc, errors, fs_related, runner
+from mic.imager import fs
+from mic.plugin import pluginmgr
+
+from mic.pluginbase import ImagerPlugin
+class FsPlugin(ImagerPlugin):
+    name = 'fs'
+
+    @classmethod
+    def do_create(self, args):
+        """${cmd_name}: create fs image
+
+        """
+        creatoropts, pkgmgr, recording_pkgs = rt_util.prepare_create(args)
+
+        creator = fs.FsImageCreator(creatoropts, pkgmgr)
+        creator._include_src = args.include_src
+
+        if len(recording_pkgs) > 0:
+            creator._recording_pkgs = recording_pkgs
+
+        self.check_image_exists(creator.destdir,
+                                creator.pack_to,
+                                [creator.name],
+                                creatoropts['release'])
+
+        try:
+            creator.check_depend_tools()
+            creator.mount(None, creatoropts["cachedir"])
+            creator.install()
+            creator.tpkinstall()
+            #Download the source packages ###private options
+            if args.include_src:
+                installed_pkgs =  creator.get_installed_packages()
+                msger.info('Generating the image with source rpms included ...')
+                if not misc.SrcpkgsDownload(installed_pkgs, creatoropts["repomd"],
+                        creator._instroot, creatoropts["cachedir"]):
+                    msger.warning("Source packages can't be downloaded")
+
+            creator.configure(creatoropts["repomd"])
+            creator.copy_kernel()
+            creator.unmount()
+            creator.package(creatoropts["destdir"])
+            creator.create_manifest()
+            if creatoropts['release'] is not None:
+                creator.release_output(args.ksfile, creatoropts['destdir'],
+                        creatoropts['release'])
+            creator.print_outimage_info()
+        except errors.CreatorError:
+            raise
+        finally:
+            creator.cleanup()
+
+        #Run script of --run_script after image created
+        if creatoropts['run_script']:
+            cmd = creatoropts['run_script']
+            try:
+                runner.show(cmd)
+            except OSError as err:
+                msger.warning(str(err))
+
+
+        msger.info("Finished.")
+        return 0
+
+    @classmethod
+    def do_chroot(self, target, cmd=[]):#chroot.py parse opts&args
+        try:
+            if len(cmd) != 0:
+                cmdline = ' '.join(cmd)
+            else:
+                cmdline = "/bin/bash"
+            envcmd = fs_related.find_binary_inchroot("env", target)
+            if envcmd:
+                cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
+            chroot.chroot(target, None, cmdline)
+        finally:
+            chroot.cleanup_after_chroot("dir", None, None, None)
+            return 1
diff --git a/mic_py2/usr/lib/mic/plugins/imager/loop_plugin.py b/mic_py2/usr/lib/mic/plugins/imager/loop_plugin.py
new file mode 100755 (executable)
index 0000000..d451422
--- /dev/null
@@ -0,0 +1,210 @@
+#! /usr/bin/python2
+#
+# 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
+import shutil
+import tempfile
+
+from mic import chroot, msger, rt_util
+from mic.utils import misc, fs_related, errors, runner
+from mic.plugin import pluginmgr
+from mic.imager.loop import LoopImageCreator, load_mountpoints
+
+from mic.pluginbase import ImagerPlugin
+class LoopPlugin(ImagerPlugin):
+    name = 'loop'
+
+    @classmethod
+    def do_create(self, args):
+        """${cmd_name}: create loop image
+        """
+
+        creatoropts, pkgmgr, recording_pkgs = rt_util.prepare_create(args)
+
+        creator = LoopImageCreator(creatoropts,
+                                   pkgmgr,
+                                   args.compress_image,
+                                   args.shrink)
+
+        if len(recording_pkgs) > 0:
+            creator._recording_pkgs = recording_pkgs
+
+        image_names = [creator.name + ".img"]
+        image_names.extend(creator.get_image_names())
+        self.check_image_exists(creator.destdir,
+                                creator.pack_to,
+                                image_names,
+                                creatoropts['release'])
+
+        try:
+            creator.check_depend_tools()
+            creator.mount(None, creatoropts["cachedir"])
+            creator.install()
+            creator.tpkinstall()
+            creator.configure(creatoropts["repomd"])
+            creator.copy_kernel()
+            creator.create_cpio_image()
+            creator.unmount()
+            creator.copy_cpio_image()
+            creator.package(creatoropts["destdir"])
+            creator.create_manifest()
+
+            if creatoropts['release'] is not None:
+                creator.release_output(args.ksfile,
+                                       creatoropts['destdir'],
+                                       creatoropts['release'])
+            creator.print_outimage_info()
+
+        except errors.CreatorError:
+            raise
+        finally:
+            creator.cleanup()
+
+        #Run script of --run_script after image created
+        if creatoropts['run_script']:
+            cmd = creatoropts['run_script']
+            try:
+                runner.show(cmd)
+            except OSError as err:
+                msger.warning(str(err))
+
+        msger.info("Finished.")
+        return 0
+
+    @classmethod
+    def _do_chroot_tar(cls, target, cmd=[]):
+        mountfp_xml = os.path.splitext(target)[0] + '.xml'
+        if not os.path.exists(mountfp_xml):
+            raise errors.CreatorError("No mount point file found for this tar "
+                                      "image, please check %s" % mountfp_xml)
+
+        import tarfile
+        tar = tarfile.open(target, 'r')
+        tmpdir = misc.mkdtemp()
+        tar.extractall(path=tmpdir)
+        tar.close()
+
+        mntdir = misc.mkdtemp()
+
+        loops = []
+        for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml):
+            if fstype in ("ext2", "ext3", "ext4"):
+                myDiskMount = fs_related.ExtDiskMount
+            elif fstype == "btrfs":
+                myDiskMount = fs_related.BtrfsDiskMount
+            elif fstype in ("vfat", "msdos"):
+                myDiskMount = fs_related.VfatDiskMount
+            else:
+                raise errors.CreatorError("Cannot support fstype: %s" % fstype)
+
+            name = os.path.join(tmpdir, name)
+            size = size * 1024 * 1024
+            loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
+                               os.path.join(mntdir, mp.lstrip('/')),
+                               fstype, size, label)
+
+            try:
+                msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
+                fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
+                loop.mount()
+
+            except:
+                loop.cleanup()
+                for lp in reversed(loops):
+                    chroot.cleanup_after_chroot("img", lp, None, mntdir)
+
+                shutil.rmtree(tmpdir, ignore_errors=True)
+                raise
+
+            loops.append(loop)
+
+        try:
+            if len(cmd) != 0:
+                cmdline = "/usr/bin/env HOME=/root " + ' '.join(cmd)
+            else:
+                cmdline = "/usr/bin/env HOME=/root /bin/bash"
+            chroot.chroot(mntdir, None, cmdline)
+        except:
+            raise errors.CreatorError("Failed to chroot to %s." % target)
+        finally:
+            for loop in reversed(loops):
+                chroot.cleanup_after_chroot("img", loop, None, mntdir)
+
+            shutil.rmtree(tmpdir, ignore_errors=True)
+
+    @classmethod
+    def do_chroot(cls, target, cmd=[]):
+        if target.endswith('.tar'):
+            import tarfile
+            if tarfile.is_tarfile(target):
+                LoopPlugin._do_chroot_tar(target, cmd)
+                return
+            else:
+                raise errors.CreatorError("damaged tarball for loop images")
+
+        img = target
+        imgsize = misc.get_file_size(img) * 1024 * 1024
+        imgtype = misc.get_image_type(img)
+        if imgtype == "btrfsimg":
+            fstype = "btrfs"
+            myDiskMount = fs_related.BtrfsDiskMount
+        elif imgtype in ("ext3fsimg", "ext4fsimg"):
+            fstype = imgtype[:4]
+            myDiskMount = fs_related.ExtDiskMount
+        elif imgtype == "f2fsimg":
+            fstype = "f2fs"
+            myDiskMount = fs_related.F2fsDiskMount
+        else:
+            raise errors.CreatorError("Unsupported filesystem type: %s" \
+                                      % imgtype)
+
+        extmnt = misc.mkdtemp()
+        extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize),
+                                                         extmnt,
+                                                         fstype,
+                                                         4096,
+                                                         "%s label" % fstype)
+        try:
+            extloop.mount()
+
+        except errors.MountError:
+            extloop.cleanup()
+            shutil.rmtree(extmnt, ignore_errors=True)
+            raise
+
+        try:
+            if cmd is not None:
+                cmdline = cmd
+            else:
+                cmdline = "/bin/bash"
+            envcmd = fs_related.find_binary_inchroot("env", extmnt)
+            if envcmd:
+                cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
+            chroot.chroot(extmnt, None, cmdline)
+        except:
+            raise errors.CreatorError("Failed to chroot to %s." % img)
+        finally:
+            chroot.cleanup_after_chroot("img", extloop, None, extmnt)
+
+    @classmethod
+    def do_unpack(cls, srcimg):
+        image = os.path.join(tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"),
+                             "target.img")
+        msger.info("Copying file system ...")
+        shutil.copyfile(srcimg, image)
+        return image
diff --git a/mic_py2/usr/lib/mic/plugins/imager/qcow_plugin.py b/mic_py2/usr/lib/mic/plugins/imager/qcow_plugin.py
new file mode 100755 (executable)
index 0000000..2329958
--- /dev/null
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 2014 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
+import shutil
+
+from mic import msger, rt_util
+from mic.plugin import pluginmgr
+from mic.pluginbase import ImagerPlugin
+from mic.imager.qcow import QcowImageCreator
+from mic.utils import errors, runner
+
+class QcowPlugin(ImagerPlugin):
+    name = 'qcow'
+
+    @classmethod
+    def do_create(cls, args):
+        """${cmd_name}: create qcow image
+        """
+
+        creatoropts, pkgmgr, recording_pkgs = rt_util.prepare_create(args)
+
+        creator = QcowImageCreator(creatoropts,
+                                   pkgmgr)
+
+        if len(recording_pkgs) > 0:
+            creator._recording_pkgs = recording_pkgs
+
+        image_names = [creator.name + ".img"]
+        image_names.extend(creator.get_image_names())
+        cls.check_image_exists(creator.destdir,
+                                creator.pack_to,
+                                image_names,
+                                creatoropts['release'])
+
+        try:
+            creator.check_depend_tools()
+            creator.mount(None, creatoropts["cachedir"])
+            creator.install()
+            creator.tpkinstall()
+            creator.configure(creatoropts["repomd"])
+            creator.copy_kernel()
+            creator.create_cpio_image()
+            creator.unmount()
+            creator.copy_cpio_image()
+            creator.package(creatoropts["destdir"])
+            creator.create_manifest()
+
+            if creatoropts['release'] is not None:
+                creator.release_output(args.ksfile,
+                                       creatoropts['destdir'],
+                                       creatoropts['release'])
+            creator.print_outimage_info()
+
+        except errors.CreatorError:
+            raise
+        finally:
+            creator.cleanup()
+
+        #Run script of --run_script after image created
+        if creatoropts['run_script']:
+            cmd = creatoropts['run_script']
+            try:
+                runner.show(cmd)
+            except OSError as err:
+                msger.warning(str(err))
+
+
+        msger.info("Finished.")
+        return 0
+
+    @classmethod
+    def do_chroot(cls, target, cmd=[]):
+        pass
+
+    @classmethod
+    def do_unpack(cls, srcimg):
+        pass
diff --git a/mic_py2/usr/lib/mic/plugins/imager/raw_plugin.py b/mic_py2/usr/lib/mic/plugins/imager/raw_plugin.py
new file mode 100755 (executable)
index 0000000..dd97b18
--- /dev/null
@@ -0,0 +1,228 @@
+#! /usr/bin/python2
+#
+# 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
+import shutil
+import re
+import tempfile
+
+from mic import chroot, msger, rt_util
+from mic.utils import misc, fs_related, errors, runner
+from mic.plugin import pluginmgr
+from mic.utils.partitionedfs import PartitionedMount
+
+import mic.imager.raw as raw
+
+from mic.pluginbase import ImagerPlugin
+class RawPlugin(ImagerPlugin):
+    name = 'raw'
+
+    @classmethod
+    def do_create(self, args):
+        """${cmd_name}: create raw image
+        """
+
+        creatoropts, pkgmgr, recording_pkgs = rt_util.prepare_create(args)
+
+        creator = raw.RawImageCreator(creatoropts, pkgmgr, args.compress_image,
+                                      args.generate_bmap, args.fstab_entry)
+
+        if len(recording_pkgs) > 0:
+            creator._recording_pkgs = recording_pkgs
+
+        images = ["%s-%s.raw" % (creator.name, disk_name)
+                  for disk_name in creator.get_disk_names()]
+        self.check_image_exists(creator.destdir,
+                                creator.pack_to,
+                                images,
+                                creatoropts['release'])
+
+        try:
+            creator.check_depend_tools()
+            creator.mount(None, creatoropts["cachedir"])
+            creator.install()
+            creator.tpkinstall()
+            creator.configure(creatoropts["repomd"])
+            creator.copy_kernel()
+            creator.unmount()
+            creator.generate_bmap()
+            creator.package(creatoropts["destdir"])
+            creator.create_manifest()
+            if creatoropts['release'] is not None:
+                creator.release_output(args.ksfile, creatoropts['destdir'], creatoropts['release'])
+            creator.print_outimage_info()
+
+        except errors.CreatorError:
+            raise
+        finally:
+            creator.cleanup()
+
+        #Run script of --run_script after image created
+        if creatoropts['run_script']:
+            cmd = creatoropts['run_script']
+            try:
+                runner.show(cmd)
+            except OSError as err:
+                msger.warning(str(err))
+
+
+        msger.info("Finished.")
+        return 0
+
+    @classmethod
+    def do_chroot(cls, target, cmd=[]):
+        img = target
+        imgsize = misc.get_file_size(img) * 1024 * 1024
+        partedcmd = fs_related.find_binary_path("parted")
+        disk = fs_related.SparseLoopbackDisk(img, imgsize)
+        imgmnt = misc.mkdtemp()
+        imgloop = PartitionedMount(imgmnt, skipformat = True)
+        imgloop.add_disk('/dev/sdb', disk)
+        img_fstype = "ext3"
+
+        msger.info("Partition Table:")
+        partnum = []
+        for line in runner.outs([partedcmd, "-s", img, "print"]).splitlines():
+            # no use strip to keep line output here
+            if "Number" in line:
+                msger.raw(line)
+            if line.strip() and line.strip()[0].isdigit():
+                partnum.append(line.strip()[0])
+                msger.raw(line)
+
+        rootpart = None
+        if len(partnum) > 1:
+            rootpart = msger.choice("please choose root partition", partnum)
+
+        # Check the partitions from raw disk.
+        # if choose root part, the mark it as mounted
+        if rootpart:
+            root_mounted = True
+        else:
+            root_mounted = False
+        partition_mounts = 0
+        for line in runner.outs([ partedcmd, "-s", img, "unit", "B", "print" ]).splitlines():
+            line = line.strip()
+
+            # Lines that start with number are the partitions,
+            # because parted can be translated we can't refer to any text lines.
+            if not line or not line[0].isdigit():
+                continue
+
+            # Some vars have extra , as list seperator.
+            line = line.replace(",","")
+
+            # Example of parted output lines that are handled:
+            # Number  Start        End          Size         Type     File system    Flags
+            #  1      512B         3400000511B  3400000000B  primary
+            #  2      3400531968B  3656384511B  255852544B   primary  linux-swap(v1)
+            #  3      3656384512B  3720347647B  63963136B    primary  fat16          boot, lba
+
+            partition_info = re.split("\s+", line)
+
+            size = partition_info[3].split("B")[0]
+
+            if len(partition_info) < 6 or partition_info[5] in ["boot"]:
+                # No filesystem can be found from partition line. Assuming
+                # btrfs, because that is the only MeeGo fs that parted does
+                # not recognize properly.
+                # TODO: Can we make better assumption?
+                fstype = "btrfs"
+            elif partition_info[5] in [ "ext2", "ext3", "ext4", "btrfs", "f2fs" ]:
+                fstype = partition_info[5]
+            elif partition_info[5] in [ "fat16", "fat32" ]:
+                fstype = "vfat"
+            elif "swap" in partition_info[5]:
+                fstype = "swap"
+            else:
+                raise errors.CreatorError("Could not recognize partition fs type '%s'." %
+                        partition_info[5])
+
+            if rootpart and rootpart == line[0]:
+                mountpoint = '/'
+            elif not root_mounted and fstype in [ "ext2", "ext3", "ext4", "btrfs", "f2fs" ]:
+                # TODO: Check that this is actually the valid root partition from /etc/fstab
+                mountpoint = "/"
+                root_mounted = True
+            elif fstype == "swap":
+                mountpoint = "swap"
+            else:
+                # TODO: Assing better mount points for the rest of the partitions.
+                partition_mounts += 1
+                mountpoint = "/media/partition_%d" % partition_mounts
+
+            if "boot" in partition_info:
+                boot = True
+            else:
+                boot = False
+
+            msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" %
+                    (size, fstype, mountpoint, boot))
+            # TODO: add_partition should take bytes as size parameter.
+            imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint,
+                    fstype = fstype, boot = boot)
+
+        try:
+            imgloop.mount()
+
+        except errors.MountError:
+            imgloop.cleanup()
+            raise
+
+        try:
+            if len(cmd) != 0:
+                cmdline = ' '.join(cmd)
+            else:
+                cmdline = "/bin/bash"
+            envcmd = fs_related.find_binary_inchroot("env", imgmnt)
+            if envcmd:
+                cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
+            chroot.chroot(imgmnt, None, cmdline)
+        except:
+            raise errors.CreatorError("Failed to chroot to %s." %img)
+        finally:
+            chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
+
+    @classmethod
+    def do_unpack(cls, srcimg):
+        srcimgsize = (misc.get_file_size(srcimg)) * 1024 * 1024
+        srcmnt = misc.mkdtemp("srcmnt")
+        disk = fs_related.SparseLoopbackDisk(srcimg, srcimgsize)
+        srcloop = PartitionedMount(srcmnt, skipformat = True)
+
+        srcloop.add_disk('/dev/sdb', disk)
+        srcloop.add_partition(srcimgsize/1024/1024, "/dev/sdb", "/", "ext3", boot=False)
+        try:
+            srcloop.mount()
+
+        except errors.MountError:
+            srcloop.cleanup()
+            raise
+
+        image = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), "target.img")
+        args = ['dd', "if=%s" % srcloop.partitions[0]['device'], "of=%s" % image]
+
+        msger.info("`dd` image ...")
+        rc = runner.show(args)
+        srcloop.cleanup()
+        shutil.rmtree(os.path.dirname(srcmnt), ignore_errors = True)
+
+        if rc != 0:
+            raise errors.CreatorError("Failed to dd")
+        else:
+            return image
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/base.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/base.py
new file mode 100644 (file)
index 0000000..75ce249
--- /dev/null
@@ -0,0 +1,467 @@
+#
+# 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,TpkPackages
+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.tpk_packages = TpkPackages()
+        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/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/__init__.py
new file mode 100644 (file)
index 0000000..da48ff5
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# 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 authconfig, autopart, autostep, bootloader, clearpart, device
+import deviceprobe, displaymode, dmraid, driverdisk, fcoe, firewall, firstboot
+import group, ignoredisk, interactive, iscsi, iscsiname, key, keyboard, lang
+import langsupport, lilocheck, logging, logvol, mediacheck, method, monitor
+import mouse, multipath, network, partition, raid, reboot, repo, rescue, rootpw
+import selinux, services, skipx, sshpw, timezone, updates, upgrade, user, vnc
+import volgroup, xconfig, zerombr, zfcp
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/authconfig.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/authconfig.py
new file mode 100644 (file)
index 0000000..9af9c0f
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+
+class FC3_Authconfig(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, *args, **kwargs)
+        self.authconfig = kwargs.get("authconfig", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.authconfig:
+            retval += "# System authorization information\nauth %s\n" % self.authconfig
+
+        return retval
+
+    def parse(self, args):
+        self.authconfig = self.currentLine[len(self.currentCmd):].strip()
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autopart.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autopart.py
new file mode 100644 (file)
index 0000000..22c3b66
--- /dev/null
@@ -0,0 +1,119 @@
+#
+# 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
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_AutoPart(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=100, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.autopart = kwargs.get("autopart", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.autopart:
+            retval += "autopart\n"
+
+        return retval
+
+    def parse(self, args):
+        if len(args) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "autopart"))
+
+        self.autopart = True
+        return self
+
+class F9_AutoPart(FC3_AutoPart):
+    removedKeywords = FC3_AutoPart.removedKeywords
+    removedAttrs = FC3_AutoPart.removedAttrs
+
+    def __init__(self, writePriority=100, *args, **kwargs):
+        FC3_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+        self.op = self._getParser()
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.autopart:
+            retval += "autopart"
+
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\""% self.passphrase
+
+        if retval != "":
+            retval += "\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        self.autopart = True
+        return self
+
+class F12_AutoPart(F9_AutoPart):
+    removedKeywords = F9_AutoPart.removedKeywords
+    removedAttrs = F9_AutoPart.removedAttrs
+
+    def __init__(self, writePriority=100, *args, **kwargs):
+        F9_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
+
+        self.escrowcert = kwargs.get("escrowcert", "")
+        self.backuppassphrase = kwargs.get("backuppassphrase", False)
+
+    def __str__(self):
+        retval = F9_AutoPart.__str__(self)
+
+        if self.encrypted and self.escrowcert != "":
+            retval = retval.strip()
+
+            retval += " --escrowcert=\"%s\"" % self.escrowcert
+
+            if self.backuppassphrase:
+                retval += " --backuppassphrase"
+
+            retval += "\n"
+
+        return retval
+
+    def _getParser(self):
+        op = F9_AutoPart._getParser(self)
+        op.add_option("--escrowcert")
+        op.add_option("--backuppassphrase", action="store_true", default=False)
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autostep.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/autostep.py
new file mode 100644 (file)
index 0000000..e6ae71c
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+class FC3_AutoStep(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.autostep = kwargs.get("autostep", False)
+        self.autoscreenshot = kwargs.get("autoscreenshot", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.autostep:
+            if self.autoscreenshot:
+                retval += "autostep --autoscreenshot\n"
+            else:
+                retval += "autostep\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--autoscreenshot", dest="autoscreenshot",
+                      action="store_true", default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        self.autostep = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/bootloader.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/bootloader.py
new file mode 100644 (file)
index 0000000..b227fac
--- /dev/null
@@ -0,0 +1,265 @@
+#
+# 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
+
+class RHEL5_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.hvArgs = kwargs.get("hvArgs", "")
+
+    def _getArgsAsStr(self):
+        ret = FC4_Bootloader._getArgsAsStr(self)
+
+        if self.hvArgs:
+            ret += " --hvargs=\"%s\"" %(self.hvArgs,)
+
+        return ret
+
+    def _getParser(self):
+        op = FC4_Bootloader._getParser(self)
+        op.add_option("--hvargs", dest="hvArgs", type="string")
+        return op
+
+class RHEL6_Bootloader(F12_Bootloader):
+    removedKeywords = F12_Bootloader.removedKeywords
+    removedAttrs = F12_Bootloader.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        F12_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+        self.isCrypted = kwargs.get("isCrypted", False)
+
+    def _getArgsAsStr(self):
+        ret = F12_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 = F12_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/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/clearpart.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/clearpart.py
new file mode 100644 (file)
index 0000000..a8089fc
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+class FC3_ClearPart(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=120, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.drives = kwargs.get("drives", [])
+        self.initAll = kwargs.get("initAll", False)
+        self.type = kwargs.get("type", None)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.type is None:
+            return retval
+
+        if self.type == CLEARPART_TYPE_NONE:
+            clearstr = "--none"
+        elif self.type == CLEARPART_TYPE_LINUX:
+            clearstr = "--linux"
+        elif self.type == CLEARPART_TYPE_ALL:
+            clearstr = "--all"
+        else:
+            clearstr = ""
+
+        if self.initAll:
+            initstr = "--initlabel"
+        else:
+            initstr = ""
+
+        if len(self.drives) > 0:
+            drivestr = "--drives=" + ",".join(self.drives)
+        else:
+            drivestr = ""
+
+        retval += "# Partition clearing information\nclearpart %s %s %s\n" % (clearstr, initstr, drivestr)
+        return retval
+
+    def _getParser(self):
+        def drive_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser()
+        op.add_option("--all", dest="type", action="store_const",
+                      const=CLEARPART_TYPE_ALL)
+        op.add_option("--drives", dest="drives", action="callback",
+                      callback=drive_cb, nargs=1, type="string")
+        op.add_option("--initlabel", dest="initAll", action="store_true",
+                      default=False)
+        op.add_option("--linux", dest="type", action="store_const",
+                      const=CLEARPART_TYPE_LINUX)
+        op.add_option("--none", dest="type", action="store_const",
+                      const=CLEARPART_TYPE_NONE)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/device.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/device.py
new file mode 100644 (file)
index 0000000..afed26c
--- /dev/null
@@ -0,0 +1,125 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F8_DeviceData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.moduleName = kwargs.get("moduleName", "")
+        self.moduleOpts = kwargs.get("moduleOpts", "")
+
+    def __eq__(self, y):
+        return self.moduleName == y.moduleName
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+
+        if self.moduleName != "":
+            retval += "device %s" % self.moduleName
+
+            if self.moduleOpts != "":
+                retval += " --opts=\"%s\"" % self.moduleOpts
+
+        return retval + "\n"
+
+class FC3_Device(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.type = kwargs.get("type", "")
+        self.moduleName = kwargs.get("moduleName", "")
+        self.moduleOpts = kwargs.get("moduleOpts", "")
+
+    def __eq__(self, y):
+        return self.moduleName == y.moduleName
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.moduleName != "":
+            retval += "device %s %s" % (self.type, self.moduleName)
+
+            if self.moduleOpts != "":
+                retval += " --opts=\"%s\"" % self.moduleOpts
+
+        return retval + "\n"
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--opts", dest="moduleOpts", default="")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 2:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("device command requires two arguments: module type and name")))
+
+        self.moduleOpts = opts.moduleOpts
+        self.type = extra[0]
+        self.moduleName = extra[1]
+        return self
+
+class F8_Device(FC3_Device):
+    removedKeywords = FC3_Device.removedKeywords
+    removedAttrs = FC3_Device.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_Device.__init__(self, writePriority, *args, **kwargs)
+        self.deviceList = kwargs.get("deviceList", [])
+
+    def __str__(self):
+        retval = ""
+        for device in self.deviceList:
+            retval += device.__str__()
+
+        return retval
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("%s command requires a single argument: %s") % ("device", "module name")))
+
+        dd = F8_DeviceData()
+        self._setToObj(self.op, opts, dd)
+        dd.lineno = self.lineno
+        dd.moduleName = extra[0]
+
+        # Check for duplicates in the data list.
+        if dd in self.dataList():
+            warnings.warn(_("A module with the name %s has already been defined.") % dd.moduleName)
+
+        return dd
+
+    def dataList(self):
+        return self.deviceList
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/deviceprobe.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/deviceprobe.py
new file mode 100644 (file)
index 0000000..9f462fd
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+
+class FC3_DeviceProbe(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.deviceprobe = kwargs.get("deviceprobe", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.deviceprobe != "":
+            retval += "deviceprobe %s\n" % self.deviceprobe
+
+        return retval
+
+    def parse(self, args):
+        self.deviceprobe = " ".join(args)
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/displaymode.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/displaymode.py
new file mode 100644 (file)
index 0000000..afd58ea
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_DisplayMode(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.displayMode = kwargs.get("displayMode", None)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.displayMode is None:
+            return retval
+
+        if self.displayMode == DISPLAY_MODE_CMDLINE:
+            retval += "cmdline\n"
+        elif self.displayMode == DISPLAY_MODE_GRAPHICAL:
+            retval += "# Use graphical install\ngraphical\n"
+        elif self.displayMode == DISPLAY_MODE_TEXT:
+            retval += "# Use text mode install\ntext\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 0:
+            raise KickstartParseError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % self.currentCmd))
+
+        if self.currentCmd == "cmdline":
+            self.displayMode = DISPLAY_MODE_CMDLINE
+        elif self.currentCmd == "graphical":
+            self.displayMode = DISPLAY_MODE_GRAPHICAL
+        elif self.currentCmd == "text":
+            self.displayMode = DISPLAY_MODE_TEXT
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/dmraid.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/dmraid.py
new file mode 100644 (file)
index 0000000..993575a
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# Chris Lumens <clumens@redhat.com>
+# Peter Jones <pjones@redhat.com>
+#
+# Copyright 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_DmRaidData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+
+        self.name = kwargs.get("name", "")
+        self.devices = kwargs.get("devices", [])
+        self.dmset = kwargs.get("dmset", None)
+
+    def __eq__(self, y):
+        return self.name == y.name and self.devices == y.devices
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "dmraid --name=%s" % self.name
+
+        for dev in self.devices:
+            retval += " --dev=\"%s\"" % dev
+
+        return retval + "\n"
+
+class FC6_DmRaid(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=60, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.dmraids = kwargs.get("dmraids", [])
+
+    def __str__(self):
+        retval = ""
+        for dm in self.dmraids:
+            retval += dm.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--name", dest="name", action="store", type="string",
+                      required=1)
+        op.add_option("--dev", dest="devices", action="append", type="string",
+                      required=1)
+        return op
+
+    def parse(self, args):
+        dm = FC6_DmRaidData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        dm.name = dm.name.split('/')[-1]
+        self._setToObj(self.op, opts, dm)
+        dm.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if dm in self.dataList():
+            warnings.warn(_("A DM RAID device with the name %s and devices %s has already been defined.") % (dm.name, dm.devices))
+
+        return dm
+
+    def dataList(self):
+        return self.dmraids
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/driverdisk.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/driverdisk.py
new file mode 100644 (file)
index 0000000..43d6259
--- /dev/null
@@ -0,0 +1,184 @@
+#
+# 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.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_DriverDiskData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+
+        self.partition = kwargs.get("partition", "")
+        self.source = kwargs.get("source", "")
+        self.type = kwargs.get("type", "")
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.partition:
+            retval += "%s" % self.partition
+
+            if hasattr(self, "type") and self.type:
+                retval += " --type=%s" % self.type
+        elif self.source:
+            retval += "--source=%s" % self.source
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "driverdisk %s\n" % self._getArgsAsStr()
+        return retval
+
+class FC4_DriverDiskData(FC3_DriverDiskData):
+    removedKeywords = FC3_DriverDiskData.removedKeywords
+    removedAttrs = FC3_DriverDiskData.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_DriverDiskData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.biospart = kwargs.get("biospart", "")
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.partition:
+            retval += "%s" % self.partition
+
+            if hasattr(self, "type") and self.type:
+                retval += " --type=%s" % self.type
+        elif self.source:
+            retval += "--source=%s" % self.source
+        elif self.biospart:
+            retval += "--biospart=%s" % self.biospart
+
+        return retval
+
+class F12_DriverDiskData(FC4_DriverDiskData):
+    removedKeywords = FC4_DriverDiskData.removedKeywords + ["type"]
+    removedAttrs = FC4_DriverDiskData.removedAttrs + ["type"]
+
+    def __init__(self, *args, **kwargs):
+        FC4_DriverDiskData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+F14_DriverDiskData = F12_DriverDiskData
+
+class FC3_DriverDisk(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.driverdiskList = kwargs.get("driverdiskList", [])
+
+    def __str__(self):
+        retval = ""
+        for dd in self.driverdiskList:
+            retval += dd.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--source")
+        op.add_option("--type")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one partition may be specified for driverdisk command.")))
+
+        if len(extra) == 1 and opts.source:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --source and partition may be specified for driverdisk command.")))
+
+        if not extra and not opts.source:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of --source or partition must be specified for driverdisk command.")))
+
+        ddd = self.handler.DriverDiskData()
+        self._setToObj(self.op, opts, ddd)
+        ddd.lineno = self.lineno
+        if len(extra) == 1:
+            ddd.partition = extra[0]
+
+        return ddd
+
+    def dataList(self):
+        return self.driverdiskList
+
+class FC4_DriverDisk(FC3_DriverDisk):
+    removedKeywords = FC3_DriverDisk.removedKeywords
+    removedAttrs = FC3_DriverDisk.removedKeywords
+
+    def _getParser(self):
+        op = FC3_DriverDisk._getParser(self)
+        op.add_option("--biospart")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one partition may be specified for driverdisk command.")))
+
+        if len(extra) == 1 and opts.source:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --source and partition may be specified for driverdisk command.")))
+        elif len(extra) == 1 and opts.biospart:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --biospart and partition may be specified for driverdisk command.")))
+        elif opts.source and opts.biospart:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --biospart and --source may be specified for driverdisk command.")))
+
+        if not extra and not opts.source and not opts.biospart:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of --source, --biospart, or partition must be specified for driverdisk command.")))
+
+        ddd = self.handler.DriverDiskData()
+        self._setToObj(self.op, opts, ddd)
+        ddd.lineno = self.lineno
+        if len(extra) == 1:
+            ddd.partition = extra[0]
+
+        return ddd
+
+class F12_DriverDisk(FC4_DriverDisk):
+    removedKeywords = FC4_DriverDisk.removedKeywords
+    removedAttrs = FC4_DriverDisk.removedKeywords
+
+    def _getParser(self):
+        op = FC4_DriverDisk._getParser(self)
+        op.add_option("--type", deprecated=1)
+        return op
+
+class F14_DriverDisk(F12_DriverDisk):
+    removedKeywords = F12_DriverDisk.removedKeywords
+    removedAttrs = F12_DriverDisk.removedKeywords
+
+    def _getParser(self):
+        op = F12_DriverDisk._getParser(self)
+        op.remove_option("--type")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/fcoe.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/fcoe.py
new file mode 100644 (file)
index 0000000..2f4b492
--- /dev/null
@@ -0,0 +1,114 @@
+#
+# Hans de Goede <hdegoede@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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F12_FcoeData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.nic = kwargs.get("nic", None)
+
+    def __eq__(self, y):
+        return self.nic == y.nic
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.nic:
+            retval += " --nic=%s" % self.nic
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "fcoe%s\n" % self._getArgsAsStr()
+        return retval
+
+class F13_FcoeData(F12_FcoeData):
+    removedKeywords = F12_FcoeData.removedKeywords
+    removedAttrs = F12_FcoeData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F12_FcoeData.__init__(self, *args, **kwargs)
+        self.dcb = kwargs.get("dcb", False)
+
+    def _getArgsAsStr(self):
+        retval = F12_FcoeData._getArgsAsStr(self)
+
+        if self.dcb:
+            retval += " --dcb"
+
+        return retval
+
+class F12_Fcoe(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=71, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.fcoe = kwargs.get("fcoe", [])
+
+    def __str__(self):
+        retval = ""
+        for fcoe in self.fcoe:
+            retval += fcoe.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--nic", dest="nic", required=1)
+        return op
+
+    def parse(self, args):
+        zd = self.handler.FcoeData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) > 0:
+            mapping = {"command": "fcoe", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))
+
+        self._setToObj(self.op, opts, zd)
+        zd.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if zd in self.dataList():
+            warnings.warn(_("A FCOE device with the name %s has already been defined.") % zd.nic)
+
+        return zd
+
+    def dataList(self):
+        return self.fcoe
+
+class F13_Fcoe(F12_Fcoe):
+    removedKeywords = F12_Fcoe.removedKeywords
+    removedAttrs = F12_Fcoe.removedAttrs
+
+    def _getParser(self):
+        op = F12_Fcoe._getParser(self)
+        op.add_option("--dcb", dest="dcb", action="store_true", default=False)
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firewall.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firewall.py
new file mode 100644 (file)
index 0000000..1d21759
--- /dev/null
@@ -0,0 +1,193 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Firewall(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.enabled = kwargs.get("enabled", None)
+        self.ports = kwargs.get("ports", [])
+        self.trusts = kwargs.get("trusts", [])
+
+    def __str__(self):
+        extra = []
+        filteredPorts = []
+
+        retval = KickstartCommand.__str__(self)
+
+        if self.enabled is None:
+            return retval
+
+        if self.enabled:
+            # It's possible we have words in the ports list instead of
+            # port:proto (s-c-kickstart may do this).  So, filter those
+            # out into their own list leaving what we expect.
+            for port in self.ports:
+                if port == "ssh":
+                    extra.append(" --ssh")
+                elif port == "telnet":
+                    extra.append(" --telnet")
+                elif port == "smtp":
+                    extra.append(" --smtp")
+                elif port == "http":
+                    extra.append(" --http")
+                elif port == "ftp":
+                    extra.append(" --ftp")
+                else:
+                    filteredPorts.append(port)
+
+            # All the port:proto strings go into a comma-separated list.
+            portstr = ",".join(filteredPorts)
+            if len(portstr) > 0:
+                portstr = " --port=" + portstr
+            else:
+                portstr = ""
+
+            extrastr = "".join(extra)
+            truststr = ",".join(self.trusts)
+
+            if len(truststr) > 0:
+                truststr = " --trust=" + truststr
+
+            # The output port list consists only of port:proto for
+            # everything that we don't recognize, and special options for
+            # those that we do.
+            retval += "# Firewall configuration\nfirewall --enabled%s%s%s\n" % (extrastr, portstr, truststr)
+        else:
+            retval += "# Firewall configuration\nfirewall --disabled\n"
+
+        return retval
+
+    def _getParser(self):
+        def firewall_port_cb (option, opt_str, value, parser):
+            for p in value.split(","):
+                p = p.strip()
+                if p.find(":") == -1:
+                    p = "%s:tcp" % p
+                parser.values.ensure_value(option.dest, []).append(p)
+
+        op = KSOptionParser(mapping={"ssh":["22:tcp"], "telnet":["23:tcp"],
+                             "smtp":["25:tcp"], "http":["80:tcp", "443:tcp"],
+                             "ftp":["21:tcp"]})
+
+        op.add_option("--disable", "--disabled", dest="enabled",
+                      action="store_false")
+        op.add_option("--enable", "--enabled", dest="enabled",
+                      action="store_true", default=True)
+        op.add_option("--ftp", "--http", "--smtp", "--ssh", "--telnet",
+                      dest="ports", action="map_extend")
+        op.add_option("--high", deprecated=1)
+        op.add_option("--medium", deprecated=1)
+        op.add_option("--port", dest="ports", action="callback",
+                      callback=firewall_port_cb, nargs=1, type="string")
+        op.add_option("--trust", dest="trusts", action="append")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 0:
+            mapping = {"command": "firewall", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))
+
+        self._setToSelf(self.op, opts)
+        return self
+
+class F9_Firewall(FC3_Firewall):
+    removedKeywords = FC3_Firewall.removedKeywords
+    removedAttrs = FC3_Firewall.removedAttrs
+
+    def _getParser(self):
+        op = FC3_Firewall._getParser(self)
+        op.remove_option("--high")
+        op.remove_option("--medium")
+        return op
+
+class F10_Firewall(F9_Firewall):
+    removedKeywords = F9_Firewall.removedKeywords
+    removedAttrs = F9_Firewall.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F9_Firewall.__init__(self, writePriority, *args, **kwargs)
+        self.services = kwargs.get("services", [])
+
+    def __str__(self):
+        if self.enabled is None:
+            return ""
+
+        retval = F9_Firewall.__str__(self)
+        if self.enabled:
+            retval = retval.strip()
+
+            svcstr = ",".join(self.services)
+            if len(svcstr) > 0:
+                svcstr = " --service=" + svcstr
+            else:
+                svcstr = ""
+
+            return retval + "%s\n" % svcstr
+        else:
+            return retval
+
+    def _getParser(self):
+        def service_cb (option, opt_str, value, parser):
+            # python2.4 does not support action="append_const" that we were
+            # using for these options.  Instead, we have to fake it by
+            # appending whatever the option string is to the service list.
+            if not value:
+                parser.values.ensure_value(option.dest, []).append(opt_str[2:])
+                return
+
+            for p in value.split(","):
+                p = p.strip()
+                parser.values.ensure_value(option.dest, []).append(p)
+
+        op = F9_Firewall._getParser(self)
+        op.add_option("--service", dest="services", action="callback",
+                      callback=service_cb, nargs=1, type="string")
+        op.add_option("--ftp", dest="services", action="callback",
+                      callback=service_cb)
+        op.add_option("--http", dest="services", action="callback",
+                      callback=service_cb)
+        op.add_option("--smtp", dest="services", action="callback",
+                      callback=service_cb)
+        op.add_option("--ssh", dest="services", action="callback",
+                      callback=service_cb)
+        op.add_option("--telnet", deprecated=1)
+        return op
+
+class F14_Firewall(F10_Firewall):
+    removedKeywords = F10_Firewall.removedKeywords + ["telnet"]
+    removedAttrs = F10_Firewall.removedAttrs + ["telnet"]
+
+    def _getParser(self):
+        op = F10_Firewall._getParser(self)
+        op.remove_option("--telnet")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firstboot.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/firstboot.py
new file mode 100644 (file)
index 0000000..05c0ac1
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.options import *
+
+class FC3_Firstboot(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.firstboot = kwargs.get("firstboot", None)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.firstboot is None:
+            return retval
+
+        if self.firstboot == FIRSTBOOT_SKIP:
+            retval += "firstboot --disable\n"
+        elif self.firstboot == FIRSTBOOT_DEFAULT:
+            retval += "# Run the Setup Agent on first boot\nfirstboot --enable\n"
+        elif self.firstboot == FIRSTBOOT_RECONFIG:
+            retval += "# Run the Setup Agent on first boot\nfirstboot --reconfig\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--disable", "--disabled", dest="firstboot",
+                      action="store_const", const=FIRSTBOOT_SKIP)
+        op.add_option("--enable", "--enabled", dest="firstboot",
+                      action="store_const", const=FIRSTBOOT_DEFAULT)
+        op.add_option("--reconfig", dest="firstboot", action="store_const",
+                      const=FIRSTBOOT_RECONFIG)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self.firstboot = opts.firstboot
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/group.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/group.py
new file mode 100644 (file)
index 0000000..80ba5bd
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F12_GroupData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.name = kwargs.get("name", "")
+        self.gid = kwargs.get("gid", None)
+
+    def __eq__(self, y):
+        return self.name == y.name
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "group"
+
+        if self.name:
+            retval += " --name=%s" % self.name
+        if self.gid:
+            retval += " --gid=%s" % self.gid
+
+        return retval + "\n"
+
+class F12_Group(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.groupList = kwargs.get("groupList", [])
+
+    def __str__(self):
+        retval = ""
+        for user in self.groupList:
+            retval += user.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--name", required=1)
+        op.add_option("--gid", type="int")
+        return op
+
+    def parse(self, args):
+        gd = self.handler.GroupData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToObj(self.op, opts, gd)
+        gd.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if gd in self.dataList():
+            warnings.warn(_("A group with the name %s has already been defined.") % gd.name)
+
+        return gd
+
+    def dataList(self):
+        return self.groupList
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/ignoredisk.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/ignoredisk.py
new file mode 100644 (file)
index 0000000..48f281d
--- /dev/null
@@ -0,0 +1,139 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007, 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_IgnoreDisk(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.ignoredisk = kwargs.get("ignoredisk", [])
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if len(self.ignoredisk) > 0:
+            retval += "ignoredisk --drives=%s\n" % ",".join(self.ignoredisk)
+
+        return retval
+
+    def _getParser(self):
+        def drive_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser()
+        op.add_option("--drives", dest="ignoredisk", action="callback",
+                      callback=drive_cb, nargs=1, type="string", required=1)
+        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_IgnoreDisk(FC3_IgnoreDisk):
+    removedKeywords = FC3_IgnoreDisk.removedKeywords
+    removedAttrs = FC3_IgnoreDisk.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_IgnoreDisk.__init__(self, writePriority, *args, **kwargs)
+
+        self.onlyuse = kwargs.get("onlyuse", [])
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if len(self.ignoredisk) > 0:
+            retval += "ignoredisk --drives=%s\n" % ",".join(self.ignoredisk)
+        elif len(self.onlyuse) > 0:
+            retval += "ignoredisk --only-use=%s\n" % ",".join(self.onlyuse)
+
+        return retval
+
+    def parse(self, args, errorCheck=True):
+        retval = FC3_IgnoreDisk.parse(self, args)
+
+        if errorCheck:
+            if (len(self.ignoredisk) == 0 and len(self.onlyuse) == 0) or (len(self.ignoredisk) > 0 and (len(self.onlyuse) > 0)):
+                raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of --drives or --only-use must be specified for ignoredisk command.")))
+
+        return retval
+
+    def _getParser(self):
+        def drive_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = FC3_IgnoreDisk._getParser(self)
+        op.add_option("--drives", dest="ignoredisk", action="callback",
+                      callback=drive_cb, nargs=1, type="string")
+        op.add_option("--only-use", dest="onlyuse", action="callback",
+                      callback=drive_cb, nargs=1, type="string")
+        return op
+
+class RHEL6_IgnoreDisk(F8_IgnoreDisk):
+    removedKeywords = F8_IgnoreDisk.removedKeywords
+    removedAttrs = F8_IgnoreDisk.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F8_IgnoreDisk.__init__(self, writePriority, *args, **kwargs)
+
+        self.interactive = kwargs.get("interactive", False)
+        if self.interactive:
+            self.ignoredisk = []
+
+    def __str__(self):
+        retval = F8_IgnoreDisk.__str__(self)
+
+        if self.interactive:
+            retval = "ignoredisk --interactive\n"
+
+        return retval
+
+    def parse(self, args):
+        retval = F8_IgnoreDisk.parse(self, args, errorCheck=False)
+
+        howmany = 0
+        if len(self.ignoredisk) > 0:
+            howmany += 1
+        if len(self.onlyuse) > 0:
+            howmany += 1
+        if self.interactive:
+            howmany += 1
+        if howmany != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of --drives , --only-use , or --interactive must be specified for ignoredisk command.")))
+
+        return retval
+
+    def _getParser(self):
+        op = F8_IgnoreDisk._getParser(self)
+        op.add_option("--interactive", dest="interactive", action="store_true",
+                      default=False)
+        return op
+
+F14_IgnoreDisk = RHEL6_IgnoreDisk
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/interactive.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/interactive.py
new file mode 100644 (file)
index 0000000..b4e286b
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Interactive(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.interactive = kwargs.get("interactive", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.interactive:
+            retval += "# Use interactive kickstart installation method\ninteractive\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "interactive"))
+
+        self.interactive = True
+        return self
+
+class F14_Interactive(DeprecatedCommand):
+    def __init__(self):
+        DeprecatedCommand.__init__(self)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsi.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsi.py
new file mode 100644 (file)
index 0000000..9c25111
--- /dev/null
@@ -0,0 +1,133 @@
+#
+# Chris Lumens <clumens@redhat.com>
+# Peter Jones <pjones@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.
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_IscsiData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.ipaddr = kwargs.get("ipaddr", "")
+        self.port = kwargs.get("port", "3260")
+        self.target = kwargs.get("target", "")
+        self.user = kwargs.get("user", None)
+        self.password = kwargs.get("password", None)
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.target != "":
+            retval += " --target=%s" % self.target
+        if self.ipaddr != "":
+            retval += " --ipaddr=%s" % self.ipaddr
+        if self.port != "3260":
+            retval += " --port=%s" % self.port
+        if self.user is not None:
+            retval += " --user=%s" % self.user
+        if self.password is not None:
+            retval += " --password=%s" % self.password
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "iscsi%s\n" % self._getArgsAsStr()
+        return retval
+
+class F10_IscsiData(FC6_IscsiData):
+    removedKeywords = FC6_IscsiData.removedKeywords
+    removedAttrs = FC6_IscsiData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC6_IscsiData.__init__(self, *args, **kwargs)
+        self.user_in = kwargs.get("user_in", None)
+        self.password_in = kwargs.get("password_in", None)
+
+    def _getArgsAsStr(self):
+        retval = FC6_IscsiData._getArgsAsStr(self)
+
+        if self.user_in is not None:
+            retval += " --reverse-user=%s" % self.user_in
+        if self.password_in is not None:
+            retval += " --reverse-password=%s" % self.password_in
+
+        return retval
+
+class FC6_Iscsi(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=71, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.iscsi = kwargs.get("iscsi", [])
+
+    def __str__(self):
+        retval = ""
+        for iscsi in self.iscsi:
+            retval += iscsi.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--target", dest="target", action="store", type="string")
+        op.add_option("--ipaddr", dest="ipaddr", action="store", type="string",
+                      required=1)
+        op.add_option("--port", dest="port", action="store", type="string")
+        op.add_option("--user", dest="user", action="store", type="string")
+        op.add_option("--password", dest="password", action="store",
+                      type="string")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 0:
+            mapping = {"command": "iscsi", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))
+
+        dd = self.handler.IscsiData()
+        self._setToObj(self.op, opts, dd)
+        dd.lineno = self.lineno
+        return dd
+
+    def dataList(self):
+        return self.iscsi
+
+class F10_Iscsi(FC6_Iscsi):
+    removedKeywords = FC6_Iscsi.removedKeywords
+    removedAttrs = FC6_Iscsi.removedAttrs
+
+    def _getParser(self):
+        op = FC6_Iscsi._getParser(self)
+        op.add_option("--reverse-user", dest="user_in", action="store",
+                      type="string")
+        op.add_option("--reverse-password", dest="password_in", action="store",
+                      type="string")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsiname.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/iscsiname.py
new file mode 100644 (file)
index 0000000..ccfbe5f
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Chris Lumens <clumens@redhat.com>
+# Peter Jones <pjones@redhat.com>
+#
+# Copyright 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_IscsiName(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=70, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.iscsiname = kwargs.get("iscsiname", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.iscsiname != "":
+            retval += "iscsiname %s\n" % self.iscsiname
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "iscsiname"))
+        self.iscsiname = extra[0]
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/key.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/key.py
new file mode 100644 (file)
index 0000000..cfeb62e
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# 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.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class RHEL5_Key(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.key = kwargs.get("key", "")
+        self.skip = kwargs.get("skip", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.key == KS_INSTKEY_SKIP:
+            retval += "key --skip\n"
+        elif self.key != "":
+            retval += "key %s\n" % self.key
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--skip", action="store_true", default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if self.skip:
+            self.key = KS_INSTKEY_SKIP
+        elif len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "key"))
+        else:
+            self.key = extra[0]
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/keyboard.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/keyboard.py
new file mode 100644 (file)
index 0000000..90379c4
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Keyboard(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.keyboard = kwargs.get("keyboard", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.keyboard != "":
+            retval += "# System keyboard\nkeyboard %s\n" % self.keyboard
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "keyboard"))
+
+        self.keyboard = extra[0]
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lang.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lang.py
new file mode 100644 (file)
index 0000000..846a356
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Lang(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.lang = kwargs.get("lang", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.lang != "":
+            retval += "# System language\nlang %s\n" % self.lang
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "lang"))
+
+        self.lang = extra[0]
+        return self
+
+    def apply(self, instroot="/"):
+        if self.lang == "": return
+        f = open(instroot + "/etc/sysconfig/i18n", "w+")
+        f.write("LANG=\"%s\"\n" %(self.lang,))
+        f.close()
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/langsupport.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/langsupport.py
new file mode 100644 (file)
index 0000000..73a9e53
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+class FC3_LangSupport(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.deflang = kwargs.get("deflang", "")
+        self.supported = kwargs.get("supported", [])
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.deflang:
+            retval += "langsupport --default=%s" % self.deflang
+
+            if self.supported:
+                retval += " %s" % " ".join(self.supported)
+
+        return retval + "\n"
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--default", dest="deflang", default="en_US.UTF-8")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        self.supported = extra
+        return self
+
+class FC5_LangSupport(DeprecatedCommand):
+    def __init__(self):
+        DeprecatedCommand.__init__(self)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lilocheck.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/lilocheck.py
new file mode 100644 (file)
index 0000000..754a32c
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_LiloCheck(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.check = kwargs.get("check", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.check:
+            retval += "lilocheck\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "lilocheck"))
+
+        self.check = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logging.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logging.py
new file mode 100644 (file)
index 0000000..0708f77
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007, 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_Logging(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.host = kwargs.get("host", "")
+        self.level = kwargs.get("level", "info")
+        self.port = kwargs.get("port", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+        retval += "# Installation logging level\nlogging --level=%s" % self.level
+
+        if self.host != "":
+            retval += " --host=%s" % self.host
+
+            if self.port != "":
+                retval += " --port=%s" % self.port
+
+        return retval + "\n"
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--host")
+        op.add_option("--level", type="choice", default="info",
+                      choices=["debug", "info", "warning", "error", "critical"])
+        op.add_option("--port")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if opts.port and not opts.host:
+            raise KickstartParseError (formatErrorMsg(self.lineno, msg=_("Can't specify --port without --host.")))
+
+        self._setToSelf(self.op, opts)
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logvol.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/logvol.py
new file mode 100644 (file)
index 0000000..08bbf14
--- /dev/null
@@ -0,0 +1,304 @@
+#
+# 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_LogVolData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.fstype = kwargs.get("fstype", "")
+        self.grow = kwargs.get("grow", False)
+        self.maxSizeMB = kwargs.get("maxSizeMB", 0)
+        self.name = kwargs.get("name", "")
+        self.format = kwargs.get("format", True)
+        self.percent = kwargs.get("percent", 0)
+        self.recommended = kwargs.get("recommended", False)
+        self.size = kwargs.get("size", None)
+        self.preexist = kwargs.get("preexist", False)
+        self.vgname = kwargs.get("vgname", "")
+        self.mountpoint = kwargs.get("mountpoint", "")
+
+    def __eq__(self, y):
+        return self.vgname == y.vgname and self.name == y.name
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        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.percent > 0:
+            retval += " --percent=%d" % self.percent
+        if self.recommended:
+            retval += " --recommended"
+        if self.size > 0:
+            retval += " --size=%d" % self.size
+        if self.preexist:
+            retval += " --useexisting"
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "logvol %s %s --name=%s --vgname=%s\n" % (self.mountpoint, self._getArgsAsStr(), self.name, self.vgname)
+        return retval
+
+class FC4_LogVolData(FC3_LogVolData):
+    removedKeywords = FC3_LogVolData.removedKeywords
+    removedAttrs = FC3_LogVolData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_LogVolData.__init__(self, *args, **kwargs)
+        self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
+        self.fsopts = kwargs.get("fsopts", "")
+
+    def _getArgsAsStr(self):
+        retval = FC3_LogVolData._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
+
+        return retval
+
+class RHEL5_LogVolData(FC4_LogVolData):
+    removedKeywords = FC4_LogVolData.removedKeywords
+    removedAttrs = FC4_LogVolData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC4_LogVolData.__init__(self, *args, **kwargs)
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC4_LogVolData._getArgsAsStr(self)
+
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\"" % self.passphrase
+
+        return retval
+
+class F9_LogVolData(FC4_LogVolData):
+    removedKeywords = FC4_LogVolData.removedKeywords + ["bytesPerInode"]
+    removedAttrs = FC4_LogVolData.removedAttrs + ["bytesPerInode"]
+
+    def __init__(self, *args, **kwargs):
+        FC4_LogVolData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.fsopts = kwargs.get("fsopts", "")
+        self.fsprofile = kwargs.get("fsprofile", "")
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC4_LogVolData._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 F12_LogVolData(F9_LogVolData):
+    removedKeywords = F9_LogVolData.removedKeywords
+    removedAttrs = F9_LogVolData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F9_LogVolData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.escrowcert = kwargs.get("escrowcert", "")
+        self.backuppassphrase = kwargs.get("backuppassphrase", False)
+
+    def _getArgsAsStr(self):
+        retval = F9_LogVolData._getArgsAsStr(self)
+
+        if self.encrypted and self.escrowcert != "":
+            retval += " --escrowcert=\"%s\"" % self.escrowcert
+
+            if self.backuppassphrase:
+                retval += " --backuppassphrase"
+
+        return retval
+
+F14_LogVolData = F12_LogVolData
+
+class F15_LogVolData(F14_LogVolData):
+    removedKeywords = F14_LogVolData.removedKeywords
+    removedAttrs = F14_LogVolData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F14_LogVolData.__init__(self, *args, **kwargs)
+        self.label = kwargs.get("label", "")
+
+    def _getArgsAsStr(self):
+        retval = F14_LogVolData._getArgsAsStr(self)
+
+        if self.label != "":
+            retval += " --label=\"%s\"" % self.label
+
+        return retval
+
+class FC3_LogVol(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=133, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.lvList = kwargs.get("lvList", [])
+
+    def __str__(self):
+        retval = ""
+
+        for part in self.lvList:
+            retval += part.__str__()
+
+        return retval
+
+    def _getParser(self):
+        def lv_cb (option, opt_str, value, parser):
+            parser.values.format = False
+            parser.values.preexist = True
+
+        op = KSOptionParser()
+        op.add_option("--fstype", 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("--name", dest="name", required=1)
+        op.add_option("--noformat", action="callback", callback=lv_cb,
+                      dest="format", default=True, nargs=0)
+        op.add_option("--percent", dest="percent", action="store", type="int",
+                      nargs=1)
+        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("--useexisting", dest="preexist", action="store_true",
+                      default=False)
+        op.add_option("--vgname", dest="vgname", required=1)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) == 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol"))
+
+        lvd = self.handler.LogVolData()
+        self._setToObj(self.op, opts, lvd)
+        lvd.lineno = self.lineno
+        lvd.mountpoint=extra[0]
+
+        # Check for duplicates in the data list.
+        if lvd in self.dataList():
+            warnings.warn(_("A logical volume with the name %s has already been defined in volume group %s.") % (lvd.device, lvd.vgname))
+
+        return lvd
+
+    def dataList(self):
+        return self.lvList
+
+class FC4_LogVol(FC3_LogVol):
+    removedKeywords = FC3_LogVol.removedKeywords
+    removedAttrs = FC3_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = FC3_LogVol._getParser(self)
+        op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
+                      type="int", nargs=1)
+        op.add_option("--fsoptions", dest="fsopts")
+        return op
+
+class RHEL5_LogVol(FC4_LogVol):
+    removedKeywords = FC4_LogVol.removedKeywords
+    removedAttrs = FC4_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = FC4_LogVol._getParser(self)
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+class F9_LogVol(FC4_LogVol):
+    removedKeywords = FC4_LogVol.removedKeywords
+    removedAttrs = FC4_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = FC4_LogVol._getParser(self)
+        op.add_option("--bytes-per-inode", deprecated=1)
+        op.add_option("--fsprofile", dest="fsprofile", action="store",
+                      type="string", nargs=1)
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+class F12_LogVol(F9_LogVol):
+    removedKeywords = F9_LogVol.removedKeywords
+    removedAttrs = F9_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = F9_LogVol._getParser(self)
+        op.add_option("--escrowcert")
+        op.add_option("--backuppassphrase", action="store_true", default=False)
+        return op
+
+class F14_LogVol(F12_LogVol):
+    removedKeywords = F12_LogVol.removedKeywords
+    removedAttrs = F12_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = F12_LogVol._getParser(self)
+        op.remove_option("--bytes-per-inode")
+        return op
+
+class F15_LogVol(F14_LogVol):
+    removedKeywords = F14_LogVol.removedKeywords
+    removedAttrs = F14_LogVol.removedAttrs
+
+    def _getParser(self):
+        op = F14_LogVol._getParser(self)
+        op.add_option("--label")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mediacheck.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mediacheck.py
new file mode 100644 (file)
index 0000000..9a785d8
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# 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.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC4_MediaCheck(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.mediacheck = kwargs.get("mediacheck", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+        if self.mediacheck:
+            retval += "mediacheck\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "mediacheck"))
+
+        self.mediacheck = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/method.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/method.py
new file mode 100644 (file)
index 0000000..3b384c1
--- /dev/null
@@ -0,0 +1,186 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007, 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.
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Method(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.method = kwargs.get("method", "")
+
+        # Set all these attributes so calls to this command's __call__
+        # method can set them.  However we don't want to provide them as
+        # arguments to __init__ because method is special.
+        self.biospart = None
+        self.partition = None
+        self.server = None
+        self.dir = None
+        self.url = None
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.method == "cdrom":
+            retval += "# Use CDROM installation media\ncdrom\n"
+        elif self.method == "harddrive":
+            msg = "# Use hard drive installation media\nharddrive --dir=%s" % self.dir
+
+            if self.biospart is not None:
+                retval += msg + " --biospart=%s\n" % self.biospart
+            else:
+                retval += msg + " --partition=%s\n" % self.partition
+        elif self.method == "nfs":
+            retval += "# Use NFS installation media\nnfs --server=%s --dir=%s\n" % (self.server, self.dir)
+        elif self.method == "url":
+            retval += "# Use network installation\nurl --url=\"%s\"\n" % self.url
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+
+        # method = "cdrom" falls through to the return
+        if self.currentCmd == "harddrive":
+            op.add_option("--biospart", dest="biospart")
+            op.add_option("--partition", dest="partition")
+            op.add_option("--dir", dest="dir", required=1)
+        elif self.currentCmd == "nfs":
+            op.add_option("--server", dest="server", required=1)
+            op.add_option("--dir", dest="dir", required=1)
+        elif self.currentCmd == "url":
+            op.add_option("--url", dest="url", required=1)
+
+        return op
+
+    def parse(self, args):
+        self.method = self.currentCmd
+
+        op = self._getParser()
+        (opts, extra) = op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(op, opts)
+
+        if self.currentCmd == "harddrive":
+            if self.biospart is None and self.partition is None or \
+               self.biospart is not None and self.partition is not None:
+                raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of biospart or partition options must be specified.")))
+
+        return self
+
+class FC6_Method(FC3_Method):
+    removedKeywords = FC3_Method.removedKeywords
+    removedAttrs = FC3_Method.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_Method.__init__(self, writePriority, *args, **kwargs)
+
+        # Same reason for this attribute as the comment in FC3_Method.
+        self.opts = None
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.method == "cdrom":
+            retval += "# Use CDROM installation media\ncdrom\n"
+        elif self.method == "harddrive":
+            msg = "# Use hard drive installation media\nharddrive --dir=%s" % self.dir
+
+            if self.biospart is not None:
+                retval += msg + " --biospart=%s\n" % self.biospart
+            else:
+                retval += msg + " --partition=%s\n" % self.partition
+        elif self.method == "nfs":
+            retval += "# Use NFS installation media\nnfs --server=%s --dir=%s" % (self.server, self.dir)
+            if self.opts is not None:
+                retval += " --opts=\"%s\"" % self.opts
+            retval += "\n"
+        elif self.method == "url":
+            retval += "# Use network installation\nurl --url=\"%s\"\n" % self.url
+
+        return retval
+
+    def _getParser(self):
+        op = FC3_Method._getParser(self)
+
+        if self.currentCmd == "nfs":
+            op.add_option("--opts", dest="opts")
+
+        return op
+
+class F13_Method(FC6_Method):
+    removedKeywords = FC6_Method.removedKeywords
+    removedAttrs = FC6_Method.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC6_Method.__init__(self, *args, **kwargs)
+
+        # And same as all the other __init__ methods.
+        self.proxy = ""
+
+    def __str__(self):
+        retval = FC6_Method.__str__(self)
+
+        if self.method == "url" and self.proxy:
+            retval = retval.strip()
+            retval += " --proxy=\"%s\"\n" % self.proxy
+
+        return retval
+
+    def _getParser(self):
+        op = FC6_Method._getParser(self)
+
+        if self.currentCmd == "url":
+            op.add_option("--proxy")
+
+        return op
+
+class F14_Method(F13_Method):
+    removedKeywords = F13_Method.removedKeywords
+    removedAttrs = F13_Method.removedAttrs    
+
+    def __init__(self, *args, **kwargs):
+        F13_Method.__init__(self, *args, **kwargs)
+
+        self.noverifyssl = False
+
+    def __str__(self):
+        retval = F13_Method.__str__(self)
+
+        if self.method == "url" and self.noverifyssl:
+            retval = retval.strip()
+            retval += " --noverifyssl\n"
+
+        return retval
+
+    def _getParser(self):
+        op = F13_Method._getParser(self)
+
+        if self.currentCmd == "url":
+            op.add_option("--noverifyssl", action="store_true", default=False)
+
+        return op
+
+RHEL6_Method = F14_Method
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/monitor.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/monitor.py
new file mode 100644 (file)
index 0000000..57f1e51
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# 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
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Monitor(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.hsync = kwargs.get("hsync", "")
+        self.monitor = kwargs.get("monitor", "")
+        self.vsync = kwargs.get("vsync", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+        retval += "monitor"
+
+        if self.hsync != "":
+            retval += " --hsync=%s" % self.hsync
+        if self.monitor != "":
+            retval += " --monitor=\"%s\"" % self.monitor
+        if self.vsync != "":
+            retval += " --vsync=%s" % self.vsync
+
+        if retval != "monitor":
+            return retval + "\n"
+        else:
+            return ""
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--hsync")
+        op.add_option("--monitor")
+        op.add_option("--vsync")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if extra:
+            mapping = {"cmd": "monitor", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(cmd)s command: %(options)s") % mapping))
+
+        self._setToSelf(self.op, opts)
+        return self
+
+class FC6_Monitor(FC3_Monitor):
+    removedKeywords = FC3_Monitor.removedKeywords
+    removedAttrs = FC3_Monitor.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_Monitor.__init__(self, writePriority, *args, **kwargs)
+        self.probe = kwargs.get("probe", True)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+        retval += "monitor"
+
+        if self.hsync != "":
+            retval += " --hsync=%s" % self.hsync
+        if self.monitor != "":
+            retval += " --monitor=\"%s\"" % self.monitor
+        if not self.probe:
+            retval += " --noprobe"
+        if self.vsync != "":
+            retval += " --vsync=%s" % self.vsync
+
+        if retval != "monitor":
+            return retval + "\n"
+        else:
+            return ""
+
+    def _getParser(self):
+        op = FC3_Monitor._getParser(self)
+        op.add_option("--noprobe", dest="probe", action="store_false",
+                      default=True)
+        return op
+
+class F10_Monitor(DeprecatedCommand):
+    def __init__(self):
+        DeprecatedCommand.__init__(self)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mouse.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/mouse.py
new file mode 100644 (file)
index 0000000..d7ad1ae
--- /dev/null
@@ -0,0 +1,70 @@
+#
+# 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.
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class RHEL3_Mouse(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.device = kwargs.get("device", "")
+        self.emulthree = kwargs.get("emulthree", False)
+        self.mouse = kwargs.get("mouse", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        opts = ""
+        if self.device:
+            opts += "--device=%s " % self.device
+        if self.emulthree:
+            opts += "--emulthree "
+
+        if self.mouse:
+            retval += "# System mouse\nmouse %s%s\n" % (opts, self.mouse)
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--device", dest="device", default="")
+        op.add_option("--emulthree", dest="emulthree", default=False, action="store_true")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "mouse"))
+
+        self.mouse = extra[0]
+        return self
+
+class FC3_Mouse(DeprecatedCommand):
+    def __init__(self):
+        DeprecatedCommand.__init__(self)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/multipath.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/multipath.py
new file mode 100644 (file)
index 0000000..4d5b26b
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# Chris Lumens <clumens@redhat.com>
+# Peter Jones <pjones@redhat.com>
+#
+# Copyright 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_MpPathData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.mpdev = kwargs.get("mpdev", "")
+        self.device = kwargs.get("device", "")
+        self.rule = kwargs.get("rule", "")
+
+    def __str__(self):
+        return " --device=%s --rule=\"%s\"" % (self.device, self.rule)
+
+class FC6_MultiPathData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.name = kwargs.get("name", "")
+        self.paths = kwargs.get("paths", [])
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+
+        for path in self.paths:
+            retval += "multipath --mpdev=%s %s\n" % (self.name, path.__str__())
+
+        return retval
+
+class FC6_MultiPath(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=50, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.mpaths = kwargs.get("mpaths", [])
+
+    def __str__(self):
+        retval = ""
+        for mpath in self.mpaths:
+            retval += mpath.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--name", dest="name", action="store", type="string",
+                      required=1)
+        op.add_option("--device", dest="device", action="store", type="string",
+                      required=1)
+        op.add_option("--rule", dest="rule", action="store", type="string",
+                      required=1)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        dd = FC6_MpPathData()
+        self._setToObj(self.op, opts, dd)
+        dd.lineno = self.lineno
+        dd.mpdev = dd.mpdev.split('/')[-1]
+
+        parent = None
+        for x in range(0, len(self.mpaths)):
+            mpath = self.mpaths[x]
+            for path in mpath.paths:
+                if path.device == dd.device:
+                    mapping = {"device": path.device, "multipathdev": path.mpdev}
+                    raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Device '%(device)s' is already used in multipath '%(multipathdev)s'") % mapping))
+            if mpath.name == dd.mpdev:
+                parent = x
+
+        if parent is None:
+            mpath = FC6_MultiPathData()
+            return mpath
+        else:
+            mpath = self.mpaths[parent]
+
+        return dd
+
+    def dataList(self):
+        return self.mpaths
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/network.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/network.py
new file mode 100644 (file)
index 0000000..9b67f92
--- /dev/null
@@ -0,0 +1,363 @@
+#
+# 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.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_NetworkData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.bootProto = kwargs.get("bootProto", BOOTPROTO_DHCP)
+        self.dhcpclass = kwargs.get("dhcpclass", "")
+        self.device = kwargs.get("device", "")
+        self.essid = kwargs.get("essid", "")
+        self.ethtool = kwargs.get("ethtool", "")
+        self.gateway = kwargs.get("gateway", "")
+        self.hostname = kwargs.get("hostname", "")
+        self.ip = kwargs.get("ip", "")
+        self.mtu = kwargs.get("mtu", "")
+        self.nameserver = kwargs.get("nameserver", "")
+        self.netmask = kwargs.get("netmask", "")
+        self.nodns = kwargs.get("nodns", False)
+        self.onboot = kwargs.get("onboot", True)
+        self.wepkey = kwargs.get("wepkey", "")
+
+    def __eq__(self, y):
+        return self.device and self.device == y.device
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.bootProto != "":
+            retval += " --bootproto=%s" % self.bootProto
+        if self.dhcpclass != "":
+            retval += " --dhcpclass=%s" % self.dhcpclass
+        if self.device != "":
+            retval += " --device=%s" % self.device
+        if self.essid != "":
+            retval += " --essid=\"%s\"" % self.essid
+        if self.ethtool != "":
+            retval += " --ethtool=\"%s\"" % self.ethtool
+        if self.gateway != "":
+            retval += " --gateway=%s" % self.gateway
+        if self.hostname != "":
+            retval += " --hostname=%s" % self.hostname
+        if self.ip != "":
+            retval += " --ip=%s" % self.ip
+        if self.mtu != "":
+            retval += " --mtu=%s" % self.mtu
+        if self.nameserver != "":
+            retval += " --nameserver=%s" % self.nameserver
+        if self.netmask != "":
+            retval += " --netmask=%s" % self.netmask
+        if self.nodns:
+            retval += " --nodns"
+        if not self.onboot:
+            retval += " --onboot=off"
+        if self.wepkey != "":
+            retval += " --wepkey=%s" % self.wepkey
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "network %s\n" % self._getArgsAsStr()
+        return retval
+
+class FC4_NetworkData(FC3_NetworkData):
+    removedKeywords = FC3_NetworkData.removedKeywords
+    removedAttrs = FC3_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_NetworkData.__init__(self, *args, **kwargs)
+        self.notksdevice = kwargs.get("notksdevice", False)
+
+    def _getArgsAsStr(self):
+        retval = FC3_NetworkData._getArgsAsStr(self)
+
+        if self.notksdevice:
+            retval += " --notksdevice"
+
+        return retval
+
+class FC6_NetworkData(FC4_NetworkData):
+    removedKeywords = FC4_NetworkData.removedKeywords
+    removedAttrs = FC4_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC4_NetworkData.__init__(self, *args, **kwargs)
+        self.noipv4 = kwargs.get("noipv4", False)
+        self.noipv6 = kwargs.get("noipv6", False)
+
+    def _getArgsAsStr(self):
+        retval = FC4_NetworkData._getArgsAsStr(self)
+
+        if self.noipv4:
+            retval += " --noipv4"
+        if self.noipv6:
+            retval += " --noipv6"
+
+        return retval
+
+class F8_NetworkData(FC6_NetworkData):
+    removedKeywords = FC6_NetworkData.removedKeywords
+    removedAttrs = FC6_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC6_NetworkData.__init__(self, *args, **kwargs)
+        self.ipv6 = kwargs.get("ipv6", "")
+
+    def _getArgsAsStr(self):
+        retval = FC6_NetworkData._getArgsAsStr(self)
+
+        if self.ipv6 != "":
+            retval += " --ipv6" % self.ipv6
+
+        return retval
+
+class F16_NetworkData(F8_NetworkData):
+    removedKeywords = F8_NetworkData.removedKeywords
+    removedAttrs = F8_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F8_NetworkData.__init__(self, *args, **kwargs)
+        self.activate = kwargs.get("activate", False)
+        self.nodefroute = kwargs.get("nodefroute", False)
+        self.wpakey = kwargs.get("wpakey", "")
+
+    def _getArgsAsStr(self):
+        retval = F8_NetworkData._getArgsAsStr(self)
+
+        if self.activate:
+            retval += " --activate"
+        if self.nodefroute:
+            retval += " --nodefroute"
+        if self.wpakey != "":
+            retval += "--wpakey=%s" % self.wpakey
+
+        return retval
+
+class RHEL4_NetworkData(FC3_NetworkData):
+    removedKeywords = FC3_NetworkData.removedKeywords
+    removedAttrs = FC3_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_NetworkData.__init__(self, *args, **kwargs)
+        self.notksdevice = kwargs.get("notksdevice", False)
+
+    def _getArgsAsStr(self):
+        retval = FC3_NetworkData._getArgsAsStr(self)
+
+        if self.notksdevice:
+            retval += " --notksdevice"
+
+        return retval
+
+class RHEL6_NetworkData(F8_NetworkData):
+    removedKeywords = F8_NetworkData.removedKeywords
+    removedAttrs = F8_NetworkData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F8_NetworkData.__init__(self, *args, **kwargs)
+        self.activate = kwargs.get("activate", False)
+        self.nodefroute = kwargs.get("nodefroute", False)
+
+    def _getArgsAsStr(self):
+        retval = F8_NetworkData._getArgsAsStr(self)
+
+        if self.activate:
+            retval += " --activate"
+        if self.nodefroute:
+            retval += " --nodefroute"
+
+        return retval
+
+class FC3_Network(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.bootprotoList = [BOOTPROTO_DHCP, BOOTPROTO_BOOTP,
+                              BOOTPROTO_STATIC]
+
+        self.op = self._getParser()
+
+        self.network = kwargs.get("network", [])
+
+    def __str__(self):
+        retval = ""
+
+        for nic in self.network:
+            retval += nic.__str__()
+
+        if retval != "":
+            return "# Network information\n" + retval
+        else:
+            return ""
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--bootproto", dest="bootProto",
+                      default=BOOTPROTO_DHCP,
+                      choices=self.bootprotoList)
+        op.add_option("--dhcpclass", dest="dhcpclass")
+        op.add_option("--device", dest="device")
+        op.add_option("--essid", dest="essid")
+        op.add_option("--ethtool", dest="ethtool")
+        op.add_option("--gateway", dest="gateway")
+        op.add_option("--hostname", dest="hostname")
+        op.add_option("--ip", dest="ip")
+        op.add_option("--mtu", dest="mtu")
+        op.add_option("--nameserver", dest="nameserver")
+        op.add_option("--netmask", dest="netmask")
+        op.add_option("--nodns", dest="nodns", action="store_true",
+                      default=False)
+        op.add_option("--onboot", dest="onboot", action="store",
+                      type="ksboolean")
+        op.add_option("--wepkey", dest="wepkey")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        nd = self.handler.NetworkData()
+        self._setToObj(self.op, opts, nd)
+        nd.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if nd in self.dataList():
+            warnings.warn(_("A network device with the name %s has already been defined.") % nd.device)
+
+        return nd
+
+    def dataList(self):
+        return self.network
+
+class FC4_Network(FC3_Network):
+    removedKeywords = FC3_Network.removedKeywords
+    removedAttrs = FC3_Network.removedAttrs
+
+    def _getParser(self):
+        op = FC3_Network._getParser(self)
+        op.add_option("--notksdevice", dest="notksdevice", action="store_true",
+                      default=False)
+        return op
+
+class FC6_Network(FC4_Network):
+    removedKeywords = FC4_Network.removedKeywords
+    removedAttrs = FC4_Network.removedAttrs
+
+    def _getParser(self):
+        op = FC4_Network._getParser(self)
+        op.add_option("--noipv4", dest="noipv4", action="store_true",
+                      default=False)
+        op.add_option("--noipv6", dest="noipv6", action="store_true",
+                      default=False)
+        return op
+
+class F8_Network(FC6_Network):
+    removedKeywords = FC6_Network.removedKeywords
+    removedAttrs = FC6_Network.removedAttrs
+
+    def _getParser(self):
+        op = FC6_Network._getParser(self)
+        op.add_option("--ipv6", dest="ipv6")
+        return op
+
+class F9_Network(F8_Network):
+    removedKeywords = F8_Network.removedKeywords
+    removedAttrs = F8_Network.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F8_Network.__init__(self, writePriority, *args, **kwargs)
+        self.bootprotoList.append(BOOTPROTO_QUERY)
+
+    def _getParser(self):
+        op = F8_Network._getParser(self)
+        op.add_option("--bootproto", dest="bootProto",
+                      default=BOOTPROTO_DHCP,
+                      choices=self.bootprotoList)
+        return op
+
+class F16_Network(F9_Network):
+    removedKeywords = F9_Network.removedKeywords
+    removedAttrs = F9_Network.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F9_Network.__init__(self, writePriority, *args, **kwargs)
+        self.bootprotoList.append(BOOTPROTO_IBFT)
+
+    def _getParser(self):
+        op = F9_Network._getParser(self)
+        op.add_option("--activate", dest="activate", action="store_true",
+                      default=False)
+        op.add_option("--nodefroute", dest="nodefroute", action="store_true",
+                      default=False)
+        op.add_option("--wpakey", dest="wpakey", action="store", default="")
+        return op
+
+class RHEL4_Network(FC3_Network):
+    removedKeywords = FC3_Network.removedKeywords
+    removedAttrs = FC3_Network.removedAttrs
+
+    def _getParser(self):
+        op = FC3_Network._getParser(self)
+        op.add_option("--notksdevice", dest="notksdevice", action="store_true",
+                      default=False)
+        return op
+
+class RHEL5_Network(FC6_Network):
+    removedKeywords = FC6_Network.removedKeywords
+    removedAttrs = FC6_Network.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC6_Network.__init__(self, writePriority, *args, **kwargs)
+        self.bootprotoList.append(BOOTPROTO_QUERY)
+
+    def _getParser(self):
+        op = FC6_Network._getParser(self)
+        op.add_option("--bootproto", dest="bootProto",
+                      default=BOOTPROTO_DHCP,
+                      choices=self.bootprotoList)
+        return op
+
+class RHEL6_Network(F9_Network):
+    removedKeywords = F9_Network.removedKeywords
+    removedAttrs = F9_Network.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F9_Network.__init__(self, writePriority, *args, **kwargs)
+        self.bootprotoList.append(BOOTPROTO_IBFT)
+
+    def _getParser(self):
+        op = F9_Network._getParser(self)
+        op.add_option("--activate", dest="activate", action="store_true",
+                      default=False)
+        op.add_option("--nodefroute", dest="nodefroute", action="store_true",
+                      default=False)
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/partition.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/partition.py
new file mode 100644 (file)
index 0000000..5dbd4d4
--- /dev/null
@@ -0,0 +1,357 @@
+#
+# 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", "")
+        self.fslabel = kwargs.get("fslabel", "")
+
+    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
+        if self.fslabel != "":
+            retval += " --fslabel=%s" % self.fslabel
+
+        return retval
+
+class RHEL5_PartData(FC4_PartData):
+    removedKeywords = FC4_PartData.removedKeywords
+    removedAttrs = FC4_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC4_PartData.__init__(self, *args, **kwargs)
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC4_PartData._getArgsAsStr(self)
+
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\"" % self.passphrase
+
+        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")
+        op.add_option("--fslabel", dest="fslabel")
+        return op
+
+class RHEL5_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("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        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/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/raid.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/raid.py
new file mode 100644 (file)
index 0000000..adf3524
--- /dev/null
@@ -0,0 +1,365 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_RaidData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.device = kwargs.get("device", None)
+        self.fstype = kwargs.get("fstype", "")
+        self.level = kwargs.get("level", "")
+        self.format = kwargs.get("format", True)
+        self.spares = kwargs.get("spares", 0)
+        self.preexist = kwargs.get("preexist", False)
+        self.mountpoint = kwargs.get("mountpoint", "")
+        self.members = kwargs.get("members", [])
+
+    def __eq__(self, y):
+        return self.device == y.device
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.device != "":
+            retval += " --device=%s" % self.device
+        if self.fstype != "":
+            retval += " --fstype=\"%s\"" % self.fstype
+        if self.level != "":
+            retval += " --level=%s" % self.level
+        if not self.format:
+            retval += " --noformat"
+        if self.spares != 0:
+            retval += " --spares=%d" % self.spares
+        if self.preexist:
+            retval += " --useexisting"
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "raid %s%s %s\n" % (self.mountpoint, self._getArgsAsStr(),
+                                      " ".join(self.members))
+        return retval
+
+class FC4_RaidData(FC3_RaidData):
+    removedKeywords = FC3_RaidData.removedKeywords
+    removedAttrs = FC3_RaidData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_RaidData.__init__(self, *args, **kwargs)
+        self.fsopts = kwargs.get("fsopts", "")
+
+    def _getArgsAsStr(self):
+        retval = FC3_RaidData._getArgsAsStr(self)
+
+        if self.fsopts != "":
+            retval += " --fsoptions=\"%s\"" % self.fsopts
+
+        return retval
+
+class FC5_RaidData(FC4_RaidData):
+    removedKeywords = FC4_RaidData.removedKeywords
+    removedAttrs = FC4_RaidData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC4_RaidData.__init__(self, *args, **kwargs)
+        self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
+
+    def _getArgsAsStr(self):
+        retval = FC4_RaidData._getArgsAsStr(self)
+
+        if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
+            retval += " --bytes-per-inode=%d" % self.bytesPerInode
+
+        return retval
+
+class RHEL5_RaidData(FC5_RaidData):
+    removedKeywords = FC5_RaidData.removedKeywords
+    removedAttrs = FC5_RaidData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC5_RaidData.__init__(self, *args, **kwargs)
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC5_RaidData._getArgsAsStr(self)
+
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\"" % self.passphrase
+
+        return retval
+
+F7_RaidData = FC5_RaidData
+
+class F9_RaidData(FC5_RaidData):
+    removedKeywords = FC5_RaidData.removedKeywords + ["bytesPerInode"]
+    removedAttrs = FC5_RaidData.removedAttrs + ["bytesPerInode"]
+
+    def __init__(self, *args, **kwargs):
+        FC5_RaidData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.fsprofile = kwargs.get("fsprofile", "")
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC5_RaidData._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 F12_RaidData(F9_RaidData):
+    removedKeywords = F9_RaidData.removedKeywords
+    removedAttrs = F9_RaidData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F9_RaidData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.escrowcert = kwargs.get("escrowcert", "")
+        self.backuppassphrase = kwargs.get("backuppassphrase", False)
+
+    def _getArgsAsStr(self):
+        retval = F9_RaidData._getArgsAsStr(self)
+
+        if self.encrypted and self.escrowcert != "":
+            retval += " --escrowcert=\"%s\"" % self.escrowcert
+
+            if self.backuppassphrase:
+                retval += " --backuppassphrase"
+        return retval
+
+F13_RaidData = F12_RaidData
+
+F14_RaidData = F13_RaidData
+
+class F15_RaidData(F14_RaidData):
+    removedKeywords = F14_RaidData.removedKeywords
+    removedAttrs = F14_RaidData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F14_RaidData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.label = kwargs.get("label", "")
+
+    def _getArgsAsStr(self):
+        retval = F14_RaidData._getArgsAsStr(self)
+
+        if self.label != "":
+            retval += " --label=%s" % self.label
+
+        return retval
+
+class FC3_Raid(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=131, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        # A dict of all the RAID levels we support.  This means that if we
+        # support more levels in the future, subclasses don't have to
+        # duplicate too much.
+        self.levelMap = { "RAID0": "RAID0", "0": "RAID0",
+                          "RAID1": "RAID1", "1": "RAID1",
+                          "RAID5": "RAID5", "5": "RAID5",
+                          "RAID6": "RAID6", "6": "RAID6" }
+
+        self.raidList = kwargs.get("raidList", [])
+
+    def __str__(self):
+        retval = ""
+
+        for raid in self.raidList:
+            retval += raid.__str__()
+
+        return retval
+
+    def _getParser(self):
+        def raid_cb (option, opt_str, value, parser):
+            parser.values.format = False
+            parser.values.preexist = True
+
+        def device_cb (option, opt_str, value, parser):
+            if value[0:2] == "md":
+                parser.values.ensure_value(option.dest, value[2:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+        def level_cb (option, opt_str, value, parser):
+            if self.levelMap.has_key(value):
+                parser.values.ensure_value(option.dest, self.levelMap[value])
+
+        op = KSOptionParser()
+        op.add_option("--device", action="callback", callback=device_cb,
+                      dest="device", type="string", nargs=1, required=1)
+        op.add_option("--fstype", dest="fstype")
+        op.add_option("--level", dest="level", action="callback",
+                      callback=level_cb, type="string", nargs=1)
+        op.add_option("--noformat", action="callback", callback=raid_cb,
+                      dest="format", default=True, nargs=0)
+        op.add_option("--spares", dest="spares", action="store", type="int",
+                      nargs=1, default=0)
+        op.add_option("--useexisting", dest="preexist", action="store_true",
+                      default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) == 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "raid"))
+        if len(extra) == 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Partitions required for %s") % "raid"))
+
+        rd = self.handler.RaidData()
+        self._setToObj(self.op, opts, rd)
+        rd.lineno = self.lineno
+
+        # --device can't just take an int in the callback above, because it
+        # could be specificed as "mdX", which causes optparse to error when
+        # it runs int().
+        rd.device = int(rd.device)
+        rd.mountpoint = extra[0]
+        rd.members = extra[1:]
+
+        # Check for duplicates in the data list.
+        if rd in self.dataList():
+            warnings.warn(_("A RAID device with the name %s has already been defined.") % rd.device)
+
+        return rd
+
+    def dataList(self):
+        return self.raidList
+
+class FC4_Raid(FC3_Raid):
+    removedKeywords = FC3_Raid.removedKeywords
+    removedAttrs = FC3_Raid.removedAttrs
+
+    def _getParser(self):
+        op = FC3_Raid._getParser(self)
+        op.add_option("--fsoptions", dest="fsopts")
+        return op
+
+class FC5_Raid(FC4_Raid):
+    removedKeywords = FC4_Raid.removedKeywords
+    removedAttrs = FC4_Raid.removedAttrs
+
+    def _getParser(self):
+        op = FC4_Raid._getParser(self)
+        op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
+                      type="int", nargs=1)
+        return op
+
+class RHEL5_Raid(FC5_Raid):
+    removedKeywords = FC5_Raid.removedKeywords
+    removedAttrs = FC5_Raid.removedAttrs
+
+    def __init__(self, writePriority=131, *args, **kwargs):
+        FC5_Raid.__init__(self, writePriority, *args, **kwargs)
+
+        self.levelMap.update({"RAID10": "RAID10", "10": "RAID10"})
+
+    def _getParser(self):
+        op = FC5_Raid._getParser(self)
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+class F7_Raid(FC5_Raid):
+    removedKeywords = FC5_Raid.removedKeywords
+    removedAttrs = FC5_Raid.removedAttrs
+
+    def __init__(self, writePriority=131, *args, **kwargs):
+        FC5_Raid.__init__(self, writePriority, *args, **kwargs)
+
+        self.levelMap.update({"RAID10": "RAID10", "10": "RAID10"})
+
+class F9_Raid(F7_Raid):
+    removedKeywords = F7_Raid.removedKeywords
+    removedAttrs = F7_Raid.removedAttrs
+
+    def _getParser(self):
+        op = F7_Raid._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 F12_Raid(F9_Raid):
+    removedKeywords = F9_Raid.removedKeywords
+    removedAttrs = F9_Raid.removedAttrs
+
+    def _getParser(self):
+        op = F9_Raid._getParser(self)
+        op.add_option("--escrowcert")
+        op.add_option("--backuppassphrase", action="store_true", default=False)
+        return op
+
+class F13_Raid(F12_Raid):
+    removedKeywords = F12_Raid.removedKeywords
+    removedAttrs = F12_Raid.removedAttrs
+
+    def __init__(self, writePriority=131, *args, **kwargs):
+        F12_Raid.__init__(self, writePriority, *args, **kwargs)
+
+        self.levelMap.update({"RAID4": "RAID4", "4": "RAID4"})
+
+class F14_Raid(F13_Raid):
+    removedKeywords = F13_Raid.removedKeywords
+    removedAttrs = F13_Raid.removedAttrs
+
+    def _getParser(self):
+        op = F13_Raid._getParser(self)
+        op.remove_option("--bytes-per-inode")
+        return op
+
+class F15_Raid(F14_Raid):
+    removedKeywords = F14_Raid.removedKeywords
+    removedAttrs = F14_Raid.removedAttrs
+
+    def _getParser(self):
+        op = F14_Raid._getParser(self)
+        op.add_option("--label")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/reboot.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/reboot.py
new file mode 100644 (file)
index 0000000..391af14
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+class FC3_Reboot(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.action = kwargs.get("action", None)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.action == KS_REBOOT:
+            retval += "# Reboot after installation\nreboot\n"
+        elif self.action == KS_SHUTDOWN:
+            retval += "# Shutdown after installation\nshutdown\n"
+
+        return retval
+
+    def parse(self, args):
+        if self.currentCmd == "reboot":
+            self.action = KS_REBOOT
+        else:
+            self.action = KS_SHUTDOWN
+
+        return self
+
+class FC6_Reboot(FC3_Reboot):
+    removedKeywords = FC3_Reboot.removedKeywords
+    removedAttrs = FC3_Reboot.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_Reboot.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.eject = kwargs.get("eject", False)
+
+    def __str__(self):
+        retval = FC3_Reboot.__str__(self).rstrip()
+
+        if self.eject:
+            retval += " --eject"
+
+        return retval + "\n"
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--eject", dest="eject", action="store_true",
+                      default=False)
+        return op
+
+    def parse(self, args):
+        FC3_Reboot.parse(self, args)
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/repo.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/repo.py
new file mode 100644 (file)
index 0000000..b673982
--- /dev/null
@@ -0,0 +1,249 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007, 2008, 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_RepoData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.baseurl = kwargs.get("baseurl", "")
+        self.mirrorlist = kwargs.get("mirrorlist", None)
+        self.name = kwargs.get("name", "")
+
+    def __eq__(self, y):
+        return self.name == y.name
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.baseurl:
+            retval += "--baseurl=%s" % self.baseurl
+        elif self.mirrorlist:
+            retval += "--mirrorlist=%s" % self.mirrorlist
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "repo --name=\"%s\" %s\n" % (self.name, self._getArgsAsStr())
+        return retval
+
+class F8_RepoData(FC6_RepoData):
+    removedKeywords = FC6_RepoData.removedKeywords
+    removedAttrs = FC6_RepoData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC6_RepoData.__init__(self, *args, **kwargs)
+        self.cost = kwargs.get("cost", None)
+        self.includepkgs = kwargs.get("includepkgs", [])
+        self.excludepkgs = kwargs.get("excludepkgs", [])
+
+    def _getArgsAsStr(self):
+        retval = FC6_RepoData._getArgsAsStr(self)
+
+        if self.cost:
+            retval += " --cost=%s" % self.cost
+        if self.includepkgs:
+            retval += " --includepkgs=\"%s\"" % ",".join(self.includepkgs)
+        if self.excludepkgs:
+            retval += " --excludepkgs=\"%s\"" % ",".join(self.excludepkgs)
+
+        return retval
+
+class F11_RepoData(F8_RepoData):
+    removedKeywords = F8_RepoData.removedKeywords
+    removedAttrs = F8_RepoData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F8_RepoData.__init__(self, *args, **kwargs)
+        self.ignoregroups = kwargs.get("ignoregroups", None)
+
+    def _getArgsAsStr(self):
+        retval = F8_RepoData._getArgsAsStr(self)
+
+        if self.ignoregroups:
+            retval += " --ignoregroups=true"
+        return retval
+
+class F13_RepoData(F11_RepoData):
+    removedKeywords = F11_RepoData.removedKeywords
+    removedAttrs = F11_RepoData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F11_RepoData.__init__(self, *args, **kwargs)
+        self.proxy = kwargs.get("proxy", "")
+
+    def _getArgsAsStr(self):
+        retval = F11_RepoData._getArgsAsStr(self)
+
+        if self.proxy:
+            retval += " --proxy=\"%s\"" % self.proxy
+
+        return retval
+
+class F14_RepoData(F13_RepoData):
+    removedKeywords = F13_RepoData.removedKeywords
+    removedAttrs = F13_RepoData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F13_RepoData.__init__(self, *args, **kwargs)
+        self.noverifyssl = kwargs.get("noverifyssl", False)
+
+    def _getArgsAsStr(self):
+        retval = F13_RepoData._getArgsAsStr(self)
+
+        if self.noverifyssl:
+            retval += " --noverifyssl"
+
+        return retval
+
+RHEL6_RepoData = F14_RepoData
+
+F15_RepoData = F14_RepoData
+
+class FC6_Repo(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    urlRequired = True
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.repoList = kwargs.get("repoList", [])
+
+    def __str__(self):
+        retval = ""
+        for repo in self.repoList:
+            retval += repo.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--name", dest="name", required=1)
+        op.add_option("--baseurl")
+        op.add_option("--mirrorlist")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 0:
+            mapping = {"command": "repo", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))
+
+        # This is lame, but I can't think of a better way to make sure only
+        # one of these two is specified.
+        if opts.baseurl and opts.mirrorlist:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --baseurl and --mirrorlist may be specified for repo command.")))
+
+        if self.urlRequired and not opts.baseurl and not opts.mirrorlist:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("One of --baseurl or --mirrorlist must be specified for repo command.")))
+
+        rd = self.handler.RepoData()
+        self._setToObj(self.op, opts, rd)
+        rd.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if rd in self.dataList():
+            warnings.warn(_("A repo with the name %s has already been defined.") % rd.name)
+
+        return rd
+
+    def dataList(self):
+        return self.repoList
+
+class F8_Repo(FC6_Repo):
+    removedKeywords = FC6_Repo.removedKeywords
+    removedAttrs = FC6_Repo.removedAttrs
+
+    def __str__(self):
+        retval = ""
+        for repo in self.repoList:
+            retval += repo.__str__()
+
+        return retval
+
+    def _getParser(self):
+        def list_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = FC6_Repo._getParser(self)
+        op.add_option("--cost", action="store", type="int")
+        op.add_option("--excludepkgs", action="callback", callback=list_cb,
+                      nargs=1, type="string")
+        op.add_option("--includepkgs", action="callback", callback=list_cb,
+                      nargs=1, type="string")
+        return op
+
+    def methodToRepo(self):
+        if not self.handler.method.url:
+            raise KickstartError (formatErrorMsg(self.handler.method.lineno, msg=_("Method must be a url to be added to the repo list.")))
+        reponame = "ks-method-url"
+        repourl = self.handler.method.url
+        rd = self.handler.RepoData(name=reponame, baseurl=repourl)
+        return rd
+
+class F11_Repo(F8_Repo):
+    removedKeywords = F8_Repo.removedKeywords
+    removedAttrs = F8_Repo.removedAttrs
+
+    def _getParser(self):
+        op = F8_Repo._getParser(self)
+        op.add_option("--ignoregroups", action="store", type="ksboolean")
+        return op
+
+class F13_Repo(F11_Repo):
+    removedKeywords = F11_Repo.removedKeywords
+    removedAttrs = F11_Repo.removedAttrs
+
+    def _getParser(self):
+        op = F11_Repo._getParser(self)
+        op.add_option("--proxy")
+        return op
+
+class F14_Repo(F13_Repo):
+    removedKeywords = F13_Repo.removedKeywords
+    removedAttrs = F13_Repo.removedAttrs
+
+    def _getParser(self):
+        op = F13_Repo._getParser(self)
+        op.add_option("--noverifyssl", action="store_true", default=False)
+        return op
+
+RHEL6_Repo = F14_Repo
+
+class F15_Repo(F14_Repo):
+    removedKeywords = F14_Repo.removedKeywords
+    removedAttrs = F14_Repo.removedAttrs
+
+    urlRequired = False
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rescue.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rescue.py
new file mode 100644 (file)
index 0000000..682fefa
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Alexander Todorov <atodorov@redhat.com>
+#
+# Copyright 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
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F10_Rescue(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.rescue = False
+        self.nomount = kwargs.get("nomount", False)
+        self.romount = kwargs.get("romount", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.rescue:
+            retval += "rescue"
+
+            if self.nomount:
+                retval += " --nomount"
+            if self.romount:
+                retval += " --romount"
+
+            retval = "# Start rescue mode\n%s\n" % retval
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--nomount", dest="nomount", action="store_true", default=False)
+        op.add_option("--romount", dest="romount", action="store_true", default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if opts.nomount and opts.romount:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Only one of --nomount and --romount may be specified for rescue command.")))
+
+        self._setToSelf(self.op, opts)
+        self.rescue = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rootpw.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/rootpw.py
new file mode 100644 (file)
index 0000000..4237db8
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_RootPw(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.isCrypted = kwargs.get("isCrypted", False)
+        self.password = kwargs.get("password", "")
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.isCrypted:
+            retval += " --iscrypted"
+
+        return retval
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.password != "":
+            retval += "# Root password\nrootpw%s %s\n" % (self._getArgsAsStr(), self.password)
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--iscrypted", dest="isCrypted", action="store_true",
+                      default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if len(extra) != 1:
+            raise KickstartValueError ( formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "rootpw"))
+
+        self.password = extra[0]
+        return self
+
+class F8_RootPw(FC3_RootPw):
+    removedKeywords = FC3_RootPw.removedKeywords
+    removedAttrs = FC3_RootPw.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_RootPw.__init__(self, writePriority, *args, **kwargs)
+        self.lock = kwargs.get("lock", False)
+
+    def _getArgsAsStr(self):
+        retval = FC3_RootPw._getArgsAsStr(self)
+
+        if self.lock:
+            retval += " --lock"
+
+        if not self.isCrypted:
+            retval += " --plaintext"
+
+        return retval
+
+    def _getParser(self):
+        op = FC3_RootPw._getParser(self)
+        op.add_option("--lock", dest="lock", action="store_true", default=False)
+        op.add_option("--plaintext", dest="isCrypted", action="store_false")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/selinux.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/selinux.py
new file mode 100644 (file)
index 0000000..9f8059c
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.constants import *
+from pykickstart.options import *
+
+class FC3_SELinux(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.selinux = kwargs.get("selinux", None)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if not retval and self.selinux is None:
+            return ""
+
+        retval += "# SELinux configuration\n"
+
+        if self.selinux == SELINUX_DISABLED:
+            retval += "selinux --disabled\n"
+        elif self.selinux == SELINUX_ENFORCING:
+            retval += "selinux --enforcing\n"
+        elif self.selinux == SELINUX_PERMISSIVE:
+            retval += "selinux --permissive\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--disabled", dest="selinux", action="store_const",
+                      const=SELINUX_DISABLED)
+        op.add_option("--enforcing", dest="selinux", action="store_const",
+                      const=SELINUX_ENFORCING)
+        op.add_option("--permissive", dest="selinux", action="store_const",
+                      const=SELINUX_PERMISSIVE)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/services.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/services.py
new file mode 100644 (file)
index 0000000..f640822
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# 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.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_Services(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.disabled = kwargs.get("disabled", [])
+        self.enabled = kwargs.get("enabled", [])
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+        args = ""
+
+        if len(self.disabled) > 0:
+            args += " --disabled=\"%s\"" % ",".join(self.disabled)
+        if len(self.enabled) > 0:
+            args += " --enabled=\"%s\"" % ",".join(self.enabled)
+
+        if args != "":
+            retval += "# System services\nservices%s\n" % args
+
+        return retval
+
+    def _getParser(self):
+        def services_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d.strip())
+
+        op = KSOptionParser()
+        op.add_option("--disabled", dest="disabled", action="callback",
+                      callback=services_cb, nargs=1, type="string")
+        op.add_option("--enabled", dest="enabled", action="callback",
+                      callback=services_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 len(self.disabled) == 0 and len(self.enabled) == 0:
+            raise KickstartParseError (formatErrorMsg(self.lineno, msg=_("One of --disabled or --enabled must be provided.")))
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/skipx.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/skipx.py
new file mode 100644 (file)
index 0000000..2067df8
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_SkipX(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.skipx = kwargs.get("skipx", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.skipx:
+            retval += "# Do not configure the X Window System\nskipx\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "skipx"))
+
+        self.skipx = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/sshpw.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/sshpw.py
new file mode 100644 (file)
index 0000000..759dbeb
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Peter Jones <pjones@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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F13_SshPwData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.username = kwargs.get("username", None)
+        self.isCrypted = kwargs.get("isCrypted", False)
+        self.password = kwargs.get("password", "")
+        self.lock = kwargs.get("lock", False)
+
+    def __eq__(self, y):
+        return self.username == y.username
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+
+        retval += "sshpw"
+        retval += self._getArgsAsStr() + '\n'
+
+        return retval
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        retval += " --username=%s" % self.username
+        if self.lock:
+            retval += " --lock"
+        if self.isCrypted:
+            retval += " --iscrypted"
+        else:
+            retval += " --plaintext"
+
+        retval += " %s" % self.password
+        return retval
+
+class F13_SshPw(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.sshUserList = kwargs.get("sshUserList", [])
+
+    def __str__(self):
+        retval = ""
+        for user in self.sshUserList:
+            retval += user.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--username", dest="username", required=True)
+        op.add_option("--iscrypted", dest="isCrypted", action="store_true",
+                      default=False)
+        op.add_option("--plaintext", dest="isCrypted", action="store_false")
+        op.add_option("--lock", dest="lock", action="store_true", default=False)
+        return op
+
+    def parse(self, args):
+        ud = self.handler.SshPwData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToObj(self.op, opts, ud)
+        ud.lineno = self.lineno
+
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "sshpw"))
+        ud.password = extra[0]
+
+        if ud in self.dataList():
+            warnings.warn(_("An ssh user with the name %s has already been defined.") % ud.name)
+
+        return ud
+
+    def dataList(self):
+        return self.sshUserList
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/timezone.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/timezone.py
new file mode 100644 (file)
index 0000000..06d09d6
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Timezone(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.isUtc = kwargs.get("isUtc", False)
+        self.timezone = kwargs.get("timezone", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.timezone != "":
+            if self.isUtc:
+                utc = "--utc"
+            else:
+                utc = ""
+
+            retval += "# System timezone\ntimezone %s %s\n" %(utc, self.timezone)
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--utc", dest="isUtc", action="store_true", default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if len(extra) != 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "timezone"))
+
+        self.timezone = extra[0]
+        return self
+
+class FC6_Timezone(FC3_Timezone):
+    removedKeywords = FC3_Timezone.removedKeywords
+    removedAttrs = FC3_Timezone.removedAttrs
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.timezone != "":
+            if self.isUtc:
+                utc = "--isUtc"
+            else:
+                utc = ""
+
+            retval += "# System timezone\ntimezone %s %s\n" %(utc, self.timezone)
+
+        return retval
+
+    def _getParser(self):
+        op = FC3_Timezone._getParser(self)
+        op.add_option("--utc", "--isUtc", dest="isUtc", action="store_true", default=False)
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/updates.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/updates.py
new file mode 100644 (file)
index 0000000..6e18af9
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# 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.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class F7_Updates(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.url = kwargs.get("url", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.url == "floppy":
+            retval += "updates\n"
+        elif self.url != "":
+            retval += "updates %s\n" % self.url
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 1:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s only takes one argument") % "updates"))
+        elif len(extra) == 0:
+            self.url = "floppy"
+        else:
+            self.url = extra[0]
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/upgrade.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/upgrade.py
new file mode 100644 (file)
index 0000000..5f44ea1
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_Upgrade(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.upgrade = kwargs.get("upgrade", None)
+        self.op = self._getParser()
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.upgrade is None:
+            return retval
+
+        if self.upgrade:
+            retval += "# Upgrade existing installation\nupgrade\n"
+        else:
+            retval += "# Install OS instead of upgrade\ninstall\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "upgrade"))
+
+        if self.currentCmd == "upgrade":
+            self.upgrade = True
+        else:
+            self.upgrade = False
+
+        return self
+
+class F11_Upgrade(FC3_Upgrade):
+    removedKeywords = FC3_Upgrade.removedKeywords
+    removedAttrs = FC3_Upgrade.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_Upgrade.__init__(self, writePriority, *args, **kwargs)
+
+        self.op = self._getParser()
+        self.root_device = kwargs.get("root_device", None)
+
+    def __str__(self):
+        if self.upgrade and (self.root_device is not None):
+            retval = KickstartCommand.__str__(self)
+            retval += "# Upgrade existing installation\nupgrade --root-device=%s\n" % self.root_device
+        else:
+            retval = FC3_Upgrade.__str__(self)
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--root-device", dest="root_device")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 0:
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "upgrade"))
+
+        if (opts.root_device is not None) and (opts.root_device == ""):
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not accept empty parameter %s") % ("upgrade", "--root-device")))
+        else:
+            self.root_device = opts.root_device
+
+        if self.currentCmd == "upgrade":
+            self.upgrade = True
+        else:
+            self.upgrade = False
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/user.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/user.py
new file mode 100644 (file)
index 0000000..189dc75
--- /dev/null
@@ -0,0 +1,173 @@
+#
+# 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.constants import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC6_UserData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.groups = kwargs.get("groups", [])
+        self.homedir = kwargs.get("homedir", "")
+        self.isCrypted = kwargs.get("isCrypted", False)
+        self.name = kwargs.get("name", "")
+        self.password = kwargs.get("password", "")
+        self.shell = kwargs.get("shell", "")
+        self.uid = kwargs.get("uid", None)
+
+    def __eq__(self, y):
+        return self.name == y.name
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+
+        if self.uid != "":
+            retval += "user"
+            retval += self._getArgsAsStr() + "\n"
+
+        return retval
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if len(self.groups) > 0:
+            retval += " --groups=%s" % ",".join(self.groups)
+        if self.homedir:
+            retval += " --homedir=%s" % self.homedir
+        if self.name:
+            retval += " --name=%s" % self.name
+        if self.password:
+            retval += " --password=%s" % self.password
+        if self.isCrypted:
+            retval += " --iscrypted"
+        if self.shell:
+            retval += " --shell=%s" % self.shell
+        if self.uid:
+            retval += " --uid=%s" % self.uid
+
+        return retval
+
+class F8_UserData(FC6_UserData):
+    removedKeywords = FC6_UserData.removedKeywords
+    removedAttrs = FC6_UserData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC6_UserData.__init__(self, *args, **kwargs)
+        self.lock = kwargs.get("lock", False)
+
+    def _getArgsAsStr(self):
+        retval = FC6_UserData._getArgsAsStr(self)
+
+        if self.lock:
+            retval += " --lock"
+
+        return retval
+
+class F12_UserData(F8_UserData):
+    removedKeywords = F8_UserData.removedKeywords
+    removedAttrs = F8_UserData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F8_UserData.__init__(self, *args, **kwargs)
+        self.gecos = kwargs.get("gecos", "")
+
+    def _getArgsAsStr(self):
+        retval = F8_UserData._getArgsAsStr(self)
+
+        if self.gecos:
+            retval += " --gecos=\"%s\"" % (self.gecos,)
+
+        return retval
+
+class FC6_User(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.userList = kwargs.get("userList", [])
+
+    def __str__(self):
+        retval = ""
+        for user in self.userList:
+            retval += user.__str__()
+
+        return retval
+
+    def _getParser(self):
+        def groups_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser()
+        op.add_option("--groups", dest="groups", action="callback",
+                      callback=groups_cb, nargs=1, type="string")
+        op.add_option("--homedir")
+        op.add_option("--iscrypted", dest="isCrypted", action="store_true",
+                      default=False)
+        op.add_option("--name", required=1)
+        op.add_option("--password")
+        op.add_option("--shell")
+        op.add_option("--uid", type="int")
+        return op
+
+    def parse(self, args):
+        ud = self.handler.UserData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToObj(self.op, opts, ud)
+        ud.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if ud in self.dataList():
+            warnings.warn(_("A user with the name %s has already been defined.") % ud.name)
+
+        return ud
+
+    def dataList(self):
+        return self.userList
+
+class F8_User(FC6_User):
+    removedKeywords = FC6_User.removedKeywords
+    removedAttrs = FC6_User.removedAttrs
+
+    def _getParser(self):
+        op = FC6_User._getParser(self)
+        op.add_option("--lock", action="store_true", default=False)
+        op.add_option("--plaintext", dest="isCrypted", action="store_false")
+        return op
+
+class F12_User(F8_User):
+    removedKeywords = F8_User.removedKeywords
+    removedAttrs = F8_User.removedAttrs
+
+    def _getParser(self):
+        op = F8_User._getParser(self)
+        op.add_option("--gecos", type="string")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/vnc.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/vnc.py
new file mode 100644 (file)
index 0000000..200ccfb
--- /dev/null
@@ -0,0 +1,114 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+class FC3_Vnc(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.enabled = kwargs.get("enabled", False)
+        self.password = kwargs.get("password", "")
+        self.connect = kwargs.get("connect", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if not self.enabled:
+            return retval
+
+        retval += "vnc"
+
+        if self.connect != "":
+            retval += " --connect=%s" % self.connect
+        if self.password != "":
+            retval += " --password=%s" % self.password
+
+        return retval + "\n"
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--connect")
+        op.add_option("--password", dest="password")
+        return op
+
+    def parse(self, args):
+        self.enabled = True
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
+
+class FC6_Vnc(FC3_Vnc):
+    removedKeywords = FC3_Vnc.removedKeywords + ["connect"]
+    removedAttrs = FC3_Vnc.removedAttrs + ["connect"]
+
+    def __init__(self, writePriority=0, host="", port="", *args, **kwargs):
+        FC3_Vnc.__init__(self, writePriority, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.host = kwargs.get("host", "")
+        self.port = kwargs.get("port", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if not self.enabled:
+            return retval
+
+        retval += "vnc"
+
+        if self.host != "":
+            retval += " --host=%s" % self.host
+
+            if self.port != "":
+                retval += " --port=%s" % self.port
+        if self.password != "":
+            retval += " --password=%s" % self.password
+
+        return retval + "\n"
+
+    def _getParser(self):
+        def connect_cb (option, opt_str, value, parser):
+            cargs = value.split(":")
+            parser.values.ensure_value("host", cargs[0])
+
+            if len(cargs) > 1:
+                parser.values.ensure_value("port", cargs[1])
+
+        op = FC3_Vnc._getParser(self)
+        op.add_option("--connect", action="callback", callback=connect_cb,
+                      nargs=1, type="string")
+        op.add_option("--host", dest="host")
+        op.add_option("--port", dest="port")
+        return op
+
+class F9_Vnc(FC6_Vnc):
+    removedKeywords = FC6_Vnc.removedKeywords
+    removedAttrs = FC6_Vnc.removedAttrs
+
+    def _getParser(self):
+        op = FC6_Vnc._getParser(self)
+        op.remove_option("--connect")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/volgroup.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/volgroup.py
new file mode 100644 (file)
index 0000000..255c47f
--- /dev/null
@@ -0,0 +1,102 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_VolGroupData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.format = kwargs.get("format", True)
+        self.pesize = kwargs.get("pesize", 32768)
+        self.preexist = kwargs.get("preexist", False)
+        self.vgname = kwargs.get("vgname", "")
+        self.physvols = kwargs.get("physvols", [])
+
+    def __eq__(self, y):
+        return self.vgname == y.vgname
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "volgroup %s" % self.vgname
+
+        if not self.format:
+            retval += " --noformat"
+        if self.pesize != 0:
+            retval += " --pesize=%d" % self.pesize
+        if self.preexist:
+            retval += " --useexisting"
+
+        return retval + " " + " ".join(self.physvols) + "\n"
+
+class FC3_VolGroup(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=132, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.vgList = kwargs.get("vgList", [])
+
+    def __str__(self):
+        retval = ""
+        for vg in self.vgList:
+            retval += vg.__str__()
+
+        return retval
+
+    def _getParser(self):
+        # Have to be a little more complicated to set two values.
+        def vg_cb (option, opt_str, value, parser):
+            parser.values.format = False
+            parser.values.preexist = True
+
+        op = KSOptionParser()
+        op.add_option("--noformat", action="callback", callback=vg_cb,
+                      dest="format", default=True, nargs=0)
+        op.add_option("--pesize", dest="pesize", type="int", nargs=1,
+                      default=32768)
+        op.add_option("--useexisting", dest="preexist", action="store_true",
+                      default=False)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        vg = self.handler.VolGroupData()
+        self._setToObj(self.op, opts, vg)
+        vg.lineno = self.lineno
+        vg.vgname = extra[0]
+        vg.physvols = extra[1:]
+
+        # Check for duplicates in the data list.
+        if vg in self.dataList():
+            warnings.warn(_("A volgroup with the name %s has already been defined.") % vg.vgname)
+
+        return vg
+
+    def dataList(self):
+        return self.vgList
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/xconfig.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/xconfig.py
new file mode 100644 (file)
index 0000000..bbde49f
--- /dev/null
@@ -0,0 +1,184 @@
+#
+# 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
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_XConfig(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.card = kwargs.get("card", "")
+        self.defaultdesktop = kwargs.get("defaultdesktop", "")
+        self.depth = kwargs.get("depth", 0)
+        self.hsync = kwargs.get("hsync", "")
+        self.monitor = kwargs.get("monitor", "")
+        self.noProbe = kwargs.get("noProbe", False)
+        self.resolution = kwargs.get("resolution", "")
+        self.server = kwargs.get("server", "")
+        self.startX = kwargs.get("startX", False)
+        self.videoRam = kwargs.get("videoRam", "")
+        self.vsync = kwargs.get("vsync", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.card != "":
+            retval += " --card=%s" % self.card
+        if self.defaultdesktop != "":
+            retval += " --defaultdesktop=%s" % self.defaultdesktop
+        if self.depth != 0:
+            retval += " --depth=%d" % self.depth
+        if self.hsync != "":
+            retval += " --hsync=%s" % self.hsync
+        if self.monitor != "":
+            retval += " --monitor=%s" % self.monitor
+        if self.noProbe:
+            retval += " --noprobe"
+        if self.resolution != "":
+            retval += " --resolution=%s" % self.resolution
+        if self.server != "":
+            retval += " --server=%s" % self.server
+        if self.startX:
+            retval += " --startxonboot"
+        if self.videoRam != "":
+            retval += " --videoram=%s" % self.videoRam
+        if self.vsync != "":
+            retval += " --vsync=%s" % self.vsync
+
+        if retval != "":
+            retval = "# X Window System configuration information\nxconfig %s\n" % retval
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--card")
+        op.add_option("--defaultdesktop")
+        op.add_option("--depth", action="store", type="int", nargs=1)
+        op.add_option("--hsync")
+        op.add_option("--monitor")
+        op.add_option("--noprobe", dest="noProbe", action="store_true",
+                      default=False)
+        op.add_option("--resolution")
+        op.add_option("--server")
+        op.add_option("--startxonboot", dest="startX", action="store_true",
+                      default=False)
+        op.add_option("--videoram", dest="videoRam")
+        op.add_option("--vsync")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        if extra:
+            mapping = {"command": "xconfig", "options": extra}
+            raise KickstartValueError (formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))
+
+        self._setToSelf(self.op, opts)
+        return self
+
+class FC6_XConfig(FC3_XConfig):
+    removedKeywords = FC3_XConfig.removedKeywords + ["card", "hsync", "monitor", "noProbe", "vsync"]
+    removedAttrs = FC3_XConfig.removedAttrs + ["card", "hsync", "monitor", "noProbe", "vsync"]
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        FC3_XConfig.__init__(self, writePriority, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.driver = kwargs.get("driver", "")
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if hasattr(self, "driver") and self.driver != "":
+            retval += " --driver=%s" % self.driver
+        if self.defaultdesktop != "":
+            retval += " --defaultdesktop=%s" % self.defaultdesktop
+        if self.depth != 0:
+            retval += " --depth=%d" % self.depth
+        if hasattr(self, "resolution") and self.resolution != "":
+            retval += " --resolution=%s" % self.resolution
+        if self.startX:
+            retval += " --startxonboot"
+        if hasattr(self, "videoRam") and self.videoRam != "":
+            retval += " --videoram=%s" % self.videoRam
+
+        if retval != "":
+            retval = "# X Window System configuration information\nxconfig %s\n" % retval
+
+        return retval
+
+    def _getParser(self):
+        op = FC3_XConfig._getParser(self)
+        op.add_option("--card", deprecated=1)
+        op.add_option("--driver", dest="driver")
+        op.add_option("--hsync", deprecated=1)
+        op.add_option("--monitor", deprecated=1)
+        op.add_option("--noprobe", deprecated=1)
+        op.add_option("--vsync", deprecated=1)
+        return op
+
+class F9_XConfig(FC6_XConfig):
+    removedKeywords = FC6_XConfig.removedKeywords
+    removedAttrs = FC6_XConfig.removedAttrs
+
+    def _getParser(self):
+        op = FC6_XConfig._getParser(self)
+        op.remove_option("--card")
+        op.remove_option("--hsync")
+        op.remove_option("--monitor")
+        op.remove_option("--noprobe")
+        op.remove_option("--vsync")
+        return op
+
+class F10_XConfig(F9_XConfig):
+    removedKeywords = F9_XConfig.removedKeywords + ["driver", "resolution", "videoRam"]
+    removedAttrs = F9_XConfig.removedAttrs + ["driver", "resolution", "videoRam"]
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        F9_XConfig.__init__(self, writePriority, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+    def _getParser(self):
+        op = F9_XConfig._getParser(self)
+        op.add_option("--driver", deprecated=1)
+        op.add_option("--depth", deprecated=1)
+        op.add_option("--resolution", deprecated=1)
+        op.add_option("--videoram", deprecated=1)
+        return op
+
+class F14_XConfig(F10_XConfig):
+    removedKeywords = F10_XConfig.removedKeywords
+    removedAttrs = F10_XConfig.removedAttrs
+
+    def _getParser(self):
+        op = F10_XConfig._getParser(self)
+        op.remove_option("--driver")
+        op.remove_option("--depth")
+        op.remove_option("--resolution")
+        op.remove_option("--videoram")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zerombr.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zerombr.py
new file mode 100644 (file)
index 0000000..e99ea8d
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# 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. 
+#
+import warnings
+
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_ZeroMbr(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=110, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+        self.zerombr = kwargs.get("zerombr", False)
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.zerombr:
+            retval += "# Clear the Master Boot Record\nzerombr\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 0:
+            warnings.warn(_("Ignoring deprecated option on line %s:  The zerombr command no longer takes any options.  In future releases, this will result in a fatal error from kickstart.  Please modify your kickstart file to remove any options.") % self.lineno, DeprecationWarning)
+
+        self.zerombr = True
+        return self
+
+class F9_ZeroMbr(FC3_ZeroMbr):
+    removedKeywords = FC3_ZeroMbr.removedKeywords
+    removedAttrs = FC3_ZeroMbr.removedAttrs
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) > 0:
+            raise KickstartParseError (formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "zerombr"))
+
+        self.zerombr = True
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zfcp.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/commands/zfcp.py
new file mode 100644 (file)
index 0000000..1ed2694
--- /dev/null
@@ -0,0 +1,134 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_ZFCPData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.devnum = kwargs.get("devnum", "")
+        self.wwpn = kwargs.get("wwpn", "")
+        self.fcplun = kwargs.get("fcplun", "")
+        self.scsiid = kwargs.get("scsiid", "")
+        self.scsilun = kwargs.get("scsilun", "")
+
+    def __eq__(self, y):
+        return self.devnum == y.devnum and self.wwpn == y.wwpn and \
+               self.fcplun == y.fcplun and self.scsiid == y.scsiid and \
+               self.scsilun == y.scsilun
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        retval += "zfcp"
+
+        if self.devnum != "":
+            retval += " --devnum=%s" % self.devnum
+        if self.wwpn != "":
+            retval += " --wwpn=%s" % self.wwpn
+        if self.fcplun != "":
+            retval += " --fcplun=%s" % self.fcplun
+        if hasattr(self, "scsiid") and self.scsiid != "":
+            retval += " --scsiid=%s" % self.scsiid
+        if hasattr(self, "scsilun") and self.scsilun != "":
+            retval += " --scsilun=%s" % self.scsilun
+
+        return retval + "\n"
+
+class F12_ZFCPData(FC3_ZFCPData):
+    removedKeywords = FC3_ZFCPData.removedKeywords + ["scsiid", "scsilun"]
+    removedAttrs = FC3_ZFCPData.removedAttrs + ["scsiid", "scsilun"]
+
+    def __init__(self, *args, **kwargs):
+        FC3_ZFCPData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+F14_ZFCPData = F12_ZFCPData
+
+class FC3_ZFCP(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=71, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.zfcp = kwargs.get("zfcp", [])
+
+    def __str__(self):
+        retval = ""
+        for zfcp in self.zfcp:
+            retval += zfcp.__str__()
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        op.add_option("--devnum", dest="devnum", required=1)
+        op.add_option("--fcplun", dest="fcplun", required=1)
+        op.add_option("--scsiid", dest="scsiid", required=1)
+        op.add_option("--scsilun", dest="scsilun", required=1)
+        op.add_option("--wwpn", dest="wwpn", required=1)
+        return op
+
+    def parse(self, args):
+        zd = self.handler.ZFCPData()
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToObj(self.op, opts, zd)
+        zd.lineno = self.lineno
+
+        # Check for duplicates in the data list.
+        if zd in self.dataList():
+            warnings.warn(_("A zfcp with this information has already been defined."))
+
+        return zd
+
+    def dataList(self):
+        return self.zfcp
+
+class F12_ZFCP(FC3_ZFCP):
+    removedKeywords = FC3_ZFCP.removedKeywords
+    removedAttrs = FC3_ZFCP.removedAttrs + ["scsiid", "scsilun"]
+
+    def __init__(self, *args, **kwargs):
+        FC3_ZFCP.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+    def _getParser(self):
+        op = FC3_ZFCP._getParser(self)
+        op.add_option("--scsiid", deprecated=1)
+        op.add_option("--scsilun", deprecated=1)
+        return op
+
+class F14_ZFCP(F12_ZFCP):
+    removedKeywords = F12_ZFCP.removedKeywords
+    removedAttrs = F12_ZFCP.removedAttrs
+
+    def _getParser(self):
+        op = F12_ZFCP._getParser(self)
+        op.remove_option("--scsiid")
+        op.remove_option("--scsilun")
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/constants.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/constants.py
new file mode 100644 (file)
index 0000000..050d124
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# 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_SCRIPT_RUN = 3
+KS_SCRIPT_UMOUNT = 4
+
+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/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/errors.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/errors.py
new file mode 100644 (file)
index 0000000..a234d99
--- /dev/null
@@ -0,0 +1,103 @@
+#
+# errors.py:  Kickstart error handling.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Error handling classes and functions.
+
+This module exports a single function:
+
+    formatErrorMsg - Properly formats an error message.
+
+It also exports several exception classes:
+
+    KickstartError - A generic exception class.
+
+    KickstartParseError - An exception for errors relating to parsing.
+
+    KickstartValueError - An exception for errors relating to option
+                          processing.
+
+    KickstartVersionError - An exception for errors relating to unsupported
+                            syntax versions.
+"""
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+def formatErrorMsg(lineno, msg=""):
+    """Properly format the error message msg for inclusion in an exception."""
+    if msg != "":
+        mapping = {"lineno": lineno, "msg": msg}
+        return _("The following problem occurred on line %(lineno)s of the kickstart file:\n\n%(msg)s\n") % mapping
+    else:
+        return _("There was a problem reading from line %s of the kickstart file") % lineno
+
+class KickstartError(Exception):
+    """A generic exception class for unspecific error conditions."""
+    def __init__(self, val = ""):
+        """Create a new KickstartError exception instance with the descriptive
+           message val.  val should be the return value of formatErrorMsg.
+        """
+        Exception.__init__(self)
+        self.value = val
+
+    def __str__ (self):
+        return self.value
+
+class KickstartParseError(KickstartError):
+    """An exception class for errors when processing the input file, such as
+       unknown options, commands, or sections.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartParseError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__(self):
+        return self.value
+
+class KickstartValueError(KickstartError):
+    """An exception class for errors when processing arguments to commands,
+       such as too many arguments, too few arguments, or missing required
+       arguments.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartValueError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
+
+class KickstartVersionError(KickstartError):
+    """An exception class for errors related to using an incorrect version of
+       kickstart syntax.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartVersionError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/control.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/control.py
new file mode 100644 (file)
index 0000000..119e32f
--- /dev/null
@@ -0,0 +1,1310 @@
+#
+# 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 *
+from mic.kickstart.custom_commands.micrepo 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 = {
+    FC3: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC3_Bootloader,
+        "cdrom": method.FC3_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "driverdisk": driverdisk.FC3_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC3_Reboot,
+        "harddrive": method.FC3_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC3_LangSupport,
+        "lilo": bootloader.FC3_Bootloader,
+        "lilocheck": lilocheck.FC3_LiloCheck,
+        "logvol": logvol.FC3_LogVol,
+        "monitor": monitor.FC3_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "network": network.FC3_Network,
+        "nfs": method.FC3_Method,
+        "part": partition.FC3_Partition,
+        "partition": partition.FC3_Partition,
+        "poweroff": reboot.FC3_Reboot,
+        "raid": raid.FC3_Raid,
+        "reboot": reboot.FC3_Reboot,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "shutdown": reboot.FC3_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC3_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC3_Method,
+        "vnc": vnc.FC3_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC3_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on fc3
+    FC4: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC4_Bootloader,
+        "cdrom": method.FC3_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC3_Reboot,
+        "harddrive": method.FC3_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC3_LangSupport,
+        "logvol": logvol.FC4_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC3_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "network": network.FC4_Network,
+        "nfs": method.FC3_Method,
+        "part": partition.FC4_Partition,
+        "partition": partition.FC4_Partition,
+        "poweroff": reboot.FC3_Reboot,
+        "raid": raid.FC4_Raid,
+        "reboot": reboot.FC3_Reboot,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "shutdown": reboot.FC3_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC3_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC3_Method,
+        "vnc": vnc.FC3_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC3_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on fc4
+    FC5: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC4_Bootloader,
+        "cdrom": method.FC3_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC3_Reboot,
+        "harddrive": method.FC3_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC5_LangSupport,
+        "logvol": logvol.FC4_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC3_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "network": network.FC4_Network,
+        "nfs": method.FC3_Method,
+        "part": partition.FC4_Partition,
+        "partition": partition.FC4_Partition,
+        "poweroff": reboot.FC3_Reboot,
+        "raid": raid.FC5_Raid,
+        "reboot": reboot.FC3_Reboot,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "shutdown": reboot.FC3_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC3_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC3_Method,
+        "vnc": vnc.FC3_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC3_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on fc5
+    FC6: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC4_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.FC6_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC5_LangSupport,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.FC4_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC6_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.FC6_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.FC4_Partition,
+        "partition": partition.FC4_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.FC5_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.FC6_Repo,
+        "tpk_repo": Mic_Tpk_Repo,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "user": user.FC6_User,
+        "url": method.FC6_Method,
+        "vnc": vnc.FC6_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC6_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on fc6
+    F7: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC4_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.FC6_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.FC4_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC6_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.FC6_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.FC4_Partition,
+        "partition": partition.FC4_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F7_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.FC6_Repo,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.FC6_User,
+        "vnc": vnc.FC6_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC6_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f7
+    F8: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F8_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.FC6_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.FC4_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC6_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F8_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.FC4_Partition,
+        "partition": partition.FC4_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F7_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F8_Repo,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.F8_User,
+        "vnc": vnc.FC6_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC6_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f8
+    F9: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F9_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F8_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.F9_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.FC6_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F9_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC6_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.F9_Partition,
+        "partition": partition.F9_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F9_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F8_Repo,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.F8_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F9_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f9
+    F10: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F9_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F8_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.F10_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F9_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.F9_Partition,
+        "partition": partition.F9_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F9_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F8_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.F8_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F10_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f10
+    F11: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F9_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F8_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.F10_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F9_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.F11_Partition,
+        "partition": partition.F11_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F9_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F11_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.F8_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F10_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f11
+    F12: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F12_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F12_DriverDisk,
+        "fcoe": fcoe.F12_Fcoe,
+        "firewall": firewall.F10_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F12_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.F12_Partition,
+        "partition": partition.F12_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F12_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F11_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.FC6_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F10_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F12_ZFCP,
+    },
+
+    # based on f12
+    F13: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F12_Bootloader,
+        "cdrom": method.F13_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F12_DriverDisk,
+        "fcoe": fcoe.F13_Fcoe,
+        "firewall": firewall.F10_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.F13_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F12_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.F13_Method,
+        "part": partition.F12_Partition,
+        "partition": partition.F12_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F13_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F13_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "sshpw": sshpw.F13_SshPw,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.F13_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F10_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F12_ZFCP,
+    },
+
+    # based on f13
+    F14: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F14_Bootloader,
+        "cdrom": method.F14_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F14_DriverDisk,
+        "fcoe": fcoe.F13_Fcoe,
+        "firewall": firewall.F14_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.F14_Method,
+        "ignoredisk": ignoredisk.F14_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "interactive": interactive.F14_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F14_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.F14_Method,
+        "part": partition.F14_Partition,
+        "partition": partition.F14_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F14_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F14_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "sshpw": sshpw.F13_SshPw,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.F14_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F14_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F14_ZFCP,
+    },
+
+    # based on f14
+    F15: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F15_Bootloader,
+        "cdrom": method.F14_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F14_DriverDisk,
+        "fcoe": fcoe.F13_Fcoe,
+        "firewall": firewall.F14_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.F14_Method,
+        "ignoredisk": ignoredisk.F14_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F15_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F9_Network,
+        "nfs": method.F14_Method,
+        "part": partition.F14_Partition,
+        "partition": partition.F14_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F15_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F15_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "sshpw": sshpw.F13_SshPw,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.F14_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F14_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F14_ZFCP,
+    },
+
+    # based on f15
+    F16: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.F15_Bootloader,
+        "cdrom": method.F14_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F14_DriverDisk,
+        "fcoe": fcoe.F13_Fcoe,
+        "firewall": firewall.F14_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.F14_Method,
+        "ignoredisk": ignoredisk.F14_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F15_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.F16_Network,
+        "nfs": method.F14_Method,
+        "part": partition.F14_Partition,
+        "partition": partition.F14_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F15_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.F15_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "sshpw": sshpw.F13_SshPw,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.F14_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F14_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F14_ZFCP,
+    },
+
+    # based on fc1
+    RHEL3: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC3_Bootloader,
+        "cdrom": method.FC3_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "driverdisk": driverdisk.FC3_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC3_Reboot,
+        "harddrive": method.FC3_Method,
+        "ignoredisk": ignoredisk.FC3_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC3_LangSupport,
+        "lilo": bootloader.FC3_Bootloader,
+        "lilocheck": lilocheck.FC3_LiloCheck,
+        "logvol": logvol.FC3_LogVol,
+        "monitor": monitor.FC3_Monitor,
+        "mouse": mouse.RHEL3_Mouse,
+        "network": network.FC3_Network,
+        "nfs": method.FC3_Method,
+        "part": partition.FC3_Partition,
+        "partition": partition.FC3_Partition,
+        "poweroff": reboot.FC3_Reboot,
+        "raid": raid.FC3_Raid,
+        "reboot": reboot.FC3_Reboot,
+        "rootpw": rootpw.FC3_RootPw,
+        "shutdown": reboot.FC3_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC3_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC3_Method,
+        "vnc": vnc.FC3_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC3_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+    },
+
+    # based on fc3
+    RHEL4: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.FC3_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.FC3_Bootloader,
+        "cdrom": method.FC3_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "driverdisk": driverdisk.FC4_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC3_Reboot,
+        "harddrive": method.FC3_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC3_LangSupport,
+        "lilo": bootloader.FC3_Bootloader,
+        "lilocheck": lilocheck.FC3_LiloCheck,
+        "logvol": logvol.FC3_LogVol,
+        "monitor": monitor.FC3_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "network": network.RHEL4_Network,
+        "nfs": method.FC3_Method,
+        "part": partition.FC3_Partition,
+        "partition": partition.FC3_Partition,
+        "poweroff": reboot.FC3_Reboot,
+        "raid": raid.FC3_Raid,
+        "reboot": reboot.FC3_Reboot,
+        "rootpw": rootpw.FC3_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "shutdown": reboot.FC3_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC3_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "url": method.FC3_Method,
+        "vnc": vnc.FC3_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC3_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on fc6
+    RHEL5: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F9_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.RHEL5_Bootloader,
+        "cdrom": method.FC6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.FC3_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F12_DriverDisk,
+        "firewall": firewall.FC3_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.FC6_Method,
+        "ignoredisk": ignoredisk.F8_IgnoreDisk,
+        "install": upgrade.FC3_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.FC6_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "key": key.RHEL5_Key,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "langsupport": langsupport.FC5_LangSupport,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.RHEL5_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.FC6_Monitor,
+        "mouse": mouse.FC3_Mouse,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.RHEL5_Network,
+        "nfs": method.FC6_Method,
+        "part": partition.RHEL5_Partition,
+        "partition": partition.RHEL5_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.RHEL5_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.FC6_Repo,
+        "rootpw": rootpw.FC3_RootPw,
+        "services": services.FC6_Services,
+        "selinux": selinux.FC3_SELinux,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "upgrade": upgrade.FC3_Upgrade,
+        "user": user.FC6_User,
+        "url": method.FC6_Method,
+        "vnc": vnc.FC6_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.FC6_XConfig,
+        "zerombr": zerombr.FC3_ZeroMbr,
+        "zfcp": zfcp.FC3_ZFCP,
+    },
+
+    # based on f13ish
+    RHEL6: {
+        "auth": authconfig.FC3_Authconfig,
+        "authconfig": authconfig.FC3_Authconfig,
+        "autopart": autopart.F12_AutoPart,
+        "autostep": autostep.FC3_AutoStep,
+        "bootloader": bootloader.RHEL6_Bootloader,
+        "cdrom": method.RHEL6_Method,
+        "clearpart": clearpart.FC3_ClearPart,
+        "cmdline": displaymode.FC3_DisplayMode,
+        "device": device.F8_Device,
+        "deviceprobe": deviceprobe.FC3_DeviceProbe,
+        "dmraid": dmraid.FC6_DmRaid,
+        "driverdisk": driverdisk.F12_DriverDisk,
+        "fcoe": fcoe.F13_Fcoe,
+        "firewall": firewall.F10_Firewall,
+        "firstboot": firstboot.FC3_Firstboot,
+        "graphical": displaymode.FC3_DisplayMode,
+        "group": group.F12_Group,
+        "halt": reboot.FC6_Reboot,
+        "harddrive": method.RHEL6_Method,
+        "ignoredisk": ignoredisk.RHEL6_IgnoreDisk,
+        "install": upgrade.F11_Upgrade,
+        "interactive": interactive.FC3_Interactive,
+        "iscsi": iscsi.F10_Iscsi,
+        "iscsiname": iscsiname.FC6_IscsiName,
+        "keyboard": keyboard.FC3_Keyboard,
+        "lang": lang.FC3_Lang,
+        "logging": logging.FC6_Logging,
+        "logvol": logvol.F12_LogVol,
+        "mediacheck": mediacheck.FC4_MediaCheck,
+        "monitor": monitor.F10_Monitor,
+        "multipath": multipath.FC6_MultiPath,
+        "network": network.RHEL6_Network,
+        "nfs": method.RHEL6_Method,
+        "part": partition.F12_Partition,
+        "partition": partition.F12_Partition,
+        "poweroff": reboot.FC6_Reboot,
+        "raid": raid.F13_Raid,
+        "reboot": reboot.FC6_Reboot,
+        "repo": repo.RHEL6_Repo,
+        "rescue": rescue.F10_Rescue,
+        "rootpw": rootpw.F8_RootPw,
+        "selinux": selinux.FC3_SELinux,
+        "services": services.FC6_Services,
+        "shutdown": reboot.FC6_Reboot,
+        "skipx": skipx.FC3_SkipX,
+        "sshpw": sshpw.F13_SshPw,
+        "text": displaymode.FC3_DisplayMode,
+        "timezone": timezone.FC6_Timezone,
+        "updates": updates.F7_Updates,
+        "upgrade": upgrade.F11_Upgrade,
+        "url": method.RHEL6_Method,
+        "user": user.F12_User,
+        "vnc": vnc.F9_Vnc,
+        "volgroup": volgroup.FC3_VolGroup,
+        "xconfig": xconfig.F10_XConfig,
+        "zerombr": zerombr.F9_ZeroMbr,
+        "zfcp": zfcp.F12_ZFCP,
+    }
+}
+
+# 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 = {
+    FC3: {
+        "DriverDiskData": driverdisk.FC3_DriverDiskData,
+        "LogVolData": logvol.FC3_LogVolData,
+        "NetworkData": network.FC3_NetworkData,
+        "PartData": partition.FC3_PartData,
+        "RaidData": raid.FC3_RaidData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    FC4: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "LogVolData": logvol.FC4_LogVolData,
+        "NetworkData": network.FC4_NetworkData,
+        "PartData": partition.FC4_PartData,
+        "RaidData": raid.FC4_RaidData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    FC5: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "LogVolData": logvol.FC4_LogVolData,
+        "NetworkData": network.FC4_NetworkData,
+        "PartData": partition.FC4_PartData,
+        "RaidData": raid.FC5_RaidData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    FC6: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.FC6_IscsiData,
+        "LogVolData": logvol.FC4_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.FC6_NetworkData,
+        "PartData": partition.FC4_PartData,
+        "RaidData": raid.FC5_RaidData,
+        "RepoData": repo.FC6_RepoData,
+        "TpkRepoData": Mic_Tpk_RepoData,
+        "UserData": user.FC6_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F7: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.FC6_IscsiData,
+        "LogVolData": logvol.FC4_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.FC6_NetworkData,
+        "PartData": partition.FC4_PartData,
+        "RaidData": raid.F7_RaidData,
+        "RepoData": repo.FC6_RepoData,
+        "UserData": user.FC6_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F8: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.FC6_IscsiData,
+        "LogVolData": logvol.FC4_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.FC4_PartData,
+        "RaidData": raid.F7_RaidData,
+        "RepoData": repo.F8_RepoData,
+        "UserData": user.F8_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F9: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.FC6_IscsiData,
+        "LogVolData": logvol.F9_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F9_PartData,
+        "RaidData": raid.F9_RaidData,
+        "RepoData": repo.F8_RepoData,
+        "UserData": user.F8_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F10: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F9_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F9_PartData,
+        "RaidData": raid.F9_RaidData,
+        "RepoData": repo.F8_RepoData,
+        "UserData": user.F8_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F11: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F9_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F11_PartData,
+        "RaidData": raid.F9_RaidData,
+        "RepoData": repo.F11_RepoData,
+        "UserData": user.F8_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    F12: {
+        "DriverDiskData": driverdisk.F12_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F12_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F12_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F12_PartData,
+        "RaidData": raid.F12_RaidData,
+        "RepoData": repo.F11_RepoData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F12_ZFCPData,
+    },
+    F13: {
+        "DriverDiskData": driverdisk.F12_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F13_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F12_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F12_PartData,
+        "RaidData": raid.F13_RaidData,
+        "RepoData": repo.F13_RepoData,
+        "SshPwData": sshpw.F13_SshPwData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F12_ZFCPData,
+    },
+    F14: {
+        "DriverDiskData": driverdisk.F14_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F13_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F14_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F14_PartData,
+        "RaidData": raid.F14_RaidData,
+        "RepoData": repo.F14_RepoData,
+        "SshPwData": sshpw.F13_SshPwData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F14_ZFCPData,
+    },
+    F15: {
+        "DriverDiskData": driverdisk.F14_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F13_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F15_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F8_NetworkData,
+        "PartData": partition.F14_PartData,
+        "RaidData": raid.F15_RaidData,
+        "RepoData": repo.F15_RepoData,
+        "SshPwData": sshpw.F13_SshPwData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F14_ZFCPData,
+    },
+    F16: {
+        "DriverDiskData": driverdisk.F14_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F13_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F15_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.F16_NetworkData,
+        "PartData": partition.F14_PartData,
+        "RaidData": raid.F15_RaidData,
+        "RepoData": repo.F15_RepoData,
+        "SshPwData": sshpw.F13_SshPwData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F14_ZFCPData,
+    },
+    RHEL3: {
+        "DriverDiskData": driverdisk.FC3_DriverDiskData,
+        "LogVolData": logvol.FC3_LogVolData,
+        "NetworkData": network.RHEL4_NetworkData,
+        "PartData": partition.FC3_PartData,
+        "RaidData": raid.FC3_RaidData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    RHEL4: {
+        "DriverDiskData": driverdisk.FC4_DriverDiskData,
+        "LogVolData": logvol.FC3_LogVolData,
+        "NetworkData": network.RHEL4_NetworkData,
+        "PartData": partition.FC3_PartData,
+        "RaidData": raid.FC3_RaidData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    RHEL5: {
+        "DriverDiskData": driverdisk.F12_DriverDiskData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "IscsiData": iscsi.FC6_IscsiData,
+        "LogVolData": logvol.RHEL5_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.FC6_NetworkData,
+        "PartData": partition.RHEL5_PartData,
+        "RaidData": raid.RHEL5_RaidData,
+        "RepoData": repo.FC6_RepoData,
+        "UserData": user.FC6_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.FC3_ZFCPData,
+    },
+    RHEL6: {
+        "DriverDiskData": driverdisk.F12_DriverDiskData,
+        "DeviceData": device.F8_DeviceData,
+        "DmRaidData": dmraid.FC6_DmRaidData,
+        "FcoeData": fcoe.F13_FcoeData,
+        "GroupData": group.F12_GroupData,
+        "IscsiData": iscsi.F10_IscsiData,
+        "LogVolData": logvol.F12_LogVolData,
+        "MultiPathData": multipath.FC6_MultiPathData,
+        "NetworkData": network.RHEL6_NetworkData,
+        "PartData": partition.F12_PartData,
+        "RaidData": raid.F13_RaidData,
+        "RepoData": repo.RHEL6_RepoData,
+        "SshPwData": sshpw.F13_SshPwData,
+        "UserData": user.F12_UserData,
+        "VolGroupData": volgroup.FC3_VolGroupData,
+        "ZFCPData": zfcp.F12_ZFCPData,
+    }
+}
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f10.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f10.py
new file mode 100644 (file)
index 0000000..17c8211
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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.version import *
+
+class F10Handler(BaseHandler):
+    version = F10
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f11.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f11.py
new file mode 100644 (file)
index 0000000..d21aee3
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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.version import *
+
+class F11Handler(BaseHandler):
+    version = F11
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f12.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f12.py
new file mode 100644 (file)
index 0000000..cea3ece
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class F12Handler(BaseHandler):
+    version = F12
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f13.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f13.py
new file mode 100644 (file)
index 0000000..b94c738
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class F13Handler(BaseHandler):
+    version = F13
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f14.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f14.py
new file mode 100644 (file)
index 0000000..478f75d
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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.base import *
+from pykickstart.version import *
+
+class F14Handler(BaseHandler):
+    version = F14
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f15.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f15.py
new file mode 100644 (file)
index 0000000..12aecb4
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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.base import *
+from pykickstart.version import *
+
+class F15Handler(BaseHandler):
+    version = F15
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f16.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f16.py
new file mode 100644 (file)
index 0000000..3c52f8d
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class F16Handler(BaseHandler):
+    version = F16
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f7.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f7.py
new file mode 100644 (file)
index 0000000..5e856ea
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class F7Handler(BaseHandler):
+    version = F7
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f8.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f8.py
new file mode 100644 (file)
index 0000000..1a97881
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class F8Handler(BaseHandler):
+    version = F8
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f9.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/f9.py
new file mode 100644 (file)
index 0000000..116f1b5
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class F9Handler(BaseHandler):
+    version = F9
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc3.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc3.py
new file mode 100644 (file)
index 0000000..a115dc2
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class FC3Handler(BaseHandler):
+    version = FC3
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc4.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc4.py
new file mode 100644 (file)
index 0000000..fd47b73
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class FC4Handler(BaseHandler):
+    version = FC4
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc5.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc5.py
new file mode 100644 (file)
index 0000000..bcdc29d
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class FC5Handler(BaseHandler):
+    version = FC5
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc6.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/fc6.py
new file mode 100644 (file)
index 0000000..c83a929
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class FC6Handler(BaseHandler):
+    version = FC6
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel3.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel3.py
new file mode 100644 (file)
index 0000000..131763c
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class RHEL3Handler(BaseHandler):
+    version = RHEL3
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel4.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel4.py
new file mode 100644 (file)
index 0000000..3496c43
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class RHEL4Handler(BaseHandler):
+    version = RHEL4
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel5.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel5.py
new file mode 100644 (file)
index 0000000..abb7a8d
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.version import *
+
+class RHEL5Handler(BaseHandler):
+    version = RHEL5
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel6.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/handlers/rhel6.py
new file mode 100644 (file)
index 0000000..7202419
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 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.base import *
+from pykickstart.version import *
+
+class RHEL6Handler(BaseHandler):
+    version = RHEL6
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/ko.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/ko.py
new file mode 100644 (file)
index 0000000..1350d19
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Base classes for internal pykickstart use.
+
+The module exports the following important classes:
+
+    KickstartObject - The base class for all classes in pykickstart
+"""
+
+class KickstartObject(object):
+    """The base class for all other classes in pykickstart."""
+    def __init__(self, *args, **kwargs):
+        """Create a new KickstartObject instance.  All other classes in
+           pykickstart should be derived from this one.  Instance attributes:
+        """
+        pass
+
+    def __str__(self):
+        return ""
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/options.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/options.py
new file mode 100644 (file)
index 0000000..d07fcf6
--- /dev/null
@@ -0,0 +1,204 @@
+#
+# 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/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/parser.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/parser.py
new file mode 100644 (file)
index 0000000..a485dfe
--- /dev/null
@@ -0,0 +1,728 @@
+#
+# 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 as 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 as 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'
+        elif self.type == constants.KS_SCRIPT_RUN:
+            retval += '\n%runscript'
+        elif self.type == constants.KS_SCRIPT_UMOUNT:
+            retval += '\n%post-umount'
+
+        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.tpk_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)
+
+class TpkPackages(KickstartObject):
+    """A class representing the %tpk_packages section of the kickstart file."""
+    def __init__(self, *args, **kwargs):
+        KickstartObject.__init__(self, *args, **kwargs)
+        self.tpk_packageList = []
+    def __str__(self):
+        tpk_pkgs = ""
+        retval = "\n%tpk_packages"
+        p = self.packageList
+        p.sort()
+        for pkg in p:
+            tpk_pkgs += "%s\n" % pkg
+        return retval + "\n" +tpk_pkgs
+    def add(self, tpkPackageList):
+        tpk_PackageSet = set(self.tpk_packageList)
+        for tpk_pkg in tpkPackageList:
+            stripped = tpk_pkg.strip()
+            tpk_PackageSet.add(stripped)
+        self.tpk_packageList = list(tpk_PackageSet)
+###
+### 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 as 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 as 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(RunScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PostUmountScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PackageSection(self.handler))
+        self.registerSection(TpkPackageSection(self.handler))
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/sections.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/sections.py
new file mode 100644 (file)
index 0000000..c360a90
--- /dev/null
@@ -0,0 +1,292 @@
+#
+# 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 errors 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 RunScriptSection(ScriptSection):
+    sectionOpen = "%runscript"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_RUN
+
+    def finalize(self):
+        ScriptSection.finalize(self)
+        if self.handler:
+            for s in self.handler.scripts:
+                if s.type == KS_SCRIPT_UMOUNT:
+                    raise KickstartError("%runscript and %post-umount " \
+                                         "can not be defined together")
+
+class PostUmountScriptSection(ScriptSection):
+    sectionOpen = "%post-umount"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_UMOUNT
+
+    def finalize(self):
+        ScriptSection.finalize(self)
+        if self.handler:
+            for s in self.handler.scripts:
+                if s.type == KS_SCRIPT_RUN:
+                    raise KickstartError("%runscript and %post-umount " \
+                                         "can not be defined together")
+
+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
+
+class TpkPackageSection(Section):
+    sectionOpen = "%tpk_packages"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+        self.handler.tpk_packages.add([line])
+
+    def handleHeader(self, lineno, args):
+        """Process the arguments to the %tpk_packages header and set attributes
+           on the Version's TpkPackages instance appropriate.  This method may be
+           overridden in a subclass if necessary.
+        """
+        Section.handleHeader(self, lineno, args)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/version.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/3rdparty/pykickstart/version.py
new file mode 100644 (file)
index 0000000..102cc37
--- /dev/null
@@ -0,0 +1,197 @@
+#
+# 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/mic_py2/usr/lib/python2.7/dist-packages/mic/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/__init__.py
new file mode 100644 (file)
index 0000000..a60b9b1
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2013 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
+
+__version__ = "0.28.19"
+
+cur_path = os.path.dirname(__file__) or '.'
+sys.path.insert(0, cur_path + '/3rdparty')
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/archive.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/archive.py
new file mode 100644 (file)
index 0000000..c6fde02
--- /dev/null
@@ -0,0 +1,450 @@
+#
+# Copyright (c) 2013 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.
+
+# Following messages should be disabled in pylint
+#  * Used * or ** magic (W0142)
+#  * Unused variable (W0612)
+#  * Used builtin function (W0141)
+#  * Invalid name for type (C0103)
+#  * Popen has no '%s' member (E1101)
+# pylint: disable= W0612, C0103, E1101
+
+""" Compression and Archiving
+
+Utility functions for creating archive files (tarballs, zip files, etc)
+and compressing files (gzip, bzip2, lzop, etc)
+"""
+
+import os
+import shutil
+import tempfile
+import subprocess
+from mic import msger
+
+__all__ = [
+            "get_compress_formats",
+            "compress",
+            "decompress",
+            "get_archive_formats",
+            "get_archive_suffixes",
+            "make_archive",
+            "extract_archive",
+            "compressing",
+            "packing",
+          ]
+
+# TODO: refine Error class for archive/extract
+
+def which(binary, path=None):
+    """ Find 'binary' in the directories listed in 'path'
+
+    @binary: the executable file to find
+    @path: the suposed path to search for, use $PATH if None
+    @retval: the absolute path if found, otherwise None
+    """
+    if path is None:
+        path = os.environ["PATH"]
+    for apath in path.split(os.pathsep):
+        fpath = os.path.join(apath, binary)
+        if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
+            return fpath
+    return None
+
+def _call_external(cmdln_or_args):
+    """ Wapper for subprocess calls.
+
+    @cmdln_or_args: command line to be joined before execution.
+    @retval: a tuple (returncode, outdata, errdata).
+    """
+    if isinstance(cmdln_or_args, list):
+        shell = False
+    else:
+        shell = True
+    msger.info("Running command: " + " ".join(cmdln_or_args))
+
+    proc = subprocess.Popen(cmdln_or_args, shell=shell,
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.STDOUT)
+    (outdata, errdata) = proc.communicate()
+
+    return (proc.returncode, outdata, errdata)
+
+def _do_gzip(input_name, compression=True):
+    """ Compress/decompress the file with 'gzip' utility.
+
+    @input_name: the file name to compress/decompress
+    @compress: True for compressing, False for decompressing
+    @retval: the path of the compressed/decompressed file
+    """
+    if which("pigz") is not None:
+        compressor = "pigz"
+    else:
+        compressor = "gzip"
+
+    if compression:
+        cmdln = [compressor, "-f", input_name]
+    else:
+        cmdln = [compressor, "-d", "-f", input_name]
+
+    _call_external(cmdln)
+
+    if compression:
+        output_name = input_name + ".gz"
+    else:
+        # suppose that file name is suffixed with ".gz"
+        output_name = os.path.splitext(input_name)[0]
+
+    return output_name
+
+def _do_bzip2(input_name, compression=True):
+    """ Compress/decompress the file with 'bzip2' utility.
+
+    @input_name: the file name to compress/decompress
+    @compress: True for compressing, False for decompressing
+    @retval: the path of the compressed/decompressed file
+    """
+    if which("pbzip2") is not None:
+        compressor = "pbzip2"
+    else:
+        compressor = "bzip2"
+
+    if compression:
+        cmdln = [compressor, "-f", input_name]
+    else:
+        cmdln = [compressor, "-d", "-f", input_name]
+
+    _call_external(cmdln)
+
+    if compression:
+        output_name = input_name + ".bz2"
+    else:
+        # suppose that file name is suffixed with ".bz2"
+        output_name = os.path.splitext(input_name)[0]
+
+    return output_name
+
+def _do_lzop(input_name, compression=True):
+    """ Compress/decompress the file with 'lzop' utility.
+
+    @input_name: the file name to compress/decompress
+    @compress: True for compressing, False for decompressing
+    @retval: the path of the compressed/decompressed file
+    """
+    compressor = "lzop"
+
+    if compression:
+        cmdln = [compressor, "-f", "-U", input_name]
+    else:
+        cmdln = [compressor, "-d", "-f", "-U", input_name]
+
+    _call_external(cmdln)
+
+    if compression:
+        output_name = input_name + ".lzo"
+    else:
+        # suppose that file name is suffixed with ".lzo"
+        output_name = os.path.splitext(input_name)[0]
+
+    return output_name
+
+_COMPRESS_SUFFIXES = {
+    ".lzo"     : [".lzo"],
+    ".gz"      : [".gz"],
+    ".bz2"     : [".bz2", ".bz"],
+    ".tar.lzo" : [".tar.lzo", ".tzo"],
+    ".tar.gz"  : [".tar.gz", ".tgz", ".taz"],
+    ".tar.bz2" : [".tar.bz2", ".tbz", ".tbz2", ".tar.bz"],
+}
+
+_COMPRESS_FORMATS = {
+    "gz" :  _do_gzip,
+    "bz2":  _do_bzip2,
+    "lzo":  _do_lzop,
+}
+
+def get_compress_formats():
+    """ Get the list of the supported compression formats
+
+    @retval: a list contained supported compress formats
+    """
+    return _COMPRESS_FORMATS.keys()
+
+def get_compress_suffixes():
+    """ Get the list of the support suffixes
+
+    @retval: a list contained all suffixes
+    """
+    suffixes = []
+    for key in _COMPRESS_SUFFIXES.keys():
+        suffix = _COMPRESS_SUFFIXES[key]
+        if (suffix):
+            suffixes.extend(suffix)
+
+    return suffixes
+
+def compress(file_path, compress_format):
+    """ Compress a given file
+
+    @file_path: the path of the file to compress
+    @compress_format: the compression format
+    @retval: the path of the compressed file
+    """
+    if not os.path.isfile(file_path):
+        raise OSError  ("can't compress a file not existed: '%s'" % file_path)
+
+    try:
+        func = _COMPRESS_FORMATS[compress_format]
+    except KeyError:
+        raise ValueError ("unknown compress format '%s'" % compress_format)
+    return func(file_path, True)
+
+def decompress(file_path, decompress_format=None):
+    """ Decompess a give file
+
+    @file_path: the path of the file to decompress
+    @decompress_format: the format for decompression, None for auto detection
+    @retval: the path of the decompressed file
+    """
+    if not os.path.isfile(file_path):
+        raise OSError ("can't decompress a file not existed: '%s'" % file_path)
+
+    (file_name, file_ext) = os.path.splitext(file_path)
+    for key, suffixes in _COMPRESS_SUFFIXES.iteritems():
+        if file_ext in suffixes:
+            file_ext = key
+            break
+
+    if file_path != (file_name + file_ext):
+        shutil.move(file_path, file_name + file_ext)
+        file_path  = file_name + file_ext
+
+    if not decompress_format:
+        decompress_format = os.path.splitext(file_path)[1].lstrip(".")
+
+    try:
+        func = _COMPRESS_FORMATS[decompress_format]
+    except KeyError:
+        raise ValueError ("unknown decompress format '%s'" % decompress_format)
+    return func(file_path, False)
+
+
+def _do_tar(archive_name, target_name):
+    """ Archive the directory or the file with 'tar' utility
+
+    @archive_name: the name of the tarball file
+    @target_name: the name of the target to tar
+    @retval: the path of the archived file
+    """
+    file_list = []
+    if os.path.isdir(target_name):
+        target_dir = target_name
+        target_name = "."
+        for target_file in os.listdir(target_dir):
+            file_list.append(target_file)
+    else:
+        target_dir = os.path.dirname(target_name)
+        target_name = os.path.basename(target_name)
+        file_list.append(target_name)
+    cmdln = ["tar", "-C", target_dir, "-cf", archive_name]
+    cmdln.extend(file_list)
+    _call_external(cmdln)
+
+    return archive_name
+
+def _do_untar(archive_name, target_dir=None):
+    """ Unarchive the archived file with 'tar' utility
+
+    @archive_name: the name of the archived file
+    @target_dir: the directory which the target locates
+    raise exception if fail to extract archive
+    """
+    if not target_dir:
+        target_dir = os.getcwd()
+    cmdln = ["tar", "-C", target_dir, "-xf", archive_name]
+    (returncode, stdout, stderr) = _call_external(cmdln)
+    if returncode != 0:
+        raise OSError (os.linesep.join([stdout, stderr]))
+
+def _imp_tarfile(archive_name, target_name):
+    """ Archive the directory or the file with tarfile module
+
+    @archive_name: the name of the tarball file
+    @target_name: the name of the target to tar
+    @retval: the path of the archived file
+    """
+    import tarfile
+
+    msger.info("Taring files to %s using tarfile module" % archive_name)
+    tar = tarfile.open(archive_name, 'w')
+    if os.path.isdir(target_name):
+        for child in os.listdir(target_name):
+            tar.add(os.path.join(target_name, child), child)
+    else:
+        tar.add(target_name, os.path.basename(target_name))
+
+    tar.close()
+    return archive_name
+
+def _make_tarball(archive_name, target_name, compressor=None):
+    """ Create a tarball from all the files under 'target_name' or itself.
+
+    @archive_name: the name of the archived file to create
+    @target_name: the directory or the file name to archive
+    @compressor: callback function to compress the tarball
+    @retval: indicate the compressing result
+    """
+    archive_dir = os.path.dirname(archive_name)
+    tarball_name = tempfile.mktemp(suffix=".tar", dir=archive_dir)
+
+    if which("tar") is not None:
+        _do_tar(tarball_name, target_name)
+    else:
+        _imp_tarfile(tarball_name, target_name)
+
+    if compressor:
+        tarball_name = compressor(tarball_name, True)
+
+    shutil.move(tarball_name, archive_name)
+
+    return os.path.exists(archive_name)
+
+def _extract_tarball(archive_name, target_dir, compressor=None):
+    """ Extract a tarball to a target directory
+
+    @archive_name: the name of the archived file to extract
+    @target_dir: the directory of the extracted target
+    """
+
+    _do_untar(archive_name, target_dir)
+
+def _make_zipfile(archive_name, target_name):
+    """ Create a zip file from all the files under 'target_name' or itself.
+
+    @archive_name: the name of the archived file
+    @target_name: the directory or the file name to archive
+    @retval: indicate the archiving result
+    """
+    import zipfile
+
+    msger.info("Zipping files to %s using zipfile module" % archive_name)
+    arv = zipfile.ZipFile(archive_name, 'w', compression=zipfile.ZIP_DEFLATED)
+
+    if os.path.isdir(target_name):
+        for dirpath, dirname, filenames in os.walk(target_name):
+            for filename in filenames:
+                filepath = os.path.normpath(os.path.join(dirpath, filename))
+                arcname = os.path.relpath(filepath, target_name)
+                if os.path.isfile(filepath):
+                    arv.write(filepath, arcname)
+    else:
+        arv.write(target_name, os.path.basename(target_name))
+
+    arv.close()
+
+    return os.path.exists(archive_name)
+
+_ARCHIVE_SUFFIXES = {
+    "zip"   : [".zip"],
+    "tar"   : [".tar"],
+    "lzotar": [".tzo", ".tar.lzo"],
+    "gztar" : [".tgz", ".taz", ".tar.gz"],
+    "bztar" : [".tbz", ".tbz2", ".tar.bz", ".tar.bz2"],
+}
+
+_ARCHIVE_FORMATS = {
+    "zip"   : ( _make_zipfile, {} ),
+    "tar"   : ( _make_tarball, {"compressor" : None} ),
+    "lzotar": ( _make_tarball, {"compressor" : _do_lzop} ),
+    "gztar" : ( _make_tarball, {"compressor" : _do_gzip} ),
+    "bztar" : ( _make_tarball, {"compressor" : _do_bzip2} ),
+}
+
+def get_archive_formats():
+    """ Get the list of the supported formats for archiving
+
+    @retval: a list contained archive formats
+    """
+    return _ARCHIVE_FORMATS.keys()
+
+def get_archive_suffixes():
+    """ Get the list of the support suffixes
+
+    @retval: a list contained all suffixes
+    """
+    suffixes = []
+    for name in _ARCHIVE_FORMATS.keys():
+        suffix = _ARCHIVE_SUFFIXES.get(name, None)
+        if (suffix):
+            suffixes.extend(suffix)
+
+    return suffixes
+
+def make_archive(archive_name, target_name):
+    """ Create an archive file (eg. tar or zip).
+
+    @archive_name: the name of the archived file
+    @target_name: the directory or the file to archive
+    @retval: the archiving result
+    """
+    if not os.path.exists(target_name):
+        raise OSError ("archive object does not exist: '%s'" % target_name)
+
+    for aformat, suffixes in _ARCHIVE_SUFFIXES.iteritems():
+        if filter(archive_name.endswith, suffixes):
+            archive_format = aformat
+            break
+    else:
+        raise ValueError ("unknown archive suffix '%s'" % archive_name)
+
+    try:
+        func, kwargs = _ARCHIVE_FORMATS[archive_format]
+    except KeyError:
+        raise ValueError ("unknown archive format '%s'" % archive_format)
+
+    archive_name = os.path.abspath(archive_name)
+    target_name = os.path.abspath(target_name)
+
+    archive_dir = os.path.dirname(archive_name)
+    if not os.path.exists(archive_dir):
+        os.makedirs(archive_dir)
+
+    return func(archive_name, target_name, **kwargs)
+
+def extract_archive(archive_name, target_name):
+    """ Extract the given file
+
+    @archive_name: the name of the archived file to extract
+    @target_name: the directory name where the target locates
+    raise exception if fail to extract archive
+    """
+    if not os.path.exists(archive_name):
+        raise OSError ("archived object does not exist: '%s'" % archive_name)
+
+    archive_name = os.path.abspath(archive_name)
+    target_name = os.path.abspath(target_name)
+
+    if os.path.exists(target_name) and not os.path.isdir(target_name):
+        raise OSError ("%s should be directory where extracted files locate"\
+                        % target_name)
+
+    if not os.path.exists(target_name):
+        os.makedirs(target_name)
+
+    _extract_tarball(archive_name, target_name)
+
+packing = make_archive
+compressing = compress
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/bootstrap.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/bootstrap.py
new file mode 100644 (file)
index 0000000..e2ea8f1
--- /dev/null
@@ -0,0 +1,346 @@
+#!/usr/bin/python -tt
+#
+# 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 tempfile
+import shutil
+import subprocess
+import rpm
+import glob
+import errno
+
+from mic import msger
+from mic.utils import errors, proxy, misc
+from mic.utils.rpmmisc import readRpmHeader, RPMInstallCallback
+from mic.chroot import cleanup_mounts, setup_chrootenv, cleanup_chrootenv
+from mic.conf import configmgr
+
+PATH_BOOTSTRAP = "/usr/sbin:/usr/bin:/sbin:/bin"
+
+RPMTRANS_FLAGS = [
+                   rpm.RPMTRANS_FLAG_ALLFILES,
+                   rpm.RPMTRANS_FLAG_NOSCRIPTS,
+                   rpm.RPMTRANS_FLAG_NOTRIGGERS,
+                 ]
+
+RPMVSF_FLAGS = [
+                 rpm._RPMVSF_NOSIGNATURES,
+                 rpm._RPMVSF_NODIGESTS
+               ]
+
+RPMPROB_FLAGS = [
+                  rpm.RPMPROB_FILTER_OLDPACKAGE,
+                  rpm.RPMPROB_FILTER_REPLACEPKG,
+                  rpm.RPMPROB_FILTER_IGNOREARCH
+                ]
+
+class MiniBackend(object):
+    def __init__(self, rootdir, arch=None, repomd=None):
+        self._ts = None
+        self.rootdir = os.path.abspath(rootdir)
+        self.arch = arch
+        self.repomd = repomd
+        self.dlpkgs = []
+        self.localpkgs = {}
+        self.optionals = []
+        self.preins = {}
+        self.postins = {}
+        self.scriptlets = False
+
+    def __del__(self):
+        try:
+            del self.ts
+        except:
+            pass
+
+    def get_ts(self):
+        if not self._ts:
+            self._ts = rpm.TransactionSet(self.rootdir)
+            self._ts.setFlags(reduce(lambda x, y: x|y, RPMTRANS_FLAGS))
+            self._ts.setVSFlags(reduce(lambda x, y: x|y, RPMVSF_FLAGS))
+            self._ts.setProbFilter(reduce(lambda x, y: x|y, RPMPROB_FLAGS))
+
+        return self._ts
+
+    def del_ts(self):
+        if self._ts:
+            self._ts.closeDB()
+            self._ts = None
+
+    ts = property(fget = lambda self: self.get_ts(),
+                  fdel = lambda self: self.del_ts(),
+                  doc="TransactionSet object")
+
+    def selectPackage(self, pkg):
+        if not pkg in self.dlpkgs:
+            self.dlpkgs.append(pkg)
+
+    def _get_local_packages(self, pkg):
+        """Return local mic-bootstrap rpm path."""
+        cropts = configmgr.create
+        if cropts['local_pkgs_path']:
+            if os.path.isdir(cropts['local_pkgs_path']):
+                pkglist = glob.glob(
+                           os.path.join(cropts['local_pkgs_path'], pkg + '*.rpm'))
+                if len(pkglist) > 1:
+                    raise errors.BootstrapError("Many %s packages in folder, put only one %s package in it." % (pkg, pkg))
+                elif len(pkglist) == 1:
+                    return ''.join(pkglist)
+            elif os.path.splitext(cropts['local_pkgs_path'])[-1] == '.rpm':
+                if cropts['local_pkgs_path'].find(pkg) >= 0:
+                    return cropts['local_pkgs_path']
+        return None
+    def runInstall(self):
+        # FIXME: check space
+        self.downloadPkgs()
+        self.installPkgs()
+
+        if not self.scriptlets:
+            return
+
+        for pkg in self.preins.keys():
+            prog, script = self.preins[pkg]
+            self.run_pkg_script(pkg, prog, script, '0')
+        for pkg in self.postins.keys():
+            prog, script = self.postins[pkg]
+            self.run_pkg_script(pkg, prog, script, '1')
+
+    def downloadPkgs(self):
+        nonexist = []
+        for pkg in self.dlpkgs:
+            localpth = self._get_local_packages(pkg)
+            if localpth is None:
+                localpth = misc.get_package(pkg, self.repomd, self.arch)
+            if localpth:
+                self.localpkgs[pkg] = localpth
+            elif pkg in self.optionals:
+                # skip optional rpm
+                continue
+            else:
+                # mark nonexist rpm
+                nonexist.append(pkg)
+
+        if nonexist:
+            raise errors.BootstrapError("Can't get rpm binary: %s" %
+                                        ','.join(nonexist))
+
+    def installPkgs(self):
+        for pkg in self.localpkgs.keys():
+            rpmpath = self.localpkgs[pkg]
+
+            hdr = readRpmHeader(self.ts, rpmpath)
+
+            # save prein and postin scripts
+            self.preins[pkg] = (hdr['PREINPROG'], hdr['PREIN'])
+            self.postins[pkg] = (hdr['POSTINPROG'], hdr['POSTIN'])
+
+            # mark pkg as install
+            self.ts.addInstall(hdr, rpmpath, 'u')
+
+        # run transaction
+        self.ts.order()
+        cb = RPMInstallCallback(self.ts)
+        errs = self.ts.run(cb.callback, '')
+
+        # ts.run() exit codes are, hmm, "creative": None means all ok, empty 
+        # list means some errors happened in the transaction and non-empty 
+        # list that there were errors preventing the ts from starting...
+        if errs is not None:
+             raise errors.BootstrapError("Transaction couldn't start: %s" % errs)
+
+    def run_pkg_script(self, pkg, prog, script, arg):
+        mychroot = lambda: os.chroot(self.rootdir)
+
+        if not script:
+            return
+
+        if prog == "<lua>":
+            prog = "/usr/bin/lua"
+
+        tmpdir = os.path.join(self.rootdir, "tmp")
+        if not os.path.exists(tmpdir):
+            os.makedirs(tmpdir)
+        tmpfd, tmpfp = tempfile.mkstemp(dir=tmpdir, prefix="%s.pre-" % pkg)
+        script = script.replace('\r', '')
+        os.write(tmpfd, script)
+        os.close(tmpfd)
+        os.chmod(tmpfp, 0o700)
+
+        try:
+            script_fp = os.path.join('/tmp', os.path.basename(tmpfp))
+            subprocess.call([prog, script_fp, arg], preexec_fn=mychroot)
+        except (OSError, IOError) as err:
+            msger.warning(str(err))
+        finally:
+            os.unlink(tmpfp)
+
+class Bootstrap(object):
+    def __init__(self, rootdir, distro, arch=None):
+        self.rootdir = misc.mkdtemp(dir=rootdir, prefix=distro)
+        self.distro = distro
+        self.arch = arch
+        self.logfile = None
+        self.pkgslist = []
+        self.repomd = None
+
+    def __del__(self):
+        self.cleanup()
+
+    def get_rootdir(self):
+        if os.path.exists(self.rootdir):
+            shutil.rmtree(self.rootdir, ignore_errors=True)
+        os.makedirs(self.rootdir)
+        return self.rootdir
+
+    def dirsetup(self, rootdir=None):
+        _path = lambda pth: os.path.join(rootdir, pth.lstrip('/'))
+
+        if not rootdir:
+            rootdir = self.rootdir
+
+        try:
+            # make /tmp and /etc path
+            tmpdir = _path('/tmp')
+            if not os.path.exists(tmpdir):
+                os.makedirs(tmpdir)
+            etcdir = _path('/etc')
+            if not os.path.exists(etcdir):
+                os.makedirs(etcdir)
+
+            # touch distro file
+            tzdist = _path('/etc/%s-release' % self.distro)
+            if not os.path.exists(tzdist):
+                with open(tzdist, 'w') as wf:
+                    wf.write("bootstrap")
+        except:
+            pass
+
+    def create(self, repomd, pkglist, optlist=()):
+        try:
+            pkgmgr = MiniBackend(self.get_rootdir())
+            pkgmgr.arch = self.arch
+            pkgmgr.repomd = repomd
+            pkgmgr.optionals = list(optlist)
+            map(pkgmgr.selectPackage, pkglist + list(optlist))
+            pkgmgr.runInstall()
+        except (OSError, IOError, errors.CreatorError) as err:
+            raise errors.BootstrapError("%s" % err)
+
+    def run(self, cmd, chdir, rootdir=None, bindmounts=None):
+        def mychroot():
+            os.chroot(rootdir)
+            os.chdir(chdir)
+
+        def sync_timesetting(rootdir):
+            try:
+                # sync time and zone info to bootstrap
+                if os.path.exists(rootdir + "/etc/localtime"):
+                    os.unlink(rootdir + "/etc/localtime")
+                shutil.copyfile("/etc/localtime", rootdir + "/etc/localtime")
+            except:
+                pass
+
+        def sync_passwdfile(rootdir):
+            try:
+                # sync passwd file to bootstrap, saving the user info
+                if os.path.exists(rootdir + "/etc/passwd"):
+                    os.unlink(rootdir + "/etc/passwd")
+                shutil.copyfile("/etc/passwd", rootdir + "/etc/passwd")
+            except:
+                pass
+
+        def sync_hostfile(rootdir):
+            try:
+                # sync host info to bootstrap
+                if os.path.exists(rootdir + "/etc/hosts"):
+                    os.unlink(rootdir + "/etc/hosts")
+                shutil.copyfile("/etc/hosts", rootdir + "/etc/hosts")
+            except:
+                pass
+
+        def sync_signfile(rootdir,homedir):
+            if os.path.exists(homedir + "/.sign"):
+                signfile = rootdir + homedir + "/.sign"
+                try:
+                    # sync sign info to bootstrap
+                    if os.path.exists(signfile):
+                        if os.path.isdir(signfile):
+                            shutil.rmtree(signfile)
+                        else:
+                            os.unlink(signfile)
+                    try:
+                        shutil.copytree(homedir + "/.sign", signfile)
+                    except OSError as exc:
+                        if exc.errno == errno.ENOTDIR:
+                            shutil.copy(homedir + "/.sign", signfile)
+                        else: raise
+                except:
+                    pass
+
+        if not rootdir:
+            rootdir = self.rootdir
+
+        if isinstance(cmd, list):
+            shell = False
+        else:
+            shell = True
+
+        env = os.environ
+        env['PATH'] = "%s:%s" % (PATH_BOOTSTRAP, env['PATH'])
+        cropts = configmgr.create
+        if cropts["ks"]:
+            lang = cropts["ks"].handler.lang.lang
+            env['LANG'] = lang
+            env['LC_ALL'] = lang
+
+        retcode = 0
+        gloablmounts = None
+        try:
+            proxy.set_proxy_environ()
+            #globalmounts is no useless, remove it, currently function always return none.
+            setup_chrootenv(rootdir, bindmounts)
+            sync_timesetting(rootdir)
+            sync_passwdfile(rootdir)
+            sync_hostfile(rootdir)
+            env['SUDO_USER'] = 'root'
+            if 'SUDO_USER' in env:
+                sync_signfile(rootdir, os.path.expanduser('~' + env['SUDO_USER']))
+            else:
+                sync_signfile(rootdir, os.path.expanduser('~'))
+            retcode = subprocess.call(cmd, preexec_fn=mychroot, env=env, shell=shell)
+        except (OSError, IOError):
+            # add additional information to original exception
+            value, tb = sys.exc_info()[1:]
+            value = '%s: %s' % (value, ' '.join(cmd))
+            raise RuntimeError (value, tb)
+        finally:
+            #if self.logfile and os.path.isfile(self.logfile):
+            #    msger.log(file(self.logfile).read())
+            cleanup_chrootenv(rootdir, bindmounts, gloablmounts)
+            proxy.unset_proxy_environ()
+        return retcode
+
+    def cleanup(self):
+        try:
+            # clean mounts
+            cleanup_mounts(self.rootdir)
+            # remove rootdir
+            shutil.rmtree(self.rootdir, ignore_errors=True)
+        except:
+            pass
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/chroot.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/chroot.py
new file mode 100644 (file)
index 0000000..27278b6
--- /dev/null
@@ -0,0 +1,334 @@
+#!/usr/bin/python -tt
+#
+# 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 re
+import shutil
+import subprocess
+
+from mic import msger
+from mic.conf import configmgr
+from mic.utils import misc, errors, runner, fs_related, lock
+
+#####################################################################
+### GLOBAL CONSTANTS
+#####################################################################
+
+chroot_bindmounts = None
+chroot_lock = None
+BIND_MOUNTS = (
+                "/proc",
+                "/proc/sys/fs/binfmt_misc",
+                "/sys",
+                "/dev",
+                "/dev/pts",
+                "/var/lib/dbus",
+                "/var/run/dbus",
+                "/var/lock",
+                "/lib/modules",
+              )
+
+#####################################################################
+### GLOBAL ROUTINE
+#####################################################################
+
+def ELF_arch(chrootdir):
+    """ detect the architecture of an ELF file """
+    #FIXME: if chkfiles are symlink, it will be complex
+    chkfiles = ('/bin/bash', '/sbin/init')
+    # regular expression to arch mapping
+    mapping = {
+                r"Intel 80[0-9]86": "i686",
+                r"x86-64": "x86_64",
+                r"ARM": "arm",
+                r"RISC-V": "riscv64",
+              }
+
+    for path in chkfiles:
+        cpath = os.path.join(chrootdir, path.lstrip('/'))
+        if not os.path.exists(cpath):
+            continue
+
+        outs = runner.outs(['file', cpath])
+        for ptn in mapping.keys():
+            if re.search(ptn, outs):
+                return mapping[ptn]
+
+    raise errors.CreatorError("Failed to detect architecture of chroot: %s" %
+                              chrootdir)
+
+def get_bindmounts(chrootdir, bindmounts = None):
+    """ calculate all bind mount entries for global usage """
+    # bindmounts should be a string like '/dev:/dev'
+    # FIXME: refine the bindmounts from string to dict
+    global chroot_bindmounts
+
+    def totuple(string):
+        """ convert string contained ':' to a tuple """
+        if ':' in string:
+            src, dst = string.split(':', 1)
+        else:
+            src = string
+            dst = None
+
+        return (src or None, dst or None)
+
+    if chroot_bindmounts:
+        return chroot_bindmounts
+
+    chroot_bindmounts = []
+    bindmounts = bindmounts or ""
+    mountlist = []
+
+    for mount in bindmounts.split(";"):
+        if not mount:
+            continue
+
+        (src, dst) = totuple(mount)
+
+        if src in BIND_MOUNTS or src == '/':
+            continue
+
+        if not os.path.exists(src):
+            os.makedirs(src)
+
+        if dst and os.path.isdir("%s/%s" % (chrootdir, dst)):
+            msger.warning("%s existed in %s , skip it." % (dst, chrootdir))
+            continue
+
+        mountlist.append(totuple(mount))
+
+    for mntpoint in BIND_MOUNTS:
+        if os.path.isdir(mntpoint):
+            mountlist.append(tuple((mntpoint, None)))
+
+    for pair in mountlist:
+        if pair[0] == "/lib/modules":
+            opt = "ro"
+        else:
+            opt = None
+        bmount = fs_related.BindChrootMount(pair[0], chrootdir, pair[1], opt)
+        chroot_bindmounts.append(bmount)
+
+    return chroot_bindmounts
+
+#####################################################################
+### SETUP CHROOT ENVIRONMENT
+#####################################################################
+
+def bind_mount(chrootmounts):
+    """ perform bind mounting """
+    for mnt in chrootmounts:
+        msger.verbose("bind_mount: %s -> %s" % (mnt.src, mnt.dest))
+        mnt.mount()
+
+def setup_resolv(chrootdir):
+    """ resolve network """
+    try:
+        shutil.copyfile("/etc/resolv.conf", chrootdir + "/etc/resolv.conf")
+    except (OSError, IOError):
+        pass
+
+def setup_mtab(chrootdir):
+    """ adjust mount table """
+    try:
+        mtab = "/etc/mtab"
+        dstmtab = chrootdir + mtab
+        if not os.path.islink(dstmtab):
+            shutil.copyfile(mtab, dstmtab)
+    except (OSError, IOError):
+        pass
+
+def setup_chrootenv(chrootdir, bindmounts = None):
+    """ setup chroot environment """
+    global chroot_lock
+
+    # acquire the lock
+    if not chroot_lock:
+        lockpath = os.path.join(chrootdir, '.chroot.lock')
+        chroot_lock = lock.SimpleLockfile(lockpath)
+    chroot_lock.acquire()
+    # bind mounting
+    bind_mount(get_bindmounts(chrootdir, bindmounts))
+    # setup resolv.conf
+    setup_resolv(chrootdir)
+    # update /etc/mtab
+    setup_mtab(chrootdir)
+
+    return None
+
+######################################################################
+### CLEANUP CHROOT ENVIRONMENT
+######################################################################
+
+def bind_unmount(chrootmounts):
+    """ perform bind unmounting """
+    for mnt in reversed(chrootmounts):
+        msger.verbose("bind_unmount: %s -> %s" % (mnt.src, mnt.dest))
+        mnt.unmount()
+
+def cleanup_resolv(chrootdir):
+    """ clear resolv.conf """
+    try:
+        fdes = open(chrootdir + "/etc/resolv.conf", "w")
+        fdes.truncate(0)
+        fdes.close()
+    except (OSError, IOError):
+        pass
+
+def kill_proc_inchroot(chrootdir):
+    """ kill all processes running inside chrootdir """
+    import glob
+    for fpath in glob.glob("/proc/*/root"):
+        try:
+            if os.readlink(fpath) == chrootdir:
+                pid = int(fpath.split("/")[2])
+                os.kill(pid, 9)
+        except (OSError, ValueError):
+            pass
+
+def cleanup_mtab(chrootdir):
+    """ remove mtab file """
+    if os.path.exists(chrootdir + "/etc/mtab"):
+        os.unlink(chrootdir + "/etc/mtab")
+
+def cleanup_mounts(chrootdir):
+    """ clean up all mount entries owned by chrootdir """
+    umountcmd = misc.find_binary_path("umount")
+    mounts = open('/proc/mounts').readlines()
+    for line in reversed(mounts):
+        if chrootdir not in line:
+            continue
+
+        point = line.split()[1]
+
+        # '/' to avoid common name prefix
+        if chrootdir == point or point.startswith(chrootdir + '/'):
+            args = [ umountcmd, "-l", point ]
+            ret = runner.quiet(args)
+            if ret != 0:
+                msger.warning("failed to unmount %s" % point)
+            if os.path.isdir(point) and len(os.listdir(point)) == 0:
+                shutil.rmtree(point)
+            else:
+                msger.warning("%s is not directory or is not empty" % point)
+
+def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()):
+    """ clean up chroot environment """
+    global chroot_lock
+
+    # kill processes
+    kill_proc_inchroot(chrootdir)
+    # clean mtab
+    cleanup_mtab(chrootdir)
+    # clean resolv.conf
+    cleanup_resolv(chrootdir)
+    # bind umounting
+    bind_unmount(get_bindmounts(chrootdir, bindmounts))
+    # FIXME: need to clean up mounts?
+    #cleanup_mounts(chrootdir)
+
+    # release the lock
+    if chroot_lock:
+        chroot_lock.release()
+        chroot_lock = None
+
+    return None
+
+#####################################################################
+### CHROOT STUFF
+#####################################################################
+
+def savefs_before_chroot(chrootdir, saveto = None):
+    """ backup chrootdir to another directory before chrooting in """
+    if configmgr.chroot['saveto']:
+        savefs = True
+        saveto = configmgr.chroot['saveto']
+        wrnmsg = "Can't save chroot fs for dir %s exists" % saveto
+        if saveto == chrootdir:
+            savefs = False
+            wrnmsg = "Dir %s is being used to chroot" % saveto
+        elif os.path.exists(saveto):
+            if msger.ask("Dir %s already exists, cleanup and continue?" %
+                         saveto):
+                shutil.rmtree(saveto, ignore_errors = True)
+                savefs = True
+            else:
+                savefs = False
+
+        if savefs:
+            msger.info("Saving image to directory %s" % saveto)
+            fs_related.makedirs(os.path.dirname(os.path.abspath(saveto)))
+            runner.quiet("cp -af %s %s" % (chrootdir, saveto))
+            devs = ['dev/fd',
+                    'dev/stdin',
+                    'dev/stdout',
+                    'dev/stderr',
+                    'etc/mtab']
+            ignlst = [os.path.join(saveto, x) for x in devs]
+            map(os.unlink, filter(os.path.exists, ignlst))
+        else:
+            msger.warning(wrnmsg)
+
+def cleanup_after_chroot(targettype, imgmount, tmpdir, tmpmnt):
+    """ clean up all temporary directories after chrooting """
+    if imgmount and targettype == "img":
+        imgmount.cleanup()
+
+    if tmpdir:
+        shutil.rmtree(tmpdir, ignore_errors = True)
+
+    if tmpmnt:
+        shutil.rmtree(tmpmnt, ignore_errors = True)
+
+def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"):
+    """ chroot the chrootdir and execute the command """
+    def mychroot():
+        """ pre-execute function """
+        os.chroot(chrootdir)
+        os.chdir("/")
+
+    arch = ELF_arch(chrootdir)
+    if arch == "arm":
+        qemu_emulators = misc.setup_qemu_emulator(chrootdir, "arm")
+    elif arch == "mipsel":
+        qemu_emulators = misc.setup_qemu_emulator(chrootdir, "mipsel")
+    elif arch == "riscv64":
+        qemu_emulators = misc.setup_qemu_emulator(chrootdir, "riscv64")
+    else:
+        qemu_emulators = []
+
+    savefs_before_chroot(chrootdir, None)
+
+    globalmounts = None
+
+    try:
+        msger.info("Launching shell. Exit to continue.\n"
+                   "----------------------------------")
+
+        #globalmounts is no useless, remove it, currently function always return none.
+        setup_chrootenv(chrootdir, bindmounts)
+        subprocess.call(execute, preexec_fn = mychroot, shell=True)
+
+    except OSError as err:
+        raise errors.CreatorError("chroot err: %s" % str(err))
+
+    finally:
+        cleanup_chrootenv(chrootdir, bindmounts, globalmounts)
+        for qemu_emulator in qemu_emulators:
+            os.unlink(chrootdir + qemu_emulator)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_chroot.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_chroot.py
new file mode 100644 (file)
index 0000000..35b089b
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/python -tt\r
+# vim: ai ts=4 sts=4 et sw=4\r
+#\r
+# Copyright (c) 2012 Intel, Inc.\r
+#\r
+# This program is free software; you can redistribute it and/or modify it\r
+# under the terms of the GNU General Public License as published by the Free\r
+# Software Foundation; version 2 of the License\r
+#\r
+# This program is distributed in the hope that it will be useful, but\r
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+# for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License along\r
+# with this program; if not, write to the Free Software Foundation, Inc., 59\r
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+"""Implementation of subcmd: chroot\r
+"""\r
+\r
+import os\r
+import os, sys, re\r
+import pwd\r
+import argparse\r
+\r
+from mic import msger\r
+from mic.utils import misc, errors\r
+from mic.conf import configmgr\r
+from mic.plugin import pluginmgr\r
+\r
+def _root_confirm():\r
+    """Make sure command is called by root\r
+    There are a lot of commands needed to be run during creating images,\r
+    some of them must be run with root privilege like mount, kpartx"""\r
+    if os.geteuid() != 0:\r
+        msger.error('Root permission is required to continue, abort')\r
+            \r
+def main(parser, args, argv):\r
+    """mic choot entry point."""\r
+\r
+    #args is argparser namespace, argv is the input cmd line\r
+    if args is None:\r
+        raise errors.Usage("Invalid arguments")\r
+\r
+    targetimage = args.imagefile\r
+    if not os.path.exists(targetimage):\r
+        raise errors.CreatorError("Cannot find the image: %s"\r
+                                  % targetimage)\r
+\r
+    _root_confirm()\r
+\r
+    configmgr.chroot['saveto'] = args.saveto\r
+\r
+    imagetype = misc.get_image_type(targetimage)\r
+    if imagetype in ("ext3fsimg", "ext4fsimg", "btrfsimg", "f2fsimg"):\r
+        imagetype = "loop"\r
+\r
+    chrootclass = None\r
+    for pname, pcls in pluginmgr.get_plugins('imager').iteritems():\r
+        if pname == imagetype and hasattr(pcls, "do_chroot"):\r
+            chrootclass = pcls\r
+            break\r
+\r
+    if not chrootclass:\r
+        raise errors.CreatorError("Cannot support image type: %s" \\r
+                                  % imagetype)\r
+\r
+    chrootclass.do_chroot(targetimage, args.cmd)\r
+        \r
+    \r
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_create.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/cmd_create.py
new file mode 100644 (file)
index 0000000..a62abc7
--- /dev/null
@@ -0,0 +1,270 @@
+#!/usr/bin/python -tt\r
+# vim: ai ts=4 sts=4 et sw=4\r
+#\r
+# Copyright (c) 2012 Intel, Inc.\r
+#\r
+# This program is free software; you can redistribute it and/or modify it\r
+# under the terms of the GNU General Public License as published by the Free\r
+# Software Foundation; version 2 of the License\r
+#\r
+# This program is distributed in the hope that it will be useful, but\r
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+# for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License along\r
+# with this program; if not, write to the Free Software Foundation, Inc., 59\r
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+"""Implementation of subcmd: create\r
+"""\r
+\r
+import os\r
+import os, sys, re\r
+import pwd\r
+import argparse\r
+\r
+from mic import msger\r
+from mic.utils import errors, rpmmisc\r
+from mic.conf import configmgr\r
+from mic.plugin import pluginmgr\r
+\r
+def main(parser, args, argv):\r
+    """mic create entry point."""\r
+    #args is argparser namespace, argv is the input cmd line\r
+    if args is None:\r
+        raise errors.Usage("Invalid arguments")\r
+\r
+    if not os.path.exists(args.ksfile):\r
+        raise errors.CreatorError("Can't find the file: %s" % args.ksfile)\r
+\r
+    if os.geteuid() != 0:\r
+        msger.error("Root permission is required, abort")\r
+        \r
+    try:\r
+        w = pwd.getpwuid(os.geteuid())\r
+    except KeyError:\r
+        msger.warning("Might fail in compressing stage for undetermined user")\r
+    \r
+    abspath = lambda pth: os.path.abspath(os.path.expanduser(pth))\r
+    if args.logfile:\r
+        logfile_abs_path = abspath(args.logfile)\r
+        if os.path.isdir(logfile_abs_path):\r
+            raise errors.Usage("logfile's path %s should be file"\r
+                               % args.logfile)\r
+        configmgr.create['logfile'] = logfile_abs_path\r
+        configmgr.set_logfile()\r
+\r
+    if args.subcommand == "auto":\r
+        do_auto(parser, args.ksfile, argv)\r
+        return\r
+\r
+    if args.interactive:\r
+        msger.enable_interactive()\r
+    else:\r
+        msger.disable_interactive()\r
+\r
+    if args.verbose:\r
+        msger.set_loglevel('VERBOSE')\r
+\r
+    if args.debug:\r
+        try:\r
+            import rpm\r
+            rpm.setVerbosity(rpm.RPMLOG_NOTICE)\r
+        except ImportError:\r
+            pass\r
+\r
+        msger.set_loglevel('DEBUG')\r
+\r
+    if args.rpm_debug:\r
+        try:\r
+            import rpm\r
+            rpm.setVerbosity(rpm.RPMLOG_DEBUG)\r
+        except ImportError:\r
+            pass\r
+    #check the imager type\r
+    createrClass = None\r
+    for subcmd, klass in pluginmgr.get_plugins('imager').iteritems():\r
+        if subcmd == args.subcommand and hasattr(klass, 'do_create'):\r
+            createrClass = klass\r
+\r
+    if createrClass is None:\r
+        raise errors.CreatorError("Can't support subcommand %s" % args.subcommand)\r
+\r
+    if args.config:\r
+        configmgr.reset()\r
+        configmgr._siteconf = args.config\r
+\r
+    if args.outdir is not None:\r
+        configmgr.create['outdir'] = abspath(args.outdir)\r
+    if args.cachedir is not None:\r
+        configmgr.create['cachedir'] = abspath(args.cachedir)\r
+    os.environ['ZYPP_LOCKFILE_ROOT'] = configmgr.create['cachedir']\r
+\r
+    for cdir in ('outdir', 'cachedir'):\r
+        if os.path.exists(configmgr.create[cdir]) \\r
+          and not os.path.isdir(configmgr.create[cdir]):\r
+            raise errors.Usage('Invalid directory specified: %s' \\r
+                               % configmgr.create[cdir])\r
+        if not os.path.exists(configmgr.create[cdir]):\r
+            os.makedirs(configmgr.create[cdir])\r
+            if os.getenv('SUDO_UID', '') and os.getenv('SUDO_GID', ''):\r
+                os.chown(configmgr.create[cdir],\r
+                         int(os.getenv('SUDO_UID')),\r
+                         int(os.getenv('SUDO_GID')))\r
+\r
+    if args.local_pkgs_path is not None:\r
+        if not os.path.exists(args.local_pkgs_path):\r
+            raise errors.Usage('Local pkgs directory: \'%s\' not exist' \\r
+                          % args.local_pkgs_path)\r
+        configmgr.create['local_pkgs_path'] = args.local_pkgs_path\r
+\r
+    if args.release:\r
+        configmgr.create['release'] = args.release.rstrip('/')\r
+\r
+    if args.record_pkgs:\r
+        configmgr.create['record_pkgs'] = []\r
+        for infotype in args.record_pkgs.split(','):\r
+            if infotype not in ('name', 'content', 'license', 'vcs'):\r
+                raise errors.Usage('Invalid pkg recording: %s, valid ones:'\r
+                                   ' "name", "content", "license", "vcs"' \\r
+                                   % infotype)\r
+\r
+            configmgr.create['record_pkgs'].append(infotype)\r
+\r
+    if args.strict_mode:\r
+      configmgr.create['strict_mode'] = args.strict_mode\r
+    if args.arch is not None:\r
+        supported_arch = sorted(rpmmisc.archPolicies.keys(), reverse=True)\r
+        if args.arch in supported_arch:\r
+            configmgr.create['arch'] = args.arch\r
+        else:\r
+            raise errors.Usage('Invalid architecture: "%s".\n'\r
+                               '  Supported architectures are: \n'\r
+                               '  %s' % (args.arch,\r
+                                           ', '.join(supported_arch)))\r
+\r
+    if args.pkgmgr is not None:\r
+        configmgr.create['pkgmgr'] = args.pkgmgr\r
+\r
+    if args.skip_set_hosts:\r
+        configmgr.create['skip_set_hosts']=args.skip_set_hosts\r
+    if args.postscripts_maxruntime:\r
+        configmgr.create['postscripts_maxruntime']=int(args.postscripts_maxruntime)\r
+    if args.block_recommends:\r
+        configmgr.create['block_recommends']=args.block_recommends\r
+    if args.runtime:\r
+        configmgr.set_runtime(args.runtime)\r
+\r
+    if args.use_mic_in_bootstrap:\r
+        configmgr.create['use_mic_in_bootstrap'] = args.use_mic_in_bootstrap\r
+\r
+    if args.pack_to is not None:\r
+        configmgr.create['pack_to'] = args.pack_to\r
+\r
+    if args.copy_kernel:\r
+        configmgr.create['copy_kernel'] = args.copy_kernel\r
+\r
+    if args.install_pkgs:\r
+        configmgr.create['install_pkgs'] = []\r
+        for pkgtype in args.install_pkgs.split(','):\r
+            if pkgtype not in ('source', 'debuginfo', 'debugsource'):\r
+                raise errors.Usage('Invalid parameter specified: "%s", '\r
+                                   'valid values: source, debuginfo, '\r
+                                   'debusource' % pkgtype)\r
+\r
+            configmgr.create['install_pkgs'].append(pkgtype)\r
+\r
+    if args.check_pkgs:\r
+        for pkg in args.check_pkgs.split(','):\r
+            configmgr.create['check_pkgs'].append(pkg)\r
+\r
+    if args.enabletmpfs:\r
+        configmgr.create['enabletmpfs'] = args.enabletmpfs\r
+\r
+    if args.repourl:\r
+        for item in args.repourl:\r
+            try:\r
+                key, val = item.split('=')\r
+            except:\r
+                continue\r
+            configmgr.create['repourl'][key] = val\r
+\r
+    if args.repo:\r
+        for optvalue in args.repo:\r
+            repo = {}\r
+            for item in optvalue.split(';'):\r
+                try:\r
+                    key, val = item.split('=')\r
+                except:\r
+                    continue\r
+                repo[key.strip()] = val.strip()\r
+            if 'name' in repo:\r
+                configmgr.create['extrarepos'][repo['name']] = repo\r
+\r
+    if args.ignore_ksrepo:\r
+        configmgr.create['ignore_ksrepo'] = args.ignore_ksrepo\r
+    if args.run_script:\r
+        configmgr.create['run_script'] = args.run_script\r
+    if args.tpk_install:\r
+        configmgr.create['tpk_install'] = args.tpk_install\r
+\r
+    creater = createrClass()\r
+    creater.do_create(args)\r
+\r
+def do_auto(parser, ksfile, argv):\r
+        """${cmd_name}: auto detect image type from magic header\r
+\r
+        Usage:\r
+            ${name} ${cmd_name} <ksfile>\r
+\r
+        ${cmd_option_list}\r
+        """\r
+        def parse_magic_line(re_str, pstr, ptype='mic'):\r
+            ptn = re.compile(re_str)\r
+            m = ptn.match(pstr)\r
+            if not m or not m.groups():\r
+                return None\r
+\r
+            inline_argv = m.group(1).strip()\r
+            if ptype == 'mic':\r
+                m2 = re.search('(?P<format>\w+)', inline_argv)\r
+            elif ptype == 'mic2':\r
+                m2 = re.search('(-f|--format(=)?)\s*(?P<format>\w+)',\r
+                               inline_argv)\r
+            else:\r
+                return None\r
+\r
+            if m2:\r
+                cmdname = m2.group('format')\r
+                inline_argv = inline_argv.replace(m2.group(0), '')\r
+                return (cmdname, inline_argv)\r
+\r
+            return None\r
+\r
+        if not os.path.exists(ksfile):\r
+            raise errors.CreatorError("Can't find the file: %s" % ksfile)\r
+\r
+        with open(ksfile, 'r') as rf:\r
+            first_line = rf.readline()\r
+\r
+        mic_re = '^#\s*-\*-mic-options-\*-\s+(.*)\s+-\*-mic-options-\*-'\r
+        mic2_re = '^#\s*-\*-mic2-options-\*-\s+(.*)\s+-\*-mic2-options-\*-'\r
+\r
+        result = parse_magic_line(mic_re, first_line, 'mic') \\r
+                 or parse_magic_line(mic2_re, first_line, 'mic2')\r
+        if not result:\r
+            raise errors.KsError("Invalid magic line in file: %s" % ksfile)\r
+        \r
+        ksargv = ' '.join(result).split()\r
+\r
+        argv.remove("auto")\r
+        index = argv.index("create")\r
+        #insert the subcommand\r
+        argv.insert(index+1, ksargv[0])\r
+        options = argv + ksargv[1:]\r
+\r
+        args = parser.parse_args(options)\r
+\r
+        main(parser, args, options)\r
+\r
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/conf.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/conf.py
new file mode 100644 (file)
index 0000000..279d14f
--- /dev/null
@@ -0,0 +1,322 @@
+#!/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, proxy, errors
+
+
+DEFAULT_GSITECONF = '/etc/mic/mic.conf'
+
+
+def get_siteconf():
+    if hasattr(sys, 'real_prefix'):
+        return os.path.join(sys.prefix, "etc/mic/mic.conf")
+    else:
+        return DEFAULT_GSITECONF
+
+def inbootstrap():
+    if os.path.exists(os.path.join("/", ".chroot.lock")):
+        return True
+    return (os.stat("/").st_ino != 2)
+
+class ConfigMgr(object):
+    prefer_backends = ["zypp", "yum"]
+
+    DEFAULTS = {'common': {
+                    "distro_name": "Default Distribution",
+                    "plugin_dir": "/usr/lib/mic/plugins", # TODO use prefix also?
+                },
+                'create': {
+                    "tmpdir": '/var/tmp/mic',
+                    "cachedir": '/var/tmp/mic/cache',
+                    "outdir": './mic-output',
+                    "destdir": None,
+                    "arch": None, # None means auto-detect
+                    "pkgmgr": "auto",
+                    "name": "output",
+                    "ksfile": None,
+                    "ks": None,
+                    "repomd": None,
+                    "local_pkgs_path": None,
+                    "release": None,
+                    "logfile": None,
+                    "releaselog": False,
+                    "record_pkgs": [],
+                    "pack_to": None,
+                    "name_prefix": None,
+                    "name_suffix": None,
+                    "proxy": None,
+                    "no_proxy": None,
+                    "ssl_verify": "yes",
+                    "copy_kernel": False,
+                    "install_pkgs": None,
+                    "check_pkgs": [],
+                    "repourl": {},
+                    "localrepos": [],  # save localrepos
+                    "localtpkrepos":[],
+                    "runtime": "bootstrap",
+                    "extrarepos": {},
+                    "ignore_ksrepo": False,
+                    "strict_mode": False,
+                    "run_script": None,
+                    "tpk_install": None,
+                    "use_mic_in_bootstrap": False,
+                    "skip_set_hosts": False,
+                    "postscripts_maxruntime": 120,
+                    "block_recommends": False,
+                },
+                'chroot': {
+                    "saveto": None,
+                },
+                'convert': {
+                    "shell": False,
+                },
+                'bootstrap': {
+                    "rootdir": '/var/tmp/mic-bootstrap',
+                    "packages": [],
+                    "distro_name": "",
+                },
+               }
+
+    # 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_siteconf(self, siteconf):
+        try:
+            self.__siteconf = siteconf
+            self._parse_siteconf(siteconf)
+        except ConfigParser.Error as error:
+            raise errors.ConfigError("%s" % error)
+    def __get_siteconf(self):
+        return self.__siteconf
+    _siteconf = property(__get_siteconf, __set_siteconf)
+
+    def __set_ksconf(self, ksconf):
+        if not os.path.isfile(ksconf):
+            raise errors.KsError('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_siteconf(self, siteconf):
+
+        if os.getenv("MIC_PLUGIN_DIR"):
+            self.common["plugin_dir"] = os.environ["MIC_PLUGIN_DIR"]
+
+        if siteconf and not os.path.exists(siteconf):
+            msger.warning("cannot find config file: %s" % siteconf)
+            siteconf = None
+
+        if not siteconf:
+            self.common["distro_name"] = "Tizen"
+            # append common section items to other sections
+            for section in self.DEFAULTS.keys():
+                if section != "common":
+                    getattr(self, section).update(self.common)
+
+            return
+
+        parser = ConfigParser.SafeConfigParser()
+        parser.read(siteconf)
+
+        for section in parser.sections():
+            if section in self.DEFAULTS:
+                getattr(self, section).update(dict(parser.items(section)))
+
+        # append common section items to other sections
+        for section in self.DEFAULTS.keys():
+            if section != "common":
+                getattr(self, section).update(self.common)
+
+        # check and normalize the scheme of proxy url
+        if self.create['proxy']:
+            m = re.match('^(\w+)://.*', self.create['proxy'])
+            if m:
+                scheme = m.group(1)
+                if scheme not in ('http', 'https', 'ftp', 'socks'):
+                    raise errors.ConfigError("%s: proxy scheme is incorrect" % siteconf)
+            else:
+                msger.warning("%s: proxy url w/o scheme, use http as default"
+                              % siteconf)
+                self.create['proxy'] = "http://" + self.create['proxy']
+
+        proxy.set_proxies(self.create['proxy'], self.create['no_proxy'])
+
+        # bootstrap option handling
+        self.set_runtime(self.create['runtime'])
+        if isinstance(self.bootstrap['packages'], basestring):
+            packages = self.bootstrap['packages'].replace('\n', ' ')
+            if packages.find(',') != -1:
+                packages = packages.split(',')
+            else:
+                packages = packages.split()
+            self.bootstrap['packages'] = packages
+
+        if type(self.create['use_mic_in_bootstrap']) != 'bool':
+            use_mic_in_bootstrap = str(self.create['use_mic_in_bootstrap'])
+            if use_mic_in_bootstrap.lower() in ('on', 'yes', 'true', '1'):
+                self.create['use_mic_in_bootstrap'] = True
+            else:
+                self.create['use_mic_in_bootstrap'] = False
+
+    def _parse_kickstart(self, ksconf=None):
+        if not ksconf:
+            return
+
+        ksconf = misc.normalize_ksfile(ksconf,
+                                       self.create['release'],
+                                       self.create['arch'])
+
+        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'])
+
+        self.create['destdir'] = self.create['outdir']
+        if self.create['release'] is not None:
+            self.create['destdir'] = "%s/%s/images/%s/" % (self.create['outdir'],
+                                                           self.create['release'],
+                                                           self.create['name'])
+            self.create['name'] = self.create['release'] + '_' + self.create['name']
+            if self.create['pack_to'] is not None:
+                if '@NAME@' in self.create['pack_to']:
+                    self.create['pack_to'] = self.create['pack_to'].replace('@NAME@', self.create['name'])
+                self.create['name'] = misc.strip_archive_suffix(self.create['pack_to'])
+                if self.create['name'] is None:
+                    raise errors.CreatorError("Not supported archive file format: %s" % self.create['pack_to'])
+
+            if not self.create['logfile']:
+                self.create['logfile'] = os.path.join(self.create['destdir'],
+                                                      self.create['name'] + ".log")
+                self.create['releaselog'] = True
+                self.set_logfile()
+
+        elif self.create['pack_to'] is not None:
+            if '@NAME@' in self.create['pack_to']:
+                self.create['pack_to'] = self.create['pack_to'].replace('@NAME@', self.create['name'])
+            self.create['name'] = misc.strip_archive_suffix(self.create['pack_to'])
+            if self.create['name'] is None:
+                raise errors.CreatorError("Not supported archive file format: %s" % self.create['pack_to'])
+
+        msger.info("Retrieving repo metadata:")
+        ksrepos = kickstart.get_repos(ks,
+                                      self.create['extrarepos'],
+                                      self.create['ignore_ksrepo'])
+        if not ksrepos:
+            raise errors.KsError('no valid repos found in ks file')
+
+        for repo in ksrepos:
+            if hasattr(repo, 'baseurl') and repo.baseurl.startswith("file:"):
+                repourl = repo.baseurl.replace('file:', '')
+                repourl = "/%s" % repourl.lstrip('/')
+                self.create['localrepos'].append(repourl)
+
+        self.create['repomd'] = misc.get_metadata_from_repos(
+                                                    ksrepos,
+                                                    self.create['cachedir'])
+        kstpkrepos = kickstart.get_tpkrepos(ks)
+        if kstpkrepos:
+            for tpk_repo in kstpkrepos:
+                if hasattr(tpk_repo,'baseurl') and tpk_repo.baseurl.startswith("file:"):
+                    tpk_repourl = tpk_repo.baseurl.replace('file:','')
+                    tpk_repourl = "/%s" % tpk_repourl.lstrip('/')
+                    self.create['localtpkrepos'].append(tpk_repourl)
+
+        msger.raw(" DONE")
+
+        target_archlist, archlist = misc.get_arch(self.create['repomd'])
+        if self.create['arch']:
+            if self.create['arch'] not in archlist:
+                raise errors.ConfigError("Invalid arch %s for repository. "
+                                  "Valid arches: %s" \
+                                  % (self.create['arch'], ', '.join(archlist)))
+        else:
+            if len(target_archlist) == 1:
+                self.create['arch'] = str(target_archlist[0])
+                msger.info("Use detected arch %s." % target_archlist[0])
+            else:
+                raise errors.ConfigError("Please specify a valid arch, "
+                                         "the choice can be: %s" \
+                                         % ', '.join(archlist))
+
+        kickstart.resolve_groups(self.create, self.create['repomd'])
+
+        # check selinux, it will block arm and btrfs image creation
+        misc.selinux_check(self.create['arch'],
+                           [p.fstype for p in ks.handler.partition.partitions])
+
+    def set_logfile(self, logfile = None):
+        if not logfile:
+            logfile = self.create['logfile']
+
+        logfile_dir = os.path.dirname(self.create['logfile'])
+        if not os.path.exists(logfile_dir):
+            os.makedirs(logfile_dir)
+        msger.set_interactive(False)
+        if inbootstrap():
+            mode = 'a'
+        else:
+            mode = 'w'
+        msger.set_logfile(self.create['logfile'], mode)
+
+    def set_runtime(self, runtime):
+        if runtime != "bootstrap":
+            raise errors.CreatorError("Invalid runtime mode: %s, only 'bootstrap' mode is allowed." % runtime)
+
+        if misc.get_distro()[0] in ("tizen", "Tizen"):
+            runtime = "native"
+        self.create['runtime'] = runtime
+
+configmgr = ConfigMgr()
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/helpformat.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/helpformat.py
new file mode 100644 (file)
index 0000000..e17f716
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/env python\r
+# vim: ai ts=4 sts=4 et sw=4\r
+#\r
+# Copyright (c) 2011 Intel, Inc.\r
+#\r
+# This program is free software; you can redistribute it and/or modify it\r
+# under the terms of the GNU General Public License as published by the Free\r
+# Software Foundation; version 2 of the License\r
+#\r
+# This program is distributed in the hope that it will be useful, but\r
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+# for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License along\r
+# with this program; if not, write to the Free Software Foundation, Inc., 59\r
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+"""Local additions to commandline parsing."""\r
+\r
+import os\r
+import re\r
+import functools\r
+\r
+from argparse import RawDescriptionHelpFormatter, ArgumentTypeError\r
+\r
+class MICHelpFormatter(RawDescriptionHelpFormatter):\r
+    """Changed default argparse help output by request from cmdln lovers."""\r
+\r
+    def __init__(self, *args, **kwargs):\r
+        super(MICHelpFormatter, self).__init__(*args, **kwargs)\r
+        self._aliases = {}\r
+\r
+    def add_argument(self, action):\r
+        """Collect aliases."""\r
+\r
+        if action.choices:\r
+            for item, parser in action.choices.iteritems():\r
+                self._aliases[str(item)] = parser.get_default('alias')\r
+\r
+        return super(MICHelpFormatter, self).add_argument(action)\r
+\r
+    def format_help(self):\r
+        """\r
+        There is no safe and documented way in argparse to reformat\r
+        help output through APIs as almost all of them are private,\r
+        so this method just parses the output and changes it.\r
+        """\r
+        result = []\r
+        subcomm = False\r
+        for line in super(MICHelpFormatter, self).format_help().split('\n'):\r
+            if line.strip().startswith('{'):\r
+                continue\r
+            if line.startswith('optional arguments:'):\r
+                line = 'Global Options:'\r
+            if line.startswith('usage:'):\r
+                line = "Usage: mic [GLOBAL-OPTS] SUBCOMMAND [OPTS]"\r
+            if subcomm:\r
+                match = re.match("[ ]+([^ ]+)[ ]+(.+)", line)\r
+                if match:\r
+                    name, help_text = match.group(1), match.group(2)\r
+                    alias = self._aliases.get(name) or ''\r
+                    if alias:\r
+                        alias = "(%s)" % alias\r
+                    line = "  %-22s%s" % ("%s %s" % (name, alias), help_text)\r
+            if line.strip().startswith('subcommands:'):\r
+                line = 'Subcommands:'\r
+                subcomm = True\r
+            result.append(line)\r
+        return '\n'.join(result)\r
+\r
+def subparser(func):\r
+    """Convenient decorator for subparsers."""\r
+    @functools.wraps(func)\r
+    def wrapper(parser):\r
+        """\r
+        Create subparser\r
+        Set first line of function's docstring as a help\r
+        and the rest of the lines as a description.\r
+        Set attribute 'module' of subparser to 'cmd'+first part of function name\r
+        """\r
+        splitted = func.__doc__.split('\n')\r
+        name = func.__name__.split('_')[0]\r
+        subpar = parser.add_parser(name, help=splitted[0],\r
+                                   description='\n'.join(splitted[1:]),\r
+                                   formatter_class=RawDescriptionHelpFormatter)\r
+        subpar.set_defaults(module="cmd_%s" % name)\r
+        return func(subpar)\r
+    return wrapper\r
+\r
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/baseimager.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/baseimager.py
new file mode 100644 (file)
index 0000000..059e670
--- /dev/null
@@ -0,0 +1,1663 @@
+#!/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 stat
+import tempfile
+import shutil
+import subprocess
+import re
+import tarfile
+import glob
+import json
+import errno
+from datetime import datetime
+import rpm
+import time
+from mic import kickstart
+from mic import msger, __version__ as VERSION
+from mic.utils.errors import CreatorError, KsError, Abort
+from mic.utils import misc, grabber, runner, fs_related as fs
+from mic.chroot import kill_proc_inchroot
+from mic.archive import get_archive_suffixes
+from mic.conf import configmgr
+from mic.utils.grabber import myurlgrab
+
+class BaseImageCreator(object):
+    """Installs a system to a chroot directory.
+
+    ImageCreator is the simplest creator class available; it will install and
+    configure 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()
+
+    """
+    # Output image format
+    img_format = ''
+
+    def __del__(self):
+        self.cleanup()
+
+    def __init__(self, createopts = None, pkgmgr = 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.pkgmgr = pkgmgr
+        self.distro_name = ""
+
+        self.__builddir = None
+        self.__bindmounts = []
+
+        self.ks = None
+        self.name = "target"
+        self.tmpdir = "/var/tmp/mic"
+        self.cachedir = "/var/tmp/mic/cache"
+        self.workdir = "/var/tmp/mic/build"
+        self.destdir = "."
+        self.installerfw_prefix = "INSTALLERFW_"
+        self.target_arch = "noarch"
+        self.strict_mode = False
+        self._local_pkgs_path = None
+        self.pack_to = None
+        self.repourl = {}
+        self.multiple_partitions = False
+        self._imgdir = None
+
+        # If the kernel is save to the destdir when copy_kernel cmd is called.
+        self._need_copy_kernel = False
+        # setup tmpfs tmpdir when enabletmpfs is True
+        self.enabletmpfs = False
+
+        if createopts:
+            # Mapping table for variables that have different names.
+            optmap = {"pkgmgr" : "pkgmgr_name",
+                      "arch" : "target_arch",
+                      "local_pkgs_path" : "_local_pkgs_path",
+                      "copy_kernel" : "_need_copy_kernel",
+                      "strict_mode" : "strict_mode",
+                     }
+
+            # 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))
+
+            if self.pack_to:
+                (tar, ext) = os.path.splitext(self.pack_to)
+                if ext in (".gz", ".bz2", ".lzo", ".bz") and tar.endswith(".tar"):
+                    ext = ".tar" + ext
+                if ext not in get_archive_suffixes():
+                    self.pack_to += ".tar"
+
+        self._dep_checks = ["ls", "bash", "cp", "echo", "modprobe"]
+
+        # Output image file names
+        self.outimage = []
+        # Output info related with manifest
+        self.image_files = {}
+        # A flag to generate checksum
+        self._genchecksum = False
+
+        self._alt_initrd_name = None
+
+        self._recording_pkgs = []
+
+        # available size in root fs, init to 0
+        self._root_fs_avail = 0
+
+        # Name of the disk image file that is created.
+        self._img_name = None
+
+        self.image_format = None
+
+        # Save qemu emulator file names in order to clean up it finally
+        self.qemu_emulators = []
+
+        # No ks provided when called by convertor, so skip the dependency check
+        if self.ks:
+            if hasattr(self.ks.handler, "env"):
+                for n, v in kickstart.get_env(self.ks):
+                    msger.debug("Setting up envvar %s = %s" % (n, v))
+                    os.environ[n] = v
+            # 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
+                if part.cpioopts:
+                    if part.fstype == "cpio": 
+                        part.fstype = "ext4"
+                    else:
+                        raise KsError("The '--fstype' in ks file need to set 'cpio' when you want to generate image by cpio.")
+            if len(self.ks.handler.partition.partitions) > 1:
+                self.multiple_partitions = True
+
+        if self.target_arch:
+            if self.target_arch.startswith("arm"):
+                for dep in self._dep_checks:
+                    if dep == "extlinux":
+                        self._dep_checks.remove(dep)
+
+                if not os.path.exists("/usr/bin/qemu-arm") or \
+                   not misc.is_statically_linked("/usr/bin/qemu-arm"):
+                    self._dep_checks.append("qemu-arm-static")
+
+                if os.path.exists("/proc/sys/vm/vdso_enabled"):
+                    vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
+                    vdso_value = vdso_fh.read().strip()
+                    vdso_fh.close()
+                    if (int)(vdso_value) == 1:
+                        msger.warning("vdso is enabled on your host, which might "
+                            "cause problems with arm emulations.\n"
+                            "\tYou can disable vdso with following command before "
+                            "starting image build:\n"
+                            "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
+            elif self.target_arch == "mipsel":
+                for dep in self._dep_checks:
+                    if dep == "extlinux":
+                        self._dep_checks.remove(dep)
+
+                if not os.path.exists("/usr/bin/qemu-mipsel") or \
+                   not misc.is_statically_linked("/usr/bin/qemu-mipsel"):
+                    self._dep_checks.append("qemu-mipsel-static")
+
+                if os.path.exists("/proc/sys/vm/vdso_enabled"):
+                    vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
+                    vdso_value = vdso_fh.read().strip()
+                    vdso_fh.close()
+                    if (int)(vdso_value) == 1:
+                        msger.warning("vdso is enabled on your host, which might "
+                            "cause problems with mipsel emulations.\n"
+                            "\tYou can disable vdso with following command before "
+                            "starting image build:\n"
+                            "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
+            elif self.target_arch == "riscv64":
+                for dep in self._dep_checks:
+                    if dep == "extlinux":
+                        self._dep_checks.remove(dep)
+
+                if not os.path.exists("/usr/bin/qemu-riscv64") or \
+                   not misc.is_statically_linked("/usr/bin/qemu-riscv64"):
+                    self._dep_checks.append("qemu-riscv64-static")
+
+                if os.path.exists("/proc/sys/vm/vdso_enabled"):
+                    vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
+                    vdso_value = vdso_fh.read().strip()
+                    vdso_fh.close()
+                    if (int)(vdso_value) == 1:
+                        msger.warning("vdso is enabled on your host, which might "
+                            "cause problems with riscv64 emulations.\n"
+                            "\tYou can disable vdso with following command before "
+                            "starting image build:\n"
+                            "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
+
+        # make sure the specified tmpdir and cachedir exist
+        if not os.path.exists(self.tmpdir):
+            os.makedirs(self.tmpdir)
+        if not os.path.exists(self.cachedir):
+            os.makedirs(self.cachedir)
+
+
+    #
+    # Properties
+    #
+    def __get_instroot(self):
+        if self.__builddir is None:
+            raise CreatorError("_instroot is not valid before calling mount()")
+        return self.__builddir + "/install_root"
+    _instroot = property(__get_instroot)
+    """The location of the install root directory.
+
+    This is the directory into which the system is installed. Subclasses may
+    mount a filesystem image here or copy files to/from here.
+
+    Note, this directory does not exist before ImageCreator.mount() is called.
+
+    Note also, this is a read-only attribute.
+
+    """
+
+    def __get_outdir(self):
+        if self.__builddir is None:
+            raise CreatorError("_outdir is not valid before calling mount()")
+        return self.__builddir + "/out"
+    _outdir = property(__get_outdir)
+    """The staging location for the final image.
+
+    This is where subclasses should stage any files that are part of the final
+    image. ImageCreator.package() will copy any files found here into the
+    requested destination directory.
+
+    Note, this directory does not exist before ImageCreator.mount() is called.
+
+    Note also, this is a read-only attribute.
+
+    """
+
+
+    #
+    # Hooks for subclasses
+    #
+    def _mount_instroot(self, base_on = None):
+        """Mount or prepare the install root directory.
+
+        This is the hook where subclasses may prepare the install root by e.g.
+        mounting creating and loopback mounting a filesystem image to
+        _instroot.
+
+        There is no default implementation.
+
+        base_on -- this is the value passed to mount() and can be interpreted
+                   as the subclass wishes; it might e.g. be the location of
+                   a previously created ISO containing a system image.
+
+        """
+        pass
+
+    def _unmount_instroot(self):
+        """Undo anything performed in _mount_instroot().
+
+        This is the hook where subclasses must undo anything which was done
+        in _mount_instroot(). For example, if a filesystem image was mounted
+        onto _instroot, it should be unmounted here.
+
+        There is no default implementation.
+
+        """
+        pass
+
+    def _create_bootconfig(self):
+        """Configure the image so that it's bootable.
+
+        This is the hook where subclasses may prepare the image for booting by
+        e.g. creating an initramfs and bootloader configuration.
+
+        This hook is called while the install root is still mounted, after the
+        packages have been installed and the kickstart configuration has been
+        applied, but before the %post scripts have been executed.
+
+        There is no default implementation.
+
+        """
+        pass
+
+    def _stage_final_image(self):
+        """Stage the final system image in _outdir.
+
+        This is the hook where subclasses should place the image in _outdir
+        so that package() can copy it to the requested destination directory.
+
+        By default, this moves the install root into _outdir.
+
+        """
+        shutil.move(self._instroot, self._outdir + "/" + self.name)
+
+    def get_installed_packages(self):
+        return self._pkgs_content.keys()
+
+    def _save_recording_pkgs(self, destdir):
+        """Save the list or content of installed packages to file.
+        """
+        pkgs = self._pkgs_content.keys()
+        pkgs.sort() # inplace op
+
+        if not os.path.exists(destdir):
+            os.makedirs(destdir)
+
+        content = None
+        if 'vcs' in self._recording_pkgs:
+            vcslst = ["%s %s" % (k, v) for (k, v) in self._pkgs_vcsinfo.items()]
+            content = '\n'.join(sorted(vcslst))
+        elif 'name' in self._recording_pkgs:
+            content = '\n'.join(pkgs)
+        if content:
+            namefile = os.path.join(destdir, self.name + '.packages')
+            f = open(namefile, "w")
+            f.write(content)
+            f.close()
+            self.outimage.append(namefile)
+
+        # if 'content', save more details
+        if 'content' in self._recording_pkgs:
+            contfile = os.path.join(destdir, self.name + '.files')
+            f = open(contfile, "w")
+
+            for pkg in pkgs:
+                content = pkg + '\n'
+
+                pkgcont = self._pkgs_content[pkg]
+                content += '    '
+                content += '\n    '.join(pkgcont)
+                content += '\n'
+
+                content += '\n'
+                f.write(content)
+            f.close()
+            self.outimage.append(contfile)
+
+        if 'license' in self._recording_pkgs:
+            licensefile = os.path.join(destdir, self.name + '.license')
+            f = open(licensefile, "w")
+
+            f.write('Summary:\n')
+            for license in reversed(sorted(self._pkgs_license, key=\
+                            lambda license: len(self._pkgs_license[license]))):
+                f.write("    - %s: %s\n" \
+                        % (license, len(self._pkgs_license[license])))
+
+            f.write('\nDetails:\n')
+            for license in reversed(sorted(self._pkgs_license, key=\
+                            lambda license: len(self._pkgs_license[license]))):
+                f.write("    - %s:\n" % (license))
+                for pkg in sorted(self._pkgs_license[license]):
+                    f.write("        - %s\n" % (pkg))
+                f.write('\n')
+
+            f.close()
+            self.outimage.append(licensefile)
+
+    def _get_required_packages(self):
+        """Return a list of required packages.
+
+        This is the hook where subclasses may specify a set of packages which
+        it requires to be installed.
+
+        This returns an empty list by default.
+
+        Note, subclasses should usually chain up to the base class
+        implementation of this hook.
+
+        """
+        return []
+
+    def _get_excluded_packages(self):
+        """Return a list of excluded packages.
+
+        This is the hook where subclasses may specify a set of packages which
+        it requires _not_ to be installed.
+
+        This returns an empty list by default.
+
+        Note, subclasses should usually chain up to the base class
+        implementation of this hook.
+
+        """
+        return []
+
+    def _get_local_packages(self):
+        """Return a list of rpm path to be local installed.
+
+        This is the hook where subclasses may specify a set of rpms which
+        it requires to be installed locally.
+
+        This returns an empty list by default.
+
+        Note, subclasses should usually chain up to the base class
+        implementation of this hook.
+
+        """
+        if self._local_pkgs_path:
+            if os.path.isdir(self._local_pkgs_path):
+                return glob.glob(
+                        os.path.join(self._local_pkgs_path, '*.rpm'))
+            elif os.path.splitext(self._local_pkgs_path)[-1] == '.rpm':
+                return [self._local_pkgs_path]
+
+        return []
+
+    def _get_fstab(self):
+        """Return the desired contents of /etc/fstab.
+
+        This is the hook where subclasses may specify the contents of
+        /etc/fstab by returning a string containing the desired contents.
+
+        A sensible default implementation is provided.
+
+        """
+        s =  "/dev/root  /         %s    %s 0 0\n" \
+             % (self._fstype,
+                "defaults,noatime" if not self._fsopts else self._fsopts)
+        s += self._get_fstab_special()
+        return s
+
+    def _get_fstab_special(self):
+        s = "devpts     /dev/pts  devpts  gid=5,mode=620   0 0\n"
+        s += "tmpfs      /dev/shm  tmpfs   defaults         0 0\n"
+        s += "proc       /proc     proc    defaults         0 0\n"
+        s += "sysfs      /sys      sysfs   defaults         0 0\n"
+        return s
+
+    def _set_part_env(self, pnum, prop, value):
+        """ This is a helper function which generates an environment variable
+        for a property "prop" with value "value" of a partition number "pnum".
+
+        The naming convention is:
+           * Variables start with INSTALLERFW_PART
+           * Then goes the partition number, the order is the same as
+             specified in the KS file
+           * Then goes the property name
+        """
+
+        if value == None:
+            value = ""
+        else:
+            value = str(value)
+
+        name = self.installerfw_prefix + ("PART%d_" % pnum) + prop
+        return { name : value }
+
+    def _get_post_scripts_env(self, in_chroot):
+        """Return an environment dict for %post scripts.
+
+        This is the hook where subclasses may specify some environment
+        variables for %post scripts by return a dict containing the desired
+        environment.
+
+        in_chroot -- whether this %post script is to be executed chroot()ed
+                     into _instroot.
+        """
+
+        env = {}
+        pnum = 0
+
+        for p in kickstart.get_partitions(self.ks):
+            env.update(self._set_part_env(pnum, "SIZE", p.size))
+            env.update(self._set_part_env(pnum, "MOUNTPOINT", p.mountpoint))
+            env.update(self._set_part_env(pnum, "FSTYPE", p.fstype))
+            env.update(self._set_part_env(pnum, "LABEL", p.label))
+            env.update(self._set_part_env(pnum, "FSOPTS", p.fsopts))
+            env.update(self._set_part_env(pnum, "BOOTFLAG", p.active))
+            env.update(self._set_part_env(pnum, "ALIGN", p.align))
+            env.update(self._set_part_env(pnum, "TYPE_ID", p.part_type))
+            env.update(self._set_part_env(pnum, "UUID", p.uuid))
+            env.update(self._set_part_env(pnum, "DEVNODE",
+                                          "/dev/%s%d" % (p.disk, pnum + 1)))
+            env.update(self._set_part_env(pnum, "DISK_DEVNODE",
+                                          "/dev/%s" % p.disk))
+            pnum += 1
+
+        # Count of paritions
+        env[self.installerfw_prefix + "PART_COUNT"] = str(pnum)
+
+        # Partition table format
+        ptable_format = self.ks.handler.bootloader.ptable
+        env[self.installerfw_prefix + "PTABLE_FORMAT"] = ptable_format
+
+        # The kerned boot parameters
+        kernel_opts = self.ks.handler.bootloader.appendLine
+        env[self.installerfw_prefix + "KERNEL_OPTS"] = kernel_opts
+
+        # Name of the image creation tool
+        env[self.installerfw_prefix + "INSTALLER_NAME"] = "mic"
+
+        # The real current location of the mounted file-systems
+        if in_chroot:
+            mount_prefix = "/"
+        else:
+            mount_prefix = self._instroot
+        env[self.installerfw_prefix + "MOUNT_PREFIX"] = mount_prefix
+
+        # These are historical variables which lack the common name prefix
+        if not in_chroot:
+            env["INSTALL_ROOT"] = self._instroot
+            env["IMG_NAME"] = self._name
+            env['ATTACHMENT_PATHS'] = ' '.join(self._attachment)
+            if self._imgdir:
+                env['IMG_DIR_PATH'] = str(self._imgdir)
+
+        return env
+
+    def __get_imgname(self):
+        return self.name
+    _name = property(__get_imgname)
+    """The name of the image file.
+
+    """
+
+    def _get_kernel_versions(self):
+        """Return a dict detailing the available kernel types/versions.
+
+        This is the hook where subclasses may override what kernel types and
+        versions should be available for e.g. creating the booloader
+        configuration.
+
+        A dict should be returned mapping the available kernel types to a list
+        of the available versions for those kernels.
+
+        The default implementation uses rpm to iterate over everything
+        providing 'kernel', finds /boot/vmlinuz-* and returns the version
+        obtained from the vmlinuz filename. (This can differ from the kernel
+        RPM's n-v-r in the case of e.g. xen)
+
+        """
+        def get_kernel_versions(instroot):
+            ret = {}
+            versions = set()
+            files = glob.glob(instroot + "/boot/vmlinuz-*")
+            for file in files:
+                version = os.path.basename(file)[8:]
+                if version is None:
+                    continue
+                versions.add(version)
+            ret["kernel"] = list(versions)
+            return ret
+
+        def get_version(header):
+            version = None
+            for f in header['filenames']:
+                if f.startswith('/boot/vmlinuz-'):
+                    version = f[14:]
+            return version
+
+        if self.ks is None:
+            return get_kernel_versions(self._instroot)
+
+        ts = rpm.TransactionSet(self._instroot)
+
+        ret = {}
+        for header in ts.dbMatch('provides', 'kernel'):
+            version = get_version(header)
+            if version is None:
+                continue
+
+            name = header['name']
+            if not name in ret:
+                ret[name] = [version]
+            elif not version in ret[name]:
+                ret[name].append(version)
+
+        return ret
+
+
+    #
+    # Helpers for subclasses
+    #
+    def _do_bindmounts(self):
+        """Mount various system directories onto _instroot.
+
+        This method is called by mount(), but may also be used by subclasses
+        in order to re-mount the bindmounts after modifying the underlying
+        filesystem.
+
+        """
+        for b in self.__bindmounts:
+            b.mount()
+
+    def _undo_bindmounts(self):
+        """Unmount the bind-mounted system directories from _instroot.
+
+        This method is usually only called by unmount(), but may also be used
+        by subclasses in order to gain access to the filesystem obscured by
+        the bindmounts - e.g. in order to create device nodes on the image
+        filesystem.
+
+        """
+        self.__bindmounts.reverse()
+        for b in self.__bindmounts:
+            b.unmount()
+
+    def _chroot(self):
+        """Chroot into the install root.
+
+        This method may be used by subclasses when executing programs inside
+        the install root e.g.
+
+          subprocess.call(["/bin/ls"], preexec_fn = self.chroot)
+
+        """
+        os.chroot(self._instroot)
+        os.chdir("/")
+
+    def _mkdtemp(self, prefix = "tmp-"):
+        """Create a temporary directory.
+
+        This method may be used by subclasses to create a temporary directory
+        for use in building the final image - e.g. a subclass might create
+        a temporary directory in order to bundle a set of files into a package.
+
+        The subclass may delete this directory if it wishes, but it will be
+        automatically deleted by cleanup().
+
+        The absolute path to the temporary directory is returned.
+
+        Note, this method should only be called after mount() has been called.
+
+        prefix -- a prefix which should be used when creating the directory;
+                  defaults to "tmp-".
+
+        """
+        self.__ensure_builddir()
+        return tempfile.mkdtemp(dir = self.__builddir, prefix = prefix)
+
+    def _mkstemp(self, prefix = "tmp-"):
+        """Create a temporary file.
+
+        This method may be used by subclasses to create a temporary file
+        for use in building the final image - e.g. a subclass might need
+        a temporary location to unpack a compressed file.
+
+        The subclass may delete this file if it wishes, but it will be
+        automatically deleted by cleanup().
+
+        A tuple containing a file descriptor (returned from os.open() and the
+        absolute path to the temporary directory is returned.
+
+        Note, this method should only be called after mount() has been called.
+
+        prefix -- a prefix which should be used when creating the file;
+                  defaults to "tmp-".
+
+        """
+        self.__ensure_builddir()
+        return tempfile.mkstemp(dir = self.__builddir, prefix = prefix)
+
+    def _mktemp(self, prefix = "tmp-"):
+        """Create a temporary file.
+
+        This method simply calls _mkstemp() and closes the returned file
+        descriptor.
+
+        The absolute path to the temporary file is returned.
+
+        Note, this method should only be called after mount() has been called.
+
+        prefix -- a prefix which should be used when creating the file;
+                  defaults to "tmp-".
+
+        """
+
+        (f, path) = self._mkstemp(prefix)
+        os.close(f)
+        return path
+
+
+    #
+    # 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 as msg:
+            raise CreatorError("Failed create build directory in %s: %s" %
+                               (self.tmpdir, msg))
+
+    def get_cachedir(self, cachedir = None):
+        if self.cachedir:
+            return self.cachedir
+
+        self.__ensure_builddir()
+        if cachedir:
+            self.cachedir = cachedir
+        else:
+            self.cachedir = self.__builddir + "/mic-cache"
+        fs.makedirs(self.cachedir)
+        return self.cachedir
+
+    def __sanity_check(self):
+        """Ensure that the config we've been given is same."""
+        if not (kickstart.get_packages(self.ks) or
+                kickstart.get_groups(self.ks)):
+            raise CreatorError("No packages or groups specified")
+
+        kickstart.convert_method_to_repo(self.ks)
+
+        if not kickstart.get_repos(self.ks):
+            raise CreatorError("No repositories specified")
+
+    def __write_fstab(self):
+        if kickstart.use_installerfw(self.ks, "fstab"):
+            # The fstab file will be generated by installer framework scripts
+            # instead.
+            return None
+        fstab_contents = self._get_fstab()
+        if fstab_contents:
+            fstab = open(self._instroot + "/etc/fstab", "w")
+            fstab.write(fstab_contents)
+            fstab.close()
+
+    def __create_minimal_dev(self):
+        """Create a minimal /dev so that we don't corrupt the host /dev"""
+        origumask = os.umask(0000)
+        devices = (('null',   1, 3, 0o666),
+                   ('urandom',1, 9, 0o666),
+                   ('random', 1, 8, 0o666),
+                   ('full',   1, 7, 0o666),
+                   ('ptmx',   5, 2, 0o666),
+                   ('tty',    5, 0, 0o666),
+                   ('zero',   1, 5, 0o666))
+
+        links = (("/proc/self/fd", "/dev/fd"),
+                 ("/proc/self/fd/0", "/dev/stdin"),
+                 ("/proc/self/fd/1", "/dev/stdout"),
+                 ("/proc/self/fd/2", "/dev/stderr"))
+
+        for (node, major, minor, perm) in devices:
+            if not os.path.exists(self._instroot + "/dev/" + node):
+                os.mknod(self._instroot + "/dev/" + node,
+                         perm | stat.S_IFCHR,
+                         os.makedev(major,minor))
+
+        for (src, dest) in links:
+            if not os.path.exists(self._instroot + dest):
+                os.symlink(src, self._instroot + dest)
+
+        os.umask(origumask)
+
+    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 cp_tpk(self):
+        #Add tpk-install option
+        createopts = configmgr.create
+        if createopts['tpk_install']:
+            path = createopts['tpk_install']
+            file_list = os.listdir(path)
+            for f in file_list:
+                sub = os.path.splitext(f)[1]
+                if sub != ".tpk":
+                    raise CreatorError("Not all files in the path: "+path +" is tpk")
+
+            tpk_dir = "/usr/apps/.preload-tpk"
+            fs.makedirs(self._instroot + "/usr/apps")
+            fs.makedirs(self._instroot + tpk_dir)
+            for f in file_list:
+                shutil.copy(path+"/"+f,self._instroot + tpk_dir)
+
+    def mount(self, base_on = None, cachedir = None):
+        """Setup the target filesystem in preparation for an install.
+
+        This function sets up the filesystem which the ImageCreator will
+        install into and configure. The ImageCreator class merely creates an
+        install root directory, bind mounts some system directories (e.g. /dev)
+        and writes out /etc/fstab. Other subclasses may also e.g. create a
+        sparse file, format it and loopback mount it to the install root.
+
+        base_on -- a previous install on which to base this install; defaults
+                   to None, causing a new image to be created
+
+        cachedir -- a directory in which to store the Yum cache; defaults to
+                    None, causing a new cache to be created; by setting this
+                    to another directory, the same cache can be reused across
+                    multiple installs.
+
+        """
+        self.__setup_tmpdir()
+        self.__ensure_builddir()
+
+        # prevent popup dialog in Ubuntu(s)
+        misc.hide_loopdev_presentation()
+
+        fs.makedirs(self._instroot)
+        fs.makedirs(self._outdir)
+
+        self._mount_instroot(base_on)
+
+        for d in ("/dev/pts",
+                  "/etc",
+                  "/boot",
+                  "/var/log",
+                  "/sys",
+                  "/proc",
+                  "/usr/bin"):
+            fs.makedirs(self._instroot + d)
+
+        if self.target_arch and self.target_arch.startswith("arm") or \
+            self.target_arch == "aarch64" or self.target_arch == "riscv64":
+            self.qemu_emulators = misc.setup_qemu_emulator(self._instroot,
+                                                          self.target_arch)
+
+        self.get_cachedir(cachedir)
+
+        # bind mount system directories into _instroot
+        for (f, dest) in [("/sys", None),
+                          ("/proc", None),
+                          ("/proc/sys/fs/binfmt_misc", None),
+                          ("/dev/pts", None)]:
+            self.__bindmounts.append(
+                    fs.BindChrootMount(
+                        f, self._instroot, dest))
+
+        self._do_bindmounts()
+
+        self.__create_minimal_dev()
+
+        if os.path.exists(self._instroot + "/etc/mtab"):
+            os.unlink(self._instroot + "/etc/mtab")
+        os.symlink("../proc/mounts", self._instroot + "/etc/mtab")
+
+        #self.__write_fstab()
+
+        # get size of available space in 'instroot' fs
+        self._root_fs_avail = misc.get_filesystem_avail(self._instroot)
+        self.cp_tpk()
+
+    def unmount(self):
+        """Unmounts the target filesystem.
+
+        The ImageCreator class detaches the system from the install root, but
+        other subclasses may also detach the loopback mounted filesystem image
+        from the install root.
+
+        """
+        try:
+            mtab = self._instroot + "/etc/mtab"
+            if not os.path.islink(mtab):
+                os.unlink(self._instroot + "/etc/mtab")
+
+            for qemu_emulator in self.qemu_emulators:
+                os.unlink(self._instroot + qemu_emulator)
+        except OSError:
+            pass
+
+        self._undo_bindmounts()
+
+        """ Clean up yum garbage """
+        try:
+            instroot_pdir = os.path.dirname(self._instroot + self._instroot)
+            if os.path.exists(instroot_pdir):
+                shutil.rmtree(instroot_pdir, ignore_errors = True)
+            yumlibdir = self._instroot + "/var/lib/yum"
+            if os.path.exists(yumlibdir):
+                shutil.rmtree(yumlibdir, ignore_errors = True)
+        except OSError:
+            pass
+
+        self._unmount_instroot()
+
+        # reset settings of popup dialog in Ubuntu(s)
+        misc.unhide_loopdev_presentation()
+
+
+    def cleanup(self):
+        """Unmounts the target filesystem and deletes temporary files.
+
+        This method calls unmount() and then deletes any temporary files and
+        directories that were created on the host system while building the
+        image.
+
+        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
+
+        kill_proc_inchroot(self._instroot)
+
+        self.unmount()
+
+        shutil.rmtree(self.__builddir, ignore_errors = True)
+        self.__builddir = None
+
+        self.__clean_tmpdir()
+
+    def __is_excluded_pkg(self, pkg):
+        if pkg in self._excluded_pkgs:
+            self._excluded_pkgs.remove(pkg)
+            return True
+
+        for xpkg in self._excluded_pkgs:
+            if xpkg.endswith('*'):
+                if pkg.startswith(xpkg[:-1]):
+                    return True
+            elif xpkg.startswith('*'):
+                if pkg.endswith(xpkg[1:]):
+                    return True
+
+        return None
+
+    def __select_packages(self, pkg_manager):
+        skipped_pkgs = []
+        for pkg in self._required_pkgs:
+            e = pkg_manager.selectPackage(pkg)
+            if e:
+                if kickstart.ignore_missing(self.ks):
+                    skipped_pkgs.append(pkg)
+                elif self.__is_excluded_pkg(pkg):
+                    skipped_pkgs.append(pkg)
+                else:
+                    raise CreatorError("Failed to find package '%s' : %s" %
+                                       (pkg, e))
+
+        for pkg in skipped_pkgs:
+            msger.warning("Skipping missing package '%s'" % (pkg,))
+
+    def __select_groups(self, pkg_manager):
+        skipped_groups = []
+        for group in self._required_groups:
+            e = pkg_manager.selectGroup(group.name, group.include)
+            if e:
+                if kickstart.ignore_missing(self.ks):
+                    skipped_groups.append(group)
+                else:
+                    raise CreatorError("Failed to find group '%s' : %s" %
+                                       (group.name, e))
+
+        for group in skipped_groups:
+            msger.warning("Skipping missing group '%s'" % (group.name,))
+
+    def __deselect_packages(self, pkg_manager):
+        for pkg in self._excluded_pkgs:
+            pkg_manager.deselectPackage(pkg)
+
+    """def __localinst_packages(self, pkg_manager):
+        for rpm_path in self._get_local_packages():
+            pkg_manager.installLocal(rpm_path)"""
+
+    def __preinstall_packages(self, pkg_manager):
+        if not self.ks:
+            return
+
+        self._preinstall_pkgs = kickstart.get_pre_packages(self.ks)
+        for pkg in self._preinstall_pkgs:
+            pkg_manager.preInstall(pkg)
+
+    def __check_packages(self, pkg_manager):
+        for pkg in self.check_pkgs:
+            pkg_manager.checkPackage(pkg)
+
+    def __attachment_packages(self, pkg_manager):
+        if not self.ks:
+            return
+
+        self._attachment = []
+        for item in kickstart.get_attachment(self.ks):
+            if item.startswith('/'):
+                fpaths = os.path.join(self._instroot, item.lstrip('/'))
+                for fpath in glob.glob(fpaths):
+                    self._attachment.append(fpath)
+                continue
+
+            filelist = pkg_manager.getFilelist(item)
+            if filelist:
+                # found rpm in rootfs
+                for pfile in pkg_manager.getFilelist(item):
+                    fpath = os.path.join(self._instroot, pfile.lstrip('/'))
+                    self._attachment.append(fpath)
+                continue
+
+            # try to retrieve rpm file
+            (url, proxies) = pkg_manager.package_url(item)
+            if not url:
+                msger.warning("Can't get url from repo for %s" % item)
+                continue
+            fpath = os.path.join(self.cachedir, os.path.basename(url))
+            if not os.path.exists(fpath):
+                # download pkgs
+                try:
+                    fpath = grabber.myurlgrab(url.full, fpath, proxies, None)
+                except CreatorError:
+                    raise
+
+            tmpdir = self._mkdtemp()
+            misc.extract_rpm(fpath, tmpdir)
+            for (root, dirs, files) in os.walk(tmpdir):
+                for fname in files:
+                    fpath = os.path.join(root, fname)
+                    self._attachment.append(fpath)
+
+    def install(self, repo_urls=None):
+        """Install packages into the install root.
+
+        This function installs the packages listed in the supplied kickstart
+        into the install root. By default, the packages are installed from the
+        repository URLs specified in the kickstart.
+
+        repo_urls -- a dict which maps a repository name to a repository;
+                     if supplied, this causes any repository URLs specified in
+                     the kickstart to be overridden.
+
+        """
+        def checkScriptletError(dirname, suffix):
+            if os.path.exists(dirname):
+                list = os.listdir(dirname)
+                for line in list:
+                    filepath = os.path.join(dirname, line)
+                    if os.path.isfile(filepath) and 0 < line.find(suffix):
+                        return True
+                    else:
+                        continue
+             
+            return False
+
+        def showErrorInfo(filepath):
+            if os.path.isfile(filepath):
+                for line in open(filepath):
+                    msger.info("The error install package info: %s" % line)
+            else:
+                msger.info("%s is not found." % filepath)
+
+        def get_ssl_verify(ssl_verify=None):
+            if ssl_verify is not None:
+                return not ssl_verify.lower().strip() == 'no'
+            else:
+                return not self.ssl_verify.lower().strip() == 'no'
+
+        # initialize pkg list to install
+        if self.ks:
+            self.__sanity_check()
+
+            self._required_pkgs = \
+                kickstart.get_packages(self.ks, self._get_required_packages())
+            self._excluded_pkgs = \
+                kickstart.get_excluded(self.ks, self._get_excluded_packages())
+            self._required_groups = kickstart.get_groups(self.ks)
+        else:
+            self._required_pkgs = None
+            self._excluded_pkgs = None
+            self._required_groups = None
+
+        if not repo_urls:
+            repo_urls = self.extrarepos
+
+        pkg_manager = self.get_pkg_manager()
+        pkg_manager.setup()
+
+        if hasattr(self, 'install_pkgs') and self.install_pkgs:
+            if 'debuginfo' in self.install_pkgs:
+                pkg_manager.install_debuginfo = True
+
+
+        for repo in kickstart.get_repos(self.ks, repo_urls, self.ignore_ksrepo):
+            (name, baseurl, mirrorlist, inc, exc,
+             proxy, proxy_username, proxy_password, debuginfo,
+             source, gpgkey, disable, ssl_verify, nocache,
+             cost, priority) = repo
+
+            ssl_verify = get_ssl_verify(ssl_verify)
+            yr = pkg_manager.addRepository(name, baseurl, mirrorlist, proxy,
+                        proxy_username, proxy_password, inc, exc, ssl_verify,
+                        nocache, cost, priority)
+
+        if kickstart.exclude_docs(self.ks):
+            rpm.addMacro("_excludedocs", "1")
+        rpm.addMacro("_dbpath", "/var/lib/rpm")
+        rpm.addMacro("__file_context_path", "%{nil}")
+        if kickstart.inst_langs(self.ks) != None:
+            rpm.addMacro("_install_langs", kickstart.inst_langs(self.ks))
+
+        try:
+            self.__preinstall_packages(pkg_manager)
+            self.__select_packages(pkg_manager)
+            self.__select_groups(pkg_manager)
+            self.__deselect_packages(pkg_manager)
+            #self.__localinst_packages(pkg_manager)
+            self.__check_packages(pkg_manager)
+
+            BOOT_SAFEGUARD = 256 * 1024 * 1024 # 256M
+            checksize = self._root_fs_avail
+            if checksize:
+                checksize -= BOOT_SAFEGUARD
+            if self.target_arch:
+                pkg_manager._add_prob_flags(rpm.RPMPROB_FILTER_IGNOREARCH)
+
+            # If we have multiple partitions, don't check diskspace when rpm run transaction
+            # because rpm check '/' partition only.
+            if self.multiple_partitions:
+                pkg_manager._add_prob_flags(rpm.RPMPROB_FILTER_DISKSPACE)
+            pkg_manager.runInstall(checksize)
+        except CreatorError as e:
+            raise
+        except  KeyboardInterrupt:
+            raise
+        else:
+            self._pkgs_content = pkg_manager.getAllContent()
+            self._pkgs_license = pkg_manager.getPkgsLicense()
+            self._pkgs_vcsinfo = pkg_manager.getVcsInfo()
+            self.__attachment_packages(pkg_manager)
+        finally:
+            pkg_manager.close()
+
+        if checkScriptletError(self._instroot + "/tmp/.postscript/error/", "_error"):
+            showErrorInfo(self._instroot + "/tmp/.preload_install_error")
+            raise CreatorError('scriptlet errors occurred')
+            
+        # hook post install
+        self.postinstall()
+
+        # do some clean up to avoid lvm info leakage.  this sucks.
+        for subdir in ("cache", "backup", "archive"):
+            lvmdir = self._instroot + "/etc/lvm/" + subdir
+            try:
+                for f in os.listdir(lvmdir):
+                    os.unlink(lvmdir + "/" + f)
+            except:
+                pass
+
+    def tpkinstall(self):
+        if self.ks:
+            tpk_pkgs = kickstart.get_tpkpackages(self.ks)
+            tpk_repoList = kickstart.get_tpkrepos(self.ks)
+            if tpk_repoList and tpk_pkgs:
+                tpk_dir = "/usr/apps/.preload-tpk"
+                fs.makedirs(self._instroot + "/usr/apps")
+                fs.makedirs(self._instroot + tpk_dir)
+            for pkg in tpk_pkgs:
+                flag = 0
+                for tpk_repo in tpk_repoList:
+                    if hasattr(tpk_repo,'baseurl') and tpk_repo.baseurl.startswith("file:"):
+                        tpk_repourl = tpk_repo.baseurl.replace('file:','')
+                        tpk_repourl = "/%s" % tpk_repourl.lstrip('/')
+                        tpk_pkgpath = tpk_repourl + "/"+ pkg
+                        if os.path.isfile(tpk_pkgpath):
+                            shutil.copy(tpk_pkgpath,self._instroot + tpk_dir)
+                            flag = 1
+                            break
+                    elif hasattr(tpk_repo,'baseurl'):
+                        url = tpk_repo.baseurl.join(pkg)
+                        filename = self._instroot+tpk_dir+"/"+pkg
+                        if tpk_repo.baseurl.startswith("http:"):
+                            import urllib
+                            status = urllib.urlopen(url).code
+                            if status == 200:
+                                filename = myurlgrab(url.full, filename, None)
+                                flag = 1
+                                break
+                            elif status == 404 or status == None:
+                                continue
+                        #url is ok, then download, url wrong, check other url.
+                        elif tpk_repo.baseurl.startswith("https:") :
+                            try:
+                                flag = 1
+                                filename = myurlgrab(url.full, filename, None)
+                            except CreatorError:
+                                continue
+                if flag == 0:
+                    raise CreatorError("Tpk package missing.")
+
+    def postinstall(self):
+        self.copy_attachment()
+
+    def _get_sign_scripts_env(self):
+        """Return an environment dict for %post-umount scripts.
+
+        This is the hook where subclasses may specify some environment
+        variables for %post-umount scripts by return a dict containing the
+        desired environment.
+        """
+
+        env = {}
+
+        # Directory path of images
+        if self._imgdir:
+            env['IMG_DIR_PATH'] = str(self._imgdir)
+
+        imgfiles = []
+        imgpaths = []
+        for item in self._instloops:
+            imgfiles.append(item['name'])
+            if self._imgdir:
+                imgpaths.append(os.path.join(self._imgdir, item['name']))
+
+        # Images file name
+        env['IMG_FILES'] = ' '.join(imgfiles)
+
+        # Absolute path of images
+        env['IMG_PATHS'] = ' '.join(imgpaths)
+
+        return env
+
+    def run_sign_scripts(self):
+        if kickstart.get_sign_scripts(self.ks)==[]:
+            return
+        msger.info("Running sign scripts ...")
+        if os.path.exists(self._instroot + "/tmp"):
+            shutil.rmtree(self._instroot + "/tmp")
+        os.mkdir (self._instroot + "/tmp", 0o755)
+        for s in kickstart.get_sign_scripts(self.ks):
+            (fd, path) = tempfile.mkstemp(prefix = "ks-runscript-",
+                                          dir = self._instroot + "/tmp")
+            s.script = s.script.replace("\r", "")
+            os.write(fd, s.script)
+            if s.interp == '/bin/sh' or s.interp == '/bin/bash':
+                os.write(fd, '\n')
+                os.write(fd, 'exit 0\n')
+            os.close(fd)
+            os.chmod(path, 0o700)
+
+            env = self._get_sign_scripts_env()
+            oldoutdir = os.getcwd()
+            os.chdir(self._imgdir)
+            try:
+                try:
+                    p = subprocess.Popen([s.interp, path],
+                                       env = env,
+                                       stdout = subprocess.PIPE,
+                                       stderr = subprocess.STDOUT)
+                    while p.poll() == None:
+                        msger.info(p.stdout.readline().strip())
+                    if p.returncode != 0:
+                        raise CreatorError("Failed to execute %%sign script "
+                                           "with '%s'" % (s.interp))
+                except OSError as msg:
+                    raise CreatorError("Failed to execute %%sign script "
+                                       "with '%s' : %s" % (s.interp, msg))
+            finally:
+                os.chdir(oldoutdir)
+                os.unlink(path)
+
+    def __run_post_scripts(self):
+        msger.info("Running post scripts ...")
+        if os.path.exists(self._instroot + "/tmp"):
+            shutil.rmtree(self._instroot + "/tmp")
+        os.mkdir (self._instroot + "/tmp", 0o755)
+        for s in kickstart.get_post_scripts(self.ks):
+            (fd, path) = tempfile.mkstemp(prefix = "ks-postscript-",
+                                          dir = self._instroot + "/tmp")
+
+            s.script = s.script.replace("\r", "")
+            os.write(fd, s.script)
+            if s.interp == '/bin/sh' or s.interp == '/bin/bash':
+                os.write(fd, '\n')
+                os.write(fd, 'exit 0\n')
+            os.close(fd)
+            os.chmod(path, 0o700)
+
+            env = self._get_post_scripts_env(s.inChroot)
+            if 'PATH' not in env:
+                env['PATH'] = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin'
+
+            if not s.inChroot:
+                preexec = None
+                script = path
+            else:
+                preexec = self._chroot
+                script = "/tmp/" + os.path.basename(path)
+            start_time = time.time()
+            try:
+                try:
+                    p = subprocess.Popen([s.interp, script],
+                                       preexec_fn = preexec,
+                                       env = env,
+                                       stdout = subprocess.PIPE,
+                                       stderr = subprocess.STDOUT)
+                    while p.poll() == None:
+                       msger.info(p.stdout.readline().strip())
+                        end_time = time.time()
+                        if (end_time - start_time)/60 > configmgr.create['postscripts_maxruntime']:
+                            raise CreatorError("Your post script is executed more than %d mins, please check it!" % configmgr.create['postscripts_maxruntime'])
+                    if p.returncode != 0:
+                        raise CreatorError("Failed to execute %%post script "
+                                           "with '%s'" % (s.interp))
+                except OSError as msg:
+                    raise CreatorError("Failed to execute %%post script "
+                                       "with '%s' : %s" % (s.interp, msg))
+            finally:
+                os.unlink(path)
+
+    def __save_repo_keys(self, repodata):
+        if not repodata:
+            return None
+
+        gpgkeydir = "/etc/pki/rpm-gpg"
+        fs.makedirs(self._instroot + gpgkeydir)
+        for repo in repodata:
+            if repo["repokey"]:
+                repokey = gpgkeydir + "/RPM-GPG-KEY-%s" %  repo["name"]
+                shutil.copy(repo["repokey"], self._instroot + repokey)
+
+    def configure(self, repodata = None):
+        """Configure the system image according to the kickstart.
+
+        This method applies the (e.g. keyboard or network) configuration
+        specified in the kickstart and executes the kickstart %post scripts.
+
+        If necessary, it also prepares the image to be bootable by e.g.
+        creating an initrd and bootloader configuration.
+
+        """
+        ksh = self.ks.handler
+
+        msger.info('Applying configurations ...')
+        try:
+            kickstart.LanguageConfig(self._instroot).apply(ksh.lang)
+            kickstart.KeyboardConfig(self._instroot).apply(ksh.keyboard)
+            kickstart.TimezoneConfig(self._instroot).apply(ksh.timezone)
+            #kickstart.AuthConfig(self._instroot).apply(ksh.authconfig)
+            kickstart.FirewallConfig(self._instroot).apply(ksh.firewall)
+            kickstart.UserConfig(self._instroot).apply(ksh.user)
+            kickstart.RootPasswordConfig(self._instroot).apply(ksh.rootpw)
+            kickstart.ServicesConfig(self._instroot).apply(ksh.services)
+            kickstart.XConfig(self._instroot).apply(ksh.xconfig)
+            kickstart.NetworkConfig(self._instroot).apply(ksh.network)
+            kickstart.RPMMacroConfig(self._instroot).apply(self.ks)
+            kickstart.DesktopConfig(self._instroot).apply(ksh.desktop)
+            self.__save_repo_keys(repodata)
+            kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata, self.repourl)
+        except:
+            msger.warning("Failed to apply configuration to image")
+            raise
+
+        self._create_bootconfig()
+        self.__run_post_scripts()
+
+    def launch_shell(self, launch):
+        """Launch a shell in the install root.
+
+        This method is launches a bash shell chroot()ed in the install root;
+        this can be useful for debugging.
+
+        """
+        if launch:
+            msger.info("Launching shell. Exit to continue.")
+            subprocess.call(["/bin/bash"], preexec_fn = self._chroot)
+
+    def do_genchecksum(self, image_name):
+        if not self._genchecksum:
+            return
+
+        md5sum = misc.get_md5sum(image_name)
+        with open(image_name + ".md5sum", "w") as f:
+            f.write("%s  %s" % (md5sum, os.path.basename(image_name)))
+        self.outimage.append(image_name+".md5sum")
+
+    def remove_exclude_image(self):
+        for item in self._instloops[:]:
+            if item['exclude_image']:
+                msger.info("Removing %s in image." % item['name'])
+                imgfile = os.path.join(self._imgdir, item['name'])
+                try:
+                    os.remove(imgfile)
+                except OSError as err:
+                    if err.errno == errno.ENOENT:
+                        pass
+                self._instloops.remove(item)
+
+    def create_cpio_image(self):
+        for item in self._instloops:
+            if item['cpioopts']:
+                msger.info("Create image by cpio.")
+                tmp_cpio = self.__builddir + "/tmp-cpio"
+                if not os.path.exists(tmp_cpio):
+                    os.mkdir(tmp_cpio)
+                tmp_cpio_imgfile = os.path.join(tmp_cpio, item['name'])
+                try:
+                    cpiocmd = fs.find_binary_path('cpio')
+                    if cpiocmd:
+                        oldoutdir = os.getcwd()
+                        os.chdir(os.path.join(self._instroot, item['mountpoint'].lstrip('/')))
+                        # find . | cpio --create --'format=newc' | gzip > ../ramdisk.img
+                        runner.show('find . | cpio --create %s | gzip > %s' % (item['cpioopts'], tmp_cpio_imgfile))
+                        os.chdir(oldoutdir)
+                except OSError as msg:
+                    raise CreatorError("Create image by cpio error: %s" % msg)
+
+    def copy_cpio_image(self):
+        for item in self._instloops:
+            if item['cpioopts']:
+                tmp_cpio = self.__builddir + "/tmp-cpio"
+                msger.info("Copy cpio image from %s to %s." %(tmp_cpio, self._imgdir))
+                try:
+                    shutil.copyfile(os.path.join(tmp_cpio, item['name']),os.path.join(self._imgdir, item['name']))
+                except IOError:
+                    raise CreatorError("Copy cpio image error")
+                os.remove(os.path.join(tmp_cpio, item['name']))
+                if not os.listdir(tmp_cpio):
+                    shutil.rmtree(tmp_cpio, ignore_errors=True)
+
+    def package(self, destdir = "."):
+        """Prepares the created image for final delivery.
+
+        In its simplest form, this method merely copies the install root to the
+        supplied destination directory; other subclasses may choose to package
+        the image by e.g. creating a bootable ISO containing the image and
+        bootloader configuration.
+
+        destdir -- the directory into which the final image should be moved;
+                   this defaults to the current directory.
+
+        """
+        self.remove_exclude_image()
+
+        self._stage_final_image()
+
+        if not os.path.exists(destdir):
+            fs.makedirs(destdir)
+
+        if self._recording_pkgs:
+            self._save_recording_pkgs(destdir)
+
+        # For image formats with two or multiple image files, it will be
+        # better to put them under a directory
+        if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"):
+            destdir = os.path.join(destdir, "%s-%s" \
+                                            % (self.name, self.image_format))
+            msger.debug("creating destination dir: %s" % destdir)
+            fs.makedirs(destdir)
+
+        # Ensure all data is flushed to _outdir
+        runner.quiet('sync')
+
+        misc.check_space_pre_cp(self._outdir, destdir)
+        for f in os.listdir(self._outdir):
+            shutil.move(os.path.join(self._outdir, f),
+                        os.path.join(destdir, f))
+            self.outimage.append(os.path.join(destdir, f))
+            self.do_genchecksum(os.path.join(destdir, f))
+
+    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)
+
+    def check_depend_tools(self):
+        for tool in self._dep_checks:
+            fs.find_binary_path(tool)
+
+    def package_output(self, image_format, destdir = ".", package="none"):
+        if not package or package == "none":
+            return
+
+        destdir = os.path.abspath(os.path.expanduser(destdir))
+        (pkg, comp) = os.path.splitext(package)
+        if comp:
+            comp=comp.lstrip(".")
+
+        if pkg == "tar":
+            if comp:
+                dst = "%s/%s-%s.tar.%s" %\
+                      (destdir, self.name, image_format, comp)
+            else:
+                dst = "%s/%s-%s.tar" %\
+                      (destdir, self.name, image_format)
+
+            msger.info("creating %s" % dst)
+            tar = tarfile.open(dst, "w:" + comp)
+
+            for file in self.outimage:
+                msger.info("adding %s to %s" % (file, dst))
+                tar.add(file,
+                        arcname=os.path.join("%s-%s" \
+                                           % (self.name, image_format),
+                                              os.path.basename(file)))
+                if os.path.isdir(file):
+                    shutil.rmtree(file, ignore_errors = True)
+                else:
+                    os.remove(file)
+
+            tar.close()
+
+            '''All the file in outimage has been packaged into tar.* file'''
+            self.outimage = [dst]
+
+    def release_output(self, config, destdir, release):
+        """ Create release directory and files
+        """
+
+        def _rpath(fn):
+            """ release path """
+            return os.path.join(destdir, fn)
+
+        outimages = self.outimage
+
+        # new ks
+        new_kspath = _rpath(self.name+'.ks')
+        with open(config) as fr:
+            with open(new_kspath, "w") as wf:
+                # When building a release we want to make sure the .ks
+                # file generates the same build even when --release not used.
+                wf.write(fr.read().replace("@BUILD_ID@", release))
+        outimages.append(new_kspath)
+
+        # save log file, logfile is only available in creator attrs
+        if hasattr(self, 'releaselog') and self.releaselog:
+            outimages.append(self.logfile)
+
+        # rename iso and usbimg
+        for f in os.listdir(destdir):
+            if f.endswith(".iso"):
+                newf = f[:-4] + '.img'
+            elif f.endswith(".usbimg"):
+                newf = f[:-7] + '.img'
+            else:
+                continue
+            os.rename(_rpath(f), _rpath(newf))
+            outimages.append(_rpath(newf))
+
+        # generate MD5SUMS SHA1SUMS SHA256SUMS
+        def generate_hashsum(hash_name, hash_method):
+            with open(_rpath(hash_name), "w") as wf:
+                for f in os.listdir(destdir):
+                    if f.endswith('SUMS'):
+                        continue
+
+                    if os.path.isdir(os.path.join(destdir, f)):
+                        continue
+
+                    hash_value = hash_method(_rpath(f))
+                    # There needs to be two spaces between the sum and
+                    # filepath to match the syntax with md5sum,sha1sum,
+                    # sha256sum. This way also *sum -c *SUMS can be used.
+                    wf.write("%s  %s\n" % (hash_value, f))
+
+            outimages.append("%s/%s" % (destdir, hash_name))
+
+        hash_dict = {
+                     'MD5SUMS'    : misc.get_md5sum,
+                     'SHA1SUMS'   : misc.get_sha1sum,
+                     'SHA256SUMS' : misc.get_sha256sum
+                    }
+
+        for k, v in hash_dict.items():
+            generate_hashsum(k, v)
+
+        # Filter out the nonexist file
+        for fp in outimages[:]:
+            if not os.path.exists("%s" % fp):
+                outimages.remove(fp)
+
+    def copy_kernel(self):
+        """ Copy kernel files to the outimage directory.
+        NOTE: This needs to be called before unmounting the instroot.
+        """
+
+        if not self._need_copy_kernel:
+            return
+
+        if not os.path.exists(self.destdir):
+            os.makedirs(self.destdir)
+
+        for kernel in glob.glob("%s/boot/vmlinuz-*" % self._instroot):
+            kernelfilename = "%s/%s-%s" % (self.destdir,
+                                           self.name,
+                                           os.path.basename(kernel))
+            msger.info('copy kernel file %s as %s' % (os.path.basename(kernel),
+                                                      kernelfilename))
+            shutil.copy(kernel, kernelfilename)
+            self.outimage.append(kernelfilename)
+
+    def copy_attachment(self):
+        """ Subclass implement it to handle attachment files
+        NOTE: This needs to be called before unmounting the instroot.
+        """
+        pass
+
+    def get_pkg_manager(self):
+        return self.pkgmgr(target_arch = self.target_arch,
+                           instroot = self._instroot,
+                           cachedir = self.cachedir,
+                           strict_mode = self.strict_mode)
+
+    def create_manifest(self):
+        def get_pack_suffix():
+            return '.' + self.pack_to.split('.', 1)[1]
+
+        if not os.path.exists(self.destdir):
+            os.makedirs(self.destdir)
+
+        now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+        manifest_dict = {'version': VERSION,
+                         'created': now}
+        if self.img_format:
+            manifest_dict.update({'format': self.img_format})
+
+        if hasattr(self, 'logfile') and self.logfile:
+            manifest_dict.update({'log_file': self.logfile})
+
+        if self.image_files:
+            if self.pack_to:
+                self.image_files.update({'pack': get_pack_suffix()})
+            manifest_dict.update({self.img_format: self.image_files})
+
+        msger.info('Creating manifest file...')
+        manifest_file_path = os.path.join(self.destdir, 'manifest.json')
+        with open(manifest_file_path, 'w') as fest_file:
+            json.dump(manifest_dict, fest_file, indent=4)
+        self.outimage.append(manifest_file_path)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/fs.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/fs.py
new file mode 100644 (file)
index 0000000..f2ccb78
--- /dev/null
@@ -0,0 +1,101 @@
+#!/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
+
+from mic import msger
+from mic.utils import runner, misc
+from mic.utils.errors import CreatorError
+from mic.utils.fs_related import find_binary_path
+from mic.imager.baseimager import BaseImageCreator
+
+class FsImageCreator(BaseImageCreator):
+    img_format = 'fs'
+
+    def __init__(self, cfgmgr = None, pkgmgr = None):
+        self.zips = {
+            "tar.bz2" : ""
+        }
+        BaseImageCreator.__init__(self, cfgmgr, pkgmgr)
+        self._fstype = None
+        self._fsopts = None
+        self._include_src = False
+
+    def package(self, destdir = "."):
+
+        ignores = ["/dev/fd",
+                   "/dev/stdin",
+                   "/dev/stdout",
+                   "/dev/stderr",
+                   "/etc/mtab"]
+
+        if not os.path.exists(destdir):
+            os.makedirs(destdir)
+
+        if self._recording_pkgs:
+            self._save_recording_pkgs(destdir)
+
+        if not self.pack_to:
+            self.image_files = {'image_files': [self.name]}
+            fsdir = os.path.join(destdir, self.name)
+
+            misc.check_space_pre_cp(self._instroot, destdir)
+            msger.info("Copying %s to %s ..." % (self._instroot, fsdir))
+            runner.show(['cp', "-af", self._instroot, fsdir])
+
+            for exclude in ignores:
+                if os.path.exists(fsdir + exclude):
+                    os.unlink(fsdir + exclude)
+
+            self.outimage.append(fsdir)
+
+        else:
+            self.image_files = {'image_files': [self.pack_to]}
+            (tar, comp) = os.path.splitext(self.pack_to)
+            try:
+                tarcreat = {'.tar': '-cf',
+                            '.gz': '-czf',
+                            '.bz2': '-cjf',
+                            '.tgz': '-czf',
+                            '.tbz': '-cjf'}[comp]
+            except KeyError:
+                raise CreatorError("Unsupported comression for this image type:"
+                                   " '%s', try '.tar', '.tar.gz', etc" % comp)
+
+            dst = os.path.join(destdir, self.pack_to)
+            msger.info("Pack rootfs to %s. Please wait..." % dst)
+
+            tar = find_binary_path('tar')
+            tar_cmdline = [tar, "--numeric-owner",
+                                "--preserve-permissions",
+                                "--one-file-system",
+                                "--directory",
+                                self._instroot]
+            for ignore_entry in ignores:
+                if ignore_entry.startswith('/'):
+                    ignore_entry = ignore_entry[1:]
+
+                tar_cmdline.append("--exclude=%s" % (ignore_entry))
+
+            tar_cmdline.extend([tarcreat, dst, "."])
+
+            rc = runner.show(tar_cmdline)
+            if rc:
+                raise CreatorError("Failed compress image with tar.bz2. "
+                                   "Cmdline: %s" % (" ".join(tar_cmdline)))
+
+            self.outimage.append(dst)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/loop.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/loop.py
new file mode 100644 (file)
index 0000000..18f226c
--- /dev/null
@@ -0,0 +1,562 @@
+#!/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 sys
+import glob
+import shutil
+
+from mic import kickstart, msger
+from mic.utils.errors import CreatorError, MountError, VdfsError
+from mic.utils import misc, runner, fs_related as fs
+from mic.imager.baseimager import BaseImageCreator
+from mic.archive import packing, compressing
+
+
+# The maximum string length supported for LoopImageCreator.fslabel
+FSLABEL_MAXLEN = 32
+# Support for Read-only file system list
+AFTER_MNT_FS = {"squashfs":".sqsh", "vdfs":".vdfs"}
+
+def save_mountpoints(fpath, loops, arch = None):
+    """Save mount points mapping to file
+
+    :fpath, the xml file to store partition info
+    :loops, dict of partition info
+    :arch, image arch
+    """
+
+    if not fpath or not loops:
+        return
+
+    from xml.dom import minidom
+    doc = minidom.Document()
+    imgroot = doc.createElement("image")
+    doc.appendChild(imgroot)
+    if arch:
+        imgroot.setAttribute('arch', arch)
+    for loop in loops:
+        part = doc.createElement("partition")
+        imgroot.appendChild(part)
+        for (key, val) in loop.items():
+            if isinstance(val, fs.Mount):
+                continue
+            part.setAttribute(key, str(val))
+
+    with open(fpath, 'w') as wf:
+        wf.write(doc.toprettyxml(indent='  '))
+
+    return
+
+def load_mountpoints(fpath):
+    """Load mount points mapping from file
+
+    :fpath, file path to load
+    """
+
+    if not fpath:
+        return
+
+    from xml.dom import minidom
+    mount_maps = []
+    with open(fpath, 'r') as rf:
+        dom = minidom.parse(rf)
+    imgroot = dom.documentElement
+    for part in imgroot.getElementsByTagName("partition"):
+        p  = dict(part.attributes.items())
+
+        try:
+            mp = (p['mountpoint'], p['label'], p['name'],
+                  int(p['size']), p['fstype'])
+        except KeyError:
+            msger.warning("Wrong format line in file: %s" % fpath)
+        except ValueError:
+            msger.warning("Invalid size '%s' in file: %s" % (p['size'], fpath))
+        else:
+            mount_maps.append(mp)
+
+    return mount_maps
+
+class LoopImageCreator(BaseImageCreator):
+    """Installs a system into a loopback-mountable filesystem image.
+
+    LoopImageCreator is a straightforward ImageCreator subclass; the system
+    is installed into an ext3 filesystem on a sparse file which can be
+    subsequently loopback-mounted.
+
+    When specifying multiple partitions in kickstart file, each partition
+    will be created as a separated loop image.
+    """
+    img_format = 'loop'
+
+    def __init__(self, creatoropts=None, pkgmgr=None,
+                 compress_image=None,
+                 shrink_image=False):
+        """Initialize a LoopImageCreator instance.
+
+        This method takes the same arguments as ImageCreator.__init__()
+        with the addition of:
+
+        fslabel -- A string used as a label for any filesystems created.
+        """
+
+        BaseImageCreator.__init__(self, creatoropts, pkgmgr)
+
+        self.compress_image = compress_image
+        self.shrink_image = shrink_image
+
+        self.__fslabel = None
+        self.fslabel = self.name
+
+        self.__blocksize = 4096
+        if self.ks:
+            self.__fstype = kickstart.get_image_fstype(self.ks,
+                                                       "ext3")
+            self.__fsopts = kickstart.get_image_fsopts(self.ks,
+                                                       "defaults,noatime")
+            if self.__fstype in AFTER_MNT_FS.keys():
+                self.__fstype = "ext4"
+
+            allloops = []
+            for part in sorted(kickstart.get_partitions(self.ks),
+                               key=lambda p: p.mountpoint):
+                aft_fstype = None
+                if part.fstype == "swap":
+                    continue
+                elif part.fstype in AFTER_MNT_FS.keys():
+                    aft_fstype = part.fstype
+                    part.fstype = "ext4"
+
+                label = part.label
+                fslabel = part.fslabel
+                if fslabel == '':
+                    fslabel = label
+                mp = part.mountpoint
+                if mp == '/':
+                    # the base image
+                    if not label:
+                        label = self.name
+                else:
+                    mp = mp.rstrip('/')
+                    if not label:
+                        msger.warning('no "label" specified for loop img at %s'
+                                      ', use the mountpoint as the name' % mp)
+                        label = mp.split('/')[-1]
+
+                imgname = misc.strip_end(label, '.img') + '.img'
+                allloops.append({
+                    'mountpoint': mp,
+                    'label': label,
+                    'fslabel':fslabel,
+                    'name': imgname,
+                    'size': part.size or 4096 * 1024 * 1024,
+                    'fstype': part.fstype or 'ext3',
+                    'fsopts': part.fsopts or None,
+                    'aft_fstype': aft_fstype or None,
+                    'extopts': part.extopts or None,
+                    'f2fsopts': part.f2fsopts or None,
+                    'vdfsopts': part.vdfsopts or None,
+                    'squashfsopts': part.squashfsopts or None,
+                    'squashfsoptions_maxsize': part.squashfsoptions_maxsize or None,
+                    'cpioopts': part.cpioopts or None,
+                    'loop': None,  # to be created in _mount_instroot
+                    'uuid': part.uuid or None,
+                    'kspart' : part,
+                    'exclude_image' : part.exclude_image or None,
+                    'no_shrink': part.no_shrink or False,
+                    'init_expand': part.init_expand or False,
+                    })
+            self._instloops = allloops
+
+        else:
+            self.__fstype = None
+            self.__fsopts = None
+            self._instloops = []
+
+        self._imgdir = None
+        self._umountdir = None
+
+        if self.ks:
+            self.__image_size = kickstart.get_image_size(self.ks,
+                                                         4096 * 1024 * 1024)
+        else:
+            self.__image_size = 0
+
+        self._img_name = self.name + ".img"
+
+    def get_image_names(self):
+        if not self._instloops:
+            return None
+
+        names = []
+        for lo in self._instloops :
+            names.append(lo['name'])
+            for ro in AFTER_MNT_FS.values():
+                names.append(lo['name'].replace('.img',ro))
+        return list(set(names))
+
+    def _set_fstype(self, fstype):
+        self.__fstype = fstype
+
+    def _set_image_size(self, imgsize):
+        self.__image_size = imgsize
+
+
+    #
+    # Properties
+    #
+    def __get_fslabel(self):
+        if self.__fslabel is None:
+            return self.name
+        else:
+            return self.__fslabel
+    def __set_fslabel(self, val):
+        if val is None:
+            self.__fslabel = None
+        else:
+            self.__fslabel = val[:FSLABEL_MAXLEN]
+    #A string used to label any filesystems created.
+    #
+    #Some filesystems impose a constraint on the maximum allowed size of the
+    #filesystem label. In the case of ext3 it's 16 characters, but in the case
+    #of ISO9660 it's 32 characters.
+    #
+    #mke2fs silently truncates the label, but mkisofs aborts if the label is
+    #too long. So, for convenience sake, any string assigned to this attribute
+    #is silently truncated to FSLABEL_MAXLEN (32) characters.
+    fslabel = property(__get_fslabel, __set_fslabel)
+
+    def __get_image(self):
+        if self._imgdir is None:
+            raise CreatorError("_image is not valid before calling mount()")
+        return os.path.join(self._imgdir, self._img_name)
+    #The location of the image file.
+    #
+    #This is the path to the filesystem image. Subclasses may use this path
+    #in order to package the image in _stage_final_image().
+    #
+    #Note, this directory does not exist before ImageCreator.mount() is called.
+    #
+    #Note also, this is a read-only attribute.
+    _image = property(__get_image)
+
+    def __get_blocksize(self):
+        return self.__blocksize
+    def __set_blocksize(self, val):
+        if self._instloops:
+            raise CreatorError("_blocksize must be set before calling mount()")
+        try:
+            self.__blocksize = int(val)
+        except ValueError:
+            raise CreatorError("'%s' is not a valid integer value "
+                               "for _blocksize" % val)
+    #The block size used by the image's filesystem.
+    #
+    #This is the block size used when creating the filesystem image. Subclasses
+    #may change this if they wish to use something other than a 4k block size.
+    #
+    #Note, this attribute may only be set before calling mount().
+    _blocksize = property(__get_blocksize, __set_blocksize)
+
+    def __get_fstype(self):
+        return self.__fstype
+    def __set_fstype(self, val):
+        if val != "ext2" and val != "ext3":
+            raise CreatorError("Unknown _fstype '%s' supplied" % val)
+        self.__fstype = val
+    #The type of filesystem used for the image.
+    #
+    #This is the filesystem type used when creating the filesystem image.
+    #Subclasses may change this if they wish to use something other ext3.
+    #
+    #Note, only ext2 and ext3 are currently supported.
+    #
+    #Note also, this attribute may only be set before calling mount().
+    _fstype = property(__get_fstype, __set_fstype)
+
+    def __get_fsopts(self):
+        return self.__fsopts
+    def __set_fsopts(self, val):
+        self.__fsopts = val
+    #Mount options of filesystem used for the image.
+    #
+    #This can be specified by --fsoptions="xxx,yyy" in part command in
+    #kickstart file.
+    _fsopts = property(__get_fsopts, __set_fsopts)
+
+
+    #
+    # Helpers for subclasses
+    #
+    def _resparse(self, size=None):
+        """Rebuild the filesystem image to be as sparse as possible.
+
+        This method should be used by subclasses when staging the final image
+        in order to reduce the actual space taken up by the sparse image file
+        to be as little as possible.
+
+        This is done by resizing the filesystem to the minimal size (thereby
+        eliminating any space taken up by deleted files) and then resizing it
+        back to the supplied size.
+
+        size -- the size in, in bytes, which the filesystem image should be
+                resized to after it has been minimized; this defaults to None,
+                causing the original size specified by the kickstart file to
+                be used (or 4GiB if not specified in the kickstart).
+        """
+        minsize = 0
+        for item in self._instloops:
+            if not item['cpioopts']:
+                if item['no_shrink']:
+                    item['loop'].resparse()
+                    continue
+                if item['name'] == self._img_name:
+                    minsize = item['loop'].resparse(size)
+                else:
+                    item['loop'].resparse(size)
+
+        return minsize
+
+    def _base_on(self, base_on=None):
+        if base_on and self._image != base_on:
+            shutil.copyfile(base_on, self._image)
+
+    def _check_imgdir(self):
+        if self._imgdir is None:
+            self._imgdir = self._mkdtemp()
+
+
+    #
+    # Actual implementation
+    #
+    def _mount_instroot(self, base_on=None):
+        if base_on and os.path.isfile(base_on):
+            self._imgdir = os.path.dirname(base_on)
+            imgname = os.path.basename(base_on)
+            self._base_on(base_on)
+            self._set_image_size(misc.get_file_size(self._image))
+
+            # here, self._instloops must be []
+            self._instloops.append({
+                 "mountpoint": "/",
+                 "label": self.name,
+                 "name": imgname,
+                 "size": self.__image_size or 4096,
+                 "fstype": self.__fstype or "ext3",
+                 "f2fsopts": None,
+                 "extopts": None,
+                 "loop": None,
+                 "uuid": None,
+                 "kspart": None,
+                 "exclude_image" : None
+                 })
+
+        self._check_imgdir()
+
+        for loop in self._instloops:
+            fstype = loop['fstype']
+            fsopt = loop['fsopts']
+            mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/'))
+            size = loop['size'] * 1024 * 1024
+            imgname = loop['name']
+
+            if fstype in ("ext2", "ext3", "ext4"):
+                MyDiskMount = fs.ExtDiskMount
+            elif fstype == "btrfs":
+                MyDiskMount = fs.BtrfsDiskMount
+            elif fstype in ("vfat", "msdos"):
+                MyDiskMount = fs.VfatDiskMount
+            elif fstype == "f2fs":
+                MyDiskMount = fs.F2fsDiskMount
+            else:
+                raise MountError('Cannot support fstype: %s' % fstype)
+
+            loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk(
+                                           os.path.join(self._imgdir, imgname),
+                                           size),
+                                       mp,
+                                       fstype,
+                                       self._blocksize,
+                                       loop['fslabel'],
+                                       fsopt,
+                                       fsuuid = loop['uuid'])
+
+            if fstype in ("ext2", "ext3", "ext4"):
+                loop['loop'].extopts = loop['extopts']
+            elif fstype == "f2fs":
+                loop['loop'].f2fsopts = loop['f2fsopts']
+
+            try:
+                msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp))
+                fs.makedirs(mp)
+                loop['loop'].mount(fsopt, init_expand=loop['init_expand'])
+                # Make an autogenerated uuid avaialble in _get_post_scripts_env()
+                if loop['kspart'] and loop['kspart'].uuid is None and \
+                   loop['loop'].uuid:
+                    loop['kspart'].uuid = loop['loop'].uuid
+
+            except MountError as e:
+                raise
+
+    def _unmount_instroot(self):
+        for item in reversed(self._instloops):
+            try:
+                item['loop'].cleanup()
+            except:
+                pass
+
+    def _get_sign_scripts_env(self):
+        env = BaseImageCreator._get_sign_scripts_env(self)
+
+        # Directory path of %post-umounts scripts
+        if self._umountdir:
+            env['UMOUNT_SCRIPTS_PATH'] = str(self._umountdir)
+
+        return env
+
+    def _stage_final_image(self):
+
+        if self.pack_to or self.shrink_image:
+            self._resparse(0)
+        else:
+            self._resparse()
+
+        for item in self._instloops:
+            imgfile = os.path.join(self._imgdir, item['name'])
+
+            if item['aft_fstype'] in AFTER_MNT_FS.keys():
+                mountpoint = misc.mkdtemp()
+                ext4img = os.path.join(self._imgdir, item['name'])
+                runner.show('mount -t ext4 %s %s' % (ext4img, mountpoint))
+                runner.show('ls -al %s' % (mountpoint))
+#                item['loop'].mount(None, 'not_create')
+#                point_mnt = os.path.join(self._instroot, item['mountpoint'].lstrip('/'))
+
+                fs_suffix = AFTER_MNT_FS[item['aft_fstype']]
+                if item['aft_fstype'] == "squashfs":
+#                    fs.mksquashfs(mountpoint, self._outdir+"/"+item['label']+fs_suffix)
+                    args = "mksquashfs " + mountpoint + " " + self._imgdir+"/"+item['label']+fs_suffix
+                    if item['squashfsopts']:
+                        squashfsopts=item['squashfsopts'].replace(',', ' ')
+                        runner.show("mksquashfs --help")
+                        runner.show("%s %s" % (args, squashfsopts))
+                    else:
+                        runner.show("%s " % args)
+
+                    if item['squashfsoptions_maxsize']:
+                        squashfsoptions_maxsize=int(item['squashfsoptions_maxsize']) * 1024 * 1024
+                        imgsize = os.stat(self._imgdir+"/"+item['label']+fs_suffix).st_size
+                        if imgsize > squashfsoptions_maxsize:
+                            msger.error("squashfs img size is too large (%d > %d)" % (imgsize, squashfsoptions_maxsize))
+                            sys.exit()
+
+                if item['aft_fstype'] == "vdfs":
+                    ##FIXME temporary code - replace this with fs.mkvdfs()
+                    if item['vdfsopts']:
+                        vdfsopts=item['vdfsopts'].replace(',', ' ')
+                    else:
+                        vdfsopts="-i -z 1024M"
+
+                    fullpathmkvdfs = "mkfs.vdfs" #find_binary_path("mkfs.vdfs")
+                    runner.show("%s --help" % fullpathmkvdfs)
+#                    fs.mkvdfs(mountpoint, self._outdir+"/"+item['label']+fs_suffix, vdfsopts)
+                    ret = runner.show('%s %s -r %s %s' % (fullpathmkvdfs, vdfsopts, mountpoint, self._imgdir+"/"+item['label']+fs_suffix))
+                    if ret != 0:
+                        runner.show("mkfs.vdfs return error")
+                        raise VdfsError("' %s' exited with error (%d)" % (fullpathmkvdfs, ret))
+
+                runner.show('umount %s' % mountpoint)
+#               os.unlink(mountpoint)
+                runner.show('mv %s %s' % (self._imgdir+"/"+item['label']+fs_suffix, self._imgdir+"/"+item['label']+".img") )
+                runner.show('ls -al %s' % self._imgdir)
+
+            if item['fstype'] == "ext4":
+                if not item['cpioopts']:
+                    runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s '
+                            % imgfile)
+                    runner.quiet(["/sbin/e2fsck", "-f", "-y", imgfile])
+            self.image_files.setdefault('partitions', {}).update(
+                    {item['mountpoint']: item['label']})
+            if self.compress_image:
+                compressing(imgfile, self.compress_image)
+                self.image_files.setdefault('image_files', []).append(
+                                '.'.join([item['name'], self.compress_image]))
+            else:
+                self.image_files.setdefault('image_files', []).append(item['name'])
+
+        for item in os.listdir(self._imgdir):
+            imgfile = os.path.join(self._imgdir, item)
+            imgsize = os.path.getsize(imgfile)
+            msger.info("filesystem size of %s : %s bytes" % (item, imgsize))
+
+        self.run_sign_scripts()
+        if not self.pack_to:
+            for item in os.listdir(self._imgdir):
+                shutil.move(os.path.join(self._imgdir, item),
+                            os.path.join(self._outdir, item))
+        else:
+            msger.info("Pack all loop images together to %s" % self.pack_to)
+            dstfile = os.path.join(self._outdir, self.pack_to)
+            packing(dstfile, self._imgdir)
+            self.image_files['image_files'] = [self.pack_to]
+
+
+        if self.pack_to:
+            mountfp_xml = os.path.splitext(self.pack_to)[0]
+            mountfp_xml = misc.strip_end(mountfp_xml, '.tar') + ".xml"
+        else:
+            mountfp_xml = self.name + ".xml"
+        # save mount points mapping file to xml
+        save_mountpoints(os.path.join(self._outdir, mountfp_xml),
+                         self._instloops,
+                         self.target_arch)
+
+    def copy_attachment(self):
+        if not hasattr(self, '_attachment') or not self._attachment:
+            return
+
+        self._check_imgdir()
+
+        msger.info("Copying attachment files...")
+        for item in self._attachment:
+            if not os.path.exists(item):
+                continue
+            dpath = os.path.join(self._imgdir, os.path.basename(item))
+            msger.verbose("Copy attachment %s to %s" % (item, dpath))
+            shutil.copy(item, dpath)
+
+    def move_post_umount_scripts(self):
+        scripts_dir = self._instroot + "/var/tmp/post_umount_scripts"
+        if not os.path.exists(scripts_dir):
+            return
+        self._umountdir = self._mkdtemp("umount")
+        msger.info("Moving post umount scripts...")
+        for item in os.listdir(scripts_dir):
+            spath = os.path.join(scripts_dir, item)
+            dpath = os.path.join(self._umountdir, item)
+            msger.verbose("Move post umount scripts %s to %s" % (spath, dpath))
+            shutil.move(spath, dpath)
+        shutil.rmtree(scripts_dir)
+
+    def postinstall(self):
+        BaseImageCreator.postinstall(self)
+        self.move_post_umount_scripts()
+
+    def create_manifest(self):
+        if self.compress_image:
+            self.image_files.update({'compress': self.compress_image})
+        super(LoopImageCreator, self).create_manifest()
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/qcow.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/qcow.py
new file mode 100644 (file)
index 0000000..f4b66fc
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2014 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.imager.loop import LoopImageCreator
+from mic.utils import errors, fs_related, runner
+
+class QcowImageCreator(LoopImageCreator):
+    img_format = 'qcow'
+
+    def __init__(self, creatoropts=None, pkgmgr=None):
+        LoopImageCreator.__init__(self, creatoropts, pkgmgr)
+        self.cmd_qemuimg = 'qemu-img'
+
+    def _stage_final_image(self):
+        try:
+            self.cmd_qemuimg = fs_related.find_binary_path('qemu-img')
+        except errors.CreatorError:
+            return LoopImageCreator._stage_final_image(self)
+
+        self._resparse()
+
+        imgfile = None
+        for item in self._instloops:
+            if item['mountpoint'] == '/':
+                if item['fstype'] == "ext4":
+                    runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s'
+                                % imgfile)
+                self.image_files.setdefault('partitions', {}).update(
+                         {item['mountpoint']: item['label']})
+                imgfile = os.path.join(self._imgdir, item['name'])
+
+        if imgfile:
+            qemuimage = imgfile + ".x86"
+            runner.show("%s convert -O qcow2 %s %s"
+                        % (self.cmd_qemuimg, imgfile, qemuimage))
+            os.unlink(imgfile)
+            os.rename(qemuimage, imgfile)
+
+        for item in os.listdir(self._imgdir):
+            shutil.move(os.path.join(self._imgdir, item),
+                        os.path.join(self._outdir, item))
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/raw.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/imager/raw.py
new file mode 100644 (file)
index 0000000..430cfd0
--- /dev/null
@@ -0,0 +1,605 @@
+#!/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 stat
+import shutil
+
+from mic import kickstart, msger
+from mic.utils import fs_related, runner, misc
+from mic.utils.partitionedfs import PartitionedMount
+from mic.utils.errors import CreatorError, MountError
+from mic.imager.baseimager import BaseImageCreator
+from mic.archive import packing, compressing
+
+class RawImageCreator(BaseImageCreator):
+    """Installs a system into a file containing a partitioned disk image.
+
+    ApplianceImageCreator is an advanced ImageCreator subclass; a sparse file
+    is formatted with a partition table, each partition loopback mounted
+    and the system installed into an virtual disk. The disk image can
+    subsequently be booted in a virtual machine or accessed with kpartx
+    """
+    img_format = 'raw'
+
+    def __init__(self, creatoropts=None, pkgmgr=None, compress_image=None, generate_bmap=None, fstab_entry="uuid"):
+        """Initialize a ApplianceImageCreator instance.
+
+            This method takes the same arguments as ImageCreator.__init__()
+        """
+        BaseImageCreator.__init__(self, creatoropts, pkgmgr)
+
+        self.__instloop = None
+        self.__imgdir = None
+        self.__disks = {}
+        self.__disk_format = "raw"
+        self._disk_names = []
+        self._ptable_format = self.ks.handler.bootloader.ptable
+        self.vmem = 512
+        self.vcpu = 1
+        self.checksum = False
+        self.use_uuid = fstab_entry == "uuid"
+        self.appliance_version = None
+        self.appliance_release = None
+        self.compress_image = compress_image
+        self.bmap_needed = generate_bmap
+        self._need_extlinux = not kickstart.use_installerfw(self.ks, "bootloader")
+        #self.getsource = False
+        #self.listpkg = False
+
+        self._dep_checks.extend(["sync", "kpartx", "parted"])
+        if self._need_extlinux:
+            self._dep_checks.extend(["extlinux"])
+
+    def configure(self, repodata = None):
+        import subprocess
+        def chroot():
+            os.chroot(self._instroot)
+            os.chdir("/")
+
+        if os.path.exists(self._instroot + "/usr/bin/Xorg"):
+            subprocess.call(["/bin/chmod", "u+s", "/usr/bin/Xorg"],
+                            preexec_fn = chroot)
+
+        BaseImageCreator.configure(self, repodata)
+
+    def _get_fstab(self):
+        s = ""
+        for mp in self.__instloop.mount_order:
+            p = None
+            for p1 in self.__instloop.partitions:
+                if p1['mountpoint'] == mp:
+                    p = p1
+                    break
+
+            if self.use_uuid and p['uuid']:
+                device = "UUID=%s" % p['uuid']
+            else:
+                device = "/dev/%s%-d" % (p['disk_name'], p['num'])
+
+            s += "%(device)s  %(mountpoint)s  %(fstype)s  %(fsopts)s 0 0\n" % {
+               'device': device,
+               'mountpoint': p['mountpoint'],
+               'fstype': p['fstype'],
+               'fsopts': "defaults,noatime" if not p['fsopts'] else p['fsopts']}
+
+            if p['mountpoint'] == "/":
+                for subvol in self.__instloop.subvolumes:
+                    if subvol['mountpoint'] == "/":
+                        continue
+                    s += "%(device)s  %(mountpoint)s  %(fstype)s  %(fsopts)s 0 0\n" % {
+                         'device': "/dev/%s%-d" % (p['disk_name'], p['num']),
+                         'mountpoint': subvol['mountpoint'],
+                         'fstype': p['fstype'],
+                         'fsopts': "defaults,noatime" if not subvol['fsopts'] else subvol['fsopts']}
+
+        s += "devpts     /dev/pts  devpts  gid=5,mode=620   0 0\n"
+        s += "tmpfs      /dev/shm  tmpfs   defaults         0 0\n"
+        s += "proc       /proc     proc    defaults         0 0\n"
+        s += "sysfs      /sys      sysfs   defaults         0 0\n"
+        return s
+
+    def _create_mkinitrd_config(self):
+        """write to tell which modules to be included in initrd"""
+
+        mkinitrd = ""
+        mkinitrd += "PROBE=\"no\"\n"
+        mkinitrd += "MODULES+=\"ext3 ata_piix sd_mod libata scsi_mod\"\n"
+        mkinitrd += "rootfs=\"ext3\"\n"
+        mkinitrd += "rootopts=\"defaults\"\n"
+
+        msger.debug("Writing mkinitrd config %s/etc/sysconfig/mkinitrd" \
+                    % self._instroot)
+        os.makedirs(self._instroot + "/etc/sysconfig/",mode=644)
+        cfg = open(self._instroot + "/etc/sysconfig/mkinitrd", "w")
+        cfg.write(mkinitrd)
+        cfg.close()
+
+    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))
+
+    #
+    # Actual implemention
+    #
+    def _mount_instroot(self, base_on = None):
+        parts = self._get_parts()
+        self.__instloop = PartitionedMount(self._instroot)
+
+        for p in parts:
+            self.__instloop.add_partition(int(p.size),
+                                          p.disk,
+                                          p.mountpoint,
+                                          p.fstype,
+                                          p.label,
+                                          fsopts = p.fsopts,
+                                          boot = p.active,
+                                          align = p.align,
+                                          part_type = p.part_type)
+
+        self.__instloop.layout_partitions(self._ptable_format)
+
+        # Create the disks
+        self.__imgdir = self._mkdtemp()
+        for disk_name, disk in self.__instloop.disks.items():
+            full_path = self._full_path(self.__imgdir, disk_name, "raw")
+            msger.debug("Adding disk %s as %s with size %s bytes" \
+                        % (disk_name, full_path, disk['min_size']))
+
+            disk_obj = fs_related.SparseLoopbackDisk(full_path,
+                                                     disk['min_size'])
+            self.__disks[disk_name] = disk_obj
+            self.__instloop.add_disk(disk_name, disk_obj)
+
+        self.__instloop.mount()
+        self._create_mkinitrd_config()
+
+    def mount(self, base_on = None, cachedir = None):
+        """
+        This method calls the base class' 'mount()' method and then creates
+        block device nodes corresponding to the image's partitions in the image
+        itself. Namely, the image has /dev/loopX device corresponding to the
+        entire image, and per-partition /dev/mapper/* devices.
+
+        We copy these files to image's "/dev" directory in order to enable
+        scripts which run in the image chroot environment to access own raw
+        partitions. For example, this can be used to install the bootloader to
+        the MBR (say, from an installer framework plugin).
+        """
+
+        def copy_devnode(src, dest):
+            """A helper function for copying device nodes."""
+
+            if not src:
+                return
+
+            stat_obj = os.stat(src)
+            assert stat.S_ISBLK(stat_obj.st_mode)
+
+            os.mknod(dest, stat_obj.st_mode,
+                     os.makedev(os.major(stat_obj.st_rdev),
+                                os.minor(stat_obj.st_rdev)))
+            # os.mknod uses process umask may create a nod with different
+            # permissions, so we use os.chmod to make sure permissions are
+            # correct.
+            os.chmod(dest, stat_obj.st_mode)
+
+        BaseImageCreator.mount(self, base_on, cachedir)
+
+        # Copy the disk loop devices
+        for name in self.__disks.keys():
+            loopdev = self.__disks[name].device
+            copy_devnode(loopdev, self._instroot + loopdev)
+
+        # Copy per-partition dm nodes
+        os.mkdir(self._instroot + "/dev/mapper", os.stat("/dev/mapper").st_mode)
+        for p in self.__instloop.partitions:
+            copy_devnode(p['mapper_device'],
+                         self._instroot + p['mapper_device'])
+            copy_devnode(p['mpath_device'],
+                         self._instroot + p['mpath_device'])
+
+    def unmount(self):
+        """
+        Remove loop/dm device nodes which we created in 'mount()' and call the
+        base class' 'unmount()' method.
+        """
+
+        for p in self.__instloop.partitions:
+            if p['mapper_device']:
+                path = self._instroot + p['mapper_device']
+                if os.path.exists(path):
+                    os.unlink(path)
+            if p['mpath_device']:
+                path = self._instroot + p['mpath_device']
+                if os.path.exists(path):
+                    os.unlink(path)
+
+        path = self._instroot + "/dev/mapper"
+        if os.path.exists(path):
+            shutil.rmtree(path, ignore_errors=True)
+
+        for name in self.__disks.keys():
+            if self.__disks[name].device:
+                path = self._instroot + self.__disks[name].device
+                if os.path.exists(path):
+                    os.unlink(path)
+
+        BaseImageCreator.unmount(self)
+
+    def _get_required_packages(self):
+        required_packages = BaseImageCreator._get_required_packages(self)
+        if self._need_extlinux:
+            if not self.target_arch or not self.target_arch.startswith("arm"):
+                required_packages += ["syslinux", "syslinux-extlinux"]
+        return required_packages
+
+    def _get_excluded_packages(self):
+        return BaseImageCreator._get_excluded_packages(self)
+
+    def _get_syslinux_boot_config(self):
+        rootdev = None
+        root_part_uuid = None
+        for p in self.__instloop.partitions:
+            if p['mountpoint'] == "/":
+                rootdev = "/dev/%s%-d" % (p['disk_name'], p['num'])
+                root_part_uuid = p['partuuid']
+
+        return (rootdev, root_part_uuid)
+
+    def _create_syslinux_config(self):
+
+        splash = os.path.join(self._instroot, "boot/extlinux")
+        if os.path.exists(splash):
+            splashline = "menu background splash.jpg"
+        else:
+            splashline = ""
+
+        (rootdev, root_part_uuid) = self._get_syslinux_boot_config()
+        options = self.ks.handler.bootloader.appendLine
+
+        #XXX don't hardcode default kernel - see livecd code
+        syslinux_conf = ""
+        syslinux_conf += "prompt 0\n"
+        syslinux_conf += "timeout 1\n"
+        syslinux_conf += "\n"
+        syslinux_conf += "default vesamenu.c32\n"
+        syslinux_conf += "menu autoboot Starting %s...\n" % self.distro_name
+        syslinux_conf += "menu hidden\n"
+        syslinux_conf += "\n"
+        syslinux_conf += "%s\n" % splashline
+        syslinux_conf += "menu title Welcome to %s!\n" % self.distro_name
+        syslinux_conf += "menu color border 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color sel 7 #ffffffff #ff000000\n"
+        syslinux_conf += "menu color title 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color tabmsg 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color unsel 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color hotsel 0 #ff000000 #ffffffff\n"
+        syslinux_conf += "menu color hotkey 7 #ffffffff #ff000000\n"
+        syslinux_conf += "menu color timeout_msg 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color timeout 0 #ffffffff #00000000\n"
+        syslinux_conf += "menu color cmdline 0 #ffffffff #00000000\n"
+
+        versions = []
+        kernels = self._get_kernel_versions()
+        symkern = "%s/boot/vmlinuz" % self._instroot
+
+        if os.path.lexists(symkern):
+            v = os.path.realpath(symkern).replace('%s-' % symkern, "")
+            syslinux_conf += "label %s\n" % self.distro_name.lower()
+            syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
+            syslinux_conf += "\tlinux ../vmlinuz\n"
+            if self._ptable_format == 'msdos':
+                rootstr = rootdev
+            else:
+                if not root_part_uuid:
+                    raise MountError("Cannot find the root GPT partition UUID")
+                rootstr = "PARTUUID=%s" % root_part_uuid
+            syslinux_conf += "\tappend ro root=%s %s\n" % (rootstr, options)
+            syslinux_conf += "\tmenu default\n"
+        else:
+            for kernel in kernels:
+                for version in kernels[kernel]:
+                    versions.append(version)
+
+            footlabel = 0
+            for v in versions:
+                syslinux_conf += "label %s%d\n" \
+                                 % (self.distro_name.lower(), footlabel)
+                syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
+                syslinux_conf += "\tlinux ../vmlinuz-%s\n" % v
+                syslinux_conf += "\tappend ro root=%s %s\n" \
+                                 % (rootdev, options)
+                if footlabel == 0:
+                    syslinux_conf += "\tmenu default\n"
+                footlabel += 1
+
+        msger.debug("Writing syslinux config %s/boot/extlinux/extlinux.conf" \
+                    % self._instroot)
+        cfg = open(self._instroot + "/boot/extlinux/extlinux.conf", "w")
+        cfg.write(syslinux_conf)
+        cfg.close()
+
+    def _install_syslinux(self):
+        for name in self.__disks.keys():
+            loopdev = self.__disks[name].device
+
+            # Set MBR
+            mbrfile = "%s/usr/share/syslinux/" % self._instroot
+            if self._ptable_format == 'gpt':
+                mbrfile += "gptmbr.bin"
+            else:
+                mbrfile += "mbr.bin"
+
+            msger.debug("Installing syslinux bootloader '%s' to %s" % \
+                        (mbrfile, loopdev))
+
+            rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev])
+            if rc != 0:
+                raise MountError("Unable to set MBR to %s" % loopdev)
+
+
+            # Ensure all data is flushed to disk before doing syslinux install
+            runner.quiet('sync')
+
+            fullpathsyslinux = fs_related.find_binary_path("extlinux")
+            rc = runner.show([fullpathsyslinux,
+                              "-i",
+                              "%s/boot/extlinux" % self._instroot])
+            if rc != 0:
+                raise MountError("Unable to install syslinux bootloader to %s" \
+                                 % loopdev)
+
+    def _create_bootconfig(self):
+        #If syslinux is available do the required configurations.
+        if self._need_extlinux \
+           and os.path.exists("%s/usr/share/syslinux/" % (self._instroot)) \
+           and os.path.exists("%s/boot/extlinux/" % (self._instroot)):
+            self._create_syslinux_config()
+            self._install_syslinux()
+
+    def _unmount_instroot(self):
+        if not self.__instloop is None:
+            try:
+                self.__instloop.cleanup()
+            except MountError as err:
+                msger.warning("%s" % err)
+
+    def _resparse(self, size = None):
+        return self.__instloop.resparse(size)
+
+    def _get_post_scripts_env(self, in_chroot):
+        env = BaseImageCreator._get_post_scripts_env(self, in_chroot)
+
+        # Export the file-system UUIDs and partition UUIDs (AKA PARTUUIDs)
+        for p in self.__instloop.partitions:
+            env.update(self._set_part_env(p['ks_pnum'], "UUID", p['uuid']))
+            env.update(self._set_part_env(p['ks_pnum'], "PARTUUID", p['partuuid']))
+            env.update(self._set_part_env(p['ks_pnum'], "DEVNODE_NOW",
+                                          p['mapper_device']))
+            env.update(self._set_part_env(p['ks_pnum'], "DISK_DEVNODE_NOW",
+                                          self.__disks[p['disk_name']].device))
+
+        return env
+
+    def _stage_final_image(self):
+        """Stage the final system image in _outdir.
+           write meta data
+        """
+        self._resparse()
+        self.image_files.update({'disks': self.__disks.keys()})
+
+        if not (self.compress_image or self.pack_to):
+            for imgfile in os.listdir(self.__imgdir):
+                if imgfile.endswith('.raw'):
+                    for disk in self.__disks.keys():
+                        if imgfile.find(disk) != -1:
+                            self.image_files.setdefault(disk, {}).update(
+                                   {'image': imgfile})
+                            self.image_files.setdefault('image_files',
+                                   []).append(imgfile)
+
+        if self.compress_image:
+            for imgfile in os.listdir(self.__imgdir):
+                if imgfile.endswith('.raw') or imgfile.endswith('bin'):
+                    imgpath = os.path.join(self.__imgdir, imgfile)
+                    msger.info("Compressing image %s" % imgfile)
+                    compressing(imgpath, self.compress_image)
+                if imgfile.endswith('.raw') and not self.pack_to:
+                    for disk in self.__disks.keys():
+                        if imgfile.find(disk) != -1:
+                            imgname = '%s.%s' % (imgfile, self.compress_image)
+                            self.image_files.setdefault(disk, {}).update(
+                                   {'image': imgname})
+                            self.image_files.setdefault('image_files',
+                                    []).append(imgname)
+
+        if self.pack_to:
+            dst = os.path.join(self._outdir, self.pack_to)
+            msger.info("Pack all raw images to %s" % dst)
+            packing(dst, self.__imgdir)
+            self.image_files.update({'image_files': self.pack_to})
+        else:
+            msger.debug("moving disks to stage location")
+            for imgfile in os.listdir(self.__imgdir):
+                src = os.path.join(self.__imgdir, imgfile)
+                dst = os.path.join(self._outdir, imgfile)
+                msger.debug("moving %s to %s" % (src,dst))
+                shutil.move(src,dst)
+
+        self._write_image_xml()
+
+    def _write_image_xml(self):
+        imgarch = "i686"
+        if self.target_arch:
+            if self.target_arch.startswith("arm"):
+                imgarch = "arm"
+            elif self.target_arch == "riscv64":
+                imgarch = "riscv64"
+        xml = "<image>\n"
+
+        name_attributes = ""
+        if self.appliance_version:
+            name_attributes += " version='%s'" % self.appliance_version
+        if self.appliance_release:
+            name_attributes += " release='%s'" % self.appliance_release
+        xml += "  <name%s>%s</name>\n" % (name_attributes, self.name)
+        xml += "  <domain>\n"
+        # XXX don't hardcode - determine based on the kernel we installed for
+        # grub baremetal vs xen
+        xml += "    <boot type='hvm'>\n"
+        xml += "      <guest>\n"
+        xml += "        <arch>%s</arch>\n" % imgarch
+        xml += "      </guest>\n"
+        xml += "      <os>\n"
+        xml += "        <loader dev='hd'/>\n"
+        xml += "      </os>\n"
+
+        i = 0
+        for name in self.__disks.keys():
+            full_name = self._full_name(name, self.__disk_format)
+            xml += "      <drive disk='%s' target='hd%s'/>\n" \
+                       % (full_name, chr(ord('a') + i))
+            i = i + 1
+
+        xml += "    </boot>\n"
+        xml += "    <devices>\n"
+        xml += "      <vcpu>%s</vcpu>\n" % self.vcpu
+        xml += "      <memory>%d</memory>\n" %(self.vmem * 1024)
+        for network in self.ks.handler.network.network:
+            xml += "      <interface/>\n"
+        xml += "      <graphics/>\n"
+        xml += "    </devices>\n"
+        xml += "  </domain>\n"
+        xml += "  <storage>\n"
+
+        if self.checksum is True:
+            for name in self.__disks.keys():
+                diskpath = self._full_path(self._outdir, name, \
+                                           self.__disk_format)
+                full_name = self._full_name(name, self.__disk_format)
+
+                msger.debug("Generating disk signature for %s" % full_name)
+
+                xml += "    <disk file='%s' use='system' format='%s'>\n" \
+                       % (full_name, self.__disk_format)
+
+                hashes = misc.calc_hashes(diskpath, ('sha1', 'sha256'))
+
+                xml +=  "      <checksum type='sha1'>%s</checksum>\n" \
+                        % hashes[0]
+                xml += "      <checksum type='sha256'>%s</checksum>\n" \
+                       % hashes[1]
+                xml += "    </disk>\n"
+        else:
+            for name in self.__disks.keys():
+                full_name = self._full_name(name, self.__disk_format)
+                xml += "    <disk file='%s' use='system' format='%s'/>\n" \
+                       % (full_name, self.__disk_format)
+
+        xml += "  </storage>\n"
+        xml += "</image>\n"
+
+        msger.debug("writing image XML to %s/%s.xml" %(self._outdir, self.name))
+        cfg = open("%s/%s.xml" % (self._outdir, self.name), "w")
+        cfg.write(xml)
+        cfg.close()
+
+    def generate_bmap(self):
+        """ Generate block map file for the image. The idea is that while disk
+        images we generate may be large (e.g., 4GiB), they may actually contain
+        only little real data, e.g., 512MiB. This data are files, directories,
+        file-system meta-data, partition table, etc. In other words, when
+        flashing the image to the target device, you do not have to copy all the
+        4GiB of data, you can copy only 512MiB of it, which is 4 times faster.
+
+        This function generates the block map file for an arbitrary image that
+        mic has generated. The block map file is basically an XML file which
+        contains a list of blocks which have to be copied to the target device.
+        The other blocks are not used and there is no need to copy them. """
+
+        if self.bmap_needed is None:
+            return
+
+        msger.info("Generating the map file(s)")
+
+        for name in self.__disks.keys():
+            image = self._full_path(self.__imgdir, name, self.__disk_format)
+            bmap_file = self._full_path(self._outdir, name, "bmap")
+            self.image_files.setdefault(name, {}).update({'bmap': \
+                                            os.path.basename(bmap_file)})
+
+            msger.debug("Generating block map file '%s'" % bmap_file)
+            
+            bmaptoolcmd = misc.find_binary_path('bmaptool')
+            rc = runner.show([bmaptoolcmd, 'create', image, '-o', bmap_file])
+            if rc != 0:
+                raise CreatorError("Failed to create bmap file: %s" % bmap_file)
+
+    def create_manifest(self):
+        if self.compress_image:
+            self.image_files.update({'compress': self.compress_image})
+        super(RawImageCreator, self).create_manifest()
+
+    def remove_exclude_image(self):
+        pass
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/__init__.py
new file mode 100644 (file)
index 0000000..46bcca2
--- /dev/null
@@ -0,0 +1,963 @@
+#!/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 collections
+
+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 desktop, micrepo, micboot, partition, installerfw
+from mic.utils.safeurl import SafeURL
+
+AUTH_URL_PTN = r"(?P<scheme>.*)://(?P<username>.*)(:?P<password>.*)?@(?P<url>.*)"
+
+
+class PrepackageSection(kssections.Section):
+    sectionOpen = "%prepackages"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+
+        self.handler.prepackages.add([line])
+
+    def handleHeader(self, lineno, args):
+        kssections.Section.handleHeader(self, lineno, args)
+
+class AttachmentSection(kssections.Section):
+    sectionOpen = "%attachment"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+
+        self.handler.attachment.add([line])
+
+    def handleHeader(self, lineno, args):
+        kssections.Section.handleHeader(self, lineno, args)
+
+class EnvSection(kssections.Section):
+    sectionOpen = "%env"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+        (n, s, v) = line.partition('=')
+        self.handler.env.append((n, v))
+
+    def handleHeader(self, lineno, args):
+        self.handler.env = []
+        kssections.Section.handleHeader(self, lineno, args)
+
+def apply_wrapper(func):
+    def wrapper(*kargs, **kwargs):
+        try:
+            func(*kargs, **kwargs)
+        except (OSError, IOError, errors.KsError) as err:
+            cfgcls = kargs[0].__class__.__name__
+            if msger.ask("Failed to apply %s, skip and continue?" % cfgcls):
+                msger.warning("%s" % err)
+                pass
+            else:
+                # just throw out the exception
+                raise
+    return wrapper
+
+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]["desktop"] = desktop.Mic_Desktop
+    commandMap[using_version]["repo"] = micrepo.Mic_Repo
+    commandMap[using_version]["tpk_repo"] = micrepo.Mic_Tpk_Repo
+    commandMap[using_version]["bootloader"] = micboot.Mic_Bootloader
+    commandMap[using_version]["part"] = partition.Mic_Partition
+    commandMap[using_version]["partition"] = partition.Mic_Partition
+    commandMap[using_version]["installerfw_plugins"] = installerfw.Mic_installerfw
+    dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData
+    dataMap[using_version]["Tpk_RepoData"] = micrepo.Mic_Tpk_RepoData
+    dataMap[using_version]["PartData"] = partition.Mic_PartData
+    superclass = ksversion.returnClassForVersion(version=using_version)
+
+    class KSHandlers(superclass):
+        def __init__(self):
+            superclass.__init__(self, mapping=commandMap[using_version])
+            self.prepackages = ksparser.Packages()
+            self.attachment = ksparser.Packages()
+
+    ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
+    ks.registerSection(PrepackageSection(ks.handler))
+    ks.registerSection(AttachmentSection(ks.handler))
+    ks.registerSection(EnvSection(ks.handler))
+
+    try:
+        ks.readKickstart(path)
+    except (kserrors.KickstartParseError, kserrors.KickstartError) as 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
+
+class KickstartConfig(object):
+    """A base class for applying kickstart configurations to a system."""
+    def __init__(self, instroot):
+        self.instroot = instroot
+
+    def path(self, subpath):
+        return self.instroot + subpath
+
+    def _check_sysconfig(self):
+        if not os.path.exists(self.path("/etc/sysconfig")):
+            fs.makedirs(self.path("/etc/sysconfig"))
+
+    def chroot(self):
+        os.chroot(self.instroot)
+        os.chdir("/")
+
+    def call(self, args):
+        if not os.path.exists("%s/%s" %(self.instroot, args[0])):
+            raise errors.KsError("Can't find %s in chroot" % args[0])
+        subprocess.call(args, preexec_fn = self.chroot)
+
+    def apply(self):
+        pass
+
+class LanguageConfig(KickstartConfig):
+    """A class to apply a kickstart language configuration to a system."""
+    @apply_wrapper
+    def apply(self, kslang):
+        self._check_sysconfig()
+        if kslang.lang:
+            f = open(self.path("/etc/sysconfig/i18n"), "w+")
+            f.write("LANG=\"" + kslang.lang + "\"\n")
+            f.close()
+
+            f = open(self.path("/etc/locale.conf"), "w+")
+            f.write("LANG=\"" + kslang.lang + "\"\n")
+            f.close()
+
+            #cp ks lang setting to other file, then can access the file in %post section
+            fs.makedirs(self.path("/etc/config"))
+            f = open(self.path("/etc/config/mic_language"), "w+")
+            f.write("LANG=\"" + kslang.lang + "\"\n")
+            f.close()
+
+class KeyboardConfig(KickstartConfig):
+    """A class to apply a kickstart keyboard configuration to a system."""
+    @apply_wrapper
+    def apply(self, kskeyboard):
+        #
+        # FIXME:
+        #   should this impact the X keyboard config too?
+        #   or do we want to make X be able to do this mapping?
+        #
+        #k = rhpl.keyboard.Keyboard()
+        #if kskeyboard.keyboard:
+        #   k.set(kskeyboard.keyboard)
+        #k.write(self.instroot)
+        pass
+
+class TimezoneConfig(KickstartConfig):
+    """A class to apply a kickstart timezone configuration to a system."""
+    @apply_wrapper
+    def apply(self, kstimezone):
+        self._check_sysconfig()
+        tz = kstimezone.timezone or "America/New_York"
+        utc = str(kstimezone.isUtc)
+
+        f = open(self.path("/etc/sysconfig/clock"), "w+")
+        f.write("ZONE=\"" + tz + "\"\n")
+        f.write("UTC=" + utc + "\n")
+        f.close()
+        if not os.path.exists("/opt/etc"):
+            fs.makedirs("/opt/etc")
+        tz_source = "/usr/share/zoneinfo/%s" % (tz)
+        tz_midst = "/opt/etc/localtime"
+        tz_dest = "/etc/localtime"
+        try:
+            lncmd = fs.find_binary_inchroot('ln', self.instroot)
+            if lncmd:
+                self.call([lncmd, "-s", tz_source, tz_midst])
+                self.call([lncmd, "-s", tz_midst, tz_dest])
+            else:
+                lncmd = fs.find_binary_path('ln')
+                subprocess.call([lncmd, "-s",
+                                 self.path(tz_source),
+                                 self.path(tz_midst)])
+                subprocess.call([lncmd, "-s",
+                                 self.path(tz_midst),
+                                 self.path(tz_dest)])
+        except (IOError, OSError) as msg:
+            raise errors.KsError("Timezone setting error: %s" % msg)
+
+class AuthConfig(KickstartConfig):
+    """A class to apply a kickstart authconfig configuration to a system."""
+    @apply_wrapper
+    def apply(self, ksauthconfig):
+        auth = ksauthconfig.authconfig or "--useshadow --enablemd5"
+        args = ["/usr/share/authconfig/authconfig.py", "--update", "--nostart"]
+        self.call(args + auth.split())
+
+class FirewallConfig(KickstartConfig):
+    """A class to apply a kickstart firewall configuration to a system."""
+    @apply_wrapper
+    def apply(self, ksfirewall):
+        #
+        # FIXME: should handle the rest of the options
+        #
+        if not os.path.exists(self.path("/usr/sbin/lokkit")):
+            return
+        if ksfirewall.enabled:
+            status = "--enabled"
+        else:
+            status = "--disabled"
+
+        self.call(["/usr/sbin/lokkit",
+                   "-f", "--quiet", "--nostart", status])
+
+class RootPasswordConfig(KickstartConfig):
+    """A class to apply a kickstart root password configuration to a system."""
+    def unset(self):
+        self.call(["/usr/bin/passwd", "-d", "root"])
+
+    def set_encrypted(self, password):
+        self.call(["/usr/sbin/usermod", "-p", password, "root"])
+
+    def set_unencrypted(self, password):
+        for p in ("/bin/echo", "/usr/sbin/chpasswd"):
+            if not os.path.exists("%s/%s" %(self.instroot, p)):
+                raise errors.KsError("Unable to set unencrypted password due "
+                                     "to lack of %s" % p)
+
+        p1 = subprocess.Popen(["/bin/echo", "root:%s" %password],
+                              stdout = subprocess.PIPE,
+                              preexec_fn = self.chroot)
+        p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-c","SHA512"],
+                              stdin = p1.stdout,
+                              stdout = subprocess.PIPE,
+                              preexec_fn = self.chroot)
+        p2.communicate()
+
+    @apply_wrapper
+    def apply(self, ksrootpw):
+        if ksrootpw.isCrypted:
+            self.set_encrypted(ksrootpw.password)
+        elif ksrootpw.password != "":
+            self.set_unencrypted(ksrootpw.password)
+        else:
+            self.unset()
+
+class UserConfig(KickstartConfig):
+    def set_empty_passwd(self, user):
+        self.call(["/usr/bin/passwd", "-d", user])
+
+    def set_encrypted_passwd(self, user, password):
+        self.call(["/usr/sbin/usermod", "-p", "%s" % password, user])
+
+    def set_unencrypted_passwd(self, user, password):
+        for p in ("/bin/echo", "/usr/sbin/chpasswd"):
+            if not os.path.exists("%s/%s" %(self.instroot, p)):
+                raise errors.KsError("Unable to set unencrypted password due "
+                                     "to lack of %s" % p)
+
+        p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)],
+                              stdout = subprocess.PIPE,
+                              preexec_fn = self.chroot)
+        p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-c","SHA512"],
+                              stdin = p1.stdout,
+                              stdout = subprocess.PIPE,
+                              preexec_fn = self.chroot)
+        p2.communicate()
+
+    def addUser(self, userconfig):
+        args = [ "/usr/sbin/useradd" ]
+        if userconfig.groups:
+            args += [ "--groups", string.join(userconfig.groups, ",") ]
+        if userconfig.name:
+            args += [ "-m"]
+            args += [ "-d", "/home/%s" % userconfig.name  ]
+            args.append(userconfig.name)
+            try:
+                dev_null = os.open("/dev/null", os.O_WRONLY)
+                msger.debug('adding user with %s' % args)
+                subprocess.call(args,
+                                 stdout = dev_null,
+                                 stderr = dev_null,
+                                 preexec_fn = self.chroot)
+                os.close(dev_null)
+            except:
+                msger.warning('Cannot add user using "useradd"')
+
+            if userconfig.password not in (None, ""):
+                if userconfig.isCrypted:
+                    self.set_encrypted_passwd(userconfig.name,
+                                              userconfig.password)
+                else:
+                    self.set_unencrypted_passwd(userconfig.name,
+                                                userconfig.password)
+            else:
+                self.set_empty_passwd(userconfig.name)
+        else:
+            raise errors.KsError("Invalid kickstart command: %s" \
+                                 % userconfig.__str__())
+
+    @apply_wrapper
+    def apply(self, user):
+        for userconfig in user.userList:
+            #There exist root user already.
+            if userconfig.name == "root":
+                msger.debug("root user, just set root user groups attribution")
+                if userconfig.groups:
+                    self.call(["/usr/sbin/usermod", "-a", "-G", "%s" % string.join(userconfig.groups, ","), "root"])
+                continue
+            self.addUser(userconfig)
+
+class ServicesConfig(KickstartConfig):
+    """A class to apply a kickstart services configuration to a system."""
+    @apply_wrapper
+    def apply(self, ksservices):
+        if not os.path.exists(self.path("/sbin/chkconfig")):
+            return
+        for s in ksservices.enabled:
+            self.call(["/sbin/chkconfig", s, "on"])
+        for s in ksservices.disabled:
+            self.call(["/sbin/chkconfig", s, "off"])
+
+class XConfig(KickstartConfig):
+    """A class to apply a kickstart X configuration to a system."""
+    @apply_wrapper
+    def apply(self, ksxconfig):
+        if ksxconfig.startX and os.path.exists(self.path("/etc/inittab")):
+            f = open(self.path("/etc/inittab"), "r+")
+            buf = f.read()
+            buf = buf.replace("id:3:initdefault", "id:5:initdefault")
+            f.seek(0)
+            f.write(buf)
+            f.close()
+        if ksxconfig.defaultdesktop:
+            self._check_sysconfig()
+            f = open(self.path("/etc/sysconfig/desktop"), "w")
+            f.write("DESKTOP="+ksxconfig.defaultdesktop+"\n")
+            f.close()
+
+class DesktopConfig(KickstartConfig):
+    """A class to apply a kickstart desktop configuration to a system."""
+    @apply_wrapper
+    def apply(self, ksdesktop):
+        if ksdesktop.defaultdesktop:
+            self._check_sysconfig()
+            f = open(self.path("/etc/sysconfig/desktop"), "w")
+            f.write("DESKTOP="+ksdesktop.defaultdesktop+"\n")
+            f.close()
+            if os.path.exists(self.path("/etc/gdm/custom.conf")):
+                f = open(self.path("/etc/skel/.dmrc"), "w")
+                f.write("[Desktop]\n")
+                f.write("Session="+ksdesktop.defaultdesktop.lower()+"\n")
+                f.close()
+        if ksdesktop.session:
+            if os.path.exists(self.path("/etc/sysconfig/uxlaunch")):
+                f = open(self.path("/etc/sysconfig/uxlaunch"), "a+")
+                f.write("session="+ksdesktop.session.lower()+"\n")
+                f.close()
+        if ksdesktop.autologinuser:
+            self._check_sysconfig()
+            f = open(self.path("/etc/sysconfig/desktop"), "a+")
+            f.write("AUTOLOGIN_USER=" + ksdesktop.autologinuser + "\n")
+            f.close()
+            if os.path.exists(self.path("/etc/gdm/custom.conf")):
+                f = open(self.path("/etc/gdm/custom.conf"), "w")
+                f.write("[daemon]\n")
+                f.write("AutomaticLoginEnable=true\n")
+                f.write("AutomaticLogin=" + ksdesktop.autologinuser + "\n")
+                f.close()
+
+class MoblinRepoConfig(KickstartConfig):
+    """A class to apply a kickstart desktop configuration to a system."""
+    def __create_repo_section(self, repo, type, fd):
+        baseurl = None
+        mirrorlist = None
+        reposuffix = {"base":"", "debuginfo":"-debuginfo", "source":"-source"}
+        reponame = repo.name + reposuffix[type]
+        if type == "base":
+            if repo.baseurl:
+                baseurl = repo.baseurl
+            if repo.mirrorlist:
+                mirrorlist = repo.mirrorlist
+
+        elif type == "debuginfo":
+            if repo.baseurl:
+                if repo.baseurl.endswith("/"):
+                    baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
+                else:
+                    baseurl = os.path.dirname(repo.baseurl)
+                baseurl += "/debug"
+
+            if repo.mirrorlist:
+                variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
+                mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
+                mirrorlist += "debug" + "-" + variant
+
+        elif type == "source":
+            if repo.baseurl:
+                if repo.baseurl.endswith("/"):
+                    baseurl = os.path.dirname(
+                                 os.path.dirname(
+                                    os.path.dirname(repo.baseurl)))
+                else:
+                    baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
+                baseurl += "/source"
+
+            if repo.mirrorlist:
+                variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
+                mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
+                mirrorlist += "source" + "-" + variant
+
+        fd.write("[" + reponame + "]\n")
+        fd.write("name=" + reponame + "\n")
+        fd.write("failovermethod=priority\n")
+        if baseurl:
+            auth_url = re.compile(AUTH_URL_PTN)
+            m = auth_url.match(baseurl)
+            if m:
+                baseurl = "%s://%s" % (m.group('scheme'), m.group('url'))
+            fd.write("baseurl=" + baseurl + "\n")
+        if mirrorlist:
+            fd.write("mirrorlist=" + mirrorlist + "\n")
+        """ Skip saving proxy settings """
+        #if repo.proxy:
+        #    fd.write("proxy=" + repo.proxy + "\n")
+        #if repo.proxy_username:
+        #    fd.write("proxy_username=" + repo.proxy_username + "\n")
+        #if repo.proxy_password:
+        #    fd.write("proxy_password=" + repo.proxy_password + "\n")
+        if repo.gpgkey:
+            fd.write("gpgkey=" + repo.gpgkey + "\n")
+            fd.write("gpgcheck=1\n")
+        else:
+            fd.write("gpgcheck=0\n")
+        if type == "source" or type == "debuginfo" or repo.disable:
+            fd.write("enabled=0\n")
+        else:
+            fd.write("enabled=1\n")
+        fd.write("\n")
+
+    def __create_repo_file(self, repo, repodir):
+        fs.makedirs(self.path(repodir))
+        f = open(self.path(repodir + "/" + repo.name + ".repo"), "w")
+        self.__create_repo_section(repo, "base", f)
+        if repo.debuginfo:
+            self.__create_repo_section(repo, "debuginfo", f)
+        if repo.source:
+            self.__create_repo_section(repo, "source", f)
+        f.close()
+
+    @apply_wrapper
+    def apply(self, ksrepo, repodata, repourl):
+        for repo in ksrepo.repoList:
+            if repo.name in repourl:
+                repo.baseurl = repourl[repo.name]
+            if repo.save:
+                #self.__create_repo_file(repo, "/etc/yum.repos.d")
+                self.__create_repo_file(repo, "/etc/zypp/repos.d")
+        """ Import repo gpg keys """
+        if repodata:
+            for repo in repodata:
+                if repo['repokey']:
+                    runner.quiet(['rpm',
+                                  "--root=%s" % self.instroot,
+                                  "--import",
+                                  repo['repokey']])
+
+class RPMMacroConfig(KickstartConfig):
+    """A class to apply the specified rpm macros to the filesystem"""
+    @apply_wrapper
+    def apply(self, ks):
+        if not ks:
+            return
+        if not os.path.exists(self.path("/etc/rpm")):
+            os.mkdir(self.path("/etc/rpm"))
+        f = open(self.path("/etc/rpm/macros.imgcreate"), "w+")
+        if exclude_docs(ks):
+            f.write("%_excludedocs 1\n")
+        f.write("%__file_context_path %{nil}\n")
+        if inst_langs(ks) != None:
+            f.write("%_install_langs ")
+            f.write(inst_langs(ks))
+            f.write("\n")
+        f.close()
+
+class NetworkConfig(KickstartConfig):
+    """A class to apply a kickstart network configuration to a system."""
+    def write_ifcfg(self, network):
+        p = self.path("/etc/sysconfig/network-scripts/ifcfg-" + network.device)
+
+        f = file(p, "w+")
+        os.chmod(p, 0o644)
+
+        f.write("DEVICE=%s\n" % network.device)
+        f.write("BOOTPROTO=%s\n" % network.bootProto)
+
+        if network.bootProto.lower() == "static":
+            if network.ip:
+                f.write("IPADDR=%s\n" % network.ip)
+            if network.netmask:
+                f.write("NETMASK=%s\n" % network.netmask)
+
+        if network.onboot:
+            f.write("ONBOOT=on\n")
+        else:
+            f.write("ONBOOT=off\n")
+
+        if network.essid:
+            f.write("ESSID=%s\n" % network.essid)
+
+        if network.ethtool:
+            if network.ethtool.find("autoneg") == -1:
+                network.ethtool = "autoneg off " + network.ethtool
+            f.write("ETHTOOL_OPTS=%s\n" % network.ethtool)
+
+        if network.bootProto.lower() == "dhcp":
+            if network.hostname:
+                f.write("DHCP_HOSTNAME=%s\n" % network.hostname)
+            if network.dhcpclass:
+                f.write("DHCP_CLASSID=%s\n" % network.dhcpclass)
+
+        if network.mtu:
+            f.write("MTU=%s\n" % network.mtu)
+
+        f.close()
+
+    def write_wepkey(self, network):
+        if not network.wepkey:
+            return
+
+        p = self.path("/etc/sysconfig/network-scripts/keys-" + network.device)
+        f = file(p, "w+")
+        os.chmod(p, 0o600)
+        f.write("KEY=%s\n" % network.wepkey)
+        f.close()
+
+    def write_sysconfig(self, useipv6, hostname, gateway):
+        path = self.path("/etc/sysconfig/network")
+        f = file(path, "w+")
+        os.chmod(path, 0o644)
+
+        f.write("NETWORKING=yes\n")
+
+        if useipv6:
+            f.write("NETWORKING_IPV6=yes\n")
+        else:
+            f.write("NETWORKING_IPV6=no\n")
+
+        if hostname:
+            f.write("HOSTNAME=%s\n" % hostname)
+        else:
+            f.write("HOSTNAME=localhost.localdomain\n")
+
+        if gateway:
+            f.write("GATEWAY=%s\n" % gateway)
+
+        f.close()
+
+    def write_hosts(self, hostname):
+        localline = ""
+        if hostname and hostname != "localhost.localdomain":
+            localline += hostname + " "
+            l = hostname.split(".")
+            if len(l) > 1:
+                localline += l[0] + " "
+        localline += "localhost.localdomain localhost"
+
+        path = self.path("/etc/hosts")
+        f = file(path, "w+")
+        os.chmod(path, 0o644)
+        f.write("127.0.0.1\t\t%s\n" % localline)
+        f.write("::1\t\tlocalhost6.localdomain6 localhost6\n")
+        f.close()
+
+    def write_resolv(self, nodns, nameservers):
+        if nodns or not nameservers:
+            return
+
+        path = self.path("/etc/resolv.conf")
+        f = file(path, "w+")
+        os.chmod(path, 0o644)
+
+        for ns in (nameservers):
+            if ns:
+                f.write("nameserver %s\n" % ns)
+
+        f.close()
+
+    @apply_wrapper
+    def apply(self, ksnet):
+        fs.makedirs(self.path("/etc/sysconfig/network-scripts"))
+
+        useipv6 = False
+        nodns = False
+        hostname = None
+        gateway = None
+        nameservers = None
+
+        for network in ksnet.network:
+            if not network.device:
+                raise errors.KsError("No --device specified with "
+                                            "network kickstart command")
+
+            if (network.onboot and network.bootProto.lower() != "dhcp" and
+                not (network.ip and network.netmask)):
+                raise errors.KsError("No IP address and/or netmask "
+                                            "specified with static "
+                                            "configuration for '%s'" %
+                                            network.device)
+
+            self.write_ifcfg(network)
+            self.write_wepkey(network)
+
+            if network.ipv6:
+                useipv6 = True
+            if network.nodns:
+                nodns = True
+
+            if network.hostname:
+                hostname = network.hostname
+            if network.gateway:
+                gateway = network.gateway
+
+            if network.nameserver:
+                nameservers = network.nameserver.split(",")
+
+        self.write_sysconfig(useipv6, hostname, gateway)
+
+        #to avoid import error because of import each other
+        from mic.conf import configmgr
+        path=self.path("/etc/hosts")
+        if configmgr.create['skip_set_hosts'] == False and os.path.exists(path) == False:
+            self.write_hosts(hostname)
+        self.write_resolv(nodns, nameservers)
+
+def use_installerfw(ks, feature):
+    """ Check if the installer framework has to be used for a feature
+    "feature". """
+
+    features = ks.handler.installerfw.features
+    if features:
+        if feature in features or "all" in features:
+            return True
+    return False
+
+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) * 1024 * 1024
+    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_modules(ks):
+    devices = []
+    if isinstance(ks.handler.device, kscommands.device.FC3_Device):
+        devices.append(ks.handler.device)
+    else:
+        devices.extend(ks.handler.device.deviceList)
+
+    modules = []
+    for device in devices:
+        if not device.moduleName:
+            continue
+        modules.extend(device.moduleName.split(":"))
+
+    return modules
+
+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
+
+RepoType = collections.namedtuple("Repo",
+               "name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy, \
+               proxy_username, proxy_password, debuginfo, \
+               source, gpgkey, disable, ssl_verify, nocache, \
+               cost, priority")
+
+def Repo(name, baseurl, mirrorlist=None, includepkgs=[], excludepkgs=[], proxy=None,
+         proxy_username=None, proxy_password=None, debuginfo=None,
+         source=None, gpgkey=None, disable=None, ssl_verify=None,
+         nocache=False, cost=None, priority=None):
+    return RepoType(name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy,
+                    proxy_username, proxy_password, debuginfo,
+                    source, gpgkey, disable, ssl_verify, nocache,
+                    cost, priority)
+
+
+def get_repos(ks, repo_urls=None, ignore_ksrepo=False):
+    repos = {}
+    for repodata in ks.handler.repo.repoList:
+        repo = {}
+        for field in RepoType._fields:
+            if hasattr(repodata, field) and getattr(repodata, field):
+                repo[field] = getattr(repodata, field)
+
+        if hasattr(repodata, 'baseurl') and getattr(repodata, 'baseurl'):
+            repo['baseurl'] = SafeURL(getattr(repodata, 'baseurl'),
+                                      getattr(repodata, 'user', None),
+                                      getattr(repodata, 'passwd', None))
+
+        if 'name' in repo:
+            repos[repo['name']] = Repo(**repo)
+
+    if repo_urls:
+        if ignore_ksrepo:
+            repos = {}
+        for name, repo in repo_urls.items():
+            if 'baseurl' in repo:
+                repo['baseurl'] = SafeURL(repo.get('baseurl'),
+                                          repo.get('user', None),
+                                          repo.get('passwd', None))
+            repos[name] = Repo(**repo)
+    return repos.values()
+
+TpkRepoType = collections.namedtuple("TpkRepo",
+               "name, baseurl,proxy,proxy_username,proxy_password,ssl_verify")
+
+def TpkRepo(name, baseurl, proxy=None,proxy_username=None, proxy_password=None,ssl_verify=None):
+    return TpkRepoType(name, baseurl,proxy,proxy_username,proxy_password,ssl_verify)
+
+
+def get_tpkrepos(ks):
+    tpkrepos = {}
+    for tpkrepodata in ks.handler.tpk_repo.tpkRepoList:
+        tpkrepo = {}
+        for field in TpkRepoType._fields:
+            if hasattr(tpkrepodata, field) and getattr(tpkrepodata, field):
+                tpkrepo[field] = getattr(tpkrepodata, field)
+
+        if hasattr(tpkrepodata, 'baseurl') and getattr(tpkrepodata, 'baseurl'):
+            tpkrepo['baseurl'] = SafeURL(getattr(tpkrepodata, 'baseurl'),getattr(tpkrepodata, 'user',None),getattr(tpkrepodata, 'passwd',None))
+
+        if 'name' in tpkrepo:
+            tpkrepos[tpkrepo['name']] = TpkRepo(**tpkrepo)
+
+    return tpkrepos.values()
+
+
+def convert_method_to_repo(ks):
+    try:
+        ks.handler.repo.methodToRepo()
+    except (AttributeError, kserrors.KickstartError):
+        pass
+
+def get_attachment(ks, required=()):
+    return ks.handler.attachment.packageList + list(required)
+
+def get_env(ks, required=()):
+    return ks.handler.env
+
+def get_pre_packages(ks, required=()):
+    return ks.handler.prepackages.packageList + list(required)
+
+def get_packages(ks, required=()):
+    return ks.handler.packages.packageList + list(required)
+
+def get_tpkpackages(ks):
+    return ks.handler.tpk_packages.tpk_packageList
+
+def get_groups(ks, required=()):
+    return ks.handler.packages.groupList + list(required)
+
+def get_excluded(ks, required=()):
+    return ks.handler.packages.excludedList + list(required)
+
+def get_partitions(ks):
+    return ks.handler.partition.partitions
+
+def ignore_missing(ks):
+    return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE
+
+def exclude_docs(ks):
+    return ks.handler.packages.excludeDocs
+
+def inst_langs(ks):
+    if hasattr(ks.handler.packages, "instLange"):
+        return ks.handler.packages.instLange
+    elif hasattr(ks.handler.packages, "instLangs"):
+        return ks.handler.packages.instLangs
+    return ""
+
+def get_post_scripts(ks):
+    scripts = []
+    for s in ks.handler.scripts:
+        if s.type != ksparser.KS_SCRIPT_POST:
+            continue
+        scripts.append(s)
+    return scripts
+
+def get_sign_scripts(ks):
+    scripts = []
+    for s in ks.handler.scripts:
+        if (s.type == ksparser.KS_SCRIPT_RUN or \
+            s.type == ksparser.KS_SCRIPT_UMOUNT):
+            scripts.append(s)
+    return scripts
+
+def add_repo(ks, repostr):
+    args = repostr.split()
+    repoobj = ks.handler.repo.parse(args[1:])
+    if repoobj and repoobj not in ks.handler.repo.repoList:
+        ks.handler.repo.repoList.append(repoobj)
+
+def remove_all_repos(ks):
+    while len(ks.handler.repo.repoList) != 0:
+        del ks.handler.repo.repoList[0]
+
+def remove_duplicate_repos(ks):
+    i = 0
+    j = i + 1
+    while True:
+        if len(ks.handler.repo.repoList) < 2:
+            break
+        if i >= len(ks.handler.repo.repoList) - 1:
+            break
+        name = ks.handler.repo.repoList[i].name
+        baseurl = ks.handler.repo.repoList[i].baseurl
+        if j < len(ks.handler.repo.repoList):
+            if (ks.handler.repo.repoList[j].name == name or \
+                ks.handler.repo.repoList[j].baseurl == baseurl):
+                del ks.handler.repo.repoList[j]
+            else:
+                j += 1
+            if j >= len(ks.handler.repo.repoList):
+                i += 1
+                j = i + 1
+        else:
+            i += 1
+            j = i + 1
+
+def resolve_groups(creatoropts, repometadata):
+    iszypp = False
+    if 'zypp' == creatoropts['pkgmgr']:
+        iszypp = True
+    ks = creatoropts['ks']
+
+    for repo in repometadata:
+        """ Mustn't replace group with package list if repo is ready for the
+            corresponding package manager.
+        """
+
+        if iszypp and repo["patterns"]:
+            continue
+        if not iszypp and repo["comps"]:
+            continue
+
+        # But we also must handle such cases, use zypp but repo only has comps,
+        # use yum but repo only has patterns, use zypp but use_comps is true,
+        # use yum but use_comps is false.
+        groupfile = None
+        if iszypp and repo["comps"]:
+            groupfile = repo["comps"]
+            get_pkglist_handler = misc.get_pkglist_in_comps
+        if not iszypp and repo["patterns"]:
+            groupfile = repo["patterns"]
+            get_pkglist_handler = misc.get_pkglist_in_patterns
+
+        if groupfile:
+            i = 0
+            while True:
+                if i >= len(ks.handler.packages.groupList):
+                    break
+                pkglist = get_pkglist_handler(
+                                        ks.handler.packages.groupList[i].name,
+                                        groupfile)
+                if pkglist:
+                    del ks.handler.packages.groupList[i]
+                    for pkg in pkglist:
+                        if pkg not in ks.handler.packages.packageList:
+                            ks.handler.packages.packageList.append(pkg)
+                else:
+                    i = i + 1
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/__init__.py
new file mode 100644 (file)
index 0000000..381c917
--- /dev/null
@@ -0,0 +1,14 @@
+from desktop import Mic_Desktop
+from micrepo import Mic_Repo, Mic_RepoData,Mic_Tpk_Repo, Mic_Tpk_RepoData
+from partition import Mic_Partition
+from installerfw import Mic_installerfw
+
+__all__ = (
+    "Mic_Desktop",
+    "Mic_Repo",
+    "Mic_RepoData",
+    "Mic_Tpk_Repo",
+    "Mic_Tpk_RepoData",
+    "Mic_Partition",
+    "Mic_installerfw",
+)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/desktop.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/desktop.py
new file mode 100644 (file)
index 0000000..a2359b3
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/python -tt
+#
+# Copyright (c) 2008, 2009, 2010 Intel, Inc.
+#
+# Yi Yang <yi.y.yang@intel.com>
+#
+# 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 *
+
+class Mic_Desktop(KickstartCommand):
+    def __init__(self, writePriority=0,
+                       defaultdesktop=None,
+                       defaultdm=None,
+                       autologinuser=None,
+                       session=None):
+
+        KickstartCommand.__init__(self, writePriority)
+
+        self.__new_version = False
+        self.op = self._getParser()
+
+        self.defaultdesktop = defaultdesktop
+        self.autologinuser = autologinuser
+        self.defaultdm = defaultdm
+        self.session = session
+
+    def __str__(self):
+        retval = ""
+
+        if self.defaultdesktop != None:
+            retval += " --defaultdesktop=%s" % self.defaultdesktop
+        if self.session != None:
+            retval += " --session=\"%s\"" % self.session
+        if self.autologinuser != None:
+            retval += " --autologinuser=%s" % self.autologinuser
+        if self.defaultdm != None:
+            retval += " --defaultdm=%s" % self.defaultdm
+
+        if retval != "":
+            retval = "# Default Desktop Settings\ndesktop %s\n" % retval
+
+        return retval
+
+    def _getParser(self):
+        try:
+            #ingnore this pylit error, the lineno argument exist in olg version. using this way can compate old version.
+            op = KSOptionParser(lineno=self.lineno)  #pylint: disable=unexpected-keyword-arg
+        except TypeError:
+            # the latest version has not lineno argument
+            op = KSOptionParser()
+            self.__new_version = True
+
+        op.add_option("--defaultdesktop", dest="defaultdesktop",
+                                          action="store",
+                                          type="string",
+                                          nargs=1)
+        op.add_option("--autologinuser", dest="autologinuser",
+                                         action="store",
+                                         type="string",
+                                         nargs=1)
+        op.add_option("--defaultdm", dest="defaultdm",
+                                     action="store",
+                                     type="string",
+                                     nargs=1)
+        op.add_option("--session", dest="session",
+                                   action="store",
+                                   type="string",
+                                   nargs=1)
+        return op
+
+    def parse(self, args):
+        if self.__new_version:
+            (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        else:
+            (opts, extra) = self.op.parse_args(args=args)
+
+        if extra:
+            m = ("Unexpected arguments to %(command)s command: %(options)s") \
+                  % {"command": "desktop", "options": extra}
+            raise KickstartValueError  (formatErrorMsg(self.lineno, msg=m))
+
+        self._setToSelf(self.op, opts)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/installerfw.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/installerfw.py
new file mode 100644 (file)
index 0000000..01deb76
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/python -tt
+#
+# Copyright (c) 2013 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 pykickstart.base import *
+from pykickstart.options import *
+from mic import msger
+
+class Mic_installerfw(KickstartCommand):
+    """ This class implements the "installerfw_plugins" KS option. The argument
+    of the option is a comman-separated list of MIC features which have to be
+    disabled and instead, will be done in the installer. For example,
+    "installerfw_plugins=bootloader" disables all the MIC code which installs
+    the bootloader to the target images, and instead, the bootlodaer will be
+    installed by the installer framework plugin.
+
+    The plugin is a program which is external to MIC, it comes from the
+    installation repositories and can be executed by MIC in order to perform
+    various configuration actions. The main point here is to make sure MIC has
+    no hard-wired knoledge about the target OS configuration. """
+
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        KickstartCommand.__init__(self, *args, **kwargs)
+        self.op = self._getParser()
+        self.features = None
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.features:
+            retval += "# Enable installer framework plugins\ninstallerfw_plugins\n"
+
+        return retval
+
+    def _getParser(self):
+        op = KSOptionParser()
+        return op
+
+    def parse(self, args):
+        (_, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        if len(extra) != 1:
+            msg = "Kickstart command \"%s\" requires one " \
+                  "argumet - a list of legacy features to disable" % self.currentCmd
+            raise KickstartValueError  (formatErrorMsg(self.lineno, msg = msg))
+
+        self.features = extra[0].split(",")
+
+        return self
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micboot.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micboot.py
new file mode 100644 (file)
index 0000000..66d1678
--- /dev/null
@@ -0,0 +1,49 @@
+#!/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/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micrepo.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/micrepo.py
new file mode 100644 (file)
index 0000000..25cdae9
--- /dev/null
@@ -0,0 +1,97 @@
+#
+# Copyright (c) 2008, 2009, 2010 Intel, Inc.
+#
+# Yi Yang <yi.y.yang@intel.com>
+#
+# 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.commands.repo import F14_RepoData, F14_Repo
+
+
+class Mic_RepoData(F14_RepoData):
+    "Mic customized repo data"
+
+    def __init__(self, *args, **kw):
+        F14_RepoData.__init__(self, *args, **kw)
+        for field in ('save', 'proxyuser', 'proxypasswd', 'debuginfo',
+                      'disable', 'source', 'gpgkey', 'ssl_verify', 'priority',
+                      'nocache', 'user', 'passwd'):
+            setattr(self, field, kw.get(field))
+
+        if hasattr(self, 'proxy') and not self.proxy:
+            # TODO: remove this code, since it only for back-compatible.
+            # Some code behind only accept None but not empty string
+            # for default proxy
+            self.proxy = None
+
+    def _getArgsAsStr(self):
+        retval = F14_RepoData._getArgsAsStr(self)
+
+        for field in ('proxyuser', 'proxypasswd', 'user', 'passwd',
+                      'gpgkey', 'ssl_verify', 'priority',
+                      ):
+            if hasattr(self, field) and getattr(self, field):
+                retval += ' --%s="%s"' % (field, getattr(self, field))
+
+        for field in ('save', 'diable', 'nocache', 'source', 'debuginfo'):
+            if hasattr(self, field) and getattr(self, field):
+                retval += ' --%s' % field
+
+        return retval
+
+class Mic_Tpk_RepoData(Mic_RepoData):
+    "Mic customized tpk repo data"
+    def __init__(self, *args, **kw):
+        Mic_RepoData.__init__(self, *args, **kw)
+    def __str__(self):
+        retval = Mic_RepoData._getArgsAsStr(self)
+        retval = "tpk_repo " + retval
+        return retval
+
+class Mic_Repo(F14_Repo):
+    "Mic customized repo command"
+
+    def _getParser(self):
+        op = F14_Repo._getParser(self)
+        op.add_option('--user')
+        op.add_option('--passwd')
+        op.add_option("--proxyuser")
+        op.add_option("--proxypasswd")
+
+        op.add_option("--save", action="store_true", default=False)
+        op.add_option("--debuginfo", action="store_true", default=False)
+        op.add_option("--source", action="store_true", default=False)
+        op.add_option("--disable", action="store_true", default=False)
+        op.add_option("--nocache", action="store_true", default=False)
+
+        op.add_option("--gpgkey")
+        op.add_option("--priority", type="int")
+        op.add_option("--ssl_verify", default=None)
+        return op
+
+
+class Mic_Tpk_Repo(Mic_Repo):
+    def __init__(self, writePriority=0, *args, **kwargs):
+        Mic_Repo.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.tpkRepoList = kwargs.get("tpkRepoList", [])
+
+    def _getParser(self):
+        op = Mic_Repo._getParser(self)
+        return op
+
+    def dataList(self):
+        return self.tpkRepoList
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/partition.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/kickstart/custom_commands/partition.py
new file mode 100644 (file)
index 0000000..b0e9246
--- /dev/null
@@ -0,0 +1,98 @@
+#!/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.f2fsopts = kwargs.get("f2fsopts", None)
+        self.part_type = kwargs.get("part_type", None)
+        self.uuid = kwargs.get("uuid", None)
+        self.exclude_image = kwargs.get("exclude_from_image", False)
+        self.vdfsopts = kwargs.get("vdfsopts", None)
+        self.squashfsopts = kwargs.get("squashfsopts", None)
+        self.squashfsoptions_maxsize = kwargs.get("squashfsoptions_maxsize", None)
+        self.cpioopts = kwargs.get("cpioopts", None)
+        self.no_shrink = kwargs.get("no_shrink", False)
+        self.init_expand = kwargs.get("init_expand", False)
+
+    def _getArgsAsStr(self):
+        retval = FC4_PartData._getArgsAsStr(self)
+
+        if self.align:
+            retval += " --align"
+        if self.extopts:
+            retval += " --extoptions=%s" % self.extopts
+        if self.f2fsopts:
+            retval += " --f2fsoptions=%s" % self.f2fsopts
+        if self.part_type:
+            retval += " --part-type=%s" % self.part_type
+        if self.uuid:
+            retval += " --uuid=%s" % self.uuid
+        if self.exclude_image:
+            retval += " --exclude-from-image"
+        if self.vdfsopts:
+            retval += " --vdfsoptions=%s" % self.vdfsopts
+        if self.squashfsopts:
+            retval += " --squashfsoptions=%s" % self.squashfsopts
+        if self.squashfsoptions_maxsize:
+            retval += " --squashfsoptions_maxsize=%s" % self.squashfsoptions_maxsize
+        if self.cpioopts:
+            retval += " --cpiooptions=%s" % self.cpioopts
+        if self.no_shrink:
+            retval += " --no-shrink"
+        if self.init_expand:
+            retval += " --init-expand"
+        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("--f2fsoptions", type="string", action="store", dest="f2fsopts",
+                      default=None)
+        op.add_option("--part-type", type="string", action="store", dest="part_type",
+                      default=None)
+        op.add_option("--uuid", dest="uuid", action="store", type="string")
+        op.add_option("--exclude-from-image", action="store_true", dest="exclude_image",
+                      default=False)
+        op.add_option("--vdfsoptions", type="string", action="store", dest="vdfsopts",
+                      default=None)
+        op.add_option("--squashfsoptions", type="string", action="store", dest="squashfsopts",
+                      default=None)
+        op.add_option("--squashfsoptions_maxsize", type="string", action="store", dest="squashfsoptions_maxsize",
+                      default=None)
+        op.add_option("--cpiooptions", type="string", action="store", dest="cpioopts",
+                      default=None)
+        op.add_option("--no-shrink", action="store_true", dest="no_shrink", default=False)
+        op.add_option("--init-expand", action="store_true", dest="init_expand", default=False)
+        return op
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/msger.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/msger.py
new file mode 100644 (file)
index 0000000..31ac9bd
--- /dev/null
@@ -0,0 +1,430 @@
+#
+# Copyright (c) 2013 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.
+
+# Following messages should be disabled in pylint:
+#  * Too many instance attributes (R0902)
+#  * Too few public methods (R0903)
+#  * Too many public methods (R0904)
+#  * Anomalous backslash in string (W1401)
+#  * __init__ method from base class %r is not called (W0231)
+#  * __init__ method from a non direct base class %r is called (W0233)
+#  * Invalid name for type (C0103)
+#  * RootLogger has no '%s' member (E1103)
+# pylint: disable=R0902,R0903,R0904,W1401,W0231,W0233,C0103,E1103
+
+""" This logging module is fully compatible with the old msger module, and
+    it supports interactive mode, logs the messages with specified levels
+    to specified stream, can also catch all error messages including the
+    involved 3rd party modules to the logger
+"""
+import os
+import sys
+import logging
+import tempfile
+
+__ALL__ = [
+    'get_loglevel',
+    'set_loglevel',
+    'set_logfile',
+    'enable_interactive',
+    'disable_interactive',
+    'enable_logstderr',
+    'disable_logstderr',
+    'raw',
+    'debug',
+    'verbose',
+    'info',
+    'warning',
+    'error',
+    'select',
+    'choice',
+    'ask',
+    'pause',
+]
+
+
+# define the color constants
+BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(30, 38)
+
+# color sequence for tty terminal
+COLOR_SEQ = "\033[%dm" 
+# reset sequence for tty terminal
+RESET_SEQ = "\033[0m"
+
+# new log level
+RAWTEXT = 25
+VERBOSE = 15
+
+# define colors for log levels
+COLORS = {
+    'DEBUG':    COLOR_SEQ % BLUE,
+    'VERBOSE':  COLOR_SEQ % MAGENTA,
+    'INFO':     COLOR_SEQ % GREEN,
+    'WARNING':  COLOR_SEQ % YELLOW,
+    'ERROR':    COLOR_SEQ % RED,
+}
+
+
+class LevelFilter(logging.Filter):
+    """ A filter that selects logging message with specified level """
+    def __init__(self, levels):
+        self._levels = levels
+
+    def filter(self, record):
+        if self._levels:
+            return record.levelname in self._levels
+        return False
+
+
+class MicStreamHandler(logging.StreamHandler):
+    """ A stream handler that print colorized levelname in tty terminal """
+    def __init__(self, stream=None):
+        logging.StreamHandler.__init__(self, stream)
+        msg_fmt = "%(color)s%(levelname)s:%(reset)s %(message)s"
+        self.setFormatter(logging.Formatter(fmt=msg_fmt))
+
+    def _use_color(self):
+        """ Check if to print in color or not """
+        in_emacs = (os.getenv("EMACS") and
+                    os.getenv("INSIDE_EMACS", "").endswith(",comint"))
+        return self.stream.isatty() and not in_emacs
+
+    def format(self, record):
+        """ Format the logging record if need color """
+        record.color = record.reset = ""
+        if self._use_color():
+            record.color = COLORS[record.levelname]
+            record.reset = RESET_SEQ
+        return logging.StreamHandler.format(self, record)
+
+
+class RedirectedStderr(object):
+    """ A faked error stream that redirect stderr to a temp file """
+    def __init__(self):
+        self.tmpfile = tempfile.NamedTemporaryFile()
+        self.fderr = None
+        self.value = None
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        """ Close the temp file and clear the buffer """
+        try:
+            self.value = None
+            self.tmpfile.close()
+        except OSError:
+            pass
+
+    def truncate(self):
+        """ Truncate the tempfile to size zero """
+        if self.tmpfile:
+            os.ftruncate(self.tmpfile.fileno(), 0)
+            os.lseek(self.tmpfile.fileno(), 0, os.SEEK_SET)
+
+    def redirect(self):
+        """ Redirect stderr to the temp file """
+        self.fderr = os.dup(2)
+        os.dup2(self.tmpfile.fileno(), 2)
+
+    def restore(self):
+        """ Restore the stderr and read the bufferred data """
+        os.dup2(self.fderr, 2)
+        self.fderr = None
+
+        if self.tmpfile:
+            self.tmpfile.seek(0, 0)
+            self.value = self.tmpfile.read()
+
+    def getvalue(self):
+        """ Read the bufferred data """
+        if self.tmpfile:
+            self.tmpfile.seek(0, 0)
+            self.value = self.tmpfile.read()
+            os.ftruncate(self.tmpfile.fileno(), 0)
+            os.lseek(self.tmpfile.fileno(), 0, os.SEEK_SET)
+            return self.value
+        return None
+
+class MicFileHandler(logging.FileHandler):
+    """ This file handler is supposed to catch the stderr output from
+        all modules even 3rd party modules involed, as it redirects
+        the stderr stream to a temp file stream, if logfile assigned,
+        it will flush the record to file stream, else it's a buffer
+        handler; once logfile assigned, the buffer will be flushed
+    """
+    def __init__(self, filename=None, mode='w', encoding=None, capacity=10):
+        # we don't use FileHandler to initialize,
+        # because filename might be expected to None
+        logging.Handler.__init__(self)
+        self.stream = None
+        if filename:
+            self.baseFilename = os.path.abspath(filename)
+        else:
+            self.baseFilename = None
+        self.mode = mode
+        self.encoding = None
+        self.capacity = capacity
+        # buffering the records
+        self.buffer = []
+
+        # set formater locally
+        msg_fmt = "[%(asctime)s] %(message)s"
+        date_fmt = "%m/%d %H:%M:%S %Z"
+        self.setFormatter(logging.Formatter(fmt=msg_fmt, datefmt=date_fmt))
+        self.olderr = sys.stderr
+        self.stderr = RedirectedStderr()
+        self.errmsg = None
+
+    def set_logfile(self, filename, mode='w'):
+        """ Set logfile path to make it possible flush records not-on-fly """
+        self.baseFilename = os.path.abspath(filename)
+        self.mode = mode
+
+    def redirect_stderr(self):
+        """ Start to redirect stderr for catching all error output """
+        self.stderr.redirect()
+
+    def restore_stderr(self):
+        """ Restore stderr stream and log the error messages to both stderr
+            and log file if error messages are not empty
+        """
+        self.stderr.restore()
+        self.errmsg = self.stderr.value
+        if self.errmsg:
+            self.logstderr()
+
+    def logstderr(self):
+        """ Log catched error message from stderr redirector """
+        if not self.errmsg:
+            return
+
+        sys.stdout.write(self.errmsg)
+        sys.stdout.flush()
+
+        record = logging.makeLogRecord({'msg': self.errmsg})
+        self.buffer.append(record)
+
+        # truncate the redirector for the errors is logged
+        self.stderr.truncate()
+        self.errmsg = None
+
+    def emit(self, record):
+        """ Emit the log record to Handler """
+        # if there error message catched, log it first
+        self.errmsg = self.stderr.getvalue()
+        if self.errmsg:
+            self.logstderr()
+
+        # if no logfile assigned, it's a buffer handler
+        if not self.baseFilename:
+            self.buffer.append(record)
+            if len(self.buffer) >= self.capacity:
+                self.buffer = []
+        else:
+            self.flushing(record)
+
+    def flushing(self, record=None):
+        """ Flush buffer and record to logfile """
+        # NOTE: 'flushing' can't be named 'flush' because of 'emit' calling it
+        # set file stream position to SEEK_END(=2)
+        if self.stream:
+            self.stream.seek(0, 2)
+        # if bufferred, flush it
+        if self.buffer:
+            for arecord in self.buffer:
+                logging.FileHandler.emit(self, arecord)
+            self.buffer = []
+        # if recorded, flush it
+        if record:
+            logging.FileHandler.emit(self, record)
+
+    def close(self):
+        """ Close handler after flushing the buffer """
+        # if any left in buffer, flush it
+        if self.stream:
+            self.flushing()
+        logging.FileHandler.close(self)
+
+
+class MicLogger(logging.Logger):
+    """ The MIC logger class, it supports interactive mode, and logs the
+        messages with specified levels tospecified stream, also can catch
+        all error messages including the involved 3rd party modules
+    """
+    def __init__(self, name, level=logging.INFO):
+        logging.Logger.__init__(self, name, level)
+        self.propagate = False
+        self.interactive = True
+        self.logfile = None
+        self._allhandlers = {
+            'default': logging.StreamHandler(sys.stdout),
+            'stdout': MicStreamHandler(sys.stdout),
+            'stderr': MicStreamHandler(sys.stderr),
+            'logfile': MicFileHandler(),
+        }
+
+        self._allhandlers['default'].addFilter(LevelFilter(['RAWTEXT']))
+        self._allhandlers['default'].setFormatter(
+            logging.Formatter(fmt="%(message)s"))
+        self.addHandler(self._allhandlers['default'])
+
+        self._allhandlers['stdout'].addFilter(LevelFilter(['DEBUG', 'VERBOSE',
+                                                          'INFO']))
+        self.addHandler(self._allhandlers['stdout'])
+
+        self._allhandlers['stderr'].addFilter(LevelFilter(['WARNING',
+                                                           'ERROR']))
+        self.addHandler(self._allhandlers['stderr'])
+
+        self.addHandler(self._allhandlers['logfile'])
+
+    def set_logfile(self, filename, mode='w'):
+        """ Set logfile path """
+        self.logfile = filename
+        self._allhandlers['logfile'].set_logfile(self.logfile, mode)
+
+    def enable_logstderr(self):
+        """ Start to log all error messages """
+        if self.logfile:
+            self._allhandlers['logfile'].redirect_stderr()
+
+    def disable_logstderr(self):
+        """ Stop to log all error messages """
+        if self.logfile:
+            self._allhandlers['logfile'].restore_stderr()
+
+    def verbose(self, msg, *args, **kwargs):
+        """ Log a message with level VERBOSE """
+        if self.isEnabledFor(VERBOSE):
+            self._log(VERBOSE, msg, args, **kwargs)
+
+    def raw(self, msg, *args, **kwargs):
+        """ Log a message in raw text format """
+        if self.isEnabledFor(RAWTEXT):
+            self._log(RAWTEXT, msg, args, **kwargs)
+
+    def select(self, msg, optdict, default=None):
+        """ Log a message in interactive mode """
+        if not optdict.keys():
+            return default
+        if default is None:
+            default = optdict.keys()[0]
+        msg += " [%s](%s): " % ('/'.join(optdict.keys()), default)
+        if not self.interactive or self.logfile:
+            reply = default
+            self.raw(msg + reply)
+        else:
+            while True:
+                reply = raw_input(msg).strip()
+                if not reply or reply in optdict:
+                    break
+            if not reply:
+                reply = default
+        return optdict[reply]
+
+
+def error(msg):
+    """ Log a message with level ERROR on the MIC logger """
+    LOGGER.error(msg)
+    sys.exit(2)
+
+def warning(msg):
+    """ Log a message with level WARNING on the MIC logger """
+    LOGGER.warning(msg)
+
+def info(msg):
+    """ Log a message with level INFO on the MIC logger """
+    LOGGER.info(msg)
+
+def verbose(msg):
+    """ Log a message with level VERBOSE on the MIC logger """
+    LOGGER.verbose(msg)
+
+def debug(msg):
+    """ Log a message with level DEBUG on the MIC logger """
+    LOGGER.debug(msg)
+
+def raw(msg):
+    """ Log a message on the MIC logger in raw text format"""
+    LOGGER.raw(msg)
+
+def select(msg, optdict, default=None):
+    """ Show an interactive scene in tty terminal and
+        logs them on MIC logger
+    """
+    return LOGGER.select(msg, optdict, default)
+
+def choice(msg, optlist, default=0):
+    """ Give some alternatives to users for answering the question """
+    return LOGGER.select(msg, dict(zip(optlist, optlist)), optlist[default])
+
+def ask(msg, ret=True):
+    """ Ask users to answer 'yes' or 'no' to the question """
+    answers = {'y': True, 'n': False}
+    default = {True: 'y', False: 'n'}[ret]
+    return LOGGER.select(msg, answers, default)
+
+def pause(msg=None):
+    """ Pause for any key """
+    if msg is None:
+        msg = "press ANY KEY to continue ..."
+    raw_input(msg)
+
+def set_logfile(logfile, mode='w'):
+    """ Set logfile path to the MIC logger """
+    LOGGER.set_logfile(logfile, mode)
+
+def set_loglevel(level):
+    """ Set loglevel to the MIC logger """
+    if isinstance(level, basestring):
+        level = logging.getLevelName(level)
+    LOGGER.setLevel(level)
+
+def get_loglevel():
+    """ Get the loglevel of the MIC logger """
+    return logging.getLevelName(LOGGER.level)
+
+def disable_interactive():
+    """ Disable the interactive mode """
+    LOGGER.interactive = False
+
+def enable_interactive():
+    """ Enable the interactive mode """
+    LOGGER.interactive = True
+
+def set_interactive(value):
+    """ Set the interactive mode (for compatibility) """
+    if value:
+        enable_interactive()
+    else:
+        disable_interactive()
+
+def enable_logstderr(fpath=None):
+    """ Start to log all error message on the MIC logger """
+    LOGGER.enable_logstderr()
+
+def disable_logstderr():
+    """ Stop to log all error message on the MIC logger """
+    LOGGER.disable_logstderr()
+
+
+# add two level to the MIC logger: 'VERBOSE', 'RAWTEXT'
+logging.addLevelName(VERBOSE, 'VERBOSE')
+logging.addLevelName(RAWTEXT, 'RAWTEXT')
+# initial the MIC logger
+logging.setLoggerClass(MicLogger)
+LOGGER = logging.getLogger("MIC")
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/plugin.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/plugin.py
new file mode 100644 (file)
index 0000000..e433e25
--- /dev/null
@@ -0,0 +1,98 @@
+#!/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.conf import configmgr
+from mic.utils import errors
+
+
+__ALL__ = ['PluginMgr', 'pluginmgr']
+
+PLUGIN_TYPES = ["imager", "backend"] # TODO  "hook"
+
+
+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):
+        self.plugin_dir = configmgr.common['plugin_dir']
+
+    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.warning("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 as err:
+                            msg = 'Failed to load plugin %s/%s: %s' \
+                                % (os.path.basename(pdir), mod, err)
+                            msger.verbose(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)
+
+        self._add_plugindir(os.path.join(self.plugin_dir, ptype))
+        self._load_all()
+
+        return pluginbase.get_plugins(ptype)
+
+pluginmgr = PluginMgr()
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/pluginbase.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/pluginbase.py
new file mode 100644 (file)
index 0000000..db438b6
--- /dev/null
@@ -0,0 +1,99 @@
+#!/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"
+
+    @classmethod
+    def check_image_exists(self, destdir, apacking=None,
+                                          images=(),
+                                          release=None):
+
+        # if it's a packing file, reset images
+        if apacking:
+            images = [apacking]
+
+        # release option will override images
+        if release is not None:
+            images = [os.path.basename(destdir.rstrip('/'))]
+            destdir = os.path.dirname(destdir.rstrip('/'))
+
+        for name in images:
+            if not name:
+                continue
+
+            image = os.path.join(destdir, name)
+            if not os.path.exists(image):
+                continue
+            if msger.ask("Target image/dir: %s already exists, "
+                         "clean up the old files and continue?" % image):
+                if os.path.isdir(image):
+                    for path, dirs, files in os.walk(os.path.abspath(image)):
+                        for fname in files:
+                            fpath = os.path.join(path, fname)
+                            if not fpath.endswith('.log'):
+                                os.remove(fpath)
+                else:
+                    os.unlink(image)
+            else:
+                raise errors.Abort("Canceled")
+
+    def do_create(self):
+        pass
+
+    def do_chroot(self):
+        pass
+
+class BackendPlugin(_Plugin):
+    mic_plugin_type="backend"
+
+    def addRepository(self):
+        pass
+
+def get_plugins(typen):
+    ps = ImagerPlugin.get_plugins()
+    if typen in ps:
+        return ps[typen]
+    else:
+        return None
+
+__all__ = ['ImagerPlugin', 'BackendPlugin', 'get_plugins']
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/rt_util.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/rt_util.py
new file mode 100644 (file)
index 0000000..b79e800
--- /dev/null
@@ -0,0 +1,316 @@
+#!/usr/bin/python -tt
+#
+# 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
+import sys
+import glob
+import re
+import shutil
+import subprocess
+import ctypes
+
+from mic import bootstrap, msger
+from mic.conf import configmgr
+from mic.utils import errors, proxy
+from mic.utils.fs_related import find_binary_path, makedirs
+from mic.chroot import setup_chrootenv, cleanup_chrootenv, ELF_arch
+
+from mic.plugin import pluginmgr
+
+_libc = ctypes.cdll.LoadLibrary(None)
+_errno = ctypes.c_int.in_dll(_libc, "errno")
+_libc.personality.argtypes = [ctypes.c_ulong]
+_libc.personality.restype = ctypes.c_int
+_libc.unshare.argtypes = [ctypes.c_int,]
+_libc.unshare.restype = ctypes.c_int
+
+expath = lambda p: os.path.abspath(os.path.expanduser(p))
+
+PER_LINUX32=0x0008
+PER_LINUX=0x0000
+personality_defs = {
+    'x86_64': PER_LINUX, 'ppc64': PER_LINUX, 'sparc64': PER_LINUX,
+    'i386': PER_LINUX32, 'i586': PER_LINUX32, 'i686': PER_LINUX32,
+    'ppc': PER_LINUX32, 'sparc': PER_LINUX32, 'sparcv9': PER_LINUX32,
+    'ia64' : PER_LINUX, 'alpha' : PER_LINUX,
+    's390' : PER_LINUX32, 's390x' : PER_LINUX,
+}
+
+def condPersonality(per=None):
+    if per is None or per in ('noarch',):
+        return
+    if personality_defs.get(per, None) is None:
+        return
+    res = _libc.personality(personality_defs[per])
+    if res == -1:
+        raise OSError(_errno.value, os.strerror(_errno.value))
+
+def inbootstrap():
+    if os.path.exists(os.path.join("/", ".chroot.lock")):
+        return True
+    return (os.stat("/").st_ino != 2)
+
+def bootstrap_mic(argv=None):
+    def mychroot():
+        os.chroot(rootdir)
+        os.chdir(cwd)
+
+    # by default, sys.argv is used to run mic in bootstrap
+    if not argv:
+        argv = sys.argv
+    if argv[0] not in ('/usr/bin/mic', 'mic'):
+        argv[0] = '/usr/bin/mic'
+
+    cropts = configmgr.create
+    bsopts = configmgr.bootstrap
+    distro = bsopts['distro_name'].lower()
+
+    rootdir = bsopts['rootdir']
+    pkglist = bsopts['packages']
+    cwd = os.getcwd()
+
+    # create bootstrap and run mic in bootstrap
+    bsenv = bootstrap.Bootstrap(rootdir, distro, cropts['arch'])
+    bsenv.logfile = cropts['logfile']
+    # rootdir is regenerated as a temp dir
+    rootdir = bsenv.rootdir
+
+    if 'optional' in bsopts:
+        optlist = bsopts['optional']
+    else:
+        optlist = []
+
+    try:
+        msger.info("Creating %s bootstrap ..." % distro)
+        bsenv.create(cropts['repomd'], pkglist, optlist)
+
+        # bootstrap is relocated under "bootstrap"
+        if os.path.exists(os.path.join(rootdir, "bootstrap")):
+            rootdir = os.path.join(rootdir, "bootstrap")
+
+        bsenv.dirsetup(rootdir)
+        if cropts['use_mic_in_bootstrap']:
+            msger.info("No copy host mic")
+        else:
+            msger.info("Copy host mic to bootstrap")
+            sync_mic(rootdir, plugin=cropts['plugin_dir'])
+
+        #FIXME: sync the ks file to bootstrap
+        if "/" == os.path.dirname(os.path.abspath(configmgr._ksconf)):
+            safecopy(configmgr._ksconf, rootdir)
+
+        msger.info("Start mic in bootstrap: %s\n" % rootdir)
+        bsarch = ELF_arch(rootdir)
+        if bsarch in personality_defs:
+            condPersonality(bsarch)
+        bindmounts = get_bindmounts(cropts)
+        ret = bsenv.run(argv, cwd, rootdir, bindmounts)
+
+    except errors.BootstrapError as err:
+        raise errors.CreatorError("Failed to download/install bootstrap package " \
+                                  "or the package is in bad format: %s" % err)
+    except RuntimeError as err:
+        #change exception type but keep the trace back
+        value,tb = sys.exc_info()[1:]
+        raise errors.CreatorError((value,tb))
+    else:
+        sys.exit(ret)
+    finally:
+        bsenv.cleanup()
+
+def get_bindmounts(cropts):
+    binddirs =  [
+                  os.getcwd(),
+                  cropts['tmpdir'],
+                  cropts['cachedir'],
+                  cropts['outdir'],
+                  cropts['local_pkgs_path'],
+                ]
+    bindfiles = [
+                  cropts['logfile'],
+                  configmgr._ksconf,
+                ]
+
+    for lrepo in cropts['localrepos']:
+        binddirs.append(lrepo)
+    for ltpkrepo in cropts['localtpkrepos']:
+        binddirs.append(ltpkrepo)
+
+    bindlist = map(expath, filter(None, binddirs))
+    bindlist += map(os.path.dirname, map(expath, filter(None, bindfiles)))
+    bindlist = sorted(set(bindlist))
+    bindmounts = ';'.join(bindlist)
+    return bindmounts
+
+
+def get_mic_binpath():
+    fp = None
+    try:
+        import pkg_resources # depends on 'setuptools'
+        dist = pkg_resources.get_distribution('mic')
+        # the real script is under EGG_INFO/scripts
+        if dist.has_metadata('scripts/mic'):
+            fp = os.path.join(dist.egg_info, "scripts/mic")
+    except ImportError:
+        pass
+    except pkg_resources.DistributionNotFound:
+        pass
+
+
+    if fp:
+        return fp
+
+    # not found script if 'flat' egg installed
+    try:
+        return find_binary_path('mic')
+    except errors.CreatorError:
+        raise errors.BootstrapError("Can't find mic binary in host OS")
+
+
+def get_mic_modpath():
+    try:
+        import mic
+    except ImportError:
+        raise errors.BootstrapError("Can't find mic module in host OS")
+    path = os.path.abspath(mic.__file__)
+    return os.path.dirname(path)
+
+def get_mic_libpath():
+    return os.getenv("MIC_LIBRARY_PATH", "/usr/lib/mic")
+
+# the hard code path is prepared for bootstrap
+def sync_mic(bootstrap, binpth = '/usr/bin/mic',
+             libpth='/usr/lib',
+             plugin='/usr/lib/mic/plugins',
+             pylib = '/usr/lib/python2.7/site-packages',
+             conf = '/etc/mic/mic.conf'):
+    _path = lambda p: os.path.join(bootstrap, p.lstrip('/'))
+
+    micpaths = {
+                 'binpth': get_mic_binpath(),
+                 'libpth': get_mic_libpath(),
+                 'plugin': plugin,
+                 'pylib': get_mic_modpath(),
+                 'conf': '/etc/mic/mic.conf',
+               }
+
+    if not os.path.exists(_path(pylib)):
+        pyptn = '/usr/lib/python?.?/site-packages'
+        pylibs = glob.glob(_path(pyptn))
+        if pylibs:
+            pylib = pylibs[0].replace(bootstrap, '')
+        else:
+            raise errors.BootstrapError("Can't find python site dir in: %s" %
+                                        bootstrap)
+
+    for key, value in micpaths.items():
+        try:
+            safecopy(value, _path(eval(key)), False, ["*.pyc", "*.pyo"])
+        except (OSError, IOError) as err:
+            raise errors.BootstrapError(err)
+
+    # auto select backend
+    conf_str = file(_path(conf)).read()
+    conf_str = re.sub("pkgmgr\s*=\s*.*", "pkgmgr=auto", conf_str)
+    with open(_path(conf), 'w') as wf:
+        wf.write(conf_str)
+
+    # chmod +x /usr/bin/mic
+    os.chmod(_path(binpth), 0o777)
+
+    # correct python interpreter
+    mic_cont = file(_path(binpth)).read()
+    mic_cont = "#!/usr/bin/python\n" + mic_cont
+    with open(_path(binpth), 'w') as wf:
+        wf.write(mic_cont)
+
+
+def safecopy(src, dst, symlinks=False, ignore_ptns=()):
+    if os.path.isdir(src):
+        if os.path.isdir(dst):
+            dst = os.path.join(dst, os.path.basename(src))
+        if os.path.exists(dst):
+            shutil.rmtree(dst, ignore_errors=True)
+
+        src = src.rstrip('/')
+        # check common prefix to ignore copying itself
+        if dst.startswith(src + '/'):
+            ignore_ptns = list(ignore_ptns) + [ os.path.basename(src) ]
+
+        ignores = shutil.ignore_patterns(*ignore_ptns)
+        try:
+            shutil.copytree(src, dst, symlinks, ignores)
+        except (OSError, IOError):
+            shutil.rmtree(dst, ignore_errors=True)
+            raise
+    else:
+        if not os.path.isdir(dst):
+            makedirs(os.path.dirname(dst))
+
+        shutil.copy2(src, dst)
+
+def prepare_create(args):
+    """
+    Usage:
+        ${name} ${cmd_name} <ksfile> [OPTS]
+
+    ${cmd_option_list}
+    """
+
+    if args is None:
+        raise errors.Usage("Invalid arguments.")
+
+    creatoropts = configmgr.create
+    ksconf = args.ksfile
+
+    if creatoropts['runtime'] == 'bootstrap':
+        configmgr._ksconf = ksconf
+        bootstrap_mic()
+
+    recording_pkgs = []
+    if len(creatoropts['record_pkgs']) > 0:
+        recording_pkgs = creatoropts['record_pkgs']
+
+    if creatoropts['release'] is not None:
+        if 'name' not in recording_pkgs:
+            recording_pkgs.append('name')
+        if 'vcs' not in recording_pkgs:
+            recording_pkgs.append('vcs')
+
+    configmgr._ksconf = ksconf
+
+    # try to find the pkgmgr
+    pkgmgr = None
+    backends = pluginmgr.get_plugins('backend')
+    if 'auto' == creatoropts['pkgmgr']:
+        for key in configmgr.prefer_backends:
+            if key in backends:
+                pkgmgr = backends[key]
+                break
+    else:
+        for key in backends.keys():
+            if key == creatoropts['pkgmgr']:
+                pkgmgr = backends[key]
+                break
+
+    if not pkgmgr:
+        raise errors.CreatorError("Can't find backend: %s, "
+                                  "available choices: %s" %
+                                  (creatoropts['pkgmgr'],
+                                   ','.join(backends.keys())))
+    return creatoropts, pkgmgr, recording_pkgs
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/__init__.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/errors.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/errors.py
new file mode 100644 (file)
index 0000000..12ddde6
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2011~2013 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.
+
+""" Collection of all error class """
+
+class CreatorError(Exception):
+    """ Based class for all mic creator errors """
+    keyword = None
+
+    def __init__(self, msg):
+        Exception.__init__(self)
+        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.msg
+
+    def __repr__(self):
+        if not hasattr(self, 'keyword') or not self.keyword:
+            self.keyword = self.__class__.__name__
+        return "<%s> %s" % (self.keyword, str(self))
+
+class Usage(CreatorError):
+    """ Error class for Usage """
+    pass
+
+class Abort(CreatorError):
+    """ Error class for Abort """
+    pass
+
+class ConfigError(CreatorError):
+    """ Error class for Config file """
+    keyword = 'Config'
+
+class KsError(CreatorError):
+    """ Error class for Kickstart module """
+    keyword = 'Kickstart'
+
+class RepoError(CreatorError):
+    """ Error class for Repository related """
+    keyword = 'Repository'
+
+class RpmError(CreatorError):
+    """ Error class for RPM related """
+    keyword = 'RPM'
+
+class MountError(CreatorError):
+    """ Error class for Mount related """
+    keyword = 'Mount'
+
+class SnapshotError(CreatorError):
+    """ Error class for Snapshot related """
+    keyword = 'Snapshot'
+
+class SquashfsError(CreatorError):
+    """ Error class for Squashfs related """
+    keyword = 'Squashfs'
+
+class VdfsError(CreatorError):
+    """ Error class for Vdfs related """
+    keyword = 'vdfs'
+
+class BootstrapError(CreatorError):
+    """ Error class for Bootstrap related """
+    keyword = 'Bootstrap'
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/fs_related.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/fs_related.py
new file mode 100644 (file)
index 0000000..9e2e2c3
--- /dev/null
@@ -0,0 +1,1179 @@
+#!/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 re
+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 *
+
+
+def find_binary_inchroot(binary, chroot):
+    paths = ["/usr/sbin",
+             "/usr/bin",
+             "/sbin",
+             "/bin"
+            ]
+
+    for path in paths:
+        bin_path = "%s/%s" % (path, binary)
+        if os.path.exists("%s/%s" % (chroot, bin_path)):
+            return bin_path
+    return None
+
+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
+    raise CreatorError("Command '%s' is not available." % binary)
+
+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 as err:
+        if err.errno != errno.EEXIST:
+            raise
+
+def mkvdfs(in_img, out_img, fsoptions):
+     """ This function is incomplete. """
+     fullpathmkvdfs = find_binary_path("mkfs.vdfs")
+#     args = fullpathmkvdfs + " -i -r "+ in_img + " -z 1024M -s " + out_img
+     args = fullpathmkvdfs + " " + fsoptions + " -r " + in_img + " " + out_img
+     msger.verbose("vdfs args: %s" % args)
+     runner.show("%s --help" % fullpathmkvdfs)
+#     if not sys.stdout.isatty():
+#         args.append("-no-progress")
+#     runner.show("%s --help" % fullpathmkvdfs)
+     ret = runner.show(args)
+     if ret != 0:
+         runner.show ("vdfs error")
+         raise VdfsError("' %s' exited with error (%d)" % (args, ret))
+
+def mksquashfs(in_img, out_img):
+    fullpathmksquashfs = find_binary_path("mksquashfs")
+    args = [fullpathmksquashfs, in_img, out_img]
+
+    if not sys.stdout.isatty():
+        args.append("-no-progress")
+
+    ret = runner.show(args)
+    if ret != 0:
+        raise SquashfsError("'%s' exited with error (%d)" % (' '.join(args), ret))
+
+def resize2fs(fs, size):
+    resize2fs = find_binary_path("resize2fs")
+    if size == 0:
+        # it means to minimalize it
+        return runner.show([resize2fs, '-M', fs])
+    else:
+        return runner.show([resize2fs, fs, "%sK" % (size / 1024,)])
+
+class BindChrootMount:
+    """Represents a bind mount of a directory into a chroot."""
+    def __init__(self, src, chroot, dest = None, option = None):
+        self.root = os.path.abspath(os.path.expanduser(chroot))
+        self.mount_option = option
+
+        self.orig_src = self.src = src
+        if os.path.islink(src):
+            self.src = os.readlink(src)
+            if not self.src.startswith('/'):
+                self.src = os.path.abspath(os.path.join(os.path.dirname(src),
+                                                        self.src))
+
+        if not dest:
+            dest = self.src
+        self.dest = os.path.join(self.root, dest.lstrip('/'))
+
+        self.mounted = False
+        self.mountcmd = find_binary_path("mount")
+        self.umountcmd = find_binary_path("umount")
+
+    def ismounted(self):
+        with open('/proc/mounts') as f:
+            for line in f:
+                if line.split()[1] == os.path.abspath(self.dest):
+                    return True
+
+        return False
+
+    def mount(self):
+        if self.mounted or self.ismounted():
+            return
+
+        try:
+            makedirs(self.dest)
+        except OSError as err:
+            if err.errno == errno.ENOSPC:
+                msger.warning("No space left on device '%s'" % err.filename)
+                return
+
+        if self.mount_option:
+            cmdline = [self.mountcmd, "-o" ,"bind", "-o", "%s" % \
+                       self.mount_option, self.src, self.dest]
+        else:
+            cmdline = [self.mountcmd, "-o" ,"bind", self.src, self.dest]
+        rc, errout = runner.runtool(cmdline, catch=2)
+        if rc != 0:
+            raise MountError("Bind-mounting '%s' to '%s' failed: %s" %
+                             (self.src, self.dest, errout))
+
+        self.mounted = True
+        if os.path.islink(self.orig_src):
+            dest = os.path.join(self.root, self.orig_src.lstrip('/'))
+            if not os.path.exists(dest):
+                os.symlink(self.src, dest)
+
+    def unmount(self):
+        if self.mounted or self.ismounted():
+            runner.show([self.umountcmd, "-l", self.dest])
+        self.mounted = False
+
+class LoopbackMount:
+    """LoopbackMount  compatibility layer for old API"""
+    def __init__(self, lofile, mountdir, fstype = None):
+        self.diskmount = DiskMount(LoopbackDisk(lofile,size = 0),mountdir,fstype,rmmountdir = True)
+        self.losetup = False
+        self.losetupcmd = find_binary_path("losetup")
+
+    def cleanup(self):
+        self.diskmount.cleanup()
+
+    def unmount(self):
+        self.diskmount.unmount()
+
+    def lounsetup(self):
+        if self.losetup:
+            runner.show([self.losetupcmd, "-d", self.loopdev])
+            self.losetup = False
+            self.loopdev = None
+
+    def loopsetup(self):
+        if self.losetup:
+            return
+
+        self.loopdev = get_loop_device(self.losetupcmd, self.lofile)
+        self.losetup = True
+
+    def mount(self):
+        self.diskmount.mount()
+
+class SparseLoopbackMount(LoopbackMount):
+    """SparseLoopbackMount  compatibility layer for old API"""
+    def __init__(self, lofile, mountdir, size, fstype = None):
+        self.diskmount = DiskMount(SparseLoopbackDisk(lofile,size),mountdir,fstype,rmmountdir = True)
+
+    def expand(self, create = False, size = None):
+        self.diskmount.disk.expand(create, size)
+
+    def truncate(self, size = None):
+        self.diskmount.disk.truncate(size)
+
+    def create(self):
+        self.diskmount.disk.create()
+
+class SparseExtLoopbackMount(SparseLoopbackMount):
+    """SparseExtLoopbackMount  compatibility layer for old API"""
+    def __init__(self, lofile, mountdir, size, fstype, blocksize, fslabel):
+        self.diskmount = ExtDiskMount(SparseLoopbackDisk(lofile,size), mountdir, fstype, blocksize, fslabel, rmmountdir = True)
+
+
+    def __format_filesystem(self):
+        self.diskmount.__format_filesystem()
+
+    def create(self):
+        self.diskmount.disk.create()
+
+    def resize(self, size = None):
+        return self.diskmount.__resize_filesystem(size)
+
+    def mount(self):
+        self.diskmount.mount()
+
+    def __fsck(self):
+        self.extdiskmount.__fsck()
+
+    def __get_size_from_filesystem(self):
+        return self.diskmount.__get_size_from_filesystem()
+
+    def __resize_to_minimal(self):
+        return self.diskmount.__resize_to_minimal()
+
+    def resparse(self, size = None):
+        return self.diskmount.resparse(size)
+
+class Disk:
+    """Generic base object for a disk
+
+    The 'create' method must make the disk visible as a block device - eg
+    by calling losetup. For RawDisk, this is obviously a no-op. The 'cleanup'
+    method must undo the 'create' operation.
+    """
+    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 RawDisk(Disk):
+    """A Disk backed by a block device.
+    Note that create() is a no-op.
+    """
+    def __init__(self, size, device):
+        Disk.__init__(self, size, device)
+
+    def fixed(self):
+        return True
+
+    def exists(self):
+        return True
+
+class LoopbackDisk(Disk):
+    """A Disk backed by a file via the loop module."""
+    def __init__(self, lofile, size):
+        Disk.__init__(self, size)
+        self.lofile = lofile
+        self.losetupcmd = find_binary_path("losetup")
+
+    def fixed(self):
+        return False
+
+    def exists(self):
+        return os.path.exists(self.lofile)
+
+    def create(self):
+        if self.device is not None:
+            return
+
+        self.device = get_loop_device(self.losetupcmd, self.lofile)
+
+    def cleanup(self):
+        if self.device is None:
+            return
+        msger.debug("Losetup remove %s" % self.device)
+        rc = runner.show([self.losetupcmd, "-d", self.device])
+        self.device = None
+
+    def reread_size(self):
+        if self.device is None:
+            return
+        msger.debug("Reread size %s" % self.device)
+        rc = runner.show([self.losetupcmd, "-c", self.device])
+        # XXX: (WORKAROUND) re-setup loop device when losetup isn't support '-c' option.
+        if rc != 0:
+            msger.debug("Fail to reread size, Try to re-setup loop device to reread the size of the file associated")
+            runner.show([self.losetupcmd, "-d", self.device])
+            runner.show([self.losetupcmd, self.device, self.lofile])
+
+class SparseLoopbackDisk(LoopbackDisk):
+    """A Disk backed by a sparse file via the loop module."""
+    def __init__(self, lofile, size):
+        LoopbackDisk.__init__(self, lofile, size)
+
+    def expand(self, create = False, size = None):
+        flags = os.O_WRONLY
+        if create:
+            flags |= os.O_CREAT
+            if not os.path.exists(self.lofile):
+                makedirs(os.path.dirname(self.lofile))
+
+        if size is None:
+            size = self.size
+
+        msger.debug("Extending sparse file %s to %d" % (self.lofile, size))
+        if create:
+            fd = os.open(self.lofile, flags, 0o644)
+        else:
+            fd = os.open(self.lofile, flags)
+
+        if size <= 0:
+            size = 1
+        try:
+            os.ftruncate(fd, size)
+        except:
+            # may be limited by 2G in 32bit env
+            os.ftruncate(fd, 2**31)
+
+        os.close(fd)
+
+    def truncate(self, size = None):
+        if size is None:
+            size = self.size
+
+        msger.debug("Truncating sparse file %s to %d" % (self.lofile, size))
+        fd = os.open(self.lofile, os.O_WRONLY)
+        os.ftruncate(fd, size)
+        os.close(fd)
+
+    def create(self):
+        if self.device is not None:
+            return
+
+        self.expand(create = True)
+        LoopbackDisk.create(self)
+
+class Mount(object):
+    """A generic base class to deal with mounting things."""
+    def __init__(self, mountdir):
+        self.mountdir = mountdir
+
+    def cleanup(self):
+        self.unmount()
+
+    def mount(self, options = None):
+        pass
+
+    def unmount(self):
+        pass
+
+class DiskMount(Mount):
+    """A Mount object that handles mounting of a Disk."""
+    def __init__(self, disk, mountdir, fstype = None, rmmountdir = True):
+        Mount.__init__(self, mountdir)
+
+        self.disk = disk
+        self.fstype = fstype
+        self.rmmountdir = rmmountdir
+
+        self.mounted = False
+        self.rmdir   = False
+        if fstype:
+            self.mkfscmd = find_binary_path("mkfs." + self.fstype)
+        else:
+            self.mkfscmd = None
+        self.mountcmd = find_binary_path("mount")
+        self.umountcmd = find_binary_path("umount")
+
+    def cleanup(self):
+        Mount.cleanup(self)
+        self.disk.cleanup()
+
+    def unmount(self):
+        if self.mounted:
+            msger.debug("Unmounting directory %s" % self.mountdir)
+            runner.quiet('sync') # sync the data on this mount point
+            rc = runner.show([self.umountcmd, "-l", self.mountdir])
+            if rc == 0:
+                self.mounted = False
+            else:
+                raise MountError("Failed to umount %s" % self.mountdir)
+        if self.rmdir and not self.mounted:
+            try:
+                os.rmdir(self.mountdir)
+            except OSError as e:
+                pass
+            self.rmdir = False
+
+
+    def __create(self):
+        self.disk.create()
+
+
+    def mount(self, options = None):
+        if self.mounted:
+            return
+
+        if not os.path.isdir(self.mountdir):
+            msger.debug("Creating mount point %s" % self.mountdir)
+            os.makedirs(self.mountdir)
+            self.rmdir = self.rmmountdir
+
+        self.__create()
+
+        msger.debug("Mounting %s at %s" % (self.disk.device, self.mountdir))
+        if options:
+            args = [ self.mountcmd, "-o", options, self.disk.device, self.mountdir ]
+        else:
+            args = [ self.mountcmd, self.disk.device, self.mountdir ]
+        if self.fstype:
+            args.extend(["-t", self.fstype])
+
+        rc = runner.show(args)
+        if rc != 0:
+            raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" %
+                             (self.disk.device, self.mountdir, " ".join(args), rc))
+
+        self.mounted = True
+
+class F2fsDiskMount(DiskMount):
+    """A DiskMount object that is able to format/resize f2fs filesystems."""
+    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None, fsuuid=None):
+        self.__check_f2fs()
+        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
+        self.blocksize = blocksize
+        self.fslabel = fslabel.replace("/", "")
+        self.uuid = fsuuid or None
+        self.skipformat = skipformat
+        self.fsopts = fsopts
+        self.__f2fsopts = None
+        self.blkidcmd = find_binary_path("blkid")
+        self.dumpe2fs = find_binary_path("dump." + self.fstype)
+        self.fsckcmd = find_binary_path("fsck." + self.fstype)
+        self.resizecmd = find_binary_path("resize." + self.fstype)
+
+    def __get_f2fsopts(self):
+        return self.__f2f2opts
+
+    def __set_f2fsopts(self, val):
+        if val is None:
+            self.__f2fsopts = None
+        else:
+            self.__f2fsopts = val
+    f2fsopts = property(__get_f2fsopts, __set_f2fsopts)
+
+    def __check_f2fs(self):
+        found = False
+        """ Need to load f2fs module to mount it """
+        load_module("f2fs")
+        for line in open("/proc/filesystems").xreadlines():
+            if line.find("f2fs") > -1:
+                found = True
+                break
+        if not found:
+            raise MountError("Your system can't mount f2fs filesystem, please make sure your kernel has f2fs support and the module f2fs.ko has been loaded.")
+
+    def __parse_field(self, output, field):
+        for line in output.split(" "):
+            if line.startswith(field + "="):
+                return line[len(field) + 1:].strip().replace("\"", "")
+
+        raise KeyError("Failed to find field '%s' in output" % field)
+
+    def __format_filesystem(self):
+        if self.skipformat:
+            msger.debug("Skip filesystem format.")
+            return
+
+        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
+
+        cmdlist = [self.mkfscmd, "-l", self.fslabel]
+        if self.__f2fsopts:
+            cmdlist.extend(self.__f2fsopts.split())
+        cmdlist.extend([self.disk.device])
+
+        rc, errout = runner.runtool(cmdlist, catch=2)
+        if rc != 0:
+            raise MountError("Error creating %s filesystem on disk %s:\n%s" %
+                             (self.fstype, self.disk.device, errout))
+
+        self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
+
+    def __resize_filesystem(self, size = None):
+        msger.info("Resizing filesystem ...")
+        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
+
+        if size is None:
+            size = self.disk.size
+
+        if size == current_size:
+            return
+
+        if size > current_size:
+            self.disk.expand(size=size)
+
+        self.__fsck()
+
+        return size
+
+    def __create(self):
+        resize = False
+        if not self.disk.fixed() and self.disk.exists():
+            resize = True
+
+        self.disk.create()
+
+        if resize:
+            self.__resize_filesystem()
+        else:
+            self.__format_filesystem()
+
+    def mount(self, options = None, init_expand = False):
+        self.__create()
+        if init_expand:
+            expand_size = long(self.disk.size * 1.5)
+            msger.info("Initial partition size expanded : %ld -> %ld" % (self.disk.size, expand_size))
+            self.__resize_filesystem(expand_size)
+            self.disk.reread_size()
+        DiskMount.mount(self, options)
+
+    def __fsck(self):
+        msger.info("Checking filesystem %s" % self.disk.lofile)
+        runner.quiet([self.fsckcmd, self.disk.lofile])
+
+    def __get_size_from_filesystem(self):
+        return self.disk.size
+
+    def __resize_to_minimal(self):
+        msger.info("Resizing filesystem to minimal ...")
+        self.__fsck()
+
+        return self.__get_size_from_filesystem()
+
+    def resparse(self, size = None):
+        self.cleanup()
+        if size == 0:
+            minsize = 0
+        else:
+            minsize = self.__resize_to_minimal()
+            self.disk.truncate(minsize)
+            self.__resize_filesystem(size)
+        return minsize
+
+class ExtDiskMount(DiskMount):
+    """A DiskMount object that is able to format/resize ext[23] filesystems."""
+    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None, fsuuid=None):
+        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
+        self.blocksize = blocksize
+        self.fslabel = fslabel.replace("/", "")
+        self.uuid = fsuuid or str(uuid.uuid4())
+        self.skipformat = skipformat
+        self.fsopts = fsopts
+        self.__extopts = None
+        self.dumpe2fs = find_binary_path("dumpe2fs")
+        self.tune2fs = find_binary_path("tune2fs")
+
+    def __get_extopts(self):
+        return self.__extopts
+
+    def __set_extopts(self, val):
+        if val is None:
+            self.__extopts = None
+        else:
+            m = re.search(r'-b\s*(?P<blocksize>\d+)', val)
+            if m:
+                self.blocksize = int(m.group('blocksize'))
+                val = val.replace(m.group(), '')
+            self.__extopts = val
+
+    extopts = property(__get_extopts, __set_extopts)
+
+    def __parse_field(self, output, field):
+        for line in output.split("\n"):
+            if line.startswith(field + ":"):
+                return line[len(field) + 1:].strip()
+
+        raise KeyError("Failed to find field '%s' in output" % field)
+
+    def __format_filesystem(self):
+        if self.skipformat:
+            msger.debug("Skip filesystem format.")
+            return
+
+        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
+        cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b",
+                   str(self.blocksize), "-U", self.uuid]
+        if self.__extopts:
+            cmdlist.extend(self.__extopts.split())
+        cmdlist.extend([self.disk.device])
+
+        rc, errout = runner.runtool(cmdlist, catch=2)
+        if rc != 0:
+            raise MountError("Error creating %s filesystem on disk %s:\n%s" %
+                             (self.fstype, self.disk.device, errout))
+
+        if not self.__extopts:
+            msger.debug("Tuning filesystem on %s" % self.disk.device)
+            runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
+
+    def __resize_filesystem(self, size = None):
+        msger.info("Resizing filesystem ...")
+        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
+
+        if size is None:
+            size = self.disk.size
+
+        if size == current_size:
+            return
+
+        if size > current_size:
+            self.disk.expand(size=size)
+
+        self.__fsck()
+
+        resize2fs(self.disk.lofile, size)
+        if size and size != os.stat(self.disk.lofile)[stat.ST_SIZE]:
+            raise MountError("Failed to resize filesystem %s to %d " % (self.disk.lofile, size))
+
+        return size
+
+    def __create(self):
+        resize = False
+        if not self.disk.fixed() and self.disk.exists():
+            resize = True
+
+        self.disk.create()
+
+        if resize:
+            self.__resize_filesystem()
+        else:
+            self.__format_filesystem()
+
+    def mount(self, options = None, init_expand = False):
+        self.__create()
+        if init_expand:
+            expand_size = long(self.disk.size * 1.5)
+            msger.info("Initial partition size expanded : %ld -> %ld" % (self.disk.size, expand_size))
+            self.__resize_filesystem(expand_size)
+            self.disk.reread_size()
+        DiskMount.mount(self, options)
+
+    def __fsck(self):
+        msger.info("Checking filesystem %s" % self.disk.lofile)
+        runner.quiet(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
+
+    def __get_size_from_filesystem(self):
+        return int(self.__parse_field(runner.outs([self.dumpe2fs, '-h', self.disk.lofile]),
+                                      "Block count")) * self.blocksize
+
+    def __resize_to_minimal(self):
+        msger.info("Resizing filesystem to minimal ...")
+        self.__fsck()
+        resize2fs(self.disk.lofile, 0)
+        return self.__get_size_from_filesystem()
+
+    def resparse(self, size = None):
+        self.cleanup()
+        if size == 0:
+            minsize = 0
+        else:
+            minsize = self.__resize_to_minimal()
+            self.disk.truncate(minsize)
+
+        self.__resize_filesystem(size)
+        return minsize
+
+class VfatDiskMount(DiskMount):
+    """A DiskMount object that is able to format vfat/msdos filesystems."""
+    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None, fsuuid = None):
+        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
+        self.blocksize = blocksize
+        self.fslabel = fslabel.replace("/", "")
+        rand1 = random.randint(0, 2**16 - 1)
+        rand2 = random.randint(0, 2**16 - 1)
+        self.uuid = fsuuid or "%04X-%04X" % (rand1, rand2)
+        self.skipformat = skipformat
+        self.fsopts = fsopts
+        self.fsckcmd = find_binary_path("fsck." + self.fstype)
+
+    def __format_filesystem(self):
+        if self.skipformat:
+            msger.debug("Skip filesystem format.")
+            return
+
+        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
+        rc = runner.show([self.mkfscmd, "-n", self.fslabel,
+                          "-i", self.uuid.replace("-", ""), self.disk.device])
+        if rc != 0:
+            raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
+
+        msger.verbose("Tuning filesystem on %s" % self.disk.device)
+
+    def __resize_filesystem(self, size = None):
+        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
+
+        if size is None:
+            size = self.disk.size
+
+        if size == current_size:
+            return
+
+        if size > current_size:
+            self.disk.expand(size=size)
+
+        self.__fsck()
+
+        #resize2fs(self.disk.lofile, size)
+        return size
+
+    def __create(self):
+        resize = False
+        if not self.disk.fixed() and self.disk.exists():
+            resize = True
+
+        self.disk.create()
+
+        if resize:
+            self.__resize_filesystem()
+        else:
+            self.__format_filesystem()
+
+    def mount(self, options = None, init_expand = False):
+        self.__create()
+        if init_expand:
+            expand_size = long(self.disk.size * 1.5)
+            msger.info("Initial partition size expanded : %ld -> %ld" % (self.disk.size, expand_size))
+            self.__resize_filesystem(expand_size)
+            self.disk.reread_size()
+        DiskMount.mount(self, options)
+
+    def __fsck(self):
+        msger.debug("Checking filesystem %s" % self.disk.lofile)
+        runner.show([self.fsckcmd, "-y", self.disk.lofile])
+
+    def __get_size_from_filesystem(self):
+        return self.disk.size
+
+    def __resize_to_minimal(self):
+        self.__fsck()
+
+        #
+        # Use a binary search to find the minimal size
+        # we can resize the image to
+        #
+        bot = 0
+        top = self.__get_size_from_filesystem()
+        return top
+
+    def resparse(self, size = None):
+        self.cleanup()
+        minsize = self.__resize_to_minimal()
+        self.disk.truncate(minsize)
+        self.__resize_filesystem(size)
+        return minsize
+
+class BtrfsDiskMount(DiskMount):
+    """A DiskMount object that is able to format/resize btrfs filesystems."""
+    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None, fsuuid = None):
+        self.__check_btrfs()
+        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
+        self.blocksize = blocksize
+        self.fslabel = fslabel.replace("/", "")
+        self.uuid  = fsuuid or None
+        self.skipformat = skipformat
+        self.fsopts = fsopts
+        self.blkidcmd = find_binary_path("blkid")
+        self.btrfsckcmd = find_binary_path("btrfsck")
+
+    def __check_btrfs(self):
+        found = False
+        """ Need to load btrfs module to mount it """
+        load_module("btrfs")
+        for line in open("/proc/filesystems").xreadlines():
+            if line.find("btrfs") > -1:
+                found = True
+                break
+        if not found:
+            raise MountError("Your system can't mount btrfs filesystem, please make sure your kernel has btrfs support and the module btrfs.ko has been loaded.")
+
+        # disable selinux, selinux will block write
+        if os.path.exists("/usr/sbin/setenforce"):
+            runner.show(["/usr/sbin/setenforce", "0"])
+
+    def __parse_field(self, output, field):
+        for line in output.split(" "):
+            if line.startswith(field + "="):
+                return line[len(field) + 1:].strip().replace("\"", "")
+
+        raise KeyError("Failed to find field '%s' in output" % field)
+
+    def __format_filesystem(self):
+        if self.skipformat:
+            msger.debug("Skip filesystem format.")
+            return
+
+        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
+        rc = runner.show([self.mkfscmd, "-L", self.fslabel, "-m", "single", self.disk.device])
+        if rc != 0:
+            raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
+
+        self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
+
+    def __resize_filesystem(self, size = None):
+        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
+
+        if size is None:
+            size = self.disk.size
+
+        if size == current_size:
+            return
+
+        if size > current_size:
+            self.disk.expand(size=size)
+
+        self.__fsck()
+        return size
+
+    def __create(self):
+        resize = False
+        if not self.disk.fixed() and self.disk.exists():
+            resize = True
+
+        self.disk.create()
+
+        if resize:
+            self.__resize_filesystem()
+        else:
+            self.__format_filesystem()
+
+    def mount(self, options = None, init_expand = False):
+        self.__create()
+        if init_expand:
+            expand_size = long(self.disk.size * 1.5)
+            msger.info("Initial partition size expanded : %ld -> %ld" % (self.disk.size, expand_size))
+            self.__resize_filesystem(expand_size)
+            self.disk.reread_size()
+        DiskMount.mount(self, options)
+
+    def __fsck(self):
+        msger.debug("Checking filesystem %s" % self.disk.lofile)
+        runner.quiet([self.btrfsckcmd, self.disk.lofile])
+
+    def __get_size_from_filesystem(self):
+        return self.disk.size
+
+    def __resize_to_minimal(self):
+        self.__fsck()
+
+        return self.__get_size_from_filesystem()
+
+    def resparse(self, size = None):
+        self.cleanup()
+        minsize = self.__resize_to_minimal()
+        self.disk.truncate(minsize)
+        self.__resize_filesystem(size)
+        return minsize
+
+class DeviceMapperSnapshot(object):
+    def __init__(self, imgloop, cowloop):
+        self.imgloop = imgloop
+        self.cowloop = cowloop
+
+        self.__created = False
+        self.__name = None
+        self.dmsetupcmd = find_binary_path("dmsetup")
+
+        """Load dm_snapshot if it isn't loaded"""
+        load_module("dm_snapshot")
+
+    def get_path(self):
+        if self.__name is None:
+            return None
+        return os.path.join("/dev/mapper", self.__name)
+    path = property(get_path)
+
+    def create(self):
+        if self.__created:
+            return
+
+        self.imgloop.create()
+        self.cowloop.create()
+
+        self.__name = "imgcreate-%d-%d" % (os.getpid(),
+                                           random.randint(0, 2**16))
+
+        size = os.stat(self.imgloop.lofile)[stat.ST_SIZE]
+
+        table = "0 %d snapshot %s %s p 8" % (size / 512,
+                                             self.imgloop.device,
+                                             self.cowloop.device)
+
+        args = [self.dmsetupcmd, "create", self.__name, "--table", table]
+        if runner.show(args) != 0:
+            self.cowloop.cleanup()
+            self.imgloop.cleanup()
+            raise SnapshotError("Could not create snapshot device using: " + ' '.join(args))
+
+        self.__created = True
+
+    def remove(self, ignore_errors = False):
+        if not self.__created:
+            return
+
+        time.sleep(2)
+        rc = runner.show([self.dmsetupcmd, "remove", self.__name])
+        if not ignore_errors and rc != 0:
+            raise SnapshotError("Could not remove snapshot device")
+
+        self.__name = None
+        self.__created = False
+
+        self.cowloop.cleanup()
+        self.imgloop.cleanup()
+
+    def get_cow_used(self):
+        if not self.__created:
+            return 0
+
+        #
+        # dmsetup status on a snapshot returns e.g.
+        #   "0 8388608 snapshot 416/1048576"
+        # or, more generally:
+        #   "A B snapshot C/D"
+        # where C is the number of 512 byte sectors in use
+        #
+        out = runner.outs([self.dmsetupcmd, "status", self.__name])
+        try:
+            return int((out.split()[3]).split('/')[0]) * 512
+        except ValueError:
+            raise SnapshotError("Failed to parse dmsetup status: " + out)
+
+def create_image_minimizer(path, image, minimal_size):
+    """
+    Builds a copy-on-write image which can be used to
+    create a device-mapper snapshot of an image where
+    the image's filesystem is as small as possible
+
+    The steps taken are:
+      1) Create a sparse COW
+      2) Loopback mount the image and the COW
+      3) Create a device-mapper snapshot of the image
+         using the COW
+      4) Resize the filesystem to the minimal size
+      5) Determine the amount of space used in the COW
+      6) Restroy the device-mapper snapshot
+      7) Truncate the COW, removing unused space
+      8) Create a squashfs of the COW
+    """
+    imgloop = LoopbackDisk(image, None) # Passing bogus size - doesn't matter
+
+    cowloop = SparseLoopbackDisk(os.path.join(os.path.dirname(path), "osmin"),
+                                 64 * 1024 * 1024)
+
+    snapshot = DeviceMapperSnapshot(imgloop, cowloop)
+
+    try:
+        snapshot.create()
+
+        resize2fs(snapshot.path, minimal_size)
+
+        cow_used = snapshot.get_cow_used()
+    finally:
+        snapshot.remove(ignore_errors = (not sys.exc_info()[0] is None))
+
+    cowloop.truncate(cow_used)
+
+    mksquashfs(cowloop.lofile, path)
+
+    os.unlink(cowloop.lofile)
+
+def load_module(module):
+    found = False
+    for line in open('/proc/modules').xreadlines():
+        if line.startswith("%s " % module):
+            found = True
+            break
+    if not found:
+        msger.info("Loading %s..." % module)
+        runner.quiet(['modprobe', module])
+
+class LoopDevice(object):
+    def __init__(self, loopid=None):
+        self.device = None
+        self.loopid = loopid
+        self.created = False
+        self.kpartxcmd = find_binary_path("kpartx")
+        self.losetupcmd = find_binary_path("losetup")
+
+    def register(self, device):
+        self.device = device
+        self.loopid = None
+        #self.created = True
+
+    def reg_atexit(self):
+        import atexit
+        atexit.register(self.close)
+
+    def _genloopid(self):
+        import glob
+        if not glob.glob("/dev/loop[0-9]*"):
+            return 10
+
+        fint = lambda x: x[9:].isdigit() and int(x[9:]) or 0
+        maxid = 1 + max(filter(lambda x: x<256,
+                               map(fint, glob.glob("/dev/loop[0-9]*"))))
+        if maxid < 10: maxid = 10
+        if maxid >= 256:
+            raise Exception("maxid >= 256")
+        return maxid
+
+    def _kpseek(self, device):
+        rc, out = runner.runtool([self.kpartxcmd, '-l', '-v', device])
+        if rc != 0:
+            raise MountError("Can't query dm snapshot on %s" % device)
+        for line in out.splitlines():
+            if line and line.startswith("loop"):
+                return True
+        return False
+
+    def _loseek(self, device):
+        import re
+        rc, out = runner.runtool([self.losetupcmd, '-a'])
+        if rc != 0:
+            raise MountError("Failed to run 'losetup -a'")
+        for line in out.splitlines():
+            m = re.match("([^:]+): .*", line)
+            if m and m.group(1) == device:
+                return True
+        return False
+
+    def create(self):
+        if not self.created:
+            if not self.loopid:
+                self.loopid = self._genloopid()
+            self.device = "/dev/loop%d" % self.loopid
+            if os.path.exists(self.device):
+                if self._loseek(self.device):
+                    raise MountError("Device busy: %s" % self.device)
+                else:
+                    self.created = True
+                    return
+
+            mknod = find_binary_path('mknod')
+            rc = runner.show([mknod, '-m664', self.device, 'b', '7', str(self.loopid)])
+            if rc != 0:
+                raise MountError("Failed to create device %s" % self.device)
+            else:
+                self.created = True
+
+    def close(self):
+        if self.created:
+            try:
+                self.cleanup()
+                self.device = None
+            except MountError  as e:
+                raise CreatorError("%s" % e)
+
+    def cleanup(self):
+
+        if self.device is None:
+            return
+
+
+        if self._kpseek(self.device):
+            runner.quiet([self.kpartxcmd, "-d", self.device])
+        if self._loseek(self.device):
+            runner.quiet([self.losetupcmd, "-d", self.device])
+        # FIXME: should sleep a while between two loseek
+        if self._loseek(self.device):
+            msger.warning("Can't cleanup loop device %s" % self.device)
+        elif self.loopid:
+            os.unlink(self.device)
+
+DEVICE_PIDFILE_DIR = "/var/tmp/mic/device"
+DEVICE_LOCKFILE = "/var/lock/__mic_loopdev.lock"
+
+def get_loop_device(losetupcmd, lofile):
+    import fcntl
+    makedirs(os.path.dirname(DEVICE_LOCKFILE))
+    fp = open(DEVICE_LOCKFILE, 'w')
+    fcntl.flock(fp, fcntl.LOCK_EX)
+    try:
+        loopdev = None
+        devinst = LoopDevice()
+
+        # clean up left loop device first
+        clean_loop_devices()
+
+        # provide an avaible loop device
+        rc, out = runner.runtool([losetupcmd, "-f"])
+        if rc == 0 and out:
+            loopdev = out.split()[0]
+            devinst.register(loopdev)
+        if not loopdev or not os.path.exists(loopdev):
+            devinst.create()
+            loopdev = devinst.device
+
+        # setup a loop device for image file
+        rc = runner.show([losetupcmd, loopdev, lofile])
+        if rc != 0:
+            raise MountError("Failed to setup loop device for '%s'" % lofile)
+
+        devinst.reg_atexit()
+
+        # try to save device and pid
+        makedirs(DEVICE_PIDFILE_DIR)
+        pidfile = os.path.join(DEVICE_PIDFILE_DIR, os.path.basename(loopdev))
+        if os.path.exists(pidfile):
+            os.unlink(pidfile)
+        with open(pidfile, 'w') as wf:
+            wf.write(str(os.getpid()))
+
+    except MountError as err:
+        raise CreatorError("%s" % str(err))
+    except:
+        raise
+    finally:
+        try:
+            fcntl.flock(fp, fcntl.LOCK_UN)
+            fp.close()
+        except:
+            pass
+
+    return loopdev
+
+def clean_loop_devices(piddir=DEVICE_PIDFILE_DIR):
+    if not os.path.exists(piddir) or not os.path.isdir(piddir):
+        return
+
+    for loopdev in os.listdir(piddir):
+        pidfile = os.path.join(piddir, loopdev)
+        try:
+            with open(pidfile, 'r') as rf:
+                devpid = int(rf.read())
+        except:
+            devpid = None
+
+        # if the process using this device is alive, skip it
+        if not devpid or os.path.exists(os.path.join('/proc', str(devpid))):
+            continue
+
+        # try to clean it up
+        try:
+            devinst = LoopDevice()
+            devinst.register(os.path.join('/dev', loopdev))
+            devinst.cleanup()
+            os.unlink(pidfile)
+        except:
+            pass
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/gpt_parser.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/gpt_parser.py
new file mode 100644 (file)
index 0000000..c499e81
--- /dev/null
@@ -0,0 +1,331 @@
+#!/usr/bin/python -tt
+#
+# Copyright (c) 2013 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.
+
+""" This module implements a simple GPT partitions parser which can read the
+GPT header and the GPT partition table. """
+
+import struct
+import uuid
+import binascii
+from mic.utils.errors import MountError
+
+_GPT_HEADER_FORMAT = "<8s4sIIIQQQQ16sQIII"
+_GPT_HEADER_SIZE = struct.calcsize(_GPT_HEADER_FORMAT)
+_GPT_ENTRY_FORMAT = "<16s16sQQQ72s"
+_GPT_ENTRY_SIZE = struct.calcsize(_GPT_ENTRY_FORMAT)
+_SUPPORTED_GPT_REVISION = '\x00\x00\x01\x00'
+
+def _stringify_uuid(binary_uuid):
+    """ A small helper function to transform a binary UUID into a string
+    format. """
+
+    uuid_str = str(uuid.UUID(bytes_le = binary_uuid))
+
+    return uuid_str.upper()
+
+def _calc_header_crc(raw_hdr):
+    """ Calculate GPT header CRC32 checksum. The 'raw_hdr' parameter has to
+    be a list or a tuple containing all the elements of the GPT header in a
+    "raw" form, meaning that it should simply contain "unpacked" disk data.
+    """
+
+    raw_hdr = list(raw_hdr)
+    raw_hdr[3] = 0
+    raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr)
+
+    return binascii.crc32(raw_hdr) & 0xFFFFFFFF
+
+def _validate_header(raw_hdr):
+    """ Validate the GPT header. The 'raw_hdr' parameter has to be a list or a
+    tuple containing all the elements of the GPT header in a "raw" form,
+    meaning that it should simply contain "unpacked" disk data. """
+
+    # Validate the signature
+    if raw_hdr[0] != 'EFI PART':
+        raise MountError("GPT partition table not found")
+
+    # Validate the revision
+    if raw_hdr[1] != _SUPPORTED_GPT_REVISION:
+        raise MountError("Unsupported GPT revision '%s', supported revision " \
+                         "is '%s'" % \
+                          (binascii.hexlify(raw_hdr[1]),
+                           binascii.hexlify(_SUPPORTED_GPT_REVISION)))
+
+    # Validate header size
+    if raw_hdr[2] != _GPT_HEADER_SIZE:
+        raise MountError("Bad GPT header size: %d bytes, expected %d" % \
+                         (raw_hdr[2], _GPT_HEADER_SIZE))
+
+    crc = _calc_header_crc(raw_hdr)
+    if raw_hdr[3] != crc:
+        raise MountError("GPT header crc mismatch: %#x, should be %#x" % \
+                         (crc, raw_hdr[3]))
+
+class GptParser:
+    """ GPT partition table parser. Allows reading the GPT header and the
+    partition table, as well as modifying the partition table records. """
+
+    def __init__(self, disk_path, sector_size = 512):
+        """ The class constructor which accepts the following parameters:
+            * disk_path - full path to the disk image or device node
+            * sector_size - size of a disk sector in bytes """
+
+        self.sector_size = sector_size
+        self.disk_path = disk_path
+
+        try:
+            self._disk_obj = open(disk_path, 'r+b')
+        except IOError as err:
+            raise MountError("Cannot open file '%s' for reading GPT " \
+                             "partitions: %s" % (disk_path, err))
+
+    def __del__(self):
+        """ The class destructor. """
+
+        self._disk_obj.close()
+
+    def _read_disk(self, offset, size):
+        """ A helper function which reads 'size' bytes from offset 'offset' of
+        the disk and checks all the error conditions. """
+
+        self._disk_obj.seek(offset)
+        try:
+            data = self._disk_obj.read(size)
+        except IOError as err:
+            raise MountError("cannot read from '%s': %s" % \
+                             (self.disk_path, err))
+
+        if len(data) != size:
+            raise MountError("cannot read %d bytes from offset '%d' of '%s', " \
+                             "read only %d bytes" % \
+                             (size, offset, self.disk_path, len(data)))
+
+        return data
+
+    def _write_disk(self, offset, buf):
+        """ A helper function which writes buffer 'buf' to offset 'offset' of
+        the disk. This function takes care of unaligned writes and checks all
+        the error conditions. """
+
+        # Since we may be dealing with a block device, we only can write in
+        # 'self.sector_size' chunks. Find the aligned starting and ending
+        # disk offsets to read.
+        start =  (offset / self.sector_size) * self.sector_size
+        end = ((start + len(buf)) / self.sector_size + 1) * self.sector_size
+
+        data = self._read_disk(start, end - start)
+        off = offset - start
+        data = data[:off] + buf + data[off + len(buf):]
+
+        self._disk_obj.seek(start)
+        try:
+            self._disk_obj.write(data)
+        except IOError as err:
+            raise MountError("cannot write to '%s': %s" % (self.disk_path, err))
+
+    def read_header(self, primary = True):
+        """ Read and verify the GPT header and return a dictionary containing
+        the following elements:
+
+        'signature'   : header signature
+        'revision'    : header revision
+        'hdr_size'    : header size in bytes
+        'hdr_crc'     : header CRC32
+        'hdr_lba'     : LBA of this header
+        'hdr_offs'    : byte disk offset of this header
+        'backup_lba'  : backup header LBA
+        'backup_offs' : byte disk offset of backup header
+        'first_lba'   : first usable LBA for partitions
+        'first_offs'  : first usable byte disk offset for partitions
+        'last_lba'    : last usable LBA for partitions
+        'last_offs'   : last usable byte disk offset for partitions
+        'disk_uuid'   : UUID of the disk
+        'ptable_lba'  : starting LBA of array of partition entries
+        'ptable_offs' : disk byte offset of the start of the partition table
+        'ptable_size' : partition table size in bytes
+        'entries_cnt' : number of available partition table entries
+        'entry_size'  : size of a single partition entry
+        'ptable_crc'  : CRC32 of the partition table
+        'primary'     : a boolean, if 'True', this is the primary GPT header,
+                        if 'False' - the secondary
+        'primary_str' : contains string "primary" if this is the primary GPT
+                        header, and "backup" otherwise
+
+        This dictionary corresponds to the GPT header format. Please, see the
+        UEFI standard for the description of these fields.
+
+        If the 'primary' parameter is 'True', the primary GPT header is read,
+        otherwise the backup GPT header is read instead. """
+
+        # Read and validate the primary GPT header
+        raw_hdr = self._read_disk(self.sector_size, _GPT_HEADER_SIZE)
+        raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr)
+        _validate_header(raw_hdr)
+        primary_str = "primary"
+
+        if not primary:
+            # Read and validate the backup GPT header
+            raw_hdr = self._read_disk(raw_hdr[6] * self.sector_size, _GPT_HEADER_SIZE)
+            raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr)
+            _validate_header(raw_hdr)
+            primary_str = "backup"
+
+        return { 'signature'   : raw_hdr[0],
+                 'revision'    : raw_hdr[1],
+                 'hdr_size'    : raw_hdr[2],
+                 'hdr_crc'     : raw_hdr[3],
+                 'hdr_lba'     : raw_hdr[5],
+                 'hdr_offs'    : raw_hdr[5] * self.sector_size,
+                 'backup_lba'  : raw_hdr[6],
+                 'backup_offs' : raw_hdr[6] * self.sector_size,
+                 'first_lba'   : raw_hdr[7],
+                 'first_offs'  : raw_hdr[7] * self.sector_size,
+                 'last_lba'    : raw_hdr[8],
+                 'last_offs'   : raw_hdr[8] * self.sector_size,
+                 'disk_uuid'   :_stringify_uuid(raw_hdr[9]),
+                 'ptable_lba'  : raw_hdr[10],
+                 'ptable_offs' : raw_hdr[10] * self.sector_size,
+                 'ptable_size' : raw_hdr[11] * raw_hdr[12],
+                 'entries_cnt' : raw_hdr[11],
+                 'entry_size'  : raw_hdr[12],
+                 'ptable_crc'  : raw_hdr[13],
+                 'primary'     : primary,
+                 'primary_str' : primary_str }
+
+    def _read_raw_ptable(self, header):
+        """ Read and validate primary or backup partition table. The 'header'
+        argument is the GPT header. If it is the primary GPT header, then the
+        primary partition table is read and validated, otherwise - the backup
+        one. The 'header' argument is a dictionary which is returned by the
+        'read_header()' method. """
+
+        raw_ptable = self._read_disk(header['ptable_offs'],
+                                     header['ptable_size'])
+
+        crc = binascii.crc32(raw_ptable) & 0xFFFFFFFF
+        if crc != header['ptable_crc']:
+            raise MountError("Partition table at LBA %d (%s) is corrupted" % \
+                             (header['ptable_lba'], header['primary_str']))
+
+        return raw_ptable
+
+    def get_partitions(self, primary = True):
+        """ This is a generator which parses the GPT partition table and
+        generates the following dictionary for each partition:
+
+        'index'       : the index of the partition table endry
+        'offs'        : byte disk offset of the partition table entry
+        'type_uuid'   : partition type UUID
+        'part_uuid'   : partition UUID
+        'first_lba'   : the first LBA
+        'last_lba'    : the last LBA
+        'flags'       : attribute flags
+        'name'        : partition name
+        'primary'     : a boolean, if 'True', this is the primary partition
+                        table, if 'False' - the secondary
+        'primary_str' : contains string "primary" if this is the primary GPT
+                        header, and "backup" otherwise
+
+        This dictionary corresponds to the GPT header format. Please, see the
+        UEFI standard for the description of these fields.
+
+        If the 'primary' parameter is 'True', partitions from the primary GPT
+        partition table are generated, otherwise partitions from the backup GPT
+        partition table are generated. """
+
+        if primary:
+            primary_str = "primary"
+        else:
+            primary_str = "backup"
+
+        header = self.read_header(primary)
+        raw_ptable = self._read_raw_ptable(header)
+
+        for index in xrange(0, header['entries_cnt']):
+            start = header['entry_size'] * index
+            end = start + header['entry_size']
+            raw_entry = struct.unpack(_GPT_ENTRY_FORMAT, raw_ptable[start:end])
+
+            if raw_entry[2] == 0 or raw_entry[3] == 0:
+                continue
+
+            part_name = str(raw_entry[5].decode('UTF-16').split('\0', 1)[0])
+
+            yield { 'index'       : index,
+                    'offs'        : header['ptable_offs'] + start,
+                    'type_uuid'   : _stringify_uuid(raw_entry[0]),
+                    'part_uuid'   : _stringify_uuid(raw_entry[1]),
+                    'first_lba'   : raw_entry[2],
+                    'last_lba'    : raw_entry[3],
+                    'flags'       : raw_entry[4],
+                    'name'        : part_name,
+                    'primary'     : primary,
+                    'primary_str' : primary_str }
+
+    def _change_partition(self, header, entry):
+        """ A helper function for 'change_partitions()' which changes a
+        a paricular instance of the partition table (primary or backup). """
+
+        if entry['index'] >= header['entries_cnt']:
+            raise MountError("Partition table at LBA %d has only %d "   \
+                             "records cannot change record number " % \
+                             (header['entries_cnt'], entry['index']))
+        # Read raw GPT header
+        raw_hdr = self._read_disk(header['hdr_offs'], _GPT_HEADER_SIZE)
+        raw_hdr = list(struct.unpack(_GPT_HEADER_FORMAT, raw_hdr))
+        _validate_header(raw_hdr)
+
+        # Prepare the new partition table entry
+        raw_entry = struct.pack(_GPT_ENTRY_FORMAT,
+                                uuid.UUID(entry['type_uuid']).bytes_le,
+                                uuid.UUID(entry['part_uuid']).bytes_le,
+                                entry['first_lba'],
+                                entry['last_lba'],
+                                entry['flags'],
+                                entry['name'].encode('UTF-16LE'))
+
+        # Write the updated entry to the disk
+        entry_offs = header['ptable_offs'] + \
+                     header['entry_size'] * entry['index']
+        self._write_disk(entry_offs, raw_entry)
+
+        # Calculate and update partition table CRC32
+        raw_ptable = self._read_disk(header['ptable_offs'],
+                                     header['ptable_size'])
+        raw_hdr[13] = binascii.crc32(raw_ptable) & 0xFFFFFFFF
+
+        # Calculate and update the GPT header CRC
+        raw_hdr[3] = _calc_header_crc(raw_hdr)
+
+        # Write the updated header to the disk
+        raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr)
+        self._write_disk(header['hdr_offs'], raw_hdr)
+
+    def change_partition(self, entry):
+        """ Change a GPT partition. The 'entry' argument has the same format as
+        'get_partitions()' returns. This function simply changes the partition
+        table record corresponding to 'entry' in both, the primary and the
+        backup GPT partition tables. The parition table CRC is re-calculated
+        and the GPT headers are modified accordingly. """
+
+        # Change the primary partition table
+        header = self.read_header(True)
+        self._change_partition(header, entry)
+
+        # Change the backup partition table
+        header = self.read_header(False)
+        self._change_partition(header, entry)
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/grabber.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/grabber.py
new file mode 100644 (file)
index 0000000..a87d5a4
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/python
+
+# Copyright (c) 2014 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 fcntl
+import struct
+import termios
+
+from mic import msger
+from mic.utils import runner
+from mic.utils.errors import CreatorError
+from mic.utils.safeurl import SafeURL
+
+from urlgrabber import grabber
+from urlgrabber import __version__ as grabber_version
+
+def myurlgrab(url, filename, proxies, progress_obj = None):
+    g = grabber.URLGrabber()
+    if progress_obj is None:
+        progress_obj = TextProgress()
+
+    if url.startswith("file:/"):
+        filepath = "/%s" % url.replace("file:", "").lstrip('/')
+        if not os.path.exists(filepath):
+            raise CreatorError("URLGrabber error: can't find file %s" % url)
+        if url.endswith('.rpm'):
+            return filepath
+        else:
+            # untouch repometadata in source path
+            runner.show(['cp', '-f', filepath, filename])
+
+    else:
+        try:
+            # cast url to str here, sometimes it can be unicode,
+            # but pycurl only accept str
+            filename = g.urlgrab(url=str(url),
+                                 filename=filename,
+                                 ssl_verify_host=False,
+                                 ssl_verify_peer=False,
+                                 proxies=proxies,
+                                 http_headers=(('Pragma', 'no-cache'),),
+                                 quote=0,
+                                 progress_obj=progress_obj)
+        except grabber.URLGrabError as err:
+            tmp = SafeURL(url)
+            msg = str(err)
+
+            if msg.find(url) < 0:
+                msg += ' on %s' % tmp
+            else:
+                msg = msg.replace(url, tmp)
+
+            raise CreatorError(msg)
+
+    return filename
+
+def terminal_width(fd=1):
+    """ Get the real terminal width """
+    try:
+        buf = 'abcdefgh'
+        buf = fcntl.ioctl(fd, termios.TIOCGWINSZ, buf)
+        return struct.unpack('hhhh', buf)[1]
+    except: # IOError
+        return 80
+
+def truncate_url(url, width):
+    return os.path.basename(url)[0:width]
+
+class TextProgress(object):
+    # make the class as singleton
+    _instance = None
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(TextProgress, cls).__new__(cls, *args, **kwargs)
+
+        return cls._instance
+
+    def __init__(self, totalnum = None):
+        self.total = totalnum
+        self.counter = 1
+
+    def start(self, filename, url, *args, **kwargs):
+        self.url = url
+        self.termwidth = terminal_width()
+        if self.total is None:
+            msger.info("Retrieving %s ..." % truncate_url(self.url, self.termwidth - 15))
+        else:
+            msger.info("Retrieving %s [%d/%d] ..." % (truncate_url(self.url, self.termwidth - 25), self.counter, self.total))
+
+    def update(self, *args):
+        pass
+
+    def end(self, *args):
+        if self.counter == self.total:
+            msger.raw("\n")
+
+        if self.total is not None:
+            self.counter += 1
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/lock.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/lock.py
new file mode 100644 (file)
index 0000000..ca8d5a0
--- /dev/null
@@ -0,0 +1,49 @@
+# 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; either version 2 of the License, or any later version.
+
+import os
+import errno
+
+class LockfileError(Exception):
+    """ Lockfile Exception"""
+    pass
+
+class SimpleLockfile(object):
+    """ Simple implementation of lockfile """
+    def __init__(self, fpath):
+        self.fpath = fpath
+        self.lockf = None
+
+    def acquire(self):
+        """ acquire the lock """
+        try:
+            self.lockf = os.open(self.fpath,
+                                 os.O_CREAT | os.O_EXCL | os.O_WRONLY)
+        except OSError as err:
+            if err.errno == errno.EEXIST:
+                raise LockfileError("File %s is locked already" % self.fpath)
+            raise
+        finally:
+            if self.lockf:
+                os.close(self.lockf)
+
+    def release(self):
+        """ release the lock """
+        try:
+            os.remove(self.fpath)
+        except OSError as err:
+            if err.errno == errno.ENOENT:
+                pass
+
+    def __enter__(self):
+        self.acquire()
+        return self
+
+    def __exit__(self, *args):
+        self.release()
+
+    def __del__(self):
+        self.release()
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/misc.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/misc.py
new file mode 100644 (file)
index 0000000..1fbbcd9
--- /dev/null
@@ -0,0 +1,1075 @@
+#!/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.
+
+from __future__ import with_statement
+import os
+import sys
+import time
+import tempfile
+import re
+import shutil
+import glob
+import hashlib
+import subprocess
+import platform
+import traceback
+
+
+try:
+    import sqlite3 as sqlite
+except ImportError:
+    import sqlite
+
+try:
+    from xml.etree import cElementTree
+except ImportError:
+    import cElementTree
+xmlparse = cElementTree.parse
+
+from mic import msger
+from mic.archive import get_archive_suffixes
+from mic.utils.errors import CreatorError, SquashfsError
+from mic.utils.fs_related import find_binary_path, makedirs
+from mic.utils.grabber import myurlgrab
+from mic.utils.proxy import get_proxy_for
+from mic.utils import runner
+from mic.utils import rpmmisc
+from mic.utils.safeurl import SafeURL
+
+
+RPM_RE  = re.compile("(.*)\.(.*) (.*)-(.*)")
+RPM_FMT = "%(name)s.%(arch)s %(version)s-%(release)s"
+SRPM_RE = re.compile("(.*)-(\d+.*)-(\d+\.\d+).src.rpm")
+
+
+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
+
+def get_distro():
+    """Detect linux distribution, support "meego"
+    """
+
+    support_dists = ('SuSE',
+                     'debian',
+                     'fedora',
+                     'redhat',
+                     'centos',
+                     'meego',
+                     'moblin',
+                     'tizen')
+    try:
+        (dist, ver, id) = platform.linux_distribution( \
+                              supported_dists = support_dists)
+    except:
+        (dist, ver, id) = platform.dist( \
+                              supported_dists = support_dists)
+
+    return (dist, ver, id)
+
+def get_hostname():
+    """Get hostname
+    """
+    return platform.node()
+
+def get_hostname_distro_str():
+    """Get composited string for current linux distribution
+    """
+    (dist, ver, id) = get_distro()
+    hostname = get_hostname()
+
+    if not dist:
+        return "%s(Unknown Linux Distribution)" % hostname
+    else:
+        distro_str = ' '.join(map(str.strip, (hostname, dist, ver, id)))
+        return distro_str.strip()
+
+_LOOP_RULE_PTH = None
+
+def hide_loopdev_presentation():
+    udev_rules = "80-prevent-loop-present.rules"
+    udev_rules_dir = [
+                       '/usr/lib/udev/rules.d/',
+                       '/lib/udev/rules.d/',
+                       '/etc/udev/rules.d/'
+                     ]
+
+    global _LOOP_RULE_PTH
+
+    for rdir in udev_rules_dir:
+        if os.path.exists(rdir):
+            _LOOP_RULE_PTH = os.path.join(rdir, udev_rules)
+
+    if not _LOOP_RULE_PTH:
+        return
+
+    try:
+        with open(_LOOP_RULE_PTH, 'w') as wf:
+            wf.write('KERNEL=="loop*", ENV{UDISKS_PRESENTATION_HIDE}="1"')
+
+        runner.quiet('udevadm trigger')
+    except:
+        pass
+
+def unhide_loopdev_presentation():
+    #global _LOOP_RULE_PTH
+
+    if not _LOOP_RULE_PTH:
+        return
+
+    try:
+        os.unlink(_LOOP_RULE_PTH)
+        runner.quiet('udevadm trigger')
+    except:
+        pass
+
+def extract_rpm(rpmfile, targetdir):
+    rpm2cpio = find_binary_path("rpm2cpio")
+    cpio = find_binary_path("cpio")
+
+    olddir = os.getcwd()
+    os.chdir(targetdir)
+
+    msger.verbose("Extract rpm file with cpio: %s" % rpmfile)
+    p1 = subprocess.Popen([rpm2cpio, rpmfile], stdout=subprocess.PIPE)
+    p2 = subprocess.Popen([cpio, "-idv"], stdin=p1.stdout,
+                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    p1.stdout.close()
+    (sout, serr) = p2.communicate()
+    msger.verbose(sout or serr)
+
+    os.chdir(olddir)
+
+def human_size(size):
+    """Return human readable string for Bytes size
+    """
+
+    if size <= 0:
+        return "0M"
+    import math
+    measure = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
+    expo = int(math.log(size, 1024))
+    mant = float(size/math.pow(1024, expo))
+    return "{0:.1f}{1:s}".format(mant, measure[expo])
+
+def get_block_size(file_obj):
+    """ Returns block size for file object 'file_obj'. Errors are indicated by
+    the 'IOError' exception. """
+
+    from fcntl import ioctl
+    import struct
+
+    # Get the block size of the host file-system for the image file by calling
+    # the FIGETBSZ ioctl (number 2).
+    binary_data = ioctl(file_obj, 2, struct.pack('I', 0))
+    return struct.unpack('I', binary_data)[0]
+
+def check_space_pre_cp(src, dst):
+    """Check whether disk space is enough before 'cp' like
+    operations, else exception will be raised.
+    """
+
+    srcsize  = get_file_size(src) * 1024 * 1024
+    freesize = get_filesystem_avail(dst)
+    if srcsize > freesize:
+        raise CreatorError("space on %s(%s) is not enough for about %s files"
+                           % (dst, human_size(freesize), human_size(srcsize)))
+
+def calc_hashes(file_path, hash_names, start = 0, end = None):
+    """ Calculate hashes for a file. The 'file_path' argument is the file
+    to calculate hash functions for, 'start' and 'end' are the starting and
+    ending file offset to calculate the has functions for. The 'hash_names'
+    argument is a list of hash names to calculate. Returns the the list
+    of calculated hash values in the hexadecimal form in the same order
+    as 'hash_names'.
+    """
+    if end == None:
+        end = os.path.getsize(file_path)
+
+    chunk_size = 65536
+    to_read = end - start
+    read = 0
+
+    hashes = []
+    for hash_name in hash_names:
+        hashes.append(hashlib.new(hash_name))
+
+    with open(file_path, "rb") as f:
+        f.seek(start)
+
+        while read < to_read:
+            if read + chunk_size > to_read:
+                chunk_size = to_read - read
+            chunk = f.read(chunk_size)
+            for hash_obj in hashes:
+                hash_obj.update(chunk)
+            read += chunk_size
+
+    result = []
+    for hash_obj in hashes:
+        result.append(hash_obj.hexdigest())
+
+    return result
+
+def get_md5sum(fpath):
+    return calc_hashes(fpath, ('md5', ))[0]
+
+def get_sha1sum(fpath):
+    return calc_hashes(fpath, ('sha1', ))[0]
+
+def get_sha256sum(fpath):
+    return calc_hashes(fpath, ('sha256', ))[0]
+
+def normalize_ksfile(ksconf, release, arch):
+    '''
+    Return the name of a normalized ks file in which macro variables
+    @BUILD_ID@ and @ARCH@ are replace with real values.
+
+    The original ks file is returned if no special macro is used, otherwise
+    a temp file is created and returned, which will be deleted when program
+    exits normally.
+    '''
+
+    if not release:
+        release = "latest"
+    if not arch or re.match(r'i.86', arch):
+        arch = "ia32"
+
+    with open(ksconf) as f:
+        ksc = f.read()
+
+    if "@ARCH@" not in ksc and "@BUILD_ID@" not in ksc:
+        return ksconf
+
+    msger.info("Substitute macro variable @BUILD_ID@/@ARCH@ in ks: %s" % ksconf)
+    ksc = ksc.replace("@ARCH@", arch)
+    ksc = ksc.replace("@BUILD_ID@", release)
+
+    fd, ksconf = tempfile.mkstemp(prefix=os.path.basename(ksconf))
+    os.write(fd, ksc)
+    os.close(fd)
+
+    msger.debug('normalized ks file:%s' % ksconf)
+
+    def remove_temp_ks():
+        try:
+            os.unlink(ksconf)
+        except OSError as err:
+            msger.warning('Failed to remove temp ks file:%s:%s' % (ksconf, err))
+
+    import atexit
+    atexit.register(remove_temp_ks)
+
+    return ksconf
+
+
+def _check_mic_chroot(rootdir):
+    def _path(path):
+        return rootdir.rstrip('/') + path
+
+    release_files = map(_path, [ "/etc/moblin-release",
+                                 "/etc/meego-release",
+                                 "/etc/tizen-release"])
+
+    if not any(map(os.path.exists, release_files)):
+        msger.warning("Dir %s is not a MeeGo/Tizen chroot env" % rootdir)
+
+    if not glob.glob(rootdir + "/boot/vmlinuz-*"):
+        msger.warning("Failed to find kernel module under %s" % rootdir)
+
+    return
+
+def selinux_check(arch, fstypes):
+    try:
+        getenforce = find_binary_path('getenforce')
+    except CreatorError:
+        return
+
+    selinux_status = runner.outs([getenforce])
+    if arch and arch.startswith("arm") and selinux_status == "Enforcing":
+        raise CreatorError("Can't create arm image if selinux is enabled, "
+                           "please run 'setenforce 0' to disable selinux")
+
+    use_btrfs = filter(lambda typ: typ == 'btrfs', fstypes)
+    if use_btrfs and selinux_status == "Enforcing":
+        raise CreatorError("Can't create btrfs image if selinux is enabled,"
+                           " please run 'setenforce 0' to disable selinux")
+
+def get_image_type(path):
+    def _get_extension_name(path):
+        match = re.search("(?<=\.)\w+$", path)
+        if match:
+            return match.group(0)
+        else:
+            return None
+
+    if os.path.isdir(path):
+        _check_mic_chroot(path)
+        return "fs"
+
+    maptab = {
+              "tar": "loop",
+              "raw":"raw",
+              "vmdk":"vmdk",
+              "vdi":"vdi",
+              "iso":"livecd",
+              "usbimg":"liveusb",
+             }
+
+    extension = _get_extension_name(path)
+    if extension in maptab:
+        return maptab[extension]
+
+    fd = open(path, "rb")
+    file_header = fd.read(1024)
+    fd.close()
+    vdi_flag = "<<< Sun VirtualBox Disk Image >>>"
+    if file_header[0:len(vdi_flag)] == vdi_flag:
+        return maptab["vdi"]
+
+    #Checking f2fs fs type.
+    blkidcmd = find_binary_path("blkid")
+    out = runner.outs([blkidcmd, '-o', 'value', '-s', 'TYPE', path])
+    if out == "f2fs":
+        return "f2fsimg"
+    output = runner.outs(['file', path])
+    isoptn = re.compile(r".*ISO 9660 CD-ROM filesystem.*(bootable).*")
+    usbimgptn = re.compile(r".*x86 boot sector.*active.*")
+    rawptn = re.compile(r".*x86 boot sector.*")
+    vmdkptn = re.compile(r".*VMware. disk image.*")
+    ext3fsimgptn = re.compile(r".*Linux.*ext3 filesystem data.*")
+    ext4fsimgptn = re.compile(r".*Linux.*ext4 filesystem data.*")
+    btrfsimgptn = re.compile(r".*BTRFS.*")
+    if isoptn.match(output):
+        return maptab["iso"]
+    elif usbimgptn.match(output):
+        return maptab["usbimg"]
+    elif rawptn.match(output):
+        return maptab["raw"]
+    elif vmdkptn.match(output):
+        return maptab["vmdk"]
+    elif ext3fsimgptn.match(output):
+        return "ext3fsimg"
+    elif ext4fsimgptn.match(output):
+        return "ext4fsimg"
+    elif btrfsimgptn.match(output):
+        return "btrfsimg"
+    else:
+        raise CreatorError("Cannot detect the type of image: %s" % path)
+
+
+def get_file_size(filename):
+    """ Return size in MB unit """
+    cmd = ['du', "-s", "-b", "-B", "1M", filename]
+    rc, duOutput  = runner.runtool(cmd)
+    if rc != 0:
+        raise CreatorError("Failed to run: %s" % ' '.join(cmd))
+    size1 = int(duOutput.split()[0])
+
+    cmd = ['du', "-s", "-B", "1M", filename]
+    rc, duOutput = runner.runtool(cmd)
+    if rc != 0:
+        raise CreatorError("Failed to run: %s" % ' '.join(cmd))
+
+    size2 = int(duOutput.split()[0])
+    return max(size1, size2)
+
+
+def get_filesystem_avail(fs):
+    vfstat = os.statvfs(fs)
+    return vfstat.f_bavail * vfstat.f_bsize
+
+def convert_image(srcimg, srcfmt, dstimg, dstfmt):
+    #convert disk format
+    if dstfmt != "raw":
+        raise CreatorError("Invalid destination image format: %s" % dstfmt)
+    msger.debug("converting %s image to %s" % (srcimg, dstimg))
+    if srcfmt == "vmdk":
+        path = find_binary_path("qemu-img")
+        argv = [path, "convert", "-f", "vmdk", srcimg, "-O", dstfmt,  dstimg]
+    elif srcfmt == "vdi":
+        path = find_binary_path("VBoxManage")
+        argv = [path, "internalcommands", "converttoraw", srcimg, dstimg]
+    else:
+        raise CreatorError("Invalid soure image format: %s" % srcfmt)
+
+    rc = runner.show(argv)
+    if rc == 0:
+        msger.debug("convert successful")
+    if rc != 0:
+        raise CreatorError("Unable to convert disk to %s" % dstfmt)
+
+def uncompress_squashfs(squashfsimg, outdir):
+    """Uncompress file system from squshfs image"""
+    unsquashfs = find_binary_path("unsquashfs")
+    args = [ unsquashfs, "-d", outdir, squashfsimg ]
+    rc = runner.show(args)
+    if (rc != 0):
+        raise SquashfsError("Failed to uncompress %s." % squashfsimg)
+
+def mkdtemp(dir = "/var/tmp", prefix = "mic-tmp-"):
+    """ FIXME: use the dir in mic.conf instead """
+
+    makedirs(dir)
+    return tempfile.mkdtemp(dir = dir, prefix = prefix)
+
+def get_repostrs_from_ks(ks):
+    def _get_temp_reponame(baseurl):
+        md5obj = hashlib.md5(baseurl)
+        tmpreponame = "%s" % md5obj.hexdigest()
+        return tmpreponame
+
+    kickstart_repos = []
+
+    for repodata in ks.handler.repo.repoList:
+        repo = {}
+        for attr in ('name',
+                     'baseurl',
+                     'mirrorlist',
+                     'includepkgs', # val is list
+                     'excludepkgs', # val is list
+                     'cost',    # int
+                     'priority',# int
+                     'save',
+                     'proxy',
+                     'proxyuser',
+                     'proxypasswd',
+                     'proxypasswd',
+                     'debuginfo',
+                     'source',
+                     'gpgkey',
+                     'ssl_verify'):
+            if hasattr(repodata, attr) and getattr(repodata, attr):
+                repo[attr] = getattr(repodata, attr)
+
+        if 'name' not in repo:
+            repo['name'] = _get_temp_reponame(repodata.baseurl)
+        if hasattr(repodata, 'baseurl') and getattr(repodata, 'baseurl'):
+            repo['baseurl'] = SafeURL(getattr(repodata, 'baseurl'),
+                                      getattr(repodata, 'user', None),
+                                      getattr(repodata, 'passwd', None))
+
+        kickstart_repos.append(repo)
+
+    return kickstart_repos
+
+def _get_uncompressed_data_from_url(url, filename, proxies):
+    filename = myurlgrab(url.full, filename, proxies)
+    suffix = None
+    if filename.endswith(".gz"):
+        suffix = ".gz"
+        runner.quiet(['gunzip', "-f", filename])
+    elif filename.endswith(".bz2"):
+        suffix = ".bz2"
+        runner.quiet(['bunzip2', "-f", filename])
+    if suffix:
+        filename = filename.replace(suffix, "")
+    return filename
+
+def _get_metadata_from_repo(baseurl, proxies, cachedir, reponame, filename,
+                            sumtype=None, checksum=None):
+    url = baseurl.join(filename)
+    filename_tmp = str("%s/%s/%s" % (cachedir, reponame, os.path.basename(filename)))
+    if os.path.splitext(filename_tmp)[1] in (".gz", ".bz2"):
+        filename = os.path.splitext(filename_tmp)[0]
+    else:
+        filename = filename_tmp
+    if sumtype and checksum and os.path.exists(filename):
+        try:
+            sumcmd = find_binary_path("%ssum" % sumtype)
+        except:
+            file_checksum = None
+        else:
+            file_checksum = runner.outs([sumcmd, filename]).split()[0]
+
+        if file_checksum and file_checksum == checksum:
+            return filename
+
+    return _get_uncompressed_data_from_url(url,filename_tmp,proxies)
+
+def get_metadata_from_repos(repos, cachedir):
+    my_repo_metadata = []
+    for repo in repos:
+        reponame = repo.name
+        baseurl = repo.baseurl
+
+        if hasattr(repo, 'proxy'):
+            proxy = repo.proxy
+        else:
+            proxy = get_proxy_for(baseurl)
+
+        proxies = None
+        if proxy:
+            proxies = {str(baseurl.split(":")[0]): str(proxy)}
+
+        makedirs(os.path.join(cachedir, reponame))
+        url = baseurl.join("repodata/repomd.xml")
+        filename = os.path.join(cachedir, reponame, 'repomd.xml')
+        repomd = myurlgrab(url.full, filename, proxies)
+        try:
+            root = xmlparse(repomd)
+        except SyntaxError:
+            raise CreatorError("repomd.xml syntax error.")
+
+        ns = root.getroot().tag
+        ns = ns[0:ns.rindex("}")+1]
+
+        filepaths = {}
+        checksums = {}
+        sumtypes = {}
+
+        for elm in root.getiterator("%sdata" % ns):
+            if elm.attrib["type"] == "patterns":
+                filepaths['patterns'] = elm.find("%slocation" % ns).attrib['href']
+                checksums['patterns'] = elm.find("%sopen-checksum" % ns).text
+                sumtypes['patterns'] = elm.find("%sopen-checksum" % ns).attrib['type']
+                break
+
+        for elm in root.getiterator("%sdata" % ns):
+            #"group" type has no "open-checksum" filed, remove it.
+            if elm.attrib["type"] == "group_gz":
+                filepaths['comps'] = elm.find("%slocation" % ns).attrib['href']
+                checksums['comps'] = elm.find("%sopen-checksum" % ns).text
+                sumtypes['comps'] = elm.find("%sopen-checksum" % ns).attrib['type']
+                break
+
+        primary_type = None
+        for elm in root.getiterator("%sdata" % ns):
+            if elm.attrib["type"] in ("primary_db", "primary"):
+                primary_type = elm.attrib["type"]
+                filepaths['primary'] = elm.find("%slocation" % ns).attrib['href']
+                checksums['primary'] = elm.find("%sopen-checksum" % ns).text
+                sumtypes['primary'] = elm.find("%sopen-checksum" % ns).attrib['type']
+                break
+
+        if not primary_type:
+            continue
+
+        for item in ("primary", "patterns", "comps"):
+            if item not in filepaths:
+                filepaths[item] = None
+                continue
+            if not filepaths[item]:
+                continue
+            filepaths[item] = _get_metadata_from_repo(baseurl,
+                                                      proxies,
+                                                      cachedir,
+                                                      reponame,
+                                                      filepaths[item],
+                                                      sumtypes[item],
+                                                      checksums[item])
+
+        """ Get repo key """
+        try:
+            repokey = _get_metadata_from_repo(baseurl,
+                                              proxies,
+                                              cachedir,
+                                              reponame,
+                                              "repodata/repomd.xml.key")
+        except CreatorError:
+            repokey = None
+            msger.debug("\ncan't get %s/%s" % (baseurl, "repodata/repomd.xml.key"))
+
+        my_repo_metadata.append({"name":reponame,
+                                 "baseurl":baseurl,
+                                 "repomd":repomd,
+                                 "primary":filepaths['primary'],
+                                 "cachedir":cachedir,
+                                 "proxies":proxies,
+                                 "patterns":filepaths['patterns'],
+                                 "comps":filepaths['comps'],
+                                 "repokey":repokey,
+                                 "priority":repo.priority})
+
+    return my_repo_metadata
+
+def get_rpmver_in_repo(repometadata):
+    for repo in repometadata:
+        if repo["primary"].endswith(".xml"):
+            root = xmlparse(repo["primary"])
+            ns = root.getroot().tag
+            ns = ns[0:ns.rindex("}")+1]
+
+            versionlist = []
+            for elm in root.getiterator("%spackage" % ns):
+                if elm.find("%sname" % ns).text == 'rpm':
+                    for node in elm.getchildren():
+                        if node.tag == "%sversion" % ns:
+                            versionlist.append(node.attrib['ver'])
+
+            if versionlist:
+                return reversed(
+                         sorted(
+                           versionlist,
+                           key = lambda ver: map(int, ver.split('.')))).next()
+
+        elif repo["primary"].endswith(".sqlite"):
+            con = sqlite.connect(repo["primary"])
+            for row in con.execute("select version from packages where "
+                                   "name=\"rpm\" ORDER by version DESC"):
+                con.close()
+                return row[0]
+
+    return None
+
+def get_arch(repometadata):
+    archlist = []
+    for repo in repometadata:
+        if repo["primary"].endswith(".xml"):
+            root = xmlparse(repo["primary"])
+            ns = root.getroot().tag
+            ns = ns[0:ns.rindex("}")+1]
+            for elm in root.getiterator("%spackage" % ns):
+                if elm.find("%sarch" % ns).text not in ("noarch", "src"):
+                    arch = elm.find("%sarch" % ns).text
+                    if arch not in archlist:
+                        archlist.append(arch)
+        elif repo["primary"].endswith(".sqlite"):
+            con = sqlite.connect(repo["primary"])
+            for row in con.execute("select arch from packages where arch not in (\"src\", \"noarch\")"):
+                if row[0] not in archlist:
+                    archlist.append(row[0])
+
+            con.close()
+
+    uniq_arch = []
+    for i in range(len(archlist)):
+        if archlist[i] not in rpmmisc.archPolicies.keys():
+            continue
+        need_append = True
+        j = 0
+        while j < len(uniq_arch):
+            if archlist[i] in rpmmisc.archPolicies[uniq_arch[j]].split(':'):
+                need_append = False
+                break
+            if uniq_arch[j] in rpmmisc.archPolicies[archlist[i]].split(':'):
+                if need_append:
+                    uniq_arch[j] = archlist[i]
+                    need_append = False
+                else:
+                    uniq_arch.remove(uniq_arch[j])
+                    continue
+            j += 1
+        if need_append:
+             uniq_arch.append(archlist[i])
+
+    return uniq_arch, archlist
+
+def get_package(pkg, repometadata, arch = None):
+    ver = ""
+    priority = 99
+    target_repo = None
+    if not arch:
+        arches = []
+    elif arch not in rpmmisc.archPolicies:
+        arches = [arch]
+    else:
+        arches = rpmmisc.archPolicies[arch].split(':')
+        arches.append('noarch')
+
+    for repo in repometadata:
+        if repo["primary"].endswith(".xml"):
+            root = xmlparse(repo["primary"])
+            ns = root.getroot().tag
+            ns = ns[0:ns.rindex("}")+1]
+            for elm in root.getiterator("%spackage" % ns):
+                if elm.find("%sname" % ns).text == pkg and elm.find("%sarch" % ns).text in arches:
+                    if repo["priority"] != None:
+                        tmpprior = int(repo["priority"])
+                        if tmpprior < priority:
+                            priority = tmpprior
+                            location = elm.find("%slocation" % ns)
+                            pkgpath = "%s" % location.attrib['href']
+                            target_repo = repo
+                            break
+                        elif tmpprior > priority:
+                            break
+                    version = elm.find("%sversion" % ns)
+                    tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
+                    if tmpver > ver:
+                        ver = tmpver
+                        location = elm.find("%slocation" % ns)
+                        pkgpath = "%s" % location.attrib['href']
+                        target_repo = repo
+                    break
+        if repo["primary"].endswith(".sqlite"):
+            con = sqlite.connect(repo["primary"])
+            if arch:
+                sql = 'select version, release, location_href from packages ' \
+                      'where name = "%s" and arch IN ("%s")' % \
+                      (pkg, '","'.join(arches))
+                for row in con.execute(sql):
+                    tmpver = "%s-%s" % (row[0], row[1])
+                    if tmpver > ver:
+                        ver = tmpver
+                        pkgpath = "%s" % row[2]
+                        target_repo = repo
+                    break
+            else:
+                sql = 'select version, release, location_href from packages ' \
+                      'where name = "%s"' % pkg
+                for row in con.execute(sql):
+                    tmpver = "%s-%s" % (row[0], row[1])
+                    if tmpver > ver:
+                        ver = tmpver
+                        pkgpath = "%s" % row[2]
+                        target_repo = repo
+                    break
+            con.close()
+    if target_repo:
+        makedirs("%s/packages/%s" % (target_repo["cachedir"], target_repo["name"]))
+        url = target_repo["baseurl"].join(pkgpath)
+        filename = str("%s/packages/%s/%s" % (target_repo["cachedir"], target_repo["name"], os.path.basename(pkgpath)))
+        if os.path.exists(filename):
+            ret = rpmmisc.checkRpmIntegrity('rpm', filename)
+            if ret == 0:
+                return filename
+
+            msger.warning("package %s is damaged: %s" %
+                          (os.path.basename(filename), filename))
+            os.unlink(filename)
+
+        pkg = myurlgrab(url.full, filename, target_repo["proxies"])
+        return pkg
+    else:
+        return None
+
+def get_source_name(pkg, repometadata):
+
+    def get_bin_name(pkg):
+        m = RPM_RE.match(pkg)
+        if m:
+            return m.group(1)
+        return None
+
+    def get_src_name(srpm):
+        m = SRPM_RE.match(srpm)
+        if m:
+            return m.group(1)
+        return None
+
+    ver = ""
+    target_repo = None
+
+    pkg_name = get_bin_name(pkg)
+    if not pkg_name:
+        return None
+
+    for repo in repometadata:
+        if repo["primary"].endswith(".xml"):
+            root = xmlparse(repo["primary"])
+            ns = root.getroot().tag
+            ns = ns[0:ns.rindex("}")+1]
+            for elm in root.getiterator("%spackage" % ns):
+                if elm.find("%sname" % ns).text == pkg_name:
+                    if elm.find("%sarch" % ns).text != "src":
+                        version = elm.find("%sversion" % ns)
+                        tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
+                        if tmpver > ver:
+                            ver = tmpver
+                            fmt = elm.find("%sformat" % ns)
+                            if fmt:
+                                fns = fmt.getchildren()[0].tag
+                                fns = fns[0:fns.rindex("}")+1]
+                                pkgpath = fmt.find("%ssourcerpm" % fns).text
+                                target_repo = repo
+                        break
+
+        if repo["primary"].endswith(".sqlite"):
+            con = sqlite.connect(repo["primary"])
+            for row in con.execute("select version, release, rpm_sourcerpm from packages where name = \"%s\" and arch != \"src\"" % pkg_name):
+                tmpver = "%s-%s" % (row[0], row[1])
+                if tmpver > ver:
+                    pkgpath = "%s" % row[2]
+                    target_repo = repo
+                break
+            con.close()
+    if target_repo:
+        return get_src_name(pkgpath)
+    else:
+        return None
+
+def get_pkglist_in_patterns(group, patterns):
+    found = False
+    pkglist = []
+    try:
+        root = xmlparse(patterns)
+    except SyntaxError:
+        raise SyntaxError("%s syntax error." % patterns)
+
+    for elm in list(root.getroot()):
+        ns = elm.tag
+        ns = ns[0:ns.rindex("}")+1]
+        name = elm.find("%sname" % ns)
+        summary = elm.find("%ssummary" % ns)
+        if name.text == group or summary.text == group:
+            found = True
+            break
+
+    if not found:
+        return pkglist
+
+    found = False
+    for requires in list(elm):
+        if requires.tag.endswith("requires"):
+            found = True
+            break
+
+    if not found:
+        return pkglist
+
+    for pkg in list(requires):
+        pkgname = pkg.attrib["name"]
+        if pkgname not in pkglist:
+            pkglist.append(pkgname)
+
+    return pkglist
+
+def get_pkglist_in_comps(group, comps):
+    found = False
+    pkglist = []
+    try:
+        root = xmlparse(comps)
+    except SyntaxError:
+        raise SyntaxError("%s syntax error." % comps)
+
+    for elm in root.getiterator("group"):
+        id = elm.find("id")
+        name = elm.find("name")
+        if id.text == group or name.text == group:
+            packagelist = elm.find("packagelist")
+            found = True
+            break
+
+    if not found:
+        return pkglist
+
+    for require in elm.getiterator("packagereq"):
+        if require.tag.endswith("packagereq"):
+            pkgname = require.text
+        if pkgname not in pkglist:
+            pkglist.append(pkgname)
+
+    return pkglist
+
+def is_statically_linked(binary):
+    return ", statically linked, " in runner.outs(['file', binary])
+
+def get_qemu_arm_binary(arch):
+    if arch == "aarch64":
+        node = "/proc/sys/fs/binfmt_misc/aarch64"
+        if os.path.exists("/usr/bin/qemu-arm64") and is_statically_linked("/usr/bin/qemu-arm64"):
+            arm_binary = "qemu-arm64"
+        elif os.path.exists("/usr/bin/qemu-aarch64") and is_statically_linked("/usr/bin/qemu-aarch64"):
+            arm_binary = "qemu-aarch64"
+        elif os.path.exists("/usr/bin/qemu-arm64-static"):
+            arm_binary = "qemu-arm64-static"
+        elif os.path.exists("/usr/bin/qemu-aarch64-static"):
+            arm_binary = "qemu-aarch64-static"
+        else:
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+    elif arch == "mipsel":
+        node = "/proc/sys/fs/binfmt_misc/mipsel"
+        arm_binary = "qemu-mipsel"
+        if not os.path.exists("/usr/bin/%s" % arm_binary) or not is_statically_linked("/usr/bin/%s"):
+            arm_binary = "qemu-mipsel-static"
+        if not os.path.exists("/usr/bin/%s" % arm_binary):
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+    elif arch == "riscv64":
+        node = "/proc/sys/fs/binfmt_misc/riscv64"
+        arm_binary = "qemu-riscv64"
+        if os.path.exists("/usr/bin/qemu-riscv64") and is_statically_linked("/usr/bin/qemu-riscv64"):
+            arm_binary = "qemu-riscv64"
+        elif os.path.exists("/usr/bin/qemu-riscv64-static"):
+            arm_binary = "qemu-riscv64-static"
+        else:
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+    else:
+        node = "/proc/sys/fs/binfmt_misc/arm"
+        arm_binary = "qemu-arm"
+        if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked("/usr/bin/qemu-arm"):
+            arm_binary = "qemu-arm-static"
+        if not os.path.exists("/usr/bin/%s" % arm_binary):
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+
+    return (arm_binary, node)
+
+def setup_qemu_emulator(rootdir, arch):
+    qemu_emulators = []
+    # mount binfmt_misc if it doesn't exist
+    if not os.path.exists("/proc/sys/fs/binfmt_misc"):
+        modprobecmd = find_binary_path("modprobe")
+        runner.show([modprobecmd, "binfmt_misc"])
+    if not os.path.exists("/proc/sys/fs/binfmt_misc/register"):
+        mountcmd = find_binary_path("mount")
+        runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
+
+    # qemu_emulator is a special case, we can't use find_binary_path
+    # qemu emulator should be a statically-linked executable file
+    arm_binary, node = get_qemu_arm_binary(arch)
+    qemu_emulator = "/usr/bin/%s" % arm_binary
+
+    if not os.path.exists(rootdir + "/usr/bin"):
+        makedirs(rootdir + "/usr/bin")
+    shutil.copy(qemu_emulator, rootdir + qemu_emulator)
+    qemu_emulators.append(qemu_emulator)
+
+    # disable selinux, selinux will block qemu emulator to run
+    if os.path.exists("/usr/sbin/setenforce"):
+        msger.info('Try to disable selinux')
+        runner.show(["/usr/sbin/setenforce", "0"])
+
+    # register qemu emulator for interpreting other arch executable file
+    if not os.path.exists(node):
+        if arch == "aarch64":
+            qemu_arm_string = ":aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:%s:\n" % qemu_emulator
+        elif arch == "mipsel":
+            qemu_arm_string = ":mipsel:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x08\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xfe\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:%s:\n" % qemu_emulator
+        elif arch == "riscv64":
+            qemu_arm_string = ":riscv64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xf3\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:%s:\n" % qemu_emulator
+        else:
+            qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator
+
+        with open("/proc/sys/fs/binfmt_misc/register", "w") as fd:
+            fd.write(qemu_arm_string)
+    else:
+        flags = ""
+        interpreter = ""
+        with open(node, "r") as fd:
+            for line in fd.readlines():
+                if line.startswith("flags:"):
+                    flags = line[len("flags:"):].strip()
+                elif line.startswith("interpreter"):
+                    interpreter = line[len("interpreter"):].strip()
+
+        if flags == "P" and interpreter.endswith("-binfmt"):
+            # copy binfmt wrapper when preserve-argv[0] flag is enabled
+            shutil.copy(os.path.realpath(interpreter), rootdir + interpreter)
+            qemu_emulators.append(interpreter)
+        elif not flags and interpreter != qemu_emulator:
+            # create symlink as registered qemu emulator
+            os.symlink(qemu_emulator, rootdir + interpreter)
+            qemu_emulators.append(interpreter)
+
+    return qemu_emulators
+
+def SrcpkgsDownload(pkgs, repometadata, instroot, cachedir):
+    def get_source_repometadata(repometadata):
+        src_repometadata=[]
+        for repo in repometadata:
+            if repo["name"].endswith("-source"):
+                src_repometadata.append(repo)
+        if src_repometadata:
+            return src_repometadata
+        return None
+
+    def get_src_name(srpm):
+        m = SRPM_RE.match(srpm)
+        if m:
+            return m.group(1)
+        return None
+
+    src_repometadata = get_source_repometadata(repometadata)
+
+    if not src_repometadata:
+        msger.warning("No source repo found")
+        return None
+
+    src_pkgs = []
+    lpkgs_dict = {}
+    lpkgs_path = []
+    for repo in src_repometadata:
+        cachepath = "%s/%s/packages/*.src.rpm" %(cachedir, repo["name"])
+        lpkgs_path += glob.glob(cachepath)
+
+    for lpkg in lpkgs_path:
+        lpkg_name = get_src_name(os.path.basename(lpkg))
+        lpkgs_dict[lpkg_name] = lpkg
+    localpkgs = lpkgs_dict.keys()
+
+    cached_count = 0
+    destdir = instroot+'/usr/src/SRPMS'
+    if not os.path.exists(destdir):
+        os.makedirs(destdir)
+
+    srcpkgset = set()
+    for _pkg in pkgs:
+        srcpkg_name = get_source_name(_pkg, repometadata)
+        if not srcpkg_name:
+            continue
+        srcpkgset.add(srcpkg_name)
+
+    for pkg in list(srcpkgset):
+        if pkg in localpkgs:
+            cached_count += 1
+            shutil.copy(lpkgs_dict[pkg], destdir)
+            src_pkgs.append(os.path.basename(lpkgs_dict[pkg]))
+        else:
+            src_pkg = get_package(pkg, src_repometadata, 'src')
+            if src_pkg:
+                shutil.copy(src_pkg, destdir)
+                src_pkgs.append(src_pkg)
+    msger.info("%d source packages gotten from cache" % cached_count)
+
+    return src_pkgs
+
+def strip_end(text, suffix):
+    if not text.endswith(suffix):
+        return text
+    return text[:-len(suffix)]
+
+def strip_archive_suffix(filename):
+    for suffix in get_archive_suffixes():
+        if filename.endswith(suffix):
+            return filename[:-len(suffix)]
+    else:
+        msger.warning("Not supported archive file format: %s" % filename)
+    return None
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/partitionedfs.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/partitionedfs.py
new file mode 100644 (file)
index 0000000..cac360b
--- /dev/null
@@ -0,0 +1,830 @@
+#!/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 MountError, CreatorError
+from mic.utils.fs_related import *
+from mic.utils.gpt_parser import GptParser
+
+# Overhead of the MBR partitioning scheme (just one sector)
+MBR_OVERHEAD = 1
+# Overhead of the GPT partitioning scheme
+GPT_OVERHEAD = 34
+
+# Size of a sector in bytes
+SECTOR_SIZE = 512
+
+def resolve_ref(ref):
+    real = os.readlink(ref)
+    if not real.startswith('/'):
+        return os.path.realpath(os.path.join(ref, real))
+    else:
+        return real
+
+class PartitionedMount(Mount):
+    def __init__(self, mountdir, skipformat = False):
+        Mount.__init__(self, mountdir)
+        self.disks = {}
+        self.partitions = []
+        self.subvolumes = []
+        self.mapped = False
+        self.mount_order = []
+        self.unmount_order = []
+        self.parted = find_binary_path("parted")
+        self.kpartx = find_binary_path("kpartx")
+        self.mkswap = find_binary_path("mkswap")
+        self.dmsetup = find_binary_path("dmsetup")
+        self.btrfscmd = None
+        self.mountcmd = find_binary_path("mount")
+        self.umountcmd = find_binary_path("umount")
+        self.skipformat = skipformat
+        self.snapshot_created = self.skipformat
+        # 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
+                  'mapped': False,  # True if kpartx mapping exists
+                  '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, fstype = None,
+                      label=None, fsopts = None, boot = False, align = None,
+                      part_type = None):
+        """ Add the next partition. Partitions 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 need to handle subvolumes for btrfs
+        if fstype == "btrfs" and fsopts and fsopts.find("subvol=") != -1:
+            self.btrfscmd = find_binary_path("btrfs")
+            subvol = None
+            opts = fsopts.split(",")
+            for opt in opts:
+                if opt.find("subvol=") != -1:
+                    subvol = opt.replace("subvol=", "").strip()
+                    break
+            if not subvol:
+                raise MountError("No subvolume: %s" % fsopts)
+            self.subvolumes.append({'size': size, # In sectors
+                                    'mountpoint': mountpoint, # Mount relative to chroot
+                                    'fstype': fstype, # Filesystem type
+                                    'fsopts': fsopts, # Filesystem mount options
+                                    'disk_name': disk_name, # physical disk name holding partition
+                                    'device': None, # kpartx device node for partition
+                                    'mapper_device': None, # mapper device node
+                                    'mpath_device': None, # multipath device of device mapper
+                                    'mount': None, # Mount object
+                                    'subvol': subvol, # Subvolume name
+                                    'boot': boot, # Bootable flag
+                                    'mounted': False # Mount flag
+                                   })
+
+        # We still need partition for "/" or non-subvolume
+        if mountpoint == "/" or not fsopts or fsopts.find("subvol=") == -1:
+            # Don't need subvolume for "/" because it will be set as default subvolume
+            if fsopts and fsopts.find("subvol=") != -1:
+                opts = fsopts.split(",")
+                for opt in opts:
+                    if opt.strip().startswith("subvol="):
+                        opts.remove(opt)
+                        break
+                fsopts = ",".join(opts)
+
+            part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file
+                     'size': size, # In sectors
+                     'mountpoint': mountpoint, # Mount relative to chroot
+                     '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
+                     'mapper_device': None, # mapper device node
+                     'mpath_device': None, # multipath device of device mapper
+                     'mount': None, # Mount object
+                     'num': None, # Partition number
+                     'boot': boot, # Bootable flag
+                     'align': align, # Partition alignment
+                     'part_type' : part_type, # Partition type
+                     'uuid': None, # Partition UUID (no-GPT use)
+                     'partuuid': None } # Partition UUID (GPT-only)
+
+            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 either "msdos" or "gpt". """
+
+        msger.debug("Assigning %s partitions to disks" % ptable_format)
+
+        if ptable_format not in ('msdos', 'gpt'):
+            raise MountError("Unknown partition table format '%s', supported " \
+                             "formats are: 'msdos' and 'gpt'" % 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 MountError("No disk %s for partition %s" \
+                                 % (p['disk_name'], p['mountpoint']))
+
+            if p['part_type'] and ptable_format != 'gpt':
+                # 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 MountError("setting custom partition type is only " \
+                                 "implemented for GPT 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
+                else:
+                    overhead = GPT_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 enlarge 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 laid out, we can calculate the
+        # minimum disk sizes.
+        for disk_name, d in self.disks.items():
+            d['min_size'] = d['offset']
+            if d['ptable_format'] == 'gpt':
+                # Account for the backup partition table at the end of the disk
+                d['min_size'] += GPT_OVERHEAD
+
+            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()
+        msger.debug("'parted': exitcode: %d, output: %s" % (rc, out))
+        # 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.
+        return rc, out
+
+    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 subtract 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()
+
+        if self.skipformat:
+            msger.debug("Skipping disk format, because skipformat flag is set.")
+            return
+
+        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']:
+                if d['ptable_format'] == 'gpt':
+                    flag_name = "legacy_boot"
+                else:
+                    flag_name = "boot"
+                msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \
+                            (flag_name, p['num'], d['disk'].device))
+                cmd = ["-s", d['disk'].device,
+                       "set", "%d" % p['num'],
+                       flag_name, "on"]
+                exitcode, output = self.__run_parted(cmd)
+                if exitcode != 0:
+                    msger.warning(
+                        "partition '%s' is marked with --active, "
+                        "but flag '%s' can't be set: "
+                        "exitcode: %s, output: %s"
+                        % (p['mountpoint'], flag_name, exitcode, output))
+
+        # If the partition table format is "gpt", find out PARTUUIDs for all
+        # the partitions. And if users specified custom parition type UUIDs,
+        # set them.
+        for disk_name, disk in self.disks.items():
+            if disk['ptable_format'] != 'gpt':
+                continue
+
+            pnum = 0
+            gpt_parser = GptParser(disk['disk'].device, SECTOR_SIZE)
+            # Iterate over all GPT partitions on this disk
+            for entry in gpt_parser.get_partitions():
+                pnum += 1
+                # Find the matching partition in the 'self.partitions' list
+                for n in disk['partitions']:
+                    p = self.partitions[n]
+                    if p['num'] == pnum:
+                        # Found, fetch PARTUUID (partition's unique ID)
+                        p['partuuid'] = entry['part_uuid']
+                        msger.debug("PARTUUID for partition %d on disk '%s' " \
+                                    "(mount point '%s') is '%s'" % (pnum, \
+                                    disk_name, p['mountpoint'], p['partuuid']))
+                        if p['part_type']:
+                            entry['type_uuid'] = p['part_type']
+                            msger.debug("Change type of partition %d on disk " \
+                                        "'%s' (mount point '%s') to '%s'" % \
+                                        (pnum, disk_name, p['mountpoint'],
+                                         p['part_type']))
+                            gpt_parser.change_partition(entry)
+
+            del gpt_parser
+
+    def __map_partitions(self):
+        """Load it if dm_snapshot isn't loaded. """
+        load_module("dm_snapshot")
+
+        for dev in self.disks.keys():
+            d = self.disks[dev]
+            if d['mapped']:
+                continue
+
+            msger.debug("Running kpartx on %s" % d['disk'].device )
+            rc, kpartx_output = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device])
+            kpartx_output = kpartx_output.splitlines()
+
+            if rc != 0:
+                raise MountError("Failed to query partition mapping for '%s'" %
+                                 d['disk'].device)
+
+            # Strip trailing blank and mask verbose output
+            i = 0
+            while i < len(kpartx_output) and kpartx_output[i][0:4] != "loop":
+                i = i + 1
+            kpartx_output = kpartx_output[i:]
+
+            # Make sure kpartx reported the right count of partitions
+            if len(kpartx_output) != d['numpart']:
+                # If this disk has more than 3 partitions, then in case of MBR
+                # paritions there is an extended parition. Different versions
+                # of kpartx behave differently WRT the extended partition -
+                # some map it, some ignore it. This is why we do the below hack
+                # - if kpartx reported one more partition and the partition
+                # table type is "msdos" and the amount of partitions is more
+                # than 3, we just assume kpartx mapped the extended parition
+                # and we remove it.
+                if len(kpartx_output) == d['numpart'] + 1 \
+                   and d['ptable_format'] == 'msdos' and len(kpartx_output) > 3:
+                    kpartx_output.pop(3)
+                else:
+                    raise MountError("Unexpected number of partitions from " \
+                                     "kpartx: %d != %d" % \
+                                        (len(kpartx_output), d['numpart']))
+
+            for i in range(len(kpartx_output)):
+                line = kpartx_output[i]
+                newdev = line.split()[0]
+                mapperdev = "/dev/mapper/" + newdev
+                loopdev = d['disk'].device + newdev[-1]
+
+                msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev))
+                pnum = d['partitions'][i]
+                self.partitions[pnum]['device'] = loopdev
+                self.partitions[pnum]['mapper_device'] = mapperdev
+
+                # grub's install wants partitions to be named
+                # to match their parent device + partition num
+                # kpartx doesn't work like this, so we add compat
+                # symlinks to point to /dev/mapper
+                if os.path.lexists(loopdev):
+                    os.unlink(loopdev)
+                os.symlink(mapperdev, loopdev)
+
+            msger.debug("Adding partx mapping for %s" % d['disk'].device)
+            rc = runner.show([self.kpartx, "-v", "-sa", d['disk'].device])
+
+            if rc != 0:
+                # Make sure that the device maps are also removed on error case.
+                # The d['mapped'] isn't set to True if the kpartx fails so
+                # failed mapping will not be cleaned on cleanup either.
+                runner.quiet([self.kpartx, "-sd", d['disk'].device])
+                raise MountError("Failed to map partitions for '%s'" %
+                                 d['disk'].device)
+
+            for p in self.partitions:
+                if p['mapper_device'] and os.path.islink(p['mapper_device']):
+                    p['mpath_device'] = resolve_ref(p['mapper_device'])
+                else:
+                    p['mpath_device'] = ''
+
+            # FIXME: need a better way to fix the latency
+            import time
+            time.sleep(1)
+
+            if not os.path.exists(mapperdev):
+                # load mapper device if not updated
+                runner.quiet([self.dmsetup, "mknodes"])
+                # still not updated, roll back
+                if not os.path.exists(mapperdev):
+                    runner.quiet([self.kpartx, "-sd", d['disk'].device])
+                    raise MountError("Failed to load mapper devices for '%s'" %
+                                     d['disk'].device)
+
+            d['mapped'] = True
+
+    def __unmap_partitions(self):
+        for dev in self.disks.keys():
+            d = self.disks[dev]
+            if not d['mapped']:
+                continue
+
+            msger.debug("Removing compat symlinks")
+            for pnum in d['partitions']:
+                if self.partitions[pnum]['device'] != None:
+                    os.unlink(self.partitions[pnum]['device'])
+                    self.partitions[pnum]['device'] = None
+
+            msger.debug("Unmapping %s" % d['disk'].device)
+            rc = runner.quiet([self.kpartx, "-sd", d['disk'].device])
+            if rc != 0:
+                raise MountError("Failed to unmap partitions for '%s'" %
+                                 d['disk'].device)
+
+            d['mapped'] = False
+
+    def __calculate_mountorder(self):
+        msger.debug("Calculating mount order")
+        for p in self.partitions:
+            if p['mountpoint']:
+                self.mount_order.append(p['mountpoint'])
+                self.unmount_order.append(p['mountpoint'])
+
+        self.mount_order.sort()
+        self.unmount_order.sort()
+        self.unmount_order.reverse()
+
+    def cleanup(self):
+        Mount.cleanup(self)
+        if self.disks:
+            self.__unmap_partitions()
+            for dev in self.disks.keys():
+                d = self.disks[dev]
+                try:
+                    d['disk'].cleanup()
+                except:
+                    pass
+
+    def unmount(self):
+        self.__unmount_subvolumes()
+        for mp in self.unmount_order:
+            if mp == 'swap':
+                continue
+            p = None
+            for p1 in self.partitions:
+                if p1['mountpoint'] == mp:
+                    p = p1
+                    break
+
+            if p['mount'] != None:
+                try:
+                    # Create subvolume snapshot here
+                    if p['fstype'] == "btrfs" and p['mountpoint'] == "/" and \
+                            not self.snapshot_created:
+                        self.__create_subvolume_snapshots(p, p["mount"])
+                    p['mount'].cleanup()
+                except:
+                    pass
+                p['mount'] = None
+
+    # Only for btrfs
+    def __get_subvolume_id(self, rootpath, subvol):
+        if not self.btrfscmd:
+            self.btrfscmd = find_binary_path("btrfs")
+        argv = [ self.btrfscmd, "subvolume", "list", rootpath ]
+
+        rc, out = runner.runtool(argv)
+        msger.debug(out)
+
+        if rc != 0:
+            raise MountError("Failed to get subvolume id from %s',"
+                    "return code: %d." % (rootpath, rc))
+
+        subvolid = -1
+        for line in out.splitlines():
+            if line.endswith(" path %s" % subvol):
+                subvolid = line.split()[1]
+                if not subvolid.isdigit():
+                    raise MountError("Invalid subvolume id: %s" % subvolid)
+                subvolid = int(subvolid)
+                break
+        return subvolid
+
+    def __create_subvolume_metadata(self, p, pdisk):
+        if len(self.subvolumes) == 0:
+            return
+
+        argv = [ self.btrfscmd, "subvolume", "list", pdisk.mountdir ]
+        rc, out = runner.runtool(argv)
+        msger.debug(out)
+
+        if rc != 0:
+            raise MountError("Failed to get subvolume id from %s', return code: %d." % (pdisk.mountdir, rc))
+
+        subvolid_items = out.splitlines()
+        subvolume_metadata = ""
+        for subvol in self.subvolumes:
+            for line in subvolid_items:
+                if line.endswith(" path %s" % subvol["subvol"]):
+                    subvolid = line.split()[1]
+                    if not subvolid.isdigit():
+                        raise MountError("Invalid subvolume id: %s" % subvolid)
+
+                    subvolid = int(subvolid)
+                    opts = subvol["fsopts"].split(",")
+                    for opt in opts:
+                        if opt.strip().startswith("subvol="):
+                            opts.remove(opt)
+                            break
+                    fsopts = ",".join(opts)
+                    subvolume_metadata += "%d\t%s\t%s\t%s\n" % (subvolid, subvol["subvol"],
+                            subvol['mountpoint'], fsopts)
+
+        if subvolume_metadata:
+            fd = open("%s/.subvolume_metadata" % pdisk.mountdir, "w")
+            fd.write(subvolume_metadata)
+            fd.close()
+
+    def __get_subvolume_metadata(self, p, pdisk):
+        subvolume_metadata_file = "%s/.subvolume_metadata" % pdisk.mountdir
+        if not os.path.exists(subvolume_metadata_file):
+            return
+
+        fd = open(subvolume_metadata_file, "r")
+        content = fd.read()
+        fd.close()
+
+        for line in content.splitlines():
+            items = line.split("\t")
+            if items and len(items) == 4:
+                self.subvolumes.append({'size': 0, # In sectors
+                                        'mountpoint': items[2], # Mount relative to chroot
+                                        'fstype': "btrfs", # Filesystem type
+                                        'fsopts': items[3] + ",subvol=%s" %  items[1], # Filesystem mount options
+                                        'disk_name': p['disk_name'], # physical disk name holding partition
+                                        'device': None, # kpartx device node for partition
+                                        'mount': None, # Mount object
+                                        'subvol': items[1], # Subvolume name
+                                        'boot': False, # Bootable flag
+                                        'mounted': False # Mount flag
+                                   })
+
+    def __create_subvolumes(self, p, pdisk):
+        """ Create all the subvolumes. """
+
+        for subvol in self.subvolumes:
+            argv = [ self.btrfscmd, "subvolume", "create", pdisk.mountdir + "/" + subvol["subvol"]]
+
+            rc = runner.show(argv)
+            if rc != 0:
+                raise MountError("Failed to create subvolume '%s', return code: %d." % (subvol["subvol"], rc))
+
+        # Set default subvolume, subvolume for "/" is default
+        subvol = None
+        for subvolume in self.subvolumes:
+            if subvolume["mountpoint"] == "/" and p['disk_name'] == subvolume['disk_name']:
+                subvol = subvolume
+                break
+
+        if subvol:
+            # Get default subvolume id
+            subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
+            # Set default subvolume
+            if subvolid != -1:
+                rc = runner.show([ self.btrfscmd, "subvolume", "set-default", "%d" %
+                        subvolid, pdisk.mountdir])
+                if rc != 0:
+                    raise MountError("Failed to set default subvolume id: %d', return code: %d."
+                            % (subvolid, rc))
+
+        self.__create_subvolume_metadata(p, pdisk)
+
+    def __mount_subvolumes(self, p, pdisk):
+        if self.skipformat:
+            # Get subvolume info
+            self.__get_subvolume_metadata(p, pdisk)
+            # Set default mount options
+            if len(self.subvolumes) != 0:
+                for subvol in self.subvolumes:
+                    if subvol["mountpoint"] == p["mountpoint"] == "/":
+                        opts = subvol["fsopts"].split(",")
+                        for opt in opts:
+                            if opt.strip().startswith("subvol="):
+                                opts.remove(opt)
+                                break
+                        pdisk.fsopts = ",".join(opts)
+                        break
+
+        if len(self.subvolumes) == 0:
+            # Return directly if no subvolumes
+            return
+
+        # Remount to make default subvolume mounted
+        rc = runner.show([self.umountcmd, pdisk.mountdir])
+        if rc != 0:
+            raise MountError("Failed to umount %s" % pdisk.mountdir)
+
+        rc = runner.show([self.mountcmd, "-o", pdisk.fsopts, pdisk.disk.device, pdisk.mountdir])
+        if rc != 0:
+            raise MountError("Failed to umount %s" % pdisk.mountdir)
+
+        for subvol in self.subvolumes:
+            if subvol["mountpoint"] == "/":
+                continue
+            subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
+            if subvolid == -1:
+                msger.debug("WARNING: invalid subvolume %s" % subvol["subvol"])
+                continue
+            # Replace subvolume name with subvolume ID
+            opts = subvol["fsopts"].split(",")
+            for opt in opts:
+                if opt.strip().startswith("subvol="):
+                    opts.remove(opt)
+                    break
+
+            opts.extend(["subvolrootid=0", "subvol=%s" % subvol["subvol"]])
+            fsopts = ",".join(opts)
+            subvol['fsopts'] = fsopts
+            mountpoint = self.mountdir + subvol['mountpoint']
+            makedirs(mountpoint)
+            rc = runner.show([self.mountcmd, "-o", fsopts, pdisk.disk.device, mountpoint])
+            if rc != 0:
+                raise MountError("Failed to mount subvolume %s to %s" % (subvol["subvol"], mountpoint))
+            subvol["mounted"] = True
+
+    def __unmount_subvolumes(self):
+        """ It may be called multiple times, so we need to chekc if it is still mounted. """
+        for subvol in self.subvolumes:
+            if subvol["mountpoint"] == "/":
+                continue
+            if not subvol["mounted"]:
+                continue
+            mountpoint = self.mountdir + subvol['mountpoint']
+            rc = runner.show([self.umountcmd, mountpoint])
+            if rc != 0:
+                raise MountError("Failed to unmount subvolume %s from %s" % (subvol["subvol"], mountpoint))
+            subvol["mounted"] = False
+
+    def __create_subvolume_snapshots(self, p, pdisk):
+        import time
+
+        if self.snapshot_created:
+            return
+
+        # Remount with subvolid=0
+        rc = runner.show([self.umountcmd, pdisk.mountdir])
+        if rc != 0:
+            raise MountError("Failed to umount %s" % pdisk.mountdir)
+        if pdisk.fsopts:
+            mountopts = pdisk.fsopts + ",subvolid=0"
+        else:
+            mountopts = "subvolid=0"
+        rc = runner.show([self.mountcmd, "-o", mountopts, pdisk.disk.device, pdisk.mountdir])
+        if rc != 0:
+            raise MountError("Failed to umount %s" % pdisk.mountdir)
+
+        # Create all the subvolume snapshots
+        snapshotts = time.strftime("%Y%m%d-%H%M")
+        for subvol in self.subvolumes:
+            subvolpath = pdisk.mountdir + "/" + subvol["subvol"]
+            snapshotpath = subvolpath + "_%s-1" % snapshotts
+            rc = runner.show([ self.btrfscmd, "subvolume", "snapshot", subvolpath, snapshotpath ])
+            if rc != 0:
+                raise MountError("Failed to create subvolume snapshot '%s' for '%s', return code:"
+                        "%d." % (snapshotpath, subvolpath, rc))
+
+        self.snapshot_created = True
+
+    def mount(self):
+        for dev in self.disks.keys():
+            d = self.disks[dev]
+            d['disk'].create()
+
+        self.__format_disks()
+        self.__map_partitions()
+        self.__calculate_mountorder()
+
+        for mp in self.mount_order:
+            p = None
+            for p1 in self.partitions:
+                if p1['mountpoint'] == mp:
+                    p = p1
+                    break
+
+            if not p['label']:
+                if p['mountpoint'] == "/":
+                    p['label'] = 'platform'
+                else:
+                    p['label'] = mp.split('/')[-1]
+
+            if mp == 'swap':
+                import uuid
+                p['uuid'] = str(uuid.uuid1())
+                runner.show([self.mkswap,
+                             '-L', p['label'],
+                             '-U', p['uuid'],
+                             p['device']])
+                continue
+
+            rmmountdir = False
+            if p['mountpoint'] == "/":
+                rmmountdir = True
+            if p['fstype'] == "vfat" or p['fstype'] == "msdos":
+                my_disk_mount = VfatDiskMount
+            elif p['fstype'] in ("ext2", "ext3", "ext4"):
+                my_disk_mount = ExtDiskMount
+            elif p['fstype'] == "btrfs":
+                my_disk_mount = BtrfsDiskMount
+            else:
+                raise MountError("Fail to support file system " + p['fstype'])
+
+            if p['fstype'] == "btrfs" and not p['fsopts']:
+                p['fsopts'] = "subvolid=0"
+
+            pdisk = my_disk_mount(RawDisk(p['size'] * self.sector_size, p['device']),
+                                 self.mountdir + p['mountpoint'],
+                                 p['fstype'],
+                                 4096,
+                                 p['label'],
+                                 rmmountdir,
+                                 self.skipformat,
+                                 fsopts = p['fsopts'])
+            pdisk.mount(pdisk.fsopts)
+            if p['fstype'] == "btrfs" and p['mountpoint'] == "/":
+                if not self.skipformat:
+                    self.__create_subvolumes(p, pdisk)
+                self.__mount_subvolumes(p, pdisk)
+            p['mount'] = pdisk
+            p['uuid'] = pdisk.uuid
+
+    def resparse(self, size = None):
+        # Can't re-sparse a disk image - too hard
+        pass
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/proxy.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/proxy.py
new file mode 100644 (file)
index 0000000..ca884a2
--- /dev/null
@@ -0,0 +1,212 @@
+#!/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 re
+import urlparse
+from mic import msger
+
+_my_proxies = {}
+_my_noproxy = None
+_my_noproxy_list = []
+
+def set_proxy_environ():
+    if not _my_proxies:
+        return
+    for key in _my_proxies.keys():
+        os.environ[key + "_proxy"] = _my_proxies[key]
+    if not _my_noproxy:
+        return
+    os.environ["no_proxy"] = _my_noproxy
+
+def unset_proxy_environ():
+    for env in ('http_proxy',
+                'https_proxy',
+                'ftp_proxy',
+                'all_proxy'):
+        if env in os.environ:
+            del os.environ[env]
+
+        env_upper = env.upper()
+        if env_upper in os.environ:
+            del os.environ[env_upper]
+
+def _set_proxies(proxy = None, no_proxy = None):
+    """Return a dictionary of scheme -> proxy server URL mappings.
+    """
+
+    global _my_noproxy, _my_proxies
+    _my_proxies = {}
+    _my_noproxy = None
+    proxies = []
+    if proxy:
+        proxies.append(("http_proxy", proxy))
+    if no_proxy:
+        proxies.append(("no_proxy", no_proxy))
+
+    # Get proxy settings from environment if not provided
+    if not proxy and not no_proxy:
+        proxies = os.environ.items()
+
+        # Remove proxy env variables, urllib2 can't handle them correctly
+        unset_proxy_environ()
+
+    for name, value in proxies:
+        name = name.lower()
+        if value and name[-6:] == '_proxy':
+            if name[0:2] != "no":
+                _my_proxies[name[:-6]] = value
+            else:
+                _my_noproxy = value
+
+def _ip_to_int(ip):
+    ipint = 0
+    shift = 24
+    for dec in ip.split("."):
+        if not dec.isdigit():
+            continue
+        ipint |= int(dec) << shift
+        shift -= 8
+    return ipint
+
+def _int_to_ip(val):
+    ipaddr = ""
+    shift = 0
+    for i in range(4):
+        dec = val >> shift
+        dec &= 0xff
+        ipaddr = ".%d%s" % (dec, ipaddr)
+        shift += 8
+    return ipaddr[1:]
+
+def _isip(host):
+    if host.replace(".", "").isdigit():
+        return True
+    return False
+
+def _set_noproxy_list():
+    global _my_noproxy, _my_noproxy_list
+    _my_noproxy_list = []
+    if not _my_noproxy:
+        return
+
+    #solve in /etc/enviroment contains command like `echo 165.xxx.xxx.{1..255} | sed 's/ /,/g'``
+    _my_noproxy_bak = _my_noproxy
+    start = _my_noproxy.find("`")
+    while(start < len(_my_noproxy) and start != -1):
+        start = _my_noproxy.find("`",start)
+        end = _my_noproxy.find("`",start+1)
+        cmd = _my_noproxy[start+1:end]
+        pstr = _my_noproxy[start:end+1]
+        start = end + 1
+
+        _my_noproxy=_my_noproxy.replace(pstr,len(pstr)*" ")
+        try:
+            c_result = os.popen(cmd).readlines()
+            if len(c_result) == 0:
+                continue
+        except Exception as e:
+            msger.warning(str(e))
+            continue
+        to_list = c_result[0].strip("\n").split(",")
+        _my_noproxy_list.extend(to_list)
+
+    for item in _my_noproxy.split(","):
+        item = item.strip()
+        if not item:
+            continue
+
+        if item[0] != '.' and item.find("/") == -1:
+            # Need to match it
+            _my_noproxy_list.append({"match":0, "needle":item})
+
+        elif item[0] == '.':
+            # Need to match at tail
+            _my_noproxy_list.append({"match":1, "needle":item})
+
+        elif item.find("/") > 3:
+            # IP/MASK, need to match at head
+            needle = item[0:item.find("/")].strip()
+            ip = _ip_to_int(needle)
+            netmask = 0
+            mask = item[item.find("/")+1:].strip()
+
+            if mask.isdigit():
+                netmask = int(mask)
+                netmask = ~((1<<(32-netmask)) - 1)
+                ip &= netmask
+            else:
+                shift = 24
+                netmask = 0
+                for dec in mask.split("."):
+                    if not dec.isdigit():
+                        continue
+                    netmask |= int(dec) << shift
+                    shift -= 8
+                ip &= netmask
+
+            _my_noproxy_list.append({"match":2, "needle":ip, "netmask":netmask})
+    _my_noproxy = _my_noproxy_bak
+
+def _isnoproxy(url):
+    host = urlparse.urlparse(url)[1]
+    # urlparse.urlparse(url) returns (scheme, host, path, parm, query, frag)
+
+    if '@' in host:
+        user_pass, host = host.split('@', 1)
+
+    if ':' in host:
+        host, port = host.split(':', 1)
+
+    hostisip = _isip(host)
+    for item in _my_noproxy_list:
+        if hostisip and item["match"] == 1:
+            continue
+
+        if item["match"] == 2 and hostisip:
+            if (_ip_to_int(host) & item["netmask"]) == item["needle"]:
+                return True
+
+        if item["match"] == 0:
+            if host == item["needle"]:
+                return True
+
+        if item["match"] == 1:
+            if re.match(r".*%s$" % item["needle"], host):
+                return True
+
+    return False
+
+def set_proxies(proxy = None, no_proxy = None):
+    _set_proxies(proxy, no_proxy)
+    _set_noproxy_list()
+    set_proxy_environ()
+
+def get_proxy_for(url):
+    if url.startswith('file:') or _isnoproxy(url):
+        return None
+
+    type = url[0:url.index(":")]
+    proxy = None
+    if _my_proxies.has_key(type):
+        proxy = _my_proxies[type]
+    elif _my_proxies.has_key("http"):
+        proxy = _my_proxies["http"]
+    else:
+        proxy = None
+
+    return proxy
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/rpmmisc.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/rpmmisc.py
new file mode 100644 (file)
index 0000000..3dde377
--- /dev/null
@@ -0,0 +1,467 @@
+#!/usr/bin/python -tt
+#
+# Copyright (c) 2008, 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
+import sys
+import re
+import rpm
+
+from mic import msger
+from mic.utils.errors import CreatorError
+from mic.utils.proxy import get_proxy_for
+from mic.utils import runner
+
+
+class RPMInstallCallback:
+    """ Command line callback class for callbacks from the RPM library.
+    """
+
+    def __init__(self, ts, output=1):
+        self.output = output
+        self.callbackfilehandles = {}
+        self.total_actions = 0
+        self.total_installed = 0
+        self.total_installing = 0
+        self.installed_pkg_names = []
+        self.total_removed = 0
+        self.mark = "+"
+        self.marks = 40
+        self.lastmsg = None
+        self.tsInfo = None # this needs to be set for anything else to work
+        self.ts = ts
+        self.filelog = False
+        self.logString = []
+        self.headmsg = "Installing"
+
+    def _dopkgtup(self, hdr):
+        tmpepoch = hdr['epoch']
+        if tmpepoch is None: epoch = '0'
+        else: epoch = str(tmpepoch)
+
+        return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
+
+    def _makeHandle(self, hdr):
+        handle = '%s:%s.%s-%s-%s' % (hdr['epoch'], hdr['name'], hdr['version'],
+          hdr['release'], hdr['arch'])
+
+        return handle
+
+    def _localprint(self, msg):
+        if self.output:
+            msger.info(msg)
+
+    def _makefmt(self, percent, progress = True):
+        l = len(str(self.total_actions))
+        size = "%s.%s" % (l, l)
+        fmt_done = "[%" + size + "s/%" + size + "s]"
+        done = fmt_done % (self.total_installing,
+                           self.total_actions)
+        marks = self.marks - (2 * l)
+        width = "%s.%s" % (marks, marks)
+        fmt_bar = "%-" + width + "s"
+        if progress:
+            bar = fmt_bar % (self.mark * int(marks * (percent / 100.0)), )
+            fmt = "%-10.10s: %-50.50s " + bar + " " + done
+        else:
+            bar = fmt_bar % (self.mark * marks, )
+            fmt = "%-10.10s: %-50.50s "  + bar + " " + done
+        return fmt
+
+    def _logPkgString(self, hdr):
+        """return nice representation of the package for the log"""
+        (n,a,e,v,r) = self._dopkgtup(hdr)
+        if e == '0':
+            pkg = '%s.%s %s-%s' % (n, a, v, r)
+        else:
+            pkg = '%s.%s %s:%s-%s' % (n, a, e, v, r)
+
+        return pkg
+
+    def callback(self, what, bytes, total, h, user):
+        if what == rpm.RPMCALLBACK_TRANS_START:
+            if bytes == 6:
+                self.total_actions = total
+
+        elif what == rpm.RPMCALLBACK_TRANS_PROGRESS:
+            pass
+
+        elif what == rpm.RPMCALLBACK_TRANS_STOP:
+            pass
+
+        elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
+            self.lastmsg = None
+            hdr = None
+            if h is not None:
+                try:
+                    hdr, rpmloc = h
+                except:
+                    rpmloc = h
+                    hdr = readRpmHeader(self.ts, h)
+
+                m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
+                if m:
+                    pkgname = m.group(1)
+                else:
+                    pkgname = os.path.basename(rpmloc)
+                msger.info("Next install: %s " % pkgname)
+
+                handle = self._makeHandle(hdr)
+                fd = os.open(rpmloc, os.O_RDONLY)
+                self.callbackfilehandles[handle]=fd
+                if hdr['name'] not in self.installed_pkg_names:
+                    self.installed_pkg_names.append(hdr['name'])
+                    self.total_installed += 1
+                return fd
+            else:
+                self._localprint("No header - huh?")
+
+        elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
+            hdr = None
+            if h is not None:
+                try:
+                    hdr, rpmloc = h
+                except:
+                    rpmloc = h
+                    hdr = readRpmHeader(self.ts, h)
+
+                handle = self._makeHandle(hdr)
+                os.close(self.callbackfilehandles[handle])
+                fd = 0
+
+                # log stuff
+                #pkgtup = self._dopkgtup(hdr)
+                self.logString.append(self._logPkgString(hdr))
+
+        elif what == rpm.RPMCALLBACK_INST_START:
+            self.total_installing += 1
+
+        elif what == rpm.RPMCALLBACK_UNINST_STOP:
+            pass
+
+        elif what == rpm.RPMCALLBACK_INST_PROGRESS:
+            if h is not None:
+                percent = (self.total_installed*100)/self.total_actions
+                if total > 0:
+                    try:
+                        hdr, rpmloc = h
+                    except:
+                        rpmloc = h
+
+                    m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
+                    if m:
+                        pkgname = m.group(1)
+                    else:
+                        pkgname = os.path.basename(rpmloc)
+                if self.output:
+                    fmt = self._makefmt(percent)
+                    msg = fmt % (self.headmsg, pkgname)
+                    if msg != self.lastmsg:
+                        self.lastmsg = msg
+
+                        msger.info(msg)
+
+                        if self.total_installed == self.total_actions:
+                            msger.raw('')
+                            msger.verbose('\n'.join(self.logString))
+
+        elif what == rpm.RPMCALLBACK_UNINST_START:
+            pass
+
+        elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
+            pass
+
+        elif what == rpm.RPMCALLBACK_UNINST_STOP:
+            self.total_removed += 1
+
+        elif what == rpm.RPMCALLBACK_REPACKAGE_START:
+            pass
+
+        elif what == rpm.RPMCALLBACK_REPACKAGE_STOP:
+            pass
+
+        elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS:
+            pass
+        elif what == rpm.RPMCALLBACK_SCRIPT_ERROR:
+            if h is not None:
+                try:
+                    hdr, rpmloc = h
+                except:
+                    rpmloc = h
+
+                m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
+                if m:
+                    pkgname = m.group(1)
+                else:
+                    pkgname = os.path.basename(rpmloc)
+
+                msger.warning('(%s) Post script failed' % pkgname)
+
+def readRpmHeader(ts, filename):
+    """ Read an rpm header. """
+
+    fd = os.open(filename, os.O_RDONLY)
+    h = ts.hdrFromFdno(fd)
+    os.close(fd)
+    return h
+
+def splitFilename(filename):
+    """ Pass in a standard style rpm fullname
+
+        Return a name, version, release, epoch, arch, e.g.::
+            foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
+            1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64
+    """
+
+    if filename[-4:] == '.rpm':
+        filename = filename[:-4]
+
+    archIndex = filename.rfind('.')
+    arch = filename[archIndex+1:]
+
+    relIndex = filename[:archIndex].rfind('-')
+    rel = filename[relIndex+1:archIndex]
+
+    verIndex = filename[:relIndex].rfind('-')
+    ver = filename[verIndex+1:relIndex]
+
+    epochIndex = filename.find(':')
+    if epochIndex == -1:
+        epoch = ''
+    else:
+        epoch = filename[:epochIndex]
+
+    name = filename[epochIndex + 1:verIndex]
+    return name, ver, rel, epoch, arch
+
+def getCanonX86Arch(arch):
+    #
+    if arch == "i586":
+        f = open("/proc/cpuinfo", "r")
+        lines = f.readlines()
+        f.close()
+        for line in lines:
+            if line.startswith("model name") and line.find("Geode(TM)") != -1:
+                return "geode"
+        return arch
+    # only athlon vs i686 isn't handled with uname currently
+    if arch != "i686":
+        return arch
+
+    # if we're i686 and AuthenticAMD, then we should be an athlon
+    f = open("/proc/cpuinfo", "r")
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if line.startswith("vendor") and line.find("AuthenticAMD") != -1:
+            return "athlon"
+        # i686 doesn't guarantee cmov, but we depend on it
+        elif line.startswith("flags") and line.find("cmov") == -1:
+            return "i586"
+
+    return arch
+
+def getCanonX86_64Arch(arch):
+    if arch != "x86_64":
+        return arch
+
+    vendor = None
+    f = open("/proc/cpuinfo", "r")
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if line.startswith("vendor_id"):
+            vendor = line.split(':')[1]
+            break
+    if vendor is None:
+        return arch
+
+    if vendor.find("Authentic AMD") != -1 or vendor.find("AuthenticAMD") != -1:
+        return "amd64"
+    if vendor.find("GenuineIntel") != -1:
+        return "ia32e"
+    return arch
+
+def getCanonArch():
+    arch = os.uname()[4]
+
+    if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"):
+        return getCanonX86Arch(arch)
+
+    if arch == "x86_64":
+        return getCanonX86_64Arch(arch)
+
+    return arch
+
+# Copy from libsatsolver:poolarch.c, with cleanup
+archPolicies = {
+    "x86_64":       "x86_64:i686:i586:i486:i386",
+    "i686":         "i686:i586:i486:i386",
+    "i586":         "i586:i486:i386",
+    "ia64":         "ia64:i686:i586:i486:i386",
+    "aarch64":      "aarch64",
+    "armv7tnhl":    "armv7tnhl:armv7thl:armv7nhl:armv7hl",
+    "armv7thl":     "armv7thl:armv7hl",
+    "armv7nhl":     "armv7nhl:armv7hl",
+    "armv7hl":      "armv7hl",
+    "armv7l":       "armv7l:armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
+    "armv6l":       "armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
+    "armv5tejl":    "armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
+    "armv5tel":     "armv5tel:armv5l:armv4tl:armv4l:armv3l",
+    "armv5l":       "armv5l:armv4tl:armv4l:armv3l",
+    "mipsel":       "mipsel",
+    "riscv64":      "riscv64",
+}
+
+# dict mapping arch -> ( multicompat, best personality, biarch personality )
+multilibArches = {
+    "x86_64":  ( "athlon", "x86_64", "athlon" ),
+}
+
+# from yumUtils.py
+arches = {
+    # ia32
+    "athlon": "i686",
+    "i686": "i586",
+    "geode": "i586",
+    "i586": "i486",
+    "i486": "i386",
+    "i386": "noarch",
+
+    # amd64
+    "x86_64": "athlon",
+    "amd64": "x86_64",
+    "ia32e": "x86_64",
+
+    # arm
+    "armv7tnhl": "armv7nhl",
+    "armv7nhl": "armv7hl",
+    "armv7hl": "noarch",
+    "armv7l": "armv6l",
+    "armv6l": "armv5tejl",
+    "armv5tejl": "armv5tel",
+    "armv5tel": "noarch",
+
+    #itanium
+    "ia64": "noarch",
+
+    "mipsel": "mipsel",
+
+    "riscv64": "noarch",
+}
+
+def isMultiLibArch(arch=None):
+    """returns true if arch is a multilib arch, false if not"""
+    if arch is None:
+        arch = getCanonArch()
+
+    if not arches.has_key(arch): # or we could check if it is noarch
+        return False
+
+    if multilibArches.has_key(arch):
+        return True
+
+    if multilibArches.has_key(arches[arch]):
+        return True
+
+    return False
+
+def getBaseArch():
+    myarch = getCanonArch()
+    if not arches.has_key(myarch):
+        return myarch
+
+    if isMultiLibArch(arch=myarch):
+        if multilibArches.has_key(myarch):
+            return myarch
+        else:
+            return arches[myarch]
+
+    if arches.has_key(myarch):
+        basearch = myarch
+        value = arches[basearch]
+        while value != 'noarch':
+            basearch = value
+            value = arches[basearch]
+
+        return basearch
+
+def checkRpmIntegrity(bin_rpm, package):
+    return runner.quiet([bin_rpm, "-K", "--nosignature", package])
+
+def checkSig(ts, package):
+    """ Takes a transaction set and a package, check it's sigs,
+        return 0 if they are all fine
+        return 1 if the gpg key can't be found
+        return 2 if the header is in someway damaged
+        return 3 if the key is not trusted
+        return 4 if the pkg is not gpg or pgp signed
+    """
+
+    value = 0
+    currentflags = ts.setVSFlags(0)
+    fdno = os.open(package, os.O_RDONLY)
+    try:
+        hdr = ts.hdrFromFdno(fdno)
+
+    except rpm.error as e:
+        if str(e) == "public key not availaiable":
+            value = 1
+        if str(e) == "public key not available":
+            value = 1
+        if str(e) == "public key not trusted":
+            value = 3
+        if str(e) == "error reading package header":
+            value = 2
+    else:
+        error, siginfo = getSigInfo(hdr)
+        if error == 101:
+            os.close(fdno)
+            del hdr
+            value = 4
+        else:
+            del hdr
+
+    try:
+        os.close(fdno)
+    except OSError:
+        pass
+
+    ts.setVSFlags(currentflags) # put things back like they were before
+    return value
+
+def getSigInfo(hdr):
+    """ checks signature from an hdr hand back signature information and/or
+        an error code
+    """
+
+    import locale
+    locale.setlocale(locale.LC_ALL, 'C')
+
+    string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|'
+    siginfo = hdr.sprintf(string)
+    if siginfo != '(none)':
+        error = 0
+        sigtype, sigdate, sigid = siginfo.split(',')
+    else:
+        error = 101
+        sigtype = 'MD5'
+        sigdate = 'None'
+        sigid = 'None'
+
+    infotuple = (sigtype, sigdate, sigid)
+    return error, infotuple
+
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/runner.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/runner.py
new file mode 100644 (file)
index 0000000..cd361a1
--- /dev/null
@@ -0,0 +1,110 @@
+#!/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
+from mic.utils import errors
+
+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 as e:
+        if e.errno == 2:
+            # [Errno 2] No such file or directory
+            raise errors.CreatorError('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]
diff --git a/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/safeurl.py b/mic_py2/usr/lib/python2.7/dist-packages/mic/utils/safeurl.py
new file mode 100644 (file)
index 0000000..0a82f8e
--- /dev/null
@@ -0,0 +1,92 @@
+# Copyright (c) 2014 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.
+
+"""
+This module provides a class SafeURL which can contain url/user/password read
+from config file, and hide plain user and password when it print to screen
+"""
+import os.path
+import urllib
+from urlparse import urlsplit, urlunsplit
+
+
+def join_userpass(href, user, passwd):
+    """Return authenticated URL with user and passwd embeded"""
+    if not user and not passwd:
+        return href
+
+    if passwd:
+        userpass = '%s:%s' % (urllib.quote(user, safe=''),
+                              urllib.quote(passwd, safe=''))
+    else:
+        userpass = urllib.quote(user, safe='')
+
+    parts = urlsplit(href)
+    netloc = '%s@%s' % (userpass, parts[1])
+    comps = list(parts)
+    comps[1] = netloc
+    return urlunsplit(comps)
+
+
+def split_userpass(href):
+    """Returns (href, user, passwd) of an authenticated URL"""
+    parts = urlsplit(href)
+
+    netloc = parts[1]
+    if '@' not in netloc:
+        return href, None, None
+
+    userpass, netloc = netloc.split('@', 1)
+    if ':' in userpass:
+        user, passwd = [ urllib.unquote(i)
+                           for i in userpass.split(':', 1) ]
+    else:
+        user, passwd = userpass, None
+
+    comps = list(parts)
+    comps[1] = netloc
+    return urlunsplit(comps), user, passwd
+
+
+class SafeURL(str):
+    '''SafeURL can hide user info when it's printed to console.
+    Use property full to get url with user info
+    '''
+    def __new__(cls, urlstring, user=None, passwd=None):
+        """Imuutable object"""
+        href, user1, passwd1 = split_userpass(urlstring)
+        user = user if user else user1
+        passwd = passwd if passwd else passwd1
+
+        obj = super(SafeURL, cls).__new__(cls, href)
+        obj.user = user
+        obj.passwd = passwd
+        obj.full = join_userpass(href, user, passwd)
+
+        parts = urlsplit(href)
+        obj.scheme = parts[0]
+        obj.netloc = parts[1]
+        obj.path = parts[2]
+        obj.host = parts.hostname
+        obj.port = parts.port
+        return obj
+
+    def join(self, *path):
+        """Returns a new SafeURL with new path. Search part is removed since
+        after join path is changed, keep the same search part is useless.
+        """
+        idx = self.full.find('?')
+        url = self.full if idx < 0 else self.full[:idx]
+        return SafeURL(os.path.join(url.rstrip('/'), *path))
index f0d3358993f38fb5cb7bcd9efa8a74ef7a0c9e12..138f07ab94c02397187af85817ad6d6ac8f47485 100755 (executable)
@@ -73,6 +73,10 @@ install -Dp -m0755 etc/bash_completion.d/%{name}.sh %{buildroot}/%{_sysconfdir}/
 install -d -m0755 %{buildroot}/%{_sysconfdir}/zsh_completion.d/
 install -Dp -m0755 etc/zsh_completion.d/_%{name} %{buildroot}/%{_sysconfdir}/zsh_completion.d/
 
+#install mic py2 code.
+mkdir -p %{buildroot}/%{_prefix}/lib/%{name}/mic_py2
+cp -rp mic_py2/* %{buildroot}%{_prefix}/lib/%{name}/mic_py2
+
 %files
 %defattr(-,root,root,-)
 %doc doc/*
@@ -88,4 +92,3 @@ install -Dp -m0755 etc/zsh_completion.d/_%{name} %{buildroot}/%{_sysconfdir}/zsh
 %{_bindir}/mic
 %{_sysconfdir}/bash_completion.d
 %{_sysconfdir}/zsh_completion.d
-