diff options
author | Mikko Ylinen <mikko.ylinen@linux.intel.com> | 2017-09-27 11:08:14 +0300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-10-07 23:20:39 +0100 |
commit | 3833ec59bf7b43c20e8e06013c66b0c7697d28e4 (patch) | |
tree | 1ba77f58d1595b8bc160a540d8d49c3824f241fe /meta/lib | |
parent | 07a31d99258e367ad331ef965c5c1dbd1e3172c7 (diff) | |
download | poky-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>
Diffstat (limited to 'meta/lib')
-rw-r--r-- | meta/lib/oe/rootfs.py | 17 |
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() |