[PATCH 1/6] Add ksimage, execute kickstart image installs

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

 



A stripped down version of the anaconda program that only does what is
needed for kickstart and images.
---
 ksimage                |  249 ++++++++++++++++++++++++++++++++++++++++++++++++
 pyanaconda/__init__.py |    3 +
 2 files changed, 252 insertions(+), 0 deletions(-)
 create mode 100755 ksimage

diff --git a/ksimage b/ksimage
new file mode 100755
index 0000000..f9001fa
--- /dev/null
+++ b/ksimage
@@ -0,0 +1,249 @@
+#!/usr/bin/python
+#
+# ksimage: The Red Hat Linux Installation program
+#
+# Copyright (C) 2011
+# Red Hat, Inc.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Brian C. Lane <bcl@xxxxxxxxxx>
+
+import sys
+import os
+import signal
+from argparse import ArgumentParser
+
+
+def AnacondaShowWarning(message, category, filename, lineno, file=sys.stderr, line=None):
+    """ Log warnings from python's warnings module to the anaconda log
+    """
+    log.warning("%s" % warnings.formatwarning(message, category, filename, lineno, line))
+
+def getAnacondaVersion():
+    """ Return the anaconda version
+
+    In the form of XX.YY
+    """
+    # Using _isys here so we don't drag in the logging stuff, which is always
+    # complicated.
+    from pyanaconda import _isys
+    return _isys.getAnacondaVersion()
+
+def parseArguments():
+    """ Parse commandline arguments (not /proc/cmdline)
+    """
+    ap = ArgumentParser()
+    ap.add_argument('--version', action='version', version="%prog " + getAnacondaVersion())
+
+    ap.add_argument("-d", "--debug", dest="debug", action="store_true", 
+                    default=False,
+                    help="Enable verbose debugging output")
+    ap.add_argument("--kickstart", dest="ksfile", required=True,
+                    help="kickstart file to execute")
+    ap.add_argument("--image", action="append", dest="images", default=[],
+                    required=True,
+                    help="Drive images to install onto")
+    ap.add_argument("--loglevel", choices=["debug", "info", "warning", "error",
+                    "critical"],
+                    help="Set the logging level for the terminal. The default "
+                    "value is info")
+    ap.add_argument("--syslog",
+                    help="Use remote syslog server for logging. Value is <host>[:<port>] ")
+
+    args = ap.parse_args()
+    if not args.ksfile:
+        print("missing kickstart file")
+    if not args.images:
+        print("missing drive image(s)")
+    if not args.ksfile or not args.images:
+        ap.print_help()
+        sys.exit(0)
+
+    return args
+
+def setupEnvironment():
+    """ Setup environmental variables
+    """
+    os.environ['HOME'] = '/tmp'
+    os.environ['LC_NUMERIC'] = 'C'
+    os.environ["GCONF_GLOBAL_LOCKS"] = "1"
+
+    # In theory, this gets rid of our LVM file descriptor warnings
+    os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1"
+
+    # make sure we have /sbin and /usr/sbin in our path
+    os.environ["PATH"] += ":/sbin:/usr/sbin"
+
+    # we can't let the LD_PRELOAD hang around because it will leak into
+    # rpm %post and the like.  ick :/
+    if os.environ.has_key("LD_PRELOAD"):
+        del os.environ["LD_PRELOAD"]
+
+def setupLoggingFromArgs(args):
+    if args.loglevel and anaconda_log.logLevelMap.has_key(args.loglevel):
+        level = anaconda_log.logLevelMap[args.loglevel]
+        anaconda_log.logger.tty_loglevel = level
+        anaconda_log.setHandlersLevel(log, level)
+        storage_log = logging.getLogger("storage")
+        anaconda_log.setHandlersLevel(storage_log, level)
+
+    if args.syslog:
+        anaconda_log.logger.remote_syslog = args.syslog
+
+def setupPythonUpdates():
+    from distutils.sysconfig import get_python_lib
+
+    if not os.path.exists("/tmp/updates"):
+        return
+
+    for pkg in os.listdir("/tmp/updates"):
+        d = "/tmp/updates/%s" % pkg
+
+        if not os.path.isdir(d):
+            continue
+
+        # See if the package exists in /usr/lib{64,}/python/?.?/site-packages.
+        # If it does, we can set it up as an update.  If not, the pkg is
+        # likely a completely new directory and should not be looked at.
+        dest = "%s/%s" % (get_python_lib(), pkg)
+        if not os.access(dest, os.R_OK):
+            dest = "%s/%s" % (get_python_lib(1), pkg)
+            if not os.access(dest, os.R_OK):
+                continue
+        # Symlink over everything that's in the python libdir but not in
+        # the updates directory.
+        symlink_updates(dest, d)
+
+    import glob
+    import shutil
+    for rule in glob.glob("/tmp/updates/*.rules"):
+        target = "/etc/udev/rules.d/" + rule.split('/')[-1]
+        shutil.copyfile(rule, target)
+
+def symlink_updates(dest_dir, update_dir):    
+    contents = os.listdir(update_dir)
+
+    for f in os.listdir(dest_dir):
+        dest_path = os.path.join(dest_dir, f)
+        update_path = os.path.join(update_dir, f)
+        if f in contents:
+            # recurse into directories, there might be files missing in updates
+            if os.path.isdir(dest_path) and os.path.isdir(update_path):
+                symlink_updates(dest_path, update_path)
+        else:
+            if f.endswith(".pyc") or f.endswith(".pyo"):
+                continue
+            os.symlink(dest_path, update_path)
+
+if __name__ == "__main__":
+    setupPythonUpdates()
+
+    # do this early so we can set flags before initializing logging
+    args = parseArguments()
+
+    from pyanaconda.flags import flags
+    if args.images:
+        flags.imageInstall = True
+    if args.debug:
+        flags.debug = True
+
+    # Set up logging as early as possible.
+    import logging
+    from pyanaconda import anaconda_log
+    anaconda_log.init()
+
+    log = logging.getLogger("anaconda")
+    stdoutLog = logging.getLogger("anaconda.stdout")
+
+    if os.geteuid() != 0:
+        stdoutLog.error("anaconda must be run as root.")
+        sys.exit(0)
+
+    log.info("%s %s" % (sys.argv[0], getAnacondaVersion()))
+
+    # pull this in to get product name and versioning
+    from pyanaconda import product
+
+    from pyanaconda import isys
+    isys.initLog()
+
+    import warnings
+
+    from pyanaconda import iutil
+    from pyanaconda import kickstart
+
+    from pyanaconda import Anaconda
+    anaconda = Anaconda()
+    warnings.showwarning = AnacondaShowWarning
+
+    # reset python's default SIGINT handler
+    signal.signal(signal.SIGINT, signal.SIG_DFL)
+    signal.signal(signal.SIGSEGV, isys.handleSegv)
+
+    setupEnvironment()
+
+    anaconda.opts = args
+    setupLoggingFromArgs(args)
+    anaconda.displayMode = 's'
+    anaconda.isHeadless = True
+
+    log.info("anaconda called with cmdline = %s" %(sys.argv,))
+
+    os.system("udevadm control --env=ANACONDA=1")
+
+    kickstart.preScriptPass(anaconda, args.ksfile)
+    anaconda.ksdata = kickstart.parseKickstart(anaconda, args.ksfile)
+
+    anaconda.initInterface()
+    anaconda.instClass.configure(anaconda)
+
+    kickstart.setSteps(anaconda)
+
+    image_count = 0
+    for image in args.images:
+        image_spec = image.rsplit(":", 1)
+        path = image_spec[0]
+        if len(image_spec) == 2 and image_spec[1].strip():
+            name = image_spec[1].strip()
+        else:
+            name = os.path.splitext(os.path.basename(path))[0]
+
+        if "/" in name or name in anaconda.storage.config.diskImages.keys():
+            name = "diskimg%d" % image_count
+
+        log.info("naming disk image '%s' '%s'" % (path, name))
+        anaconda.storage.config.diskImages[name] = path
+        image_count += 1
+
+    if image_count:
+        anaconda.storage.setupDiskImages()
+    else:
+        log.error("No disk images to install to")
+        # TODO: Need to call some kind of cleanup here...
+        sys.exit(0)
+
+    from pyanaconda.exception import initExceptionHandling
+    anaconda.mehConfig = initExceptionHandling(anaconda)
+
+    # add our own additional signal handlers
+    signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState())
+
+    try:
+        anaconda.dispatch.run()
+    except SystemExit, code:
+        anaconda.intf.shutdown()
+
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py
index ccbf07b..839a160 100644
--- a/pyanaconda/__init__.py
+++ b/pyanaconda/__init__.py
@@ -252,6 +252,9 @@ class Anaconda(object):
         if self.displayMode == 'c':
             from cmdline import InstallInterface
 
+        if self.displayMode == 's':
+            from script import InstallInterface
+
         self._intf = InstallInterface()
         return self._intf
 
-- 
1.7.4.4

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


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