[PATCH] Restrict payload kernel versions to kernels in the payload (#1074358)

David Lehman dlehman at redhat.com
Wed Jan 21 16:16:24 UTC 2015


On 01/20/2015 01:53 PM, David Shea wrote:
> Remove the generic implementation of kernelVersionList from Payload.
> Instead, have each payload return an iterable of the kernels that were
> actually in the payload. Add a method to the packaging module to handle
> version comparisons in the non-package payload types.
>
> Remove rescueKernelList, since the bootloader was the only thing to use
> this, so the bootloader can look for resuce kernels on its own.

So we'll still make initrds for all kernels on live install?

David

> ---
>   pyanaconda/bootloader.py            |  7 +++++-
>   pyanaconda/packaging/__init__.py    | 44 ++++++++-----------------------------
>   pyanaconda/packaging/dnfpayload.py  |  7 ++++++
>   pyanaconda/packaging/livepayload.py | 36 ++++++++++++++++++++++++++++++
>   pyanaconda/packaging/tarpayload.py  |  8 +++++--
>   pyanaconda/packaging/yumpayload.py  |  8 +++++++
>   6 files changed, 72 insertions(+), 38 deletions(-)
>
> diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
> index ac9ac5c..b017265 100644
> --- a/pyanaconda/bootloader.py
> +++ b/pyanaconda/bootloader.py
> @@ -27,6 +27,7 @@ import re
>   import struct
>   import blivet
>   from parted import PARTITION_BIOS_GRUB
> +from glob import glob
>
>   from pyanaconda import iutil
>   from blivet.devicelibs import raid
> @@ -2387,7 +2388,11 @@ def writeBootLoader(storage, payload, instClass, ksdata):
>           return
>
>       # get a list of installed kernel packages
> -    kernel_versions = payload.kernelVersionList + payload.rescueKernelList
> +    # add whatever rescue kernels we can find to the end
> +    kernel_versions = list(payload.kernelVersionList)
> +    kernel_versions += glob(iutil.getSysroot() + "/boot/vmlinuz-*-rescue-*")
> +    kernel_versions += glob(iutil.getSysroot() + "/boot/efi/EFI/%s/vmlinuz-*-rescue-*" % instClass.efi_dir)
> +
>       if not kernel_versions:
>           log.warning("no kernel was installed -- boot loader config unchanged")
>           return
> diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
> index 64985ac..42fe959 100644
> --- a/pyanaconda/packaging/__init__.py
> +++ b/pyanaconda/packaging/__init__.py
> @@ -72,8 +72,15 @@ from pyanaconda.product import productName, productVersion
>   import urlgrabber
>   urlgrabber.grabber.default_grabber.opts.user_agent = "%s (anaconda)/%s" %(productName, productVersion)
>
> +from distutils.version import LooseVersion
> +
>   REPO_NOT_SET = False
>
> +def versionCmp(v1, v2):
> +    """ Compare two version number strings. """
> +
> +    return LooseVersion(v1).__cmp__(LooseVersion(v2))
> +
>   ###
>   ### ERROR HANDLING
>   ###
> @@ -128,8 +135,6 @@ class Payload(object):
>           self.data = data
>           self.storage = None
>           self.instclass = None
> -        self._kernelVersionList = []
> -        self._rescueVersionList = []
>           self.txID = None
>
>       def setup(self, storage, instClass):
> @@ -302,29 +307,6 @@ class Payload(object):
>           self.data.packages.excludedGroupList.append(grp)
>
>       ###
> -    ### METHODS FOR WORKING WITH PACKAGES
> -    ###
> -    def _updateKernelVersionList(self):
> -        try:
> -            import yum
> -        except ImportError:
> -            cmpfunc = cmp
> -        else:
> -            cmpfunc = yum.rpmUtils.miscutils.compareVerOnly
> -
> -        files = glob(iutil.getSysroot() + "/boot/vmlinuz-*")
> -        files.extend(glob(iutil.getSysroot() + "/boot/efi/EFI/%s/vmlinuz-*" % self.instclass.efi_dir))
> -
> -        versions = sorted((f.split("/")[-1][8:] for f in files if os.path.isfile(f)), cmp=cmpfunc)
> -        log.debug("kernel versions: %s", versions)
> -
> -        # Store regular and rescue kernels separately
> -        self._kernelVersionList = (
> -                [v for v in versions if "-rescue-" not in v],
> -                [v for v in versions if "-rescue-" in v]
> -                )
> -
> -    ###
>       ### METHODS FOR QUERYING STATE
>       ###
>       @property
> @@ -334,16 +316,8 @@ class Payload(object):
>
>       @property
>       def kernelVersionList(self):
> -        if not self._kernelVersionList:
> -            self._updateKernelVersionList()
> -
> -        return self._kernelVersionList[0]
> -
> -    @property
> -    def rescueKernelList(self):
> -        # do re-scan if looking for rescue kernel
> -        self._updateKernelVersionList()
> -        return self._kernelVersionList[1]
> +        """ An iterator of the kernel versions installed by the payload. """
> +        raise NotImplementedError()
>
>       ##
>       ## METHODS FOR TREE VERIFICATION
> diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py
> index d0eb90e..d3c481b 100644
> --- a/pyanaconda/packaging/dnfpayload.py
> +++ b/pyanaconda/packaging/dnfpayload.py
> @@ -818,3 +818,10 @@ class DNFPayload(packaging.PackagePayload):
>                   log.error(e)
>
>           super(DNFPayload, self).postInstall()
> +
> +    @property
> +    def kernelVersionList(self):
> +        return ('%s-%s.%s' % (p.version, p.release, p.arch) for p in
> +                sorted(self._base.sack.query().filter(name='kernel'),
> +                       cmp=dnf.rpm.miscutils.compareEVR,
> +                       key=lambda p: (p.epoch, p.version, p.release)))
> diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py
> index 17c1bac..1dac9c7 100644
> --- a/pyanaconda/packaging/livepayload.py
> +++ b/pyanaconda/packaging/livepayload.py
> @@ -56,6 +56,7 @@ from blivet.size import Size
>   import blivet.util
>   from pyanaconda.threads import threadMgr, AnacondaThread
>   from pyanaconda.i18n import _
> +from pyanaconda.packaging import versionCmp
>
>   class LiveImagePayload(ImagePayload):
>       """ A LivePayload copies the source image onto the target system. """
> @@ -67,6 +68,8 @@ class LiveImagePayload(ImagePayload):
>           self.pct_lock = None
>           self.source_size = 1
>
> +        self._kernelVersionList = []
> +
>       def setup(self, storage, instClass):
>           super(LiveImagePayload, self).setup(storage, instClass)
>
> @@ -80,6 +83,9 @@ class LiveImagePayload(ImagePayload):
>           if rc != 0:
>               raise PayloadInstallError("Failed to mount the install tree")
>
> +        # Grab the kernel version list now so it's available after umount
> +        self._updateKernelVersionList()
> +
>           source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
>           self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
>
> @@ -180,6 +186,17 @@ class LiveImagePayload(ImagePayload):
>       def spaceRequired(self):
>           return Size(iutil.getDirSize("/")*1024)
>
> +    def _updateKernelVersionList(self):
> +        files = glob.glob(INSTALL_TREE + "/boot/vmlinuz-*")
> +        files.extend(glob.glob(INSTALL_TREE + "/boot/efi/EFI/%s/vmlinuz-*" % self.instclass.efi_dir))
> +
> +        self._kernelVersionList = sorted([f.split("/")[-1][8:] for f in files
> +           if os.path.isfile(f) and "-rescue-" not in f], cmp=versionCmp)
> +
> +    @property
> +    def kernelVersionList(self):
> +        return self._kernelVersionList
> +
>   class URLGrabberProgress(object):
>       """ Provide methods for urlgrabber progress."""
>       def start(self, filename, url, basename, size, text):
> @@ -388,6 +405,7 @@ class LiveImageKSPayload(LiveImagePayload):
>
>           # Nothing more to mount
>           if not os.path.exists(INSTALL_TREE+"/LiveOS"):
> +            self._updateKernelVersionList()
>               return
>
>           # Mount the first .img in the directory on INSTALL_TREE
> @@ -415,6 +433,8 @@ class LiveImageKSPayload(LiveImagePayload):
>                   if errorHandler.cb(exn) == ERROR_RAISE:
>                       raise exn
>
> +            self._updateKernelVersionList()
> +
>               source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
>               self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
>
> @@ -493,3 +513,19 @@ class LiveImageKSPayload(LiveImagePayload):
>               return Size(self._min_size)
>           else:
>               return Size(1024*1024*1024)
> +
> +    @property
> +    def kernelVersionList(self):
> +        # If it doesn't look like a tarfile use the super's kernelVersionList
> +        if not self.is_tarfile:
> +            return super(LiveImageKSPayload, self).kernelVersionList
> +
> +        import tarfile
> +        with tarfile.open(self.image_path) as archive:
> +            names = archive.getnames()
> +
> +            # Strip out vmlinuz- from the names
> +            kernels = [n.split("/")[-1][8:] for n in names if "boot/vmlinuz-" in n]
> +            kernels.sort(cmp=versionCmp)
> +
> +            return kernels
> diff --git a/pyanaconda/packaging/tarpayload.py b/pyanaconda/packaging/tarpayload.py
> index b6328e0..3082530 100644
> --- a/pyanaconda/packaging/tarpayload.py
> +++ b/pyanaconda/packaging/tarpayload.py
> @@ -36,7 +36,7 @@ except ImportError:
>       log.error("import of tarfile failed")
>       tarfile = None
>
> -from pyanaconda.packaging import ArchivePayload, PayloadError
> +from pyanaconda.packaging import ArchivePayload, PayloadError, versionCmp
>   from pyanaconda import iutil
>
>   # TarPayload is not yet fully implemented
> @@ -73,7 +73,11 @@ class TarPayload(ArchivePayload):
>       @property
>       def kernelVersionList(self):
>           names = self.archive.getnames()
> -        kernels = [n for n in names if "boot/vmlinuz-" in n]
> +
> +        # Strip out vmlinuz- from the names
> +        kernels = [n.split("/")[-1][8:] for n in names if "boot/vmlinuz-" in n]
> +        kernels.sort(cmp=versionCmp)
> +
>           return kernels
>
>       def install(self):
> diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py
> index 742edad..73caa49 100644
> --- a/pyanaconda/packaging/yumpayload.py
> +++ b/pyanaconda/packaging/yumpayload.py
> @@ -988,6 +988,14 @@ reposdir=%s
>               else:
>                   return environment.groups
>
> +    @property
> +    def kernelVersionList(self):
> +        with _yum_lock:
> +            return ("%s-%s.%s" % (p.version, p.release, p.arch) for p in
> +                    sorted(self._yum.pkgSack.searchNames(['kernel']),
> +                           cmp=yum.rpmUtils.miscutils.compareEVR,
> +                           key=lambda p: (p.epoch, p.version, p.release)))
> +
>       ###
>       ### METHODS FOR WORKING WITH GROUPS
>       ###
>



More information about the anaconda-patches mailing list