[master 1/2] Turn sshd setup, kicstart execution and the rescue mode into dispatch steps.

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

 



Involves:
- making the RescueInterface compatible with the gui and tui
  interfaces (so they all can be instantiated in the same way)
- the rescue step is disabled by default and never returns. It is
  enabled if kickstart/command line requires it.
- kickstart step is disabled by default, enabled only if a
  kickstart file was provided.
- all the sshd methods (setting user accounts, generating keys)
  were moved to a separete file, 'sshd.py'
- the order of actions during anaconda startup had to be changed
  (setupDisplay() was called before we parsed kickstart which tells us
  whether or not to use vnc)

Related: https://fedoraproject.org/wiki/Anaconda/Features/Rework_dispatch
---
 anaconda                           |  159 ++++++------------------------------
 pyanaconda/__init__.py             |    4 +
 pyanaconda/dispatch.py             |    7 ++-
 pyanaconda/installclass.py         |    1 +
 pyanaconda/installinterfacebase.py |    3 +
 pyanaconda/iutil.py                |   15 ++++
 pyanaconda/kickstart.py            |   62 +++++++-------
 pyanaconda/rescue.py               |   53 ++++++------
 pyanaconda/sshd.py                 |   89 ++++++++++++++++++++
 9 files changed, 203 insertions(+), 190 deletions(-)
 create mode 100644 pyanaconda/sshd.py

diff --git a/anaconda b/anaconda
index a0a8fad..212ce6b 100755
--- a/anaconda
+++ b/anaconda
@@ -381,101 +381,10 @@ def setupGraphicalLinks():
         except:
             pass
 
-def handleSshPw(anaconda):
-    if not anaconda.ksdata:
-        return
-
-    from pyanaconda import users
-    u = users.Users(anaconda)
-
-    userdata = anaconda.ksdata.sshpw.dataList()
-    for ud in userdata:
-        if u.checkUserExists(ud.username, root="/"):
-            u.setUserPassword(username=ud.username, password=ud.password,
-                              isCrypted=ud.isCrypted, lock=ud.lock)
-        else:
-            kwargs = ud.__dict__
-            kwargs.update({"root": "/", "mkmailspool": False})
-            u.createUser(ud.username, **kwargs)
-
-    del u
-
-def createSshKey(algorithm, keyfile):
-    path = '/etc/ssh/%s' % (keyfile,)
-    argv = ['-q','-t',algorithm,'-f',path,'-C','','-N','']
-    if os.access(path, os.R_OK):
-        return
-    log.info("running \"%s\"" % (" ".join(['ssh-keygen']+argv),))
-
-    so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,)
-    se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,)
-    iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se)
-
-def fork_orphan():
-    """Forks an orphan.
-    
-    Returns 1 in the parent and 0 in the orphaned child.
-    """
-    intermediate = os.fork()
-    if not intermediate:
-        if os.fork():
-            # the intermediate child dies
-            os._exit(0)
-        return 0;
-    # the original process waits for the intermediate child
-    os.waitpid(intermediate, 0)
-    return 1
-
-def startSsh():
-    if iutil.isS390():
-        return
-
-    if not fork_orphan():
-        os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644)
-        ssh_keys = {
-            'rsa1':'ssh_host_key',
-            'rsa':'ssh_host_rsa_key',
-            'dsa':'ssh_host_dsa_key',
-            }
-        for (algorithm, keyfile) in ssh_keys.items():
-            createSshKey(algorithm, keyfile)
-        sshd = iutil.find_program_in_path("sshd")
-        args = [sshd, "-f", "/etc/ssh/sshd_config.anaconda"]
-        os.execv(sshd, args)
-        sys.exit(1)
-
 def startDebugger(signum, frame):
     import epdb
     epdb.serve(skip=1)
 
-def runRescueMode(anaconda, opts):
-    anaconda.rescue = True
-
-    from pyanaconda import rescue
-
-    if anaconda.ksdata:
-        anaconda.instClass.configure(anaconda)
-
-        # We need an interface before running kickstart execute methods for
-        # storage.
-        from snack import SnackScreen
-        screen = SnackScreen()
-        anaconda.intf = rescue.RescueInterface(screen)
-
-        anaconda.ksdata.execute()
-
-        anaconda.intf = None
-        screen.finish()
-
-        # command line 'nomount' overrides kickstart /same for vnc/
-        anaconda.rescue_mount = not (opts.rescue_nomount or
-                                     anaconda.ksdata.rescue.nomount)
-
-    rescue.runRescue(anaconda)
-
-    # shouldn't get back here
-    sys.exit(1)
-
 def setupDisplay(anaconda, opts):
     graphical_failed = 0
     vncS = vnc.VncServer()          # The vnc Server object.
