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