[PATCH] Handle 'rescue' and %post in rescue mode

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

 



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

[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