Пример #1
0
def upgradeMountFilesystems(anaconda):
    # mount everything and turn on swap

    try:
        mountExistingSystem(anaconda, anaconda.id.upgradeRoot[0], allowDirty=0)
    except ValueError as e:
        log.error("Error mounting filesystem: %s" % e)
        anaconda.intf.messageWindow(
            _("Mount failed"),
            _("The following error occurred when mounting the file "
              "systems listed in /etc/fstab.  Please fix this problem "
              "and try to upgrade again.\n%s" % e))
        sys.exit(0)
    except IndexError as e:
        # The upgrade root is search earlier but we give the message here.
        log.debug("No upgrade root was found.")
        if anaconda.isKickstart and anaconda.id.ksdata.upgrade.upgrade:
            anaconda.intf.messageWindow(
                _("Upgrade root not found"),
                _("The root for the previously installed system was not "
                  "found."),
                type="custom",
                custom_icon="info",
                custom_buttons=[_("Exit installer")])
            sys.exit(0)
        else:
            rc = anaconda.intf.messageWindow(
                _("Upgrade root not found"),
                _("The root for the previously installed system was not "
                  "found.  You can exit installer or backtrack to choose "
                  "installation instead of upgrade."),
                type="custom",
                custom_buttons=[_("_Back"), _("_Exit installer")],
                custom_icon="question")
            if rc == 0:
                return DISPATCH_BACK
            elif rc == 1:
                sys.exit(0)

    checkLinks = ('/etc', '/var', '/var/lib', '/var/lib/rpm', '/boot', '/tmp',
                  '/var/tmp', '/root', '/bin/sh', '/usr/tmp')
    badLinks = []
    for n in checkLinks:
        if not os.path.islink(anaconda.rootPath + n): continue
        l = os.readlink(anaconda.rootPath + n)
        if l[0] == '/':
            badLinks.append(n)

    if badLinks:
        message = _("The following files are absolute symbolic "
                    "links, which we do not support during an "
                    "upgrade. Please change them to relative "
                    "symbolic links and restart the upgrade.\n\n")
        for n in badLinks:
            message = message + '\t' + n + '\n'
        anaconda.intf.messageWindow(_("Absolute Symlinks"), message)
        sys.exit(0)

    # fix for 80446
    badLinks = []
    mustBeLinks = ('/usr/tmp', )
    for n in mustBeLinks:
        if not os.path.islink(anaconda.rootPath + n):
            badLinks.append(n)

    if badLinks:
        message = _("The following are directories which should instead "
                    "be symbolic links, which will cause problems with the "
                    "upgrade.  Please return them to their original state "
                    "as symbolic links and restart the upgrade.\n\n")
        for n in badLinks:
            message = message + '\t' + n + '\n'
        anaconda.intf.messageWindow(_("Invalid Directories"), message)
        sys.exit(0)

    anaconda.id.storage.turnOnSwap(upgrading=True)
    anaconda.id.storage.mkDevRoot()

    # Move /etc/rpm/platform out of the way.
    if os.path.exists(anaconda.rootPath + "/etc/rpm/platform"):
        shutil.move(anaconda.rootPath + "/etc/rpm/platform",
                    anaconda.rootPath + "/etc/rpm/platform.rpmsave")

    # if they've been booting with selinux disabled, then we should
    # disable it during the install as well (#242510)
    try:
        if os.path.exists(anaconda.rootPath + "/.autorelabel"):
            ctx = selinux.getfilecon(anaconda.rootPath + "/.autorelabel")[1]
            if not ctx or ctx == "unlabeled":
                flags.selinux = False
                log.info("Disabled SELinux for upgrade based on /.autorelabel")
    except Exception, e:
        log.warning("error checking selinux state: %s" % (e, ))
