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