@@ -506,7 +415,9 @@ def setupDisplay(anaconda, opts):
         anaconda.xdriver = opts.xdriver
         anaconda.writeXdriver(root="/")
 
-    if not opts.rescue:
+    if anaconda.rescue:
+        anaconda.displayMode = 'r'
+    else:
         if anaconda.ksdata:
             if anaconda.ksdata.vnc.enabled:
                 flags.usevnc = 1
@@ -629,9 +540,9 @@ def setupDisplay(anaconda, opts):
             runVNC(vncS)
             doStartupX11Actions()
 
-        # with X running we can initialize the UI interface
-        anaconda.initInterface()
-        anaconda.instClass.configure(anaconda)
+    # with X running we can initialize the UI interface
+    anaconda.initInterface()
+    anaconda.instClass.configure(anaconda)
 
 def runDogtail(opts):
     import urlgrabber
@@ -707,7 +618,6 @@ if __name__ == "__main__":
 
     from pyanaconda import iutil
     from pyanaconda import vnc
-    from pyanaconda import users
     from pyanaconda import kickstart
 
     import gettext
@@ -805,7 +715,7 @@ if __name__ == "__main__":
     if opts.targetArch:
         flags.targetarch = opts.targetArch
 
-    # set flags 
+    # set flags
     flags.dmraid = opts.dmraid
     flags.mpath = opts.mpath
     flags.selinux = opts.selinux
@@ -825,12 +735,31 @@ if __name__ == "__main__":
     if opts.debug:
         flags.debug = True
 
+    if opts.rescue:
+        anaconda.rescue = True
+
     log.info("anaconda called with cmdline = %s" %(sys.argv,))
     log.info("Default encoding = %s " % sys.getdefaultencoding())
-    setupDisplay(anaconda, opts)
 
     os.system("udevadm control --env=ANACONDA=1")
 
+    # parse (not execute) kickstart now, the ks commands can affect things like
+    # UI interface type or enabling rescue mode
+    if opts.ksfile:
+        kickstart.preScriptPass(anaconda, opts.ksfile)
+        anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile)
+        if anaconda.ksdata.rescue.rescue:
+            anaconda.rescue = True
+    # now start the interface
+    setupDisplay(anaconda, opts)
+    # setting the install steps requires interface to be running
+    if opts.ksfile:
+        kickstart.setSteps(anaconda)
+    else:
+        anaconda.instClass.setSteps(anaconda)
+    if anaconda.rescue:
+        anaconda.dispatch.skipStep("rescue", skip=0)
+
     image_count = 0
     for image in opts.images:
         image_spec = image.rsplit(":", 1)
@@ -851,26 +780,6 @@ if __name__ == "__main__":
     if image_count:
         anaconda.storage.setupDiskImages()
 
-    # This is the one place we do all kickstart file parsing.
-    if opts.ksfile:
-        kickstart.preScriptPass(anaconda, opts.ksfile)
-        anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile)
-        opts.rescue = opts.rescue or anaconda.ksdata.rescue.rescue
-
-    if flags.sshd:
-        # we need to have a libuser.conf that points to the installer root for
-        # sshpw, but after that we start sshd, we need one that points to the
-        # install target.
-        luserConf = users.createLuserConf(instPath="")
-        handleSshPw(anaconda)
-        startSsh()
-        del(os.environ["LIBUSER_CONF"])
-
-    users.createLuserConf(anaconda.rootPath)
-
-    if opts.rescue:
-        runRescueMode(anaconda, opts)
-
     # comment out the next line to make exceptions non-fatal
     from pyanaconda.exception import initExceptionHandling
     anaconda.mehConfig = initExceptionHandling(anaconda)
@@ -896,24 +805,10 @@ if __name__ == "__main__":
         anaconda.keyboard.set(opts.keymap)
         anaconda.keyboard.activate()
 
