All changes to handle the new rescue command and %post scripts when in rescue mode.
anaconda | 41 ++++++++++++++++ kickstart.py | 7 +++ loader2/loader.c | 10 ++-- rescue.py | 135 +++++++++++++++++++++++++++++++++--------------------- 4 files changed, 136 insertions(+), 57 deletions(-) diff --git a/anaconda b/anaconda index cd8e8eb..c7b43d3 100755 --- a/anaconda +++ b/anaconda @@ -325,6 +325,35 @@ def setVNCFromKickstart(opts): return handler.vnc +def setRescueModeFromKickstart(opts): + from kickstart import KickstartError, RescueHandler + from pykickstart.parser import KickstartParser, preprocessKickstart + + try: + opts.ksfile = preprocessKickstart(opts.ksfile) + except KickstartError, msg: + stdoutLog.critical(_("Error processing %%ksappend lines: %s") % e) + sys.exit(1) + except Exception, e: + stdoutLog.critical(_("Unknown error processing %%ksappend lines: %s") % e) + sys.exit(1) + + # now see if they enabled rescue mode via the kickstart file. + handler = RescueHandler() + ksparser = KickstartParser(handler, missingIncludeIsFatal=False) + + # We don't have an intf by now so the best we can do is just print the + # exception out. + try: + ksparser.readKickstart(opts.ksfile) + except KickstartError, e: + print _("The following error was found while parsing your " + "kickstart configuration:\n\n%s") % e + sys.exit(1) + + # True or False + return handler.rescue.rescue + def setupPythonPath(): # For anaconda in test mode if (os.path.exists('isys')): @@ -743,12 +772,24 @@ if __name__ == "__main__": # # must specify install, rescue mode # + if opts.ksfile and (not opts.rescue): + opts.rescue = setRescueModeFromKickstart(opts) + if opts.rescue: anaconda.rescue = True import rescue, instdata anaconda.id = instdata.InstallData(anaconda, [], opts.display_mode) + + if opts.ksfile: + anaconda.isKickstart = True + instClass.setInstallData(anaconda) + kickstart.processKickstartFile(anaconda, opts.ksfile) + + # command line 'nomount' overrides kickstart /same for vnc/ + anaconda.rescue_mount = not (opts.rescue_nomount or anaconda.id.ksdata.rescue.nomount) + rescue.runRescue(anaconda, instClass) # shouldn't get back here diff --git a/kickstart.py b/kickstart.py index fa8b315..068922e 100644 --- a/kickstart.py +++ b/kickstart.py @@ -818,6 +818,7 @@ commandMap = { "raid": Raid, "reboot": Reboot, "repo": commands.repo.F8_Repo, + "rescue": commands.rescue.F10_Rescue, "rootpw": RootPw, "selinux": SELinux, "services": commands.services.FC6_Services, @@ -862,6 +863,12 @@ class VNCHandler(superclass): superclass.__init__(self, mapping=commandMap) self.maskAllExcept(["vnc", "displaymode", "text", "cmdline", "graphical"]) +class RescueHandler(superclass): + # We're only interested in the handler for the rescue command + def __init__(self, anaconda=None): + superclass.__init__(self, mapping=commandMap) + self.maskAllExcept(["rescue"]) + class KickstartPreParser(KickstartParser): def __init__ (self, handler, followIncludes=True, errorsAreFatal=True, missingIncludeIsFatal=True): diff --git a/loader2/loader.c b/loader2/loader.c index 6dd0018..ccd425b 100644 --- a/loader2/loader.c +++ b/loader2/loader.c @@ -2000,6 +2000,11 @@ int main(int argc, char ** argv) { if (FL_NOIPV6(flags)) *argptr++ = "--noipv6"; + if (FL_KICKSTART(flags)) { + *argptr++ = "--kickstart"; + *argptr++ = loaderData.ksFile; + } + if (FL_SERIAL(flags)) *argptr++ = "--serial"; @@ -2019,11 +2024,6 @@ int main(int argc, char ** argv) { else if (FL_SELINUX(flags)) *argptr++ = "--selinux"; - if (FL_KICKSTART(flags)) { - *argptr++ = "--kickstart"; - *argptr++ = loaderData.ksFile; - } - if (FL_VIRTPCONSOLE(flags)) { *argptr++ = "--virtpconsole"; *argptr++ = virtpcon; diff --git a/rescue.py b/rescue.py index 3f77e75..028471c 100644 --- a/rescue.py +++ b/rescue.py @@ -277,40 +277,53 @@ def runRescue(anaconda, instClass): # Early shell access with no disk access attempts if not anaconda.rescue_mount: - runShell() - sys.exit(0) + # the %post should be responsible for mounting all needed file systems + # NOTE: 1st script must be bash or simple python as nothing else might be available in the rescue image + if anaconda.isKickstart: + from kickstart import runPostScripts + runPostScripts(anaconda) + else: + runShell() - screen = SnackScreen() - anaconda.intf = RescueInterface(screen) - - # prompt to see if we should try and find root filesystem and mount - # everything in /etc/fstab on that root - rc = ButtonChoiceWindow(screen, _("Rescue"), - _("The rescue environment will now attempt to find your " - "Linux installation and mount it under the directory " - "%s. You can then make any changes required to your " - "system. If you want to proceed with this step choose " - "'Continue'. You can also choose to mount your file systems " - "read-only instead of read-write by choosing 'Read-Only'." - "\n\n" - "If for some reason this process fails you can choose 'Skip' " - "and this step will be skipped and you will go directly to a " - "command shell.\n\n") % (anaconda.rootPath,), - [_("Continue"), _("Read-Only"), _("Skip")] ) - - if rc == string.lower(_("Skip")): - runShell(screen) sys.exit(0) - elif rc == string.lower(_("Read-Only")): - readOnly = 1 + + if anaconda.isKickstart: + if anaconda.id.ksdata.rescue and anaconda.id.ksdata.rescue.romount: + readOnly = 1 + else: + readOnly = 0 else: - readOnly = 0 + screen = SnackScreen() + anaconda.intf = RescueInterface(screen) + + # prompt to see if we should try and find root filesystem and mount + # everything in /etc/fstab on that root + rc = ButtonChoiceWindow(screen, _("Rescue"), + _("The rescue environment will now attempt to find your " + "Linux installation and mount it under the directory " + "%s. You can then make any changes required to your " + "system. If you want to proceed with this step choose " + "'Continue'. You can also choose to mount your file systems " + "read-only instead of read-write by choosing 'Read-Only'." + "\n\n" + "If for some reason this process fails you can choose 'Skip' " + "and this step will be skipped and you will go directly to a " + "command shell.\n\n") % (anaconda.rootPath,), + [_("Continue"), _("Read-Only"), _("Skip")] ) + + if rc == string.lower(_("Skip")): + runShell(screen) + sys.exit(0) + elif rc == string.lower(_("Read-Only")): + readOnly = 1 + else: + readOnly = 0 disks = upgrade.findExistingRoots(anaconda, upgradeany = 1) if not disks: root = None - elif len(disks) == 1: + elif (len(disks) == 1) or anaconda.isKickstart: root = disks[0] else: height = min (len (disks), 12) @@ -352,22 +365,28 @@ def runRescue(anaconda, instClass): readOnly = readOnly) if rc == -1: - ButtonChoiceWindow(screen, _("Rescue"), - _("Your system had dirty file systems which you chose not " - "to mount. Press return to get a shell from which " - "you can fsck and mount your partitions. The system " - "will reboot automatically when you exit from the " - "shell."), [_("OK")], width = 50) + if anaconda.isKickstart: + log.error("System had dirty file systems which you chose not to mount") + else: + ButtonChoiceWindow(screen, _("Rescue"), + _("Your system had dirty file systems which you chose not " + "to mount. Press return to get a shell from which " + "you can fsck and mount your partitions. The system " + "will reboot automatically when you exit from the " + "shell."), [_("OK")], width = 50) rootmounted = 0 else: - ButtonChoiceWindow(screen, _("Rescue"), - _("Your system has been mounted under %s.\n\n" - "Press <return> to get a shell. If you would like to " - "make your system the root environment, run the command:\n\n" - "\tchroot %s\n\nThe system will reboot " - "automatically when you exit from the shell.") % - (anaconda.rootPath, anaconda.rootPath), - [_("OK")] ) + if anaconda.isKickstart: + log.info("System has been mounted under: %s" % anaconda.rootPath) + else: + ButtonChoiceWindow(screen, _("Rescue"), + _("Your system has been mounted under %s.\n\n" + "Press <return> to get a shell. If you would like to " + "make your system the root environment, run the command:\n\n" + "\tchroot %s\n\nThe system will reboot " + "automatically when you exit from the shell.") % + (anaconda.rootPath, anaconda.rootPath), + [_("OK")] ) rootmounted = 1 # now turn on swap @@ -438,18 +457,24 @@ def runRescue(anaconda, instClass): if exc in (IndexError, ValueError, SyntaxError): raise exc, val, sys.exc_info()[2] - ButtonChoiceWindow(screen, _("Rescue"), - _("An error occurred trying to mount some or all of your " - "system. Some of it may be mounted under %s.\n\n" - "Press <return> to get a shell. The system will reboot " - "automatically when you exit from the shell.") % (anaconda.rootPath,), - [_("OK")] ) + if anaconda.isKickstart: + log.error("An error occurred trying to mount some or all of your system") + else: + ButtonChoiceWindow(screen, _("Rescue"), + _("An error occurred trying to mount some or all of your " + "system. Some of it may be mounted under %s.\n\n" + "Press <return> to get a shell. The system will reboot " + "automatically when you exit from the shell.") % (anaconda.rootPath,), + [_("OK")] ) else: - ButtonChoiceWindow(screen, _("Rescue Mode"), - _("You don't have any Linux partitions. Press " - "return to get a shell. The system will reboot " - "automatically when you exit from the shell."), - [ _("OK") ], width = 50) + if anaconda.isKickstart: + log.info("No Linux partitions found") + else: + ButtonChoiceWindow(screen, _("Rescue Mode"), + _("You don't have any Linux partitions. Press " + "return to get a shell. The system will reboot " + "automatically when you exit from the shell."), + [ _("OK") ], width = 50) msgStr = "" @@ -461,5 +486,11 @@ def runRescue(anaconda, instClass): log.error("error making a resolv.conf: %s" %(e,)) msgStr = _("Your system is mounted under the %s directory.") % (anaconda.rootPath,) - runShell(screen, msgStr) + # run %post if we've mounted everything + if anaconda.isKickstart: + from kickstart import runPostScripts + runPostScripts(anaconda) + else: + runShell(screen, msgStr) + sys.exit(0)
_______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list