From 2d61be2c4c3679b60bbeb25b759294de62d6dda8 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Sat, 22 Sep 2018 19:34:17 +0200 Subject: [PATCH] [kswitch] fix kernel-switcher behavior when kernels are in external repos. See the code documentation for more info. --- lib/kswitch/__init__.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/kswitch/__init__.py b/lib/kswitch/__init__.py index dfe04271e..1700824fe 100644 --- a/lib/kswitch/__init__.py +++ b/lib/kswitch/__init__.py @@ -29,7 +29,6 @@ import entropy.tools KERNEL_BINARY_VIRTUAL = const_convert_to_unicode("virtual/linux-binary") KERNEL_BINARY_LTS_VIRTUAL = const_convert_to_unicode("virtual/linux-binary-lts") -KERNEL_CATEGORY = const_convert_to_unicode("sys-kernel") KERNELS_DIR = const_convert_to_rawstring("/etc/kernels") RELEASE_LEVEL = const_convert_to_rawstring("RELEASE_LEVEL") @@ -154,23 +153,33 @@ class KernelSwitcher(object): def _get_kernels(self): """ - Return a list of kernel package matches. + Return a set of kernel package matches. """ + # We may have virtual/ kernels in multiple repos, make sure + # to pick them all up. kernel_virtual_pkgs, _rc = self._entropy.atom_match( KERNEL_BINARY_VIRTUAL, multi_match=True, multi_repo=True) - kernel_packages = [] - + # virtual/ kernels have a runtime dependency against a kernel + # package provider. So, get the list of runtime deps from them. + kernels = set() for pkg_id, repo_id in kernel_virtual_pkgs: repo = self._entropy.open_repository(repo_id) - kernel_pkg_ids = repo.retrieveReverseDependencies(pkg_id) - for kernel_pkg_id in kernel_pkg_ids: - atom = repo.retrieveAtom(kernel_pkg_id) - category = entropy.dep.dep_getcat(atom) - if category == KERNEL_CATEGORY: - kernel_packages.append((atom, kernel_pkg_id, repo_id)) + kernel_deps = repo.retrieveRuntimeDependencies(pkg_id) + kernels.update(kernel_deps) + # Match the dependencies collected against all repositories, + # or we won't be able to pick up binaries in all of them. + kernel_packages = set() + for kernel in kernels: + kernel_pkgs, _rc = self._entropy.atom_match( + kernel, multi_match=True, multi_repo=True) + kernel_packages.update(kernel_pkgs) + + # There is no safety check for random packages to be pulled in. + # The assumption is that virtual packages are listing just kernel + # binaries in their dependencies. return kernel_packages def _get_target_tag(self, kernel_match): @@ -390,6 +399,6 @@ class KernelSwitcher(object): @rtype: list """ matches = self._get_kernels() - key_sorter = lambda x: x[0] - return [(pkg_id, repo_id) for _atom, pkg_id, repo_id - in sorted(matches, key=key_sorter)] + key_sorter = lambda x: self._entropy.open_repository( + x[1]).retrieveAtom(x[0]) + return sorted(matches, key=key_sorter)