-    if anaconda.ksdata:
-        from pyanaconda import storage
-        storage.storageInitialize(anaconda)
-
-        # Now having initialized storage, we can apply all the other kickstart
-        # commands.  This gives us the ability to check that storage commands
-        # are correctly formed and refer to actual devices.
-        anaconda.ksdata.execute()
-
     # set up the headless case
     if anaconda.isHeadless:
         anaconda.dispatch.skipStep("keyboard", permanent = 1)
 
-    if not anaconda.ksdata:
-        anaconda.instClass.setSteps(anaconda)
-    else:
-        kickstart.setSteps(anaconda)
-
     try:
         anaconda.dispatch.run()
     except SystemExit, code:
diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py
index 4a0edba..ccbf07b 100644
--- a/pyanaconda/__init__.py
+++ b/pyanaconda/__init__.py
@@ -245,6 +245,10 @@ class Anaconda(object):
             if not os.environ.has_key("LANG"):
                 os.environ["LANG"] = "en_US.UTF-8"
 
+        if self.displayMode == 'r':
+            import rescue
+            InstallInterface = rescue.RescueInterface
+
         if self.displayMode == 'c':
             from cmdline import InstallInterface
 
diff --git a/pyanaconda/dispatch.py b/pyanaconda/dispatch.py
index c67e96a..6c778bf 100644
--- a/pyanaconda/dispatch.py
+++ b/pyanaconda/dispatch.py
@@ -40,7 +40,9 @@ from upgrade import restoreTime
 from upgrade import upgradeSwapSuggestion, upgradeMigrateFind
 from upgrade import findRootParts, queryUpgradeContinue
 from installmethod import doMethodComplete
-from kickstart import runPostScripts
+from kickstart import doKickstart, runPostScripts
+from sshd import doSshd
+from rescue import doRescue
 
 from backend import doPostSelection, doBackendSetup, doBasePackageSelect
 from backend import doPreInstall, doPostInstall, doInstall
