summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikko Ylinen <mikko.ylinen@linux.intel.com>2017-09-27 11:08:14 +0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-10-07 23:20:39 +0100
commit3833ec59bf7b43c20e8e06013c66b0c7697d28e4 (patch)
tree1ba77f58d1595b8bc160a540d8d49c3824f241fe
parent07a31d99258e367ad331ef965c5c1dbd1e3172c7 (diff)
downloadpoky-3833ec59bf7b43c20e8e06013c66b0c7697d28e4.tar.gz
rootfs.py: remove update-alternatives correctly
With "read-only-rootfs" in IMAGE_FEATURES, packages in ROOTFS_RO_UNNEEDED are removed when building the rootfs. The list of packages to remove is passed to the package manager and the list is sorted so that update-alternatives provider is the last entry. This is with the assumption that the last entry on the list/command line is removed last. However, it turns out rpm does not care about "last on the command line" and update-alternatives provider is removed before other the packages get to run their %preun scripts for update-alternatives. This leaves broken alternative symlinks in rootfs. The fix is to first remove all but update-alternatives provider and after that update-alternatives provider in its own remove() call. (From OE-Core rev: 0a8639593c11ef0cfb3a3a514b17e36318b8e8f2) Signed-off-by: Mikko Ylinen <mikko.ylinen@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/rootfs.py17
1 files changed, 12 insertions, 5 deletions
diff --git a/meta/lib/oe/rootfs.py b/meta/lib/oe/rootfs.py
index 71bd1a78dc..754ef563ab 100644
--- a/meta/lib/oe/rootfs.py
+++ b/meta/lib/oe/rootfs.py
@@ -261,15 +261,22 @@ class Rootfs(object, metaclass=ABCMeta):
261 # Remove components that we don't need if it's a read-only rootfs 261 # Remove components that we don't need if it's a read-only rootfs
262 unneeded_pkgs = self.d.getVar("ROOTFS_RO_UNNEEDED").split() 262 unneeded_pkgs = self.d.getVar("ROOTFS_RO_UNNEEDED").split()
263 pkgs_installed = image_list_installed_packages(self.d) 263 pkgs_installed = image_list_installed_packages(self.d)
264 # Make sure update-alternatives is last on the command line, so 264 # Make sure update-alternatives is removed last. This is
265 # that it is removed last. This makes sure that its database is 265 # because its database has to available while uninstalling
266 # available while uninstalling packages, allowing alternative 266 # other packages, allowing alternative symlinks of packages
267 # symlinks of packages to be uninstalled to be managed correctly. 267 # to be uninstalled or to be managed correctly otherwise.
268 provider = self.d.getVar("VIRTUAL-RUNTIME_update-alternatives") 268 provider = self.d.getVar("VIRTUAL-RUNTIME_update-alternatives")
269 pkgs_to_remove = sorted([pkg for pkg in pkgs_installed if pkg in unneeded_pkgs], key=lambda x: x == provider) 269 pkgs_to_remove = sorted([pkg for pkg in pkgs_installed if pkg in unneeded_pkgs], key=lambda x: x == provider)
270 270
271 # update-alternatives provider is removed in its own remove()
272 # call because all package managers do not guarantee the packages
273 # are removed in the order they given in the list (which is
274 # passed to the command line). The sorting done earlier is
275 # utilized to implement the 2-stage removal.
276 if len(pkgs_to_remove) > 1:
277 self.pm.remove(pkgs_to_remove[:-1], False)
271 if len(pkgs_to_remove) > 0: 278 if len(pkgs_to_remove) > 0:
272 self.pm.remove(pkgs_to_remove, False) 279 self.pm.remove([pkgs_to_remove[-1]], False)
273 280
274 if delayed_postinsts: 281 if delayed_postinsts:
275 self._save_postinsts() 282 self._save_postinsts()