[PATCH 06/10] Enable bootloader install.

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

 



Includes implementation of Payload.kernelVersionList property and
Payload.dracutSetupArgs method, along with reworked writeBootLoader.

I have renamed writeBootloader to writeBootLoader as well.
---
 pyanaconda/bootloader.py         |  127 ++++++++++++++++++-------------------
 pyanaconda/dispatch.py           |    4 +-
 pyanaconda/install.py            |   15 ++++-
 pyanaconda/packaging/__init__.py |   38 +++++++++++-
 4 files changed, 114 insertions(+), 70 deletions(-)

diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index baac116..1a9c90a 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1888,112 +1888,109 @@ class SILO(YabootSILOBase):
 
 # anaconda-specific functions
 
-def writeSysconfigKernel(anaconda, default_kernel):
+def writeSysconfigKernel(storage, version):
+    # get the name of the default kernel package based on the version
+    kernel_basename = "vmlinuz-" + version
+    kernel_file = "/boot/%s" % kernel_basename
+    if not os.path.isfile(ROOT_PATH + kernel_file):
+        kernel_file = "/boot/efi/EFI/redhat/%s" % kernel_basename
+        if not os.path.isfile(ROOT_PATH + kernel_file):
+            log.error("failed to recreate path to default kernel image")
+            return
+
+    try:
+        import rpm
+    except ImportError:
+        log.error("failed to import rpm python module")
+        return
+
+    ts = rpm.TransactionSet(ROOT_PATH)
+    mi = ts.dbMatch('basenames', kernel_file)
+    try:
+        h = mi.next()
+    except StopIteration:
+        log.error("failed to get package name for default kernel")
+        return
+
+    kernel = h.name
+
     f = open(ROOT_PATH + "/etc/sysconfig/kernel", "w+")
     f.write("# UPDATEDEFAULT specifies if new-kernel-pkg should make\n"
             "# new kernels the default\n")
     # only update the default if we're setting the default to linux (#156678)
-    if anaconda.bootloader.default.device == anaconda.storage.rootDevice:
+    if storage.bootloader.default.device == storage.rootDevice:
         f.write("UPDATEDEFAULT=yes\n")
     else:
         f.write("UPDATEDEFAULT=no\n")
     f.write("\n")
     f.write("# DEFAULTKERNEL specifies the default kernel package type\n")
-    f.write("DEFAULTKERNEL=%s\n" % default_kernel)
+    f.write("DEFAULTKERNEL=%s\n" % kernel)
     f.close()
 
-
-def writeBootloader(anaconda):
+def writeBootLoader(storage, payload):
     """ Write bootloader configuration to disk.
 
         When we get here, the bootloader will already have a default linux
         image. We only have to add images for the non-default kernels and
         adjust the default to reflect whatever the default variant is.
     """
+    from pyanaconda.errors import *
 
-    # TODO: Verify the bootloader configuration has all it needs.
-    #
-    #       - zipl doesn't need to have a stage1 device set.
-    #       - Isn't it possible for stage1 to be unset on iSeries if not using
-    #         yaboot? If so, presumably they told us not to install any
-    #         bootloader.
-    stage1_device = anaconda.bootloader.stage1_device
+    stage1_device = storage.bootloader.stage1_device
     log.info("bootloader stage1 target device is %s" % stage1_device.name)
-    stage2_device = anaconda.bootloader.stage2_device
+    stage2_device = storage.bootloader.stage2_device
     log.info("bootloader stage2 target device is %s" % stage2_device.name)
 
-    w = None
-    if anaconda.intf:
-        w = anaconda.intf.waitWindow(_("Bootloader"),
-                                     _("Installing bootloader."))
-
     # get a list of installed kernel packages
-    kernel_versions = anaconda.backend.kernelVersionList()
+    kernel_versions = payload.kernelVersionList
     if not kernel_versions:
         log.warning("no kernel was installed -- bootloader config unchanged")
-        if anaconda.intf:
-            anaconda.intf.messageWindow(_("Warning"),
-                        _("No kernel packages were installed on the system. "
-                          "Bootloader configuration will not be changed."))
         return
 