@@ -66,6 +68,9 @@ log = logging.getLogger("anaconda")
 # All install steps take the anaconda object as their sole argument.  This
 # gets passed in when we call the function.
 installSteps = [
+    ("sshd", doSshd),
+    ("rescue", doRescue),
+    ("kickstart", doKickstart),
     ("language", ),
     ("keyboard", ),
     ("betanag", betaNagScreen, ),
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
index 7b2719f..8092e94 100644
--- a/pyanaconda/installclass.py
+++ b/pyanaconda/installclass.py
@@ -84,6 +84,7 @@ class BaseInstallClass(object):
     def setSteps(self, anaconda):
         dispatch = anaconda.dispatch
 	dispatch.setStepList(
+		 "sshd",
 		 "language",
 		 "keyboard",
                  "filtertype",
diff --git a/pyanaconda/installinterfacebase.py b/pyanaconda/installinterfacebase.py
index 898c863..7a65017 100644
--- a/pyanaconda/installinterfacebase.py
+++ b/pyanaconda/installinterfacebase.py
@@ -33,6 +33,9 @@ class InstallInterfaceBase(object):
         self._initLabelAnswers = {}
         self._inconsistentLVMAnswers = {}
 
+    def setSteps(self, anaconda):
+        pass
+
     def messageWindow(self, title, text, type="ok", default = None,
              custom_buttons=None,  custom_icon=None):
         raise NotImplementedError
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 139d61d..2387576 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -950,3 +950,18 @@ def find_program_in_path(prog, raise_on_error=False):
     if raise_on_error:
         raise RuntimeError("Unable to locate a needed executable: '%s'" % prog)
     return None
+
+def fork_orphan():
+    """Forks an orphan.
+
+    Returns 1 in the parent and 0 in the orphaned child.
+    """
+    intermediate = os.fork()
+    if not intermediate:
+        if os.fork():
+            # the intermediate child dies
+            os._exit(0)
+        return 0;
+    # the original process waits for the intermediate child
+    os.waitpid(intermediate, 0)
+    return 1
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 0dfecd2..cc7e891 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -226,7 +226,7 @@ class AutoPart(commands.autopart.F12_AutoPart):
             self.anaconda.storage.autoPartAddBackupPassphrase = \
                 self.backuppassphrase
 
-        self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+        map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
 
 class AutoStep(commands.autostep.FC3_AutoStep):
     def execute(self):
@@ -249,9 +249,9 @@ class Bootloader(commands.bootloader.F15_Bootloader):
             self.anaconda.bootloader.update_only = True
 
         if location is None:
-            self.anaconda.ksdata.permanentSkipSteps.append("instbootloader")
+            self.anaconda.dispatch.skipStep("instbootloader", permanent=1)
         else:
-            self.anaconda.ksdata.showSteps.append("bootloader")
+            self.anaconda.dispatch.skipStep("bootloader", skip=0)
 
             if self.appendLine:
                 args = self.appendLine.split()
@@ -276,7 +276,8 @@ class Bootloader(commands.bootloader.F15_Bootloader):
 
             self.anaconda.bootloader.drive_order = self.driveorder
 
-        self.anaconda.ksdata.permanentSkipSteps.extend(["upgbootloader", "bootloader"])
+        map(lambda step: self.anaconda.dispatch.skipStep(step, permanent=1),
+            ["upgbootloader", "bootloader"])
 
 class ClearPart(commands.clearpart.FC3_ClearPart):
     def parse(self, args):
@@ -306,7 +307,7 @@ class ClearPart(commands.clearpart.FC3_ClearPart):
             self.anaconda.storage.config.reinitializeDisks = self.initAll
 
         clearPartitions(self.anaconda.storage)
-        self.anaconda.ksdata.skipSteps.append("cleardiskssel")
+        self.anaconda.dispatch.skipStep("cleardiskssel")
 
 class Fcoe(commands.fcoe.F13_Fcoe):
     def parse(self, args):
@@ -359,7 +360,7 @@ class IgnoreDisk(commands.ignoredisk.RHEL6_IgnoreDisk):
 
     def execute(self):
         if not self.interactive:
-            self.anaconda.ksdata.skipSteps.extend(["filter", "filtertype"])
+            map(self.anaconda.dispatch.skipStep, ["filter", "filtertype"])
 
 class Iscsi(commands.iscsi.F10_Iscsi):
     class Login(object):
@@ -408,14 +409,14 @@ class Keyboard(commands.keyboard.FC3_Keyboard):
     def execute(self):
         self.anaconda.keyboard.set(self.keyboard)
         self.anaconda.keyboard.beenset = 1
-        self.anaconda.ksdata.skipSteps.append("keyboard")
+        self.anaconda.dispatch.skipStep("keyboard")
 
 class Lang(commands.lang.FC3_Lang):
     def execute(self):
         self.anaconda.instLanguage.instLang = self.lang
         self.anaconda.instLanguage.systemLang = self.lang
         self.anaconda.instLanguage.buildLocale()
-        self.anaconda.ksdata.skipSteps.append("language")
+        self.anaconda.dispatch.skipStep("language")
 
 class LogVolData(commands.logvol.F15_LogVolData):
     def execute(self):
@@ -457,7 +458,7 @@ class LogVolData(commands.logvol.F15_LogVolData):
 
             dev.format.mountpoint = self.mountpoint
             dev.format.mountopts = self.fsopts
-            self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
             return
 
         # Make sure this LV name is not already used in the requested VG.
@@ -540,7 +541,7 @@ class LogVolData(commands.logvol.F15_LogVolData):
                                      parents=request)
             storage.createDevice(luksdev)
 
-        self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+        map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
 
 class Logging(commands.logging.FC6_Logging):
     def execute(self):
@@ -768,7 +769,7 @@ class PartitionData(commands.partition.F12_PartData):
 
             dev.format.mountpoint = self.mountpoint
             dev.format.mountopts = self.fsopts
-            self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
             return
 
         # Now get a format to hold a lot of these extra values.
@@ -857,11 +858,11 @@ class PartitionData(commands.partition.F12_PartData):
                                      parents=request)
             storage.createDevice(luksdev)
 
-        self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+        map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
 
 class Reboot(commands.reboot.FC6_Reboot):
     def execute(self):
-        self.anaconda.ksdata.skipSteps.append("complete")
+        self.anaconda.dispatch.skipStep("complete")
 
 class RaidData(commands.raid.F15_RaidData):
     def execute(self):
@@ -910,7 +911,7 @@ class RaidData(commands.raid.F15_RaidData):
 
             dev.format.mountpoint = self.mountpoint
             dev.format.mountopts = self.fsopts
-            self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
             return
 
         # Get a list of all the RAID members.
@@ -1003,14 +1004,14 @@ class RaidData(commands.raid.F15_RaidData):
                                      parents=request)
             storage.createDevice(luksdev)
 