Пример #2
0
def runRescue(anaconda, instClass):
    for file in [ "services", "protocols", "group", "joe", "man.config",
                  "nsswitch.conf", "selinux", "mke2fs.conf" ]:
        try:
            os.symlink('/mnt/runtime/etc/' + file, '/etc/' + file)
        except:
            pass

    # see if they would like networking enabled
    if not network.hasActiveNetDev():
        screen = SnackScreen()

        while True:
            rc = ButtonChoiceWindow(screen, _("Setup Networking"),
                _("Do you want to start the network interfaces on "
                  "this system?"), [_("Yes"), _("No")])

            if rc != string.lower(_("No")):
                anaconda.intf = RescueInterface(screen)

                if not anaconda.intf.enableNetwork(anaconda):
                    anaconda.intf.messageWindow(_("No Network Available"),
                        _("Unable to activate a networking device.  Networking "
                          "will not be available in rescue mode."))
                    break

                startNetworking(anaconda.id.network, anaconda.intf)
                break
            else:
                break

        anaconda.intf = None
        screen.finish()

    # Early shell access with no disk access attempts
    if not anaconda.rescue_mount:
        # 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 and anaconda.id.ksdata.scripts:
           from kickstart import runPostScripts
           runPostScripts(anaconda)
        else:
           runShell()

        sys.exit(0)

    screen = SnackScreen()
    anaconda.intf = RescueInterface(screen)

    if anaconda.isKickstart:
        if anaconda.id.ksdata.rescue and anaconda.id.ksdata.rescue.romount:
            readOnly = 1
        else:
            readOnly = 0
    else:
        # prompt to see if we should try and find root filesystem and mount
        # everything in /etc/fstab on that root
        while True:
            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'.  "
                  "If you need to activate SAN devices choose 'Advanced'."
                  "\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"), _("Advanced")] )

            if rc == string.lower(_("Skip")):
                runShell(screen)
                sys.exit(0)
            elif rc == string.lower(_("Advanced")):
                addDialog = addDriveDialog(anaconda)
                addDialog.addDriveDialog(screen)
                continue
            elif rc == string.lower(_("Read-Only")):
                readOnly = 1
            else:
                readOnly = 0
            break

    import storage
    storage.storageInitialize(anaconda)

    disks = upgrade.findExistingRoots(anaconda, upgradeany=True)

    if not disks:
        root = None
    elif (len(disks) == 1) or anaconda.isKickstart:
        root = disks[0]
    else:
        height = min (len (disks), 12)
        if height == 12:
            scroll = 1
        else:
            scroll = 0

        devList = []
        for (device, relstr) in disks:
            if getattr(device.format, "label", None):
                devList.append("%s (%s) - %s" % (device.name, device.format.label, relstr))
            else:
                devList.append("%s - %s" % (device.name, relstr))

        (button, choice) = \
            ListboxChoiceWindow(screen, _("System to Rescue"),
                                _("Which device holds the root partition "
                                  "of your installation?"), devList,
                                [ _("OK"), _("Exit") ], width = 30,
                                scroll = scroll, height = height,
                                help = "multipleroot")

        if button == string.lower (_("Exit")):
            root = None
        else:
            root = disks[choice]

    rootmounted = 0

    if root:
        try:
            rc = mountExistingSystem(anaconda, root,
                                     allowDirty = 1, warnDirty = 1,
                                     readOnly = readOnly)

            if rc == -1:
                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:
                if anaconda.isKickstart:
                    log.info("System has been mounted under: %s" % anaconda.rootPath)
                else:
                    ButtonChoiceWindow(screen, _("Rescue"),
                       _("Your system has been mounted under %(rootPath)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 %(rootPath)s\n\nThe system will reboot "
                         "automatically when you exit from the shell.") %
                                       {'rootPath': anaconda.rootPath},
                                       [_("OK")] )
                rootmounted = 1

                # now turn on swap
                if not readOnly:
                    try:
                        anaconda.id.storage.turnOnSwap()
                    except:
                        log.error("Error enabling swap")

                # and /selinux too
                if flags.selinux and os.path.isdir("%s/selinux" %(anaconda.rootPath,)):
                    try:
                        isys.mount("/selinux", "%s/selinux" %(anaconda.rootPath,),
                                   "selinuxfs")
                    except Exception, e:
                        log.error("error mounting selinuxfs: %s" %(e,))

                    fd = open("%s/.autorelabel" % anaconda.rootPath, "w+")
                    fd.close()

                # set a library path to use mounted fs
                libdirs = os.environ["LD_LIBRARY_PATH"].split(":")
                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)

                # find groff data dir
                try:
                    glst = os.listdir("/mnt/sysimage/usr/share/groff")

                    # find a directory which is a numeral, its where
                    # data files are
                    gversion = None
                    for gdir in glst:
                        try:
                            isone = 1
                            for idx in range(0, len(gdir)):
                                if string.find(string.digits + '.', gdir[idx]) == -1:
                                    isone = 0
                                    break
                            if isone:
                                gversion = gdir
                                break
                        except:
                            gversion = None
                            continue
                except:
                    gversion = None

                if gversion is not None:
                    gpath = "/mnt/sysimage/usr/share/groff/"+gversion
                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
                    os.environ["GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (gpath + '/tmac',)

                # do we have bash?
                try:
                    if os.access("/usr/bin/bash", os.R_OK):
                        os.symlink ("/usr/bin/bash", "/bin/bash")
                except:
                    pass
        except:
            # This looks horrible, but all it does is catch every exception,
            # and reraise those in the tuple check. This lets programming
            # errors raise exceptions, while any runtime error will
            # still result in a shell
            (exc, val) = sys.exc_info()[0:2]
            log.error(str(exc)+": "+str(val))
            if exc in (IndexError, ValueError, SyntaxError):
                raise exc, val, sys.exc_info()[2]

            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:
        if anaconda.isKickstart and \
               anaconda.id.ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
            log.info("No Linux partitions found")
            screen.finish()
            print(_("You don't have any Linux partitions.  Rebooting.\n"))
            sys.exit(0)
        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 = ""

    if rootmounted and not readOnly:
        makeMtab(anaconda.rootPath, anaconda.id.storage)
        try:
            makeResolvConf(anaconda.rootPath)
        except Exception, e:
            log.error("error making a resolv.conf: %s" %(e,))
        msgStr = _("Your system is mounted under the %s directory.") % (anaconda.rootPath,)
        ButtonChoiceWindow(screen, _("Rescue"), msgStr, [_("OK")] )
Пример #3
0
def upgradeMountFilesystems(anaconda):
    # mount everything and turn on swap

    try:
        mountExistingSystem(anaconda, anaconda.upgradeRoot[0], allowDirty = 0)
    except ValueError as e:
        log.error("Error mounting filesystem: %s" % e)
        anaconda.intf.messageWindow(_("Mount failed"),
            _("The following error occurred when mounting the file "
              "systems listed in /etc/fstab.  Please fix this problem "
              "and try to upgrade again.\n%s" % e))
        sys.exit(0)
    except IndexError as e:
        # The upgrade root is search earlier but we give the message here.
        log.debug("No upgrade root was found.")
        if anaconda.ksdata and anaconda.ksdata.upgrade.upgrade:
            anaconda.intf.messageWindow(_("Upgrade root not found"),
                _("The root for the previously installed system was not "
                  "found."), type="custom",
                custom_icon="info",
                custom_buttons=[_("Exit installer")])
            sys.exit(0)
        else:
            rc = anaconda.intf.messageWindow(_("Upgrade root not found"),
                    _("The root for the previously installed system was not "
                      "found.  You can exit installer or backtrack to choose "
                      "installation instead of upgrade."),
                type="custom",
                custom_buttons = [ _("_Back"),
                                   _("_Exit installer") ],
                custom_icon="question")
            if rc == 0:
                return DISPATCH_BACK
            elif rc == 1:
                sys.exit(0)

    checkLinks = ( '/etc', '/var', '/var/lib', '/var/lib/rpm',
                   '/boot', '/tmp', '/var/tmp', '/root',
                   '/bin/sh', '/usr/tmp')
    badLinks = []
    for n in checkLinks:
        if not os.path.islink(anaconda.rootPath + n): continue
        l = os.readlink(anaconda.rootPath + n)
        if l[0] == '/':
            badLinks.append(n)

    if badLinks:
        message = _("The following files are absolute symbolic " 
                    "links, which we do not support during an " 
                    "upgrade. Please change them to relative "
                    "symbolic links and restart the upgrade.\n\n")
        for n in badLinks:
            message = message + '\t' + n + '\n'
        anaconda.intf.messageWindow(_("Absolute Symlinks"), message)
        sys.exit(0)

    # fix for 80446
    badLinks = []
    mustBeLinks = ( '/usr/tmp', )
    for n in mustBeLinks:
        if not os.path.islink(anaconda.rootPath + n):
            badLinks.append(n)

    if badLinks: 
        message = _("The following are directories which should instead "
                    "be symbolic links, which will cause problems with the "
                    "upgrade.  Please return them to their original state "
                    "as symbolic links and restart the upgrade.\n\n")
        for n in badLinks:
            message = message + '\t' + n + '\n'
        anaconda.intf.messageWindow(_("Invalid Directories"), message)
        sys.exit(0)

    anaconda.storage.turnOnSwap(upgrading=True)
    anaconda.storage.mkDevRoot()

    # Move /etc/rpm/platform out of the way.
    if os.path.exists(anaconda.rootPath + "/etc/rpm/platform"):
        shutil.move(anaconda.rootPath + "/etc/rpm/platform",
                    anaconda.rootPath + "/etc/rpm/platform.rpmsave")

    # if they've been booting with selinux disabled, then we should
    # disable it during the install as well (#242510)
    try:
        if os.path.exists(anaconda.rootPath + "/.autorelabel"):
            ctx = selinux.getfilecon(anaconda.rootPath + "/.autorelabel")[1]
            if not ctx or ctx == "unlabeled":
                flags.selinux = False
                log.info("Disabled SELinux for upgrade based on /.autorelabel")
    except Exception, e:
        log.warning("error checking selinux state: %s" %(e,))
Пример #4
0
def runRescue(anaconda):
    for file in [ "services", "protocols", "group", "joe", "man.config",
                  "nsswitch.conf", "selinux", "mke2fs.conf" ]:
        try:
            os.symlink('/mnt/runtime/etc/' + file, '/etc/' + file)
        except:
            pass

    # see if they would like networking enabled
    if not network.hasActiveNetDev():
        screen = SnackScreen()

        while True:
            rc = ButtonChoiceWindow(screen, _("Setup Networking"),
                _("Do you want to start the network interfaces on "
                  "this system?"), [_("Yes"), _("No")])

            if rc != string.lower(_("No")):
                anaconda.intf = RescueInterface(screen)

                if not anaconda.intf.enableNetwork(anaconda):
                    anaconda.intf.messageWindow(_("No Network Available"),
                        _("Unable to activate a networking device.  Networking "
                          "will not be available in rescue mode."))
                    break

                startNetworking(anaconda.network, anaconda.intf)
                break
            else:
                break

        anaconda.intf = None
        screen.finish()

    # Early shell access with no disk access attempts
    if not anaconda.rescue_mount:
        # 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.ksdata and anaconda.ksdata.scripts:
           from kickstart import runPostScripts
           runPostScripts(anaconda)
        else:
           runShell()

        sys.exit(0)

    screen = SnackScreen()
    anaconda.intf = RescueInterface(screen)

    if anaconda.ksdata:
        if anaconda.ksdata.rescue and anaconda.ksdata.rescue.romount:
            readOnly = 1
        else:
            readOnly = 0
    else:
        # prompt to see if we should try and find root filesystem and mount
        # everything in /etc/fstab on that root
        while True:
            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'.  "
                  "If you need to activate SAN devices choose 'Advanced'."
                  "\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"), _("Advanced")] )

            if rc == string.lower(_("Skip")):
                runShell(screen)
                sys.exit(0)
            elif rc == string.lower(_("Advanced")):
                addDialog = addDriveDialog(anaconda)
                addDialog.addDriveDialog(screen)
                continue
            elif rc == string.lower(_("Read-Only")):
                readOnly = 1
            else:
                readOnly = 0
            break

    import storage
    storage.storageInitialize(anaconda)

    (disks, notUpgradable) = upgrade.findExistingRoots(anaconda, upgradeany=True)

    if not disks:
        root = None
    elif (len(disks) == 1) or anaconda.ksdata:
        root = disks[0]
    else:
        height = min (len (disks), 12)
        if height == 12:
            scroll = 1
        else:
            scroll = 0

        devList = []
        for (device, relstr) in disks:
            if getattr(device.format, "label", None):
                devList.append("%s (%s) - %s" % (device.name, device.format.label, relstr))
            else:
                devList.append("%s - %s" % (device.name, relstr))

        (button, choice) = \
            ListboxChoiceWindow(screen, _("System to Rescue"),
                                _("Which device holds the root partition "
                                  "of your installation?"), devList,
                                [ _("OK"), _("Exit") ], width = 30,
                                scroll = scroll, height = height,
                                help = "multipleroot")

        if button == string.lower (_("Exit")):
            root = None
        else:
            root = disks[choice]

    rootmounted = 0

    if root:
        try:
            rc = mountExistingSystem(anaconda, root,
                                     allowDirty = 1, warnDirty = 1,
                                     readOnly = readOnly)

            if rc == -1:
                if anaconda.ksdata:
                    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:
                if anaconda.ksdata:
                    log.info("System has been mounted under: %s" % anaconda.rootPath)
                else:
                    ButtonChoiceWindow(screen, _("Rescue"),
                       _("Your system has been mounted under %(rootPath)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 %(rootPath)s\n\nThe system will reboot "
                         "automatically when you exit from the shell.") %
                                       {'rootPath': anaconda.rootPath},
                                       [_("OK")] )
                rootmounted = 1

                # now turn on swap
                if not readOnly:
                    try:
                        anaconda.storage.turnOnSwap()
                    except:
                        log.error("Error enabling swap")

                # and /sys/fs/selinux too
                if flags.selinux and os.path.isdir("%s/sys/fs/selinux" %(anaconda.rootPath,)):
                    try:
                        isys.mount("/sys/fs/selinux", "%s/sys/fs/selinux" %(anaconda.rootPath,),
                                   "selinuxfs")
                    except Exception, e:
                        log.error("error mounting selinuxfs: %s" %(e,))

                    # we have to catch the possible exception
                    # because we support read-only mounting
                    try:
                        fd = open("%s/.autorelabel" % anaconda.rootPath, "w+")
                        fd.close()
                    except Exception, e:
                        log.warning("cannot touch /.autorelabel")

                # set a library path to use mounted fs
                libdirs = os.environ["LD_LIBRARY_PATH"].split(":")
                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)

                # find groff data dir
                try:
                    glst = os.listdir("/mnt/sysimage/usr/share/groff")

                    # find a directory which is a numeral, its where
                    # data files are
                    gversion = None
                    for gdir in glst:
                        try:
                            isone = 1
                            for idx in range(0, len(gdir)):
                                if string.find(string.digits + '.', gdir[idx]) == -1:
                                    isone = 0
                                    break
                            if isone:
                                gversion = gdir
                                break
                        except:
                            gversion = None
                            continue
                except:
                    gversion = None

                if gversion is not None:
                    gpath = "/mnt/sysimage/usr/share/groff/"+gversion
                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
                    os.environ["GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (gpath + '/tmac',)

                # do we have bash?
                try:
                    if os.access("/usr/bin/bash", os.R_OK):
                        os.symlink ("/usr/bin/bash", "/bin/bash")
                except:
                    pass
Пример #5
0
def doRescue(anaconda):
    for file in [ "services", "protocols", "group", "joe", "man.config",
                  "nsswitch.conf", "selinux", "mke2fs.conf" ]:
        try:
            os.symlink('/mnt/runtime/etc/' + file, '/etc/' + file)
        except OSError:
            pass

    # see if they would like networking enabled
    if not network.hasActiveNetDev():

        while True:
            rc = ButtonChoiceWindow(anaconda.intf.screen, _("Setup Networking"),
                _("Do you want to start the network interfaces on "
                  "this system?"), [_("Yes"), _("No")])

            if rc != _("No").lower():
                if not anaconda.intf.enableNetwork(anaconda):
                    anaconda.intf.messageWindow(_("No Network Available"),
                        _("Unable to activate a networking device.  Networking "
                          "will not be available in rescue mode."))
                    break

                startNetworking(anaconda.network, anaconda.intf)
                break
            else:
                break

    # shutdown the interface now
    anaconda.intf.shutdown()
    anaconda.intf = None

    # Early shell access with no disk access attempts
    if not anaconda.rescue_mount:
        # 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.ksdata and anaconda.ksdata.scripts:
           from kickstart import runPostScripts
           runPostScripts(anaconda)
        else:
           runShell()

        sys.exit(0)

    anaconda.intf = RescueInterface()

    if anaconda.ksdata:
        if anaconda.ksdata.rescue and anaconda.ksdata.rescue.romount:
            readOnly = 1
        else:
            readOnly = 0
    else:
        # prompt to see if we should try and find root filesystem and mount
        # everything in /etc/fstab on that root
        while True:
            rc = ButtonChoiceWindow(anaconda.intf.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'.  "
                  "If you need to activate SAN devices choose 'Advanced'."
                  "\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") % (ROOT_PATH,),
                  [_("Continue"), _("Read-Only"), _("Skip"), _("Advanced")] )

            if rc == _("Skip").lower():
                runShell(anaconda.intf.screen)
                sys.exit(0)
            elif rc == _("Advanced").lower():
                addDialog = addDriveDialog(anaconda)
                addDialog.addDriveDialog(anaconda.intf.screen)
                continue
            elif rc == _("Read-Only").lower():
                readOnly = 1
            else:
                readOnly = 0
            break

    import storage
    storage.storageInitialize(anaconda)

    (disks, notUpgradable) = storage.findExistingRootDevices(anaconda, upgradeany=True)

    if not disks:
        root = None
    elif (len(disks) == 1) or anaconda.ksdata:
        root = disks[0]
    else:
        height = min (len (disks), 12)
        if height == 12:
            scroll = 1
        else:
            scroll = 0

        devList = []
        for (device, relstr) in disks:
            if getattr(device.format, "label", None):
                devList.append("%s (%s) - %s" % (device.name, device.format.label, relstr))
            else:
                devList.append("%s - %s" % (device.name, relstr))

        (button, choice) = \
            ListboxChoiceWindow(anaconda.intf.screen, _("System to Rescue"),
                                _("Which device holds the root partition "
                                  "of your installation?"), devList,
                                [ _("OK"), _("Exit") ], width = 30,
                                scroll = scroll, height = height,
                                help = "multipleroot")

        if button == _("Exit").lower():
            root = None
        else:
            root = disks[choice]

    rootmounted = 0

    if root:
        try:
            rc = mountExistingSystem(anaconda, root,
                                     allowDirty = 1, warnDirty = 1,
                                     readOnly = readOnly)

            if not flags.imageInstall:
                msg = _("The system will reboot automatically when you exit "
                        "from the shell.")
            else:
                msg = _("Run %s to unmount the system "
                        "when you are finished.") % ANACONDA_CLEANUP

            if rc == -1:
                if anaconda.ksdata:
                    log.error("System had dirty file systems which you chose not to mount")
                else:
                    ButtonChoiceWindow(anaconda.intf.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. %s") % msg,
                        [_("OK")], width = 50)
                rootmounted = 0
            else:
                if anaconda.ksdata:
                    log.info("System has been mounted under: %s" % ROOT_PATH)
                else:
                    ButtonChoiceWindow(anaconda.intf.screen, _("Rescue"),
                       _("Your system has been mounted under %(rootPath)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 %(rootPath)s\n\n%(msg)s") %
                                       {'rootPath': ROOT_PATH,
                                        'msg': msg},
                                       [_("OK")] )
                rootmounted = 1

                # now turn on swap
                if not readOnly:
                    try:
                        anaconda.storage.turnOnSwap()
                    except StorageError:
                        log.error("Error enabling swap")

                # and selinux too
                if flags.selinux:
                    # we have to catch the possible exception
                    # because we support read-only mounting
                    try:
                        fd = open("%s/.autorelabel" % ROOT_PATH, "w+")
                        fd.close()
                    except IOError:
                        log.warning("cannot touch /.autorelabel")

                # set a library path to use mounted fs
                libdirs = os.environ.get("LD_LIBRARY_PATH", "").split(":")
                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)

                # find groff data dir
                gversion = None
                try:
                    glst = os.listdir("/mnt/sysimage/usr/share/groff")
                except OSError:
                    pass
                else:
                    # find a directory which is a numeral, its where
                    # data files are
                    for gdir in glst:
                        if re.match(r'\d[.\d]+\d$', gdir):
                            gversion = gdir
                            break

                if gversion is not None:
                    gpath = "/mnt/sysimage/usr/share/groff/"+gversion
                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
                    os.environ["GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (gpath + '/tmac',)

                # do we have bash?
                try:
                    if os.access("/usr/bin/bash", os.R_OK):
                        os.symlink ("/usr/bin/bash", "/bin/bash")
                except OSError:
                    pass
        except (ValueError, LookupError, SyntaxError, NameError):
            raise
        except Exception as e:
            log.error("doRescue caught exception: %s" % e)
            if anaconda.ksdata:
                log.error("An error occurred trying to mount some or all of your system")
            else:
                if not flags.imageInstall:
                    msg = _("The system will reboot automatically when you "
                            "exit from the shell.")
                else:
                    msg = _("Run %s to unmount the system "
                            "when you are finished.") % ANACONDA_CLEANUP

                ButtonChoiceWindow(anaconda.intf.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.") % ROOT_PATH + msg,
                      [_("OK")] )
    else:
        if anaconda.ksdata and \
               anaconda.ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
            log.info("No Linux partitions found")
            anaconda.intf.screen.finish()
            print(_("You don't have any Linux partitions.  Rebooting.\n"))
            sys.exit(0)
        else:
            if not flags.imageInstall:
                msg = _(" The system will reboot automatically when you exit "
                        "from the shell.")
            else:
                msg = ""
            ButtonChoiceWindow(anaconda.intf.screen, _("Rescue Mode"),
                               _("You don't have any Linux partitions. Press "
                                 "return to get a shell.%s") % msg,
                               [ _("OK") ], width = 50)

    msgStr = ""

    if rootmounted and not readOnly:
        anaconda.storage.makeMtab()
        try:
            makeResolvConf(ROOT_PATH)
        except (OSError, IOError) as e:
            log.error("error making a resolv.conf: %s" %(e,))
        msgStr = _("Your system is mounted under the %s directory.") % (ROOT_PATH,)
        ButtonChoiceWindow(anaconda.intf.screen, _("Rescue"), msgStr, [_("OK")] )

    # we do not need ncurses anymore, shut them down
    anaconda.intf.shutdown()

    #create /etc/fstab in ramdisk, so it is easier to work with RO mounted filesystems
    makeFStab()

    # run %post if we've mounted everything
    if rootmounted and not readOnly and anaconda.ksdata:
        from kickstart import runPostScripts
        runPostScripts(anaconda)

    # start shell if reboot wasn't requested
    if not anaconda.ksdata or \
           not anaconda.ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
        runShell(msg=msgStr)

    sys.exit(0)