+    # all the linux images' labels are based on the default image's
+    base_label = productName
+    base_short_label = "linux"
+
     # The first one is the default kernel. Update the bootloader's default
     # entry to reflect the details of the default kernel.
-    (version, arch, nick) = kernel_versions.pop(0)
-    default_image = LinuxBootLoaderImage(device=anaconda.storage.rootDevice,
+    version = kernel_versions.pop(0)
+    default_image = LinuxBootLoaderImage(device=storage.rootDevice,
                                          version=version,
-                                         label=productName,
-                                         short="linux")
-    anaconda.bootloader.add_image(default_image)
-    anaconda.bootloader.default = default_image
+                                         label=base_label,
+                                         short=base_short_label)
+    storage.bootloader.add_image(default_image)
+    storage.bootloader.default = default_image
 
-    # all the linux images' labels are based on the default image's
-    base_label = default_image.label
-    base_short = default_image.short_label
-
-    # get the name of the default kernel package for use in
-    # /etc/sysconfig/kernel
-    default_kernel = "kernel"
-    if nick != "base":
-        default_kernel += "-%s" % nick
+    # write out /etc/sysconfig/kernel
+    writeSysconfigKernel(storage, version)
 
     # now add an image for each of the other kernels
-    used = ["base"]
-    for (version, arch, nick) in kernel_versions:
-        if nick in used:
-            nick += "-%s" % version
-
-        used.append(nick)
-        label = "%s-%s" % (base_label, nick)
-        short = "%s-%s" % (base_short, nick)
-        if anaconda.bootloader.trusted_boot:
+    for version in kernel_versions:
+        label = "%s-%s" % (base_label, version)
+        short = "%s-%s" % (base_short_label, version)
+        if storage.bootloader.trusted_boot:
             image = TbootLinuxBootLoaderImage(
-                                         device=anaconda.storage.rootDevice,
+                                         device=storage.rootDevice,
                                          version=version,
                                          label=label, short=short)
         else:
-            image = LinuxBootLoaderImage(device=anaconda.storage.rootDevice,
+            image = LinuxBootLoaderImage(device=storage.rootDevice,
                                          version=version,
                                          label=label, short=short)
-        anaconda.bootloader.add_image(image)
-
-    # write out /etc/sysconfig/kernel
-    writeSysconfigKernel(anaconda, default_kernel)
+        storage.bootloader.add_image(image)
 
     # set up dracut/fips boot args
-    anaconda.bootloader.set_boot_args(keyboard=anaconda.keyboard,
-                                      storage=anaconda.storage,
-                                      language=anaconda.instLanguage,
-                                      network=anaconda.network)
+    # XXX FIXME: do this from elsewhere?
+    #storage.bootloader.set_boot_args(keyboard=anaconda.keyboard,
+    #                                 storage=anaconda.storage,
+    #                                 language=anaconda.instLanguage,
+    #                                 network=anaconda.network)
+    storage.bootloader.set_boot_args(storage=storage,
+                                     payload=payload)
 
     try:
-        anaconda.bootloader.write()
+        storage.bootloader.write()
     except BootLoaderError as e:
-        if anaconda.intf:
-            anaconda.intf.messageWindow(_("Warning"),
-                            _("There was an error installing the bootloader.  "
-                              "The system may not be bootable."))
-    finally:
-        if w:
-            w.pop()
+        if errorHandler.cb(e) == ERROR_RAISE:
+            raise
 
diff --git a/pyanaconda/dispatch.py b/pyanaconda/dispatch.py
index 07f8fde..2f422fa 100644
--- a/pyanaconda/dispatch.py
+++ b/pyanaconda/dispatch.py
@@ -32,7 +32,7 @@ from packages import setupTimezone
 from storage import storageInitialize
 from storage import storageComplete
 from storage.partitioning import doAutoPartition
-from bootloader import writeBootloader
+from bootloader import writeBootLoader
 from flags import flags
 from upgrade import upgradeMountFilesystems
 from upgrade import restoreTime
@@ -283,7 +283,7 @@ class Dispatcher(object):
         self.add_step("postinstallconfig", doPostInstall)
         self.add_step("writeconfig", writeConfiguration)
         self.add_step("firstboot", firstbootConfiguration)
-        self.add_step("instbootloader", writeBootloader)
+        self.add_step("instbootloader", writeBootLoader)
         self.add_step("reipl", doReIPL)
         self.add_step("writeksconfig", writeKSConfiguration)
         self.add_step("methodcomplete", doMethodComplete)
diff --git a/pyanaconda/install.py b/pyanaconda/install.py
index a19d04b..13aad2e 100644
--- a/pyanaconda/install.py
+++ b/pyanaconda/install.py
@@ -22,6 +22,11 @@
 
 from pyanaconda.errors import errorHandler
 from pyanaconda.storage import turnOnFilesystems
+from pyanaconda.bootloader import writeBootLoader
+from pyanaconda.progress import progress_report
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
 
 def doInstall(storage, payload, ksdata, instClass):
     """Perform an installation.  This method takes the ksdata as prepared by
@@ -41,7 +46,7 @@ def doInstall(storage, payload, ksdata, instClass):
     steps = len(storage.devicetree.findActions(type="create", object="format")) + \
             len(storage.devicetree.findActions(type="resize", object="format")) + \
             len(storage.devicetree.findActions(type="migrate", object="format"))
-    steps += 2  # package install setup, package install
+    steps += 4  # packages setup, packages, bootloader, post install
     progress.send_init(steps)
 
     # Do partitioning.
@@ -50,6 +55,12 @@ def doInstall(storage, payload, ksdata, instClass):
     # Do packaging.
     payload.preInstall(packages=storage.packages)
     payload.install()
-    payload.postInstall()
+
+    with progress_report(_("Performing post-install setup tasks")):
+        payload.postInstall()
+
+    # Do bootloader.
+    with progress_report(_("Installing bootloader")):
+        writeBootLoader(storage, payload)
 
     progress.send_complete()
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index 07704da..61d0100 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -120,6 +120,7 @@ class Payload(object):
     def __init__(self, data):
         self.data = data
         self.proxy = None
+        self._kernelVersionList = []
 
     def setup(self, storage):
         """ Do any payload-specific setup. """
@@ -320,7 +321,24 @@ class Payload(object):
 
     @property
     def kernelVersionList(self):
-        raise NotImplementedError()
+        if not self._kernelVersionList:
+            import glob
+            try:
+                from yum.rpmUtils.miscutils import compareVerOnly
+            except ImportError:
+                cmpfunc = cmp
+            else:
+                cmpfunc = compareVerOnly
+
+            files = glob.glob(ROOT_PATH + "/boot/vmlinuz-*")
+            files.extend(glob.glob(ROOT_PATH + "/boot/efi/EFI/redhat/vmlinuz-*"))
+            # strip off everything up to and including vmlinuz- to get versions
+            versions = [f.split("/")[-1][8:] for f in files if os.path.isfile(f)]
+            versions.sort(cmp=cmpfunc)
+            log.debug("kernel versions: %s" % versions)
+            self._kernelVersionList = versions
+
+        return self._kernelVersionList
 
     ##
     ## METHODS FOR TREE VERIFICATION
@@ -522,6 +540,24 @@ class Payload(object):
             os.unlink(symlink_path)
         os.symlink('/usr/lib/systemd/system/' + default_target, symlink_path)
 
+    def dracutSetupArgs(self):
+        args = []
+        try:
+            import rpm
+        except ImportError:
+            pass
+        else:
+            iutil.resetRpmDb()
+            ts = rpm.TransactionSet(ROOT_PATH)
+
+            # Only add "rhgb quiet" on non-s390, non-serial installs
+            if iutil.isConsoleOnVirtualTerminal() and \
+               (ts.dbMatch('provides', 'rhgb').count() or \
+                ts.dbMatch('provides', 'plymouth').count()):
+                args.extend(["rhgb", "quiet"])
+
+        return args
+
     def postInstall(self):
         """ Perform post-installation tasks. """
 
-- 
1.7.7.6

_______________________________________________
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