-        self.anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+        map(self.anaconda.dispatch.skipStep, ["partition", "zfcpconfig", "parttype"])
 
 class RootPw(commands.rootpw.F8_RootPw):
     def execute(self):
         self.anaconda.users.rootPassword["password"] = self.password
         self.anaconda.users.rootPassword["isCrypted"] = self.isCrypted
         self.anaconda.users.rootPassword["lock"] = self.lock
-        self.anaconda.ksdata.skipSteps.append("accounts")
+        self.anaconda.dispatch.skipStep("accounts")
 
 class SELinux(commands.selinux.FC3_SELinux):
     def execute(self):
@@ -1030,7 +1031,7 @@ class Timezone(commands.timezone.FC6_Timezone):
             log.warning("Timezone %s set in kickstart is not valid." % (self.timezone,))
 
         self.anaconda.timezone.setTimezoneInfo(self.timezone, self.isUtc)
-        self.anaconda.ksdata.skipSteps.append("timezone")
+        self.anaconda.dispatch.skipStep("timezone")
 
 class Upgrade(commands.upgrade.F11_Upgrade):
     def execute(self):
@@ -1151,9 +1152,6 @@ class AnacondaKSHandler(superclass):
         superclass.__init__(self, commandUpdates=commandMap, dataUpdates=dataMap)
         self.packages = AnacondaKSPackages()
 
-        self.permanentSkipSteps = []
-        self.skipSteps = []
-        self.showSteps = []
         self.anaconda = anaconda
         self.onPart = {}
 
@@ -1266,6 +1264,13 @@ class AnacondaKSParser(KickstartParser):
         self.handler.add(retval)
         return retval
 
+def doKickstart(anaconda):
+    storage.storageInitialize(anaconda)
+    # Having initialized storage, we can apply all the other kickstart commands.
+    # This gives us the ability to check that storage commands are correctly
+    # formed and refer to actual devices.
+    anaconda.ksdata.execute()
+
 def preScriptPass(anaconda, file):
     # The first pass through kickstart file processing - look for %pre scripts
     # and run them.  This must come in a separate pass in case a script
@@ -1476,6 +1481,7 @@ def setSteps(anaconda):
     else:
         anaconda.instClass.setSteps(anaconda)
         dispatch.skipStep("findrootparts")
+    dispatch.skipStep("kickstart", skip = 0)
 
     dispatch.skipStep("betanag")
     dispatch.skipStep("network")
@@ -1496,25 +1502,19 @@ def setSteps(anaconda):
 
     # If the package section included anything, skip group selection.
     if ksdata.upgrade.upgrade:
-        ksdata.skipSteps.extend(["tasksel", "group-selection"])
+        map(anaconda.dispatch.skipStep, ["tasksel", "group-selection"])
 
         # Special check for this, since it doesn't make any sense.
         if ksdata.packages.seen:
             warnings.warn("Ignoring contents of %packages section due to upgrade.")
     elif havePackages(ksdata.packages):
-        ksdata.skipSteps.extend(["tasksel", "group-selection"])
+        map(anaconda.dispatch.skipStep, ["tasksel", "group-selection"])
     else:
         if ksdata.packages.seen:
-            ksdata.skipSteps.extend(["tasksel", "group-selection"])
+            map(anaconda.dispatch.skipStep, ["tasksel", "group-selection"])
         else:
-            ksdata.showSteps.extend(["tasksel", "group-selection"])
-
-    for n in ksdata.skipSteps:
-        dispatch.skipStep(n)
-    for n in ksdata.permanentSkipSteps:
-        dispatch.skipStep(n, permanent=1)
-    for n in ksdata.showSteps:
-        dispatch.skipStep(n, skip = 0)
+            map(lambda step: anaconda.dispatch.skipStep(step, skip=0),
+                ["tasksel", "group-selection"])
 
     # Text mode doesn't have all the steps that graphical mode does, so we
     # can't stop and prompt for missing information.  Make sure we've got
diff --git a/pyanaconda/rescue.py b/pyanaconda/rescue.py
index 245a597..69786b5 100644
--- a/pyanaconda/rescue.py
+++ b/pyanaconda/rescue.py
@@ -126,7 +126,7 @@ class RescueInterface(InstallInterfaceBase):
         return 1
 
     def shutdown (self):
-        pass
+        self.screen.finish()
 
     def suspend(self):
         pass
