$Id: patch7.in /main/4 2009/07/10 01:14:52 alfords Exp $ Copyright 2009 Automatic Data Processing, Inc. See the README file in the first patch of this series for important details. kickstart.py.patch has most of our changes to the anaconda code. These changes include: * an --interactive flag for pre- and post-install scripts. That causes anaconda to allow regular "cooked" output on a serial console terminal or the regular keyboard, video monitor and mouse (KVM.) * support for tape restore. We introduce a new install type, "restore", which skips many of the regular kickstart install steps. This enables a post-install script to re-install the system from a backup tape. * passing the -s command line flag for post-install scripts when they were running on a serial console. We needed to be prepared for a user restoring a tape from a KVM system onto a serial console system, and vice versa. This way the post restore script knows it may need to adjust system configuration files for the other kind of console. This change also may result in pre-install scripts being passed a -s flag. We only ever tested or used -s in post-install scripts. We cannot say for sure because our pre-install scripts do not try to process command line flags. --Seth Alford ADP Dealer Services seth_alford@xxxxxxx ----kickstart.py.patch follows---- --- a_naconda-11.1.2.168/kickstart.py 2008-12-18 02:21:19.000000000 -0800 +++ anaconda-11.1.2.168/kickstart.py 2009-05-11 12:54:42.000000000 -0700 @@ -12,6 +12,7 @@ # import iutil +import subprocess import isys import os from installclass import BaseInstallClass, availableClasses, getBaseInstallClass @@ -37,6 +38,13 @@ from anaconda_log import logger, logLevelMap class AnacondaKSScript(Script): + def __init__(self, script, interp = "/bin/sh", inChroot = False, + logfile = None, errorOnFail = False, type = KS_SCRIPT_PRE, + userinput = False): + Script.__init__(self, script, interp, inChroot, logfile, + errorOnFail, type) + self.userinput = userinput + def run(self, chroot, serial, intf = None): import tempfile import os.path @@ -56,14 +64,30 @@ messages = self.logfile elif serial: messages = "%s.log" % path + sflag = "-s" else: messages = "/dev/tty3" + sflag = "" + + tmppath = "/tmp/%s" % (os.path.basename(path)) if intf: intf.suspend() - rc = iutil.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)], - stdin = messages, stdout = messages, stderr = messages, - root = scriptRoot) + + if self.userinput: + try: + proc = subprocess.Popen([self.interp, tmppath, sflag], + cwd=scriptRoot) + rc = proc.wait() + except OSError, (errno, msg): + raise RuntimeError, "Error running " + tmppath + sflag + ": " + msg + #NOTREACHED + + else: + rc = iutil.execWithRedirect(self.interp, [tmppath, sflag], + stdin = messages, stdout = messages, stderr = messages, + root = scriptRoot) + if intf: intf.resume() @@ -86,11 +110,16 @@ os.unlink(path) if serial or self.logfile is not None: - os.chmod("%s" % messages, 0600) + if os.path.exists("%s" % messages): + os.chmod("%s" % messages, 0600) class AnacondaKSHandlers(KickstartHandlers): def __init__ (self, ksdata, anaconda): KickstartHandlers.__init__(self, ksdata) + self.ksdata.reboot["eject"] = True + self.handlers["restore"] = self.doRestore + log.info ("Added restore to handlers in AnacondaKSHandlers") + self.permanentSkipSteps = [] self.skipSteps = [] self.showSteps = [] @@ -107,6 +136,20 @@ self.lineno = 0 self.currentCmd = "" + def doRestore(self, args): + self.skipSteps.extend([ + "bootloader", + "bootloaderadvanced", + "bootloadersetup", + "firstboot", + "instbootloader", + "install", + "installpackages", + "postinstallconfig", + "writeconfig", + "writeksconfig", + ]) + def doAuthconfig(self, args): KickstartHandlers.doAuthconfig(self, args) self.id.auth = self.ksdata.authconfig @@ -703,7 +746,7 @@ KickstartHandlers.__init__(self, ksdata) self.resetHandlers() self.handlers["vnc"] = self.doVnc - + self.handlers["restore"] = None # ADP self.handlers["text"] = self.doDisplayMode self.handlers["cmdline"] = self.doDisplayMode self.handlers["graphical"] = self.doDisplayMode @@ -718,7 +761,9 @@ if self.state == STATE_PRE: s = AnacondaKSScript (self.script["body"], self.script["interp"], self.script["chroot"], self.script["log"], - self.script["errorOnFail"]) + self.script["errorOnFail"], + self.script["type"], + self.script["userinput"]) self.ksdata.scripts.append(s) def addPackages (self, line): @@ -739,6 +784,8 @@ default=False) op.add_option("--interpreter", dest="interpreter", default="/bin/sh") op.add_option("--log", "--logfile", dest="log") + op.add_option("--userinput", dest="userInput", action="store_true", + default=False) (opts, extra) = op.parse_args(args=args[1:]) @@ -746,11 +793,15 @@ self.script["log"] = opts.log self.script["errorOnFail"] = opts.errorOnFail self.script["chroot"] = False + self.script["userinput"] = opts.userInput class AnacondaKSParser(KickstartParser): - def __init__ (self, ksdata, kshandlers): + def __init__ (self, ksdata, kshandlers, followIncludes=True, + errorsAreFatal=True, missingIncludeIsFatal=True): self.sawPackageSection = False - KickstartParser.__init__(self, ksdata, kshandlers) + KickstartParser.__init__(self, ksdata, kshandlers, + followIncludes, errorsAreFatal, + missingIncludeIsFatal) # Map old broken Everything group to the new futuristic package globs def addPackages (self, line): @@ -766,7 +817,8 @@ s = AnacondaKSScript (self.script["body"], self.script["interp"], self.script["chroot"], self.script["log"], - self.script["errorOnFail"], self.script["type"]) + self.script["errorOnFail"], self.script["type"], + self.script["userinput"]) self.ksdata.scripts.append(s) @@ -789,6 +841,31 @@ self.handler.lineno = lineno self.handler.handlers[cmd](cmdArgs) + def handleScriptHdr (self, lineno, args): + op = KSOptionParser(lineno=lineno) + 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") + op.add_option("--userinput", dest="userInput", action="store_true", + default=False) + + if args[0] == "%pre" or args[0] == "%traceback": + self.script["chroot"] = False + elif args[0] == "%post": + self.script["chroot"] = True + op.add_option("--nochroot", dest="nochroot", action="store_true", + default=False) + + (opts, extra) = op.parse_args(args=args[1:]) + + self.script["interp"] = opts.interpreter + self.script["log"] = opts.log + self.script["errorOnFail"] = opts.errorOnFail + if hasattr(opts, "nochroot"): + self.script["chroot"] = not opts.nochroot + self.script["userinput"] = opts.userInput + cobject = getBaseInstallClass() # The anaconda kickstart processor. This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system. _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list