@@ -134,9 +134,13 @@ class RescueInterface(InstallInterfaceBase):
     def resume(self):
         pass
 
-    def __init__(self, screen):
+    def run(self, anaconda):
+        self.anaconda = anaconda
+        self.anaconda.dispatch.dispatch()
+
+    def __init__(self):
         InstallInterfaceBase.__init__(self)
-        self.screen = screen
+        self.screen = SnackScreen()
 
 def makeFStab(instPath = ""):
     if os.access("/proc/mounts", os.R_OK):
@@ -231,7 +235,7 @@ def runShell(screen = None, msg=""):
     if screen:
         screen.finish()
 
-def runRescue(anaconda):
+def doRescue(anaconda):
     for file in [ "services", "protocols", "group", "joe", "man.config",
                   "nsswitch.conf", "selinux", "mke2fs.conf" ]:
         try:
@@ -241,16 +245,13 @@ def runRescue(anaconda):
 
     # see if they would like networking enabled
     if not network.hasActiveNetDev():
-        screen = SnackScreen()
 
         while True:
-            rc = ButtonChoiceWindow(screen, _("Setup Networking"),
+            rc = ButtonChoiceWindow(anaconda.intf.screen, _("Setup Networking"),
                 _("Do you want to start the network interfaces on "
                   "this system?"), [_("Yes"), _("No")])
 
             if rc != _("No").lower():
-                anaconda.intf = RescueInterface(screen)
-
                 if not anaconda.intf.enableNetwork(anaconda):
                     anaconda.intf.messageWindow(_("No Network Available"),
                         _("Unable to activate a networking device.  Networking "
@@ -262,8 +263,9 @@ def runRescue(anaconda):
             else:
                 break
 
-        anaconda.intf = None
-        screen.finish()
+    # shutdown the interface now
+    anaconda.intf.shutdown()
+    anaconda.intf = None
 
     # Early shell access with no disk access attempts
     if not anaconda.rescue_mount:
@@ -277,8 +279,7 @@ def runRescue(anaconda):
 
         sys.exit(0)
 
-    screen = SnackScreen()
-    anaconda.intf = RescueInterface(screen)
+    anaconda.intf = RescueInterface()
 
     if anaconda.ksdata:
         if anaconda.ksdata.rescue and anaconda.ksdata.rescue.romount:
@@ -289,7 +290,7 @@ def runRescue(anaconda):
         # 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"),
+            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 "
@@ -304,11 +305,11 @@ def runRescue(anaconda):
                   [_("Continue"), _("Read-Only"), _("Skip"), _("Advanced")] )
 
             if rc == _("Skip").lower():
-                runShell(screen)
+                runShell(anaconda.intf.screen)
                 sys.exit(0)
             elif rc == _("Advanced").lower():
                 addDialog = addDriveDialog(anaconda)
-                addDialog.addDriveDialog(screen)
+                addDialog.addDriveDialog(anaconda.intf.screen)
                 continue
             elif rc == _("Read-Only").lower():
                 readOnly = 1
@@ -340,7 +341,7 @@ def runRescue(anaconda):
                 devList.append("%s - %s" % (device.name, relstr))
 
         (button, choice) = \
-            ListboxChoiceWindow(screen, _("System to Rescue"),
+            ListboxChoiceWindow(anaconda.intf.screen, _("System to Rescue"),
                                 _("Which device holds the root partition "
                                   "of your installation?"), devList,
                                 [ _("OK"), _("Exit") ], width = 30,
@@ -371,7 +372,7 @@ def runRescue(anaconda):
                 if anaconda.ksdata:
                     log.error("System had dirty file systems which you chose not to mount")
                 else:
-                    ButtonChoiceWindow(screen, _("Rescue"),
+                    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,
@@ -381,7 +382,7 @@ def runRescue(anaconda):
                 if anaconda.ksdata:
                     log.info("System has been mounted under: %s" % anaconda.rootPath)
                 else:
-                    ButtonChoiceWindow(screen, _("Rescue"),
+                    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"
@@ -441,7 +442,7 @@ def runRescue(anaconda):
         except (ValueError, LookupError, SyntaxError, NameError):
             raise
         except Exception as e:
-            log.error("runRescue caught exception: %s" % 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:
@@ -452,7 +453,7 @@ def runRescue(anaconda):
                     msg = _("Run %s to unmount the system "
                             "when you are finished.") % ANACONDA_CLEANUP
 
-                ButtonChoiceWindow(screen, _("Rescue"),
+                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.") % anaconda.rootPath + msg,
@@ -461,7 +462,7 @@ def runRescue(anaconda):
         if anaconda.ksdata and \
                anaconda.ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
             log.info("No Linux partitions found")
-            screen.finish()
+            anaconda.intf.screen.finish()
             print(_("You don't have any Linux partitions.  Rebooting.\n"))
             sys.exit(0)
         else:
@@ -470,7 +471,7 @@ def runRescue(anaconda):
                         "from the shell.")
             else:
                 msg = ""
-            ButtonChoiceWindow(screen, _("Rescue Mode"),
+            ButtonChoiceWindow(anaconda.intf.screen, _("Rescue Mode"),
                                _("You don't have any Linux partitions. Press "
                                  "return to get a shell.%s") % msg,
                                [ _("OK") ], width = 50)
@@ -484,11 +485,11 @@ def runRescue(anaconda):
         except (OSError, IOError) as 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")] )
+        ButtonChoiceWindow(anaconda.intf.screen, _("Rescue"), msgStr, [_("OK")] )
 
     # we do not need ncurses anymore, shut them down
-    screen.finish()
-    
+    anaconda.intf.shutdown()
+
     #create /etc/fstab in ramdisk, so it is easier to work with RO mounted filesystems
     makeFStab()
 
@@ -500,6 +501,6 @@ def runRescue(anaconda):
     # start shell if reboot wasn't requested
     if not anaconda.ksdata or \
            not anaconda.ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
-        runShell(screen, msgStr)
+        runShell(msg=msgStr)
 
     sys.exit(0)
diff --git a/pyanaconda/sshd.py b/pyanaconda/sshd.py
new file mode 100644
index 0000000..8f1110c
--- /dev/null
+++ b/pyanaconda/sshd.py
@@ -0,0 +1,89 @@
+# sshd.py
+# Configuring the sshd daemon from Anaconda.
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties 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, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+
+
+import logging
+import os
+log = logging.getLogger("anaconda")
+
+import iutil
+import users
+from flags import flags
+
+def createSshKey(algorithm, keyfile):
+    path = '/etc/ssh/%s' % (keyfile,)
+    argv = ['-q','-t',algorithm,'-f',path,'-C','','-N','']
+    if os.access(path, os.R_OK):
+        return
+    log.debug("running \"%s\"" % (" ".join(['ssh-keygen']+argv),))
+
+    so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,)
+    se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,)
+    iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se)
+
+def doSshd(anaconda):
+    if flags.sshd:
+        # we need to have a libuser.conf that points to the installer root for
+        # sshpw, but after that we start sshd, we need one that points to the
+        # install target.
+        luserConf = users.createLuserConf(instPath="")
+        handleSshPw(anaconda)
+        startSsh()
+        del(os.environ["LIBUSER_CONF"])
+    else:
+        log.info("sshd: not enabled, skipping.")
+
+    users.createLuserConf(anaconda.rootPath)
+
+def handleSshPw(anaconda):
+    if not anaconda.ksdata:
+        return
+
+    u = users.Users(anaconda)
+
+    userdata = anaconda.ksdata.sshpw.dataList()
+    for ud in userdata:
+        if u.checkUserExists(ud.username, root="/"):
+            u.setUserPassword(username=ud.username, password=ud.password,
+                              isCrypted=ud.isCrypted, lock=ud.lock)
+        else:
+            kwargs = ud.__dict__
+            kwargs.update({"root": "/", "mkmailspool": False})
+            u.createUser(ud.username, **kwargs)
+
+    del u
+
+def startSsh():
+    if iutil.isS390():
+        return
+
+    if not iutil.fork_orphan():
+        os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644)
+        ssh_keys = {
+            'rsa1':'ssh_host_key',
+            'rsa':'ssh_host_rsa_key',
+            'dsa':'ssh_host_dsa_key',
+            }
+        for (algorithm, keyfile) in ssh_keys.items():
+            createSshKey(algorithm, keyfile)
+        sshd = iutil.find_program_in_path("sshd")
+        args = [sshd, "-f", "/etc/ssh/sshd_config.anaconda"]
+        os.execv(sshd, args)
+        sys.exit(1)
-- 
1.7.3.3

_______________________________________________
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