yifengyou / rpms / yum

Forked from rpms/yum 3 years ago
Clone

Blame SOURCES/BZ-1477574-update-honor-multilib-policy-for-obsoletes.patch

5e9bef
commit 25a1cf0a8f0002b16d6ef9c24d530019fd88fd64
5e9bef
Author: Michal Domonkos <mdomonko@redhat.com>
5e9bef
Date:   Wed May 16 17:40:22 2018 +0200
5e9bef
5e9bef
    update(): honor multilib_policy for obsoletes. BZ 1477574
5e9bef
    
5e9bef
    When a package migrates from noarch to arch during an update, we usually
5e9bef
    don't want to install all the newly available multilib arches.
5e9bef
    
5e9bef
    For "yum install", this is already controlled by multilib_policy, even
5e9bef
    if the noarch package is already installed (since yum will try to update
5e9bef
    it).  However, with "yum update", multilib_policy isn't checked.
5e9bef
    
5e9bef
    This commit adds the check to update() so that "yum update" works the
5e9bef
    same as "yum install" in the noarch->arch scenario.
5e9bef
    
5e9bef
    Tests calling "update" without arguments now need to specify
5e9bef
    multilib_policy='all'.
5e9bef
5e9bef
diff --git a/test/simpleobsoletestests.py b/test/simpleobsoletestests.py
5e9bef
index 6cede1e0..a26a5d42 100644
5e9bef
--- a/test/simpleobsoletestests.py
5e9bef
+++ b/test/simpleobsoletestests.py
5e9bef
@@ -38,7 +38,8 @@ class SimpleObsoletesTests(OperationsTests):
5e9bef
 
5e9bef
     def testObsoletenoarchToi386(self):
5e9bef
         p = self.pkgs
5e9bef
-        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_i386])
5e9bef
+        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_i386],
5e9bef
+                                     {'multilib_policy': 'all'})
5e9bef
         self.assert_(res=='ok', msg)
5e9bef
         self.assertResult((p.obsoletes_i386,))
5e9bef
     def testObsoletenoarchToi386ForDependency(self):
5e9bef
@@ -50,7 +51,8 @@ class SimpleObsoletesTests(OperationsTests):
5e9bef
 
5e9bef
     def testObsoletenoarchTox86_64(self):
5e9bef
         p = self.pkgs
5e9bef
-        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_x86_64])
5e9bef
+        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_x86_64],
5e9bef
+                                     {'multilib_policy': 'all'})
5e9bef
         self.assert_(res=='ok', msg)
5e9bef
         self.assertResult((p.obsoletes_x86_64,))
5e9bef
     def testObsoletenoarchTox86_64ForDependency(self):
5e9bef
@@ -62,7 +64,8 @@ class SimpleObsoletesTests(OperationsTests):
5e9bef
 
5e9bef
     def testObsoletenoarchToMultiarch(self):
5e9bef
         p = self.pkgs
5e9bef
-        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_i386, p.obsoletes_x86_64])
5e9bef
+        res, msg = self.runOperation(['update'], [p.installed_noarch], [p.obsoletes_i386, p.obsoletes_x86_64],
5e9bef
+                                     {'multilib_policy': 'all'})
5e9bef
         self.assert_(res=='ok', msg)
5e9bef
         if new_behavior:
5e9bef
             self.assertResult((p.obsoletes_x86_64,), (p.obsoletes_i386,))
5e9bef
diff --git a/yum/__init__.py b/yum/__init__.py
5e9bef
index a156a6a6..7b7293f3 100644
5e9bef
--- a/yum/__init__.py
5e9bef
+++ b/yum/__init__.py
5e9bef
@@ -4779,6 +4779,21 @@ much more problems).
5e9bef
             return False
5e9bef
         return True
5e9bef
 
5e9bef
+    def _valid_obsoleter_arch(self, obsoleter, obsoletee):
5e9bef
+        """Return whether this obsoleter meets multilib_policy in case we are
5e9bef
+        dealing with the noarch->arch obsoletion case."""
5e9bef
+        if not self.arch.multilib or self.conf.multilib_policy != 'best':
5e9bef
+            # Install everything
5e9bef
+            return True
5e9bef
+        if obsoletee.arch != 'noarch' or obsoleter.arch == 'noarch':
5e9bef
+            # We do respect any arch->(no)arch obsoletions (having
5e9bef
+            # obsoletee.i386 installed on x86_64, you'd still expect
5e9bef
+            # obsoleter.i386 to replace it, even if you have
5e9bef
+            # multilib_policy=best).
5e9bef
+            return True
5e9bef
+        # noarch->arch case
5e9bef
+        return obsoleter.arch in self.arch.legit_multi_arches
5e9bef
+
5e9bef
     def install(self, po=None, **kwargs):
5e9bef
         """Mark the specified item for installation.  If a package
5e9bef
         object is given, mark it for installation.  Otherwise, mark
5e9bef
@@ -5146,10 +5161,12 @@ much more problems).
5e9bef
                                                        allow_missing=True)
5e9bef
                 if obsoleting_pkg is None:
5e9bef
                     continue
5e9bef
+                installed_pkg =  self.getInstalledPackageObject(installed)
5e9bef
+                if not self._valid_obsoleter_arch(obsoleting_pkg, installed_pkg):
5e9bef
+                    continue
5e9bef
                 topkg = self._test_loop(obsoleting_pkg, self._pkg2obspkg)
5e9bef
                 if topkg is not None:
5e9bef
                     obsoleting_pkg = topkg
5e9bef
-                installed_pkg =  self.getInstalledPackageObject(installed)
5e9bef
                 txmbr = self.tsInfo.addObsoleting(obsoleting_pkg, installed_pkg)
5e9bef
                 self.tsInfo.addObsoleted(installed_pkg, obsoleting_pkg)
5e9bef
                 if requiringPo:
5e9bef
@@ -5183,6 +5200,7 @@ much more problems).
5e9bef
         
5e9bef
         instpkgs = []
5e9bef
         availpkgs = []
5e9bef
+        arch_specified = True
5e9bef
         if po: # just a po
5e9bef
             if po.repoid == 'installed':
5e9bef
                 instpkgs.append(po)
5e9bef
@@ -5244,6 +5262,8 @@ much more problems).
5e9bef
                 self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
5e9bef
                 if not self.conf.skip_missing_names_on_update:
5e9bef
                     raise Errors.UpdateMissingNameError, _('Not tolerating missing names on update, stopping.')
5e9bef
+
5e9bef
+            arch_specified = '.' in kwargs['pattern']
5e9bef
         
5e9bef
         else: # we have kwargs, sort them out.
5e9bef
             nevra_dict = self._nevra_kwarg_parse(kwargs)
5e9bef
@@ -5296,12 +5316,16 @@ much more problems).
5e9bef
                                                            allow_missing=True)
5e9bef
                     if obsoleting_pkg is None:
5e9bef
                         continue
5e9bef
+                    if not arch_specified and not self._valid_obsoleter_arch(obsoleting_pkg, installed_pkg):
5e9bef
+                        continue
5e9bef
                     obs_pkgs.append(obsoleting_pkg)
5e9bef
                 # NOTE: Broekn wrt. repoid
5e9bef
                 for obsoleting_pkg in packagesNewestByName(obs_pkgs):
5e9bef
                     tx_return.extend(self.install(po=obsoleting_pkg))
5e9bef
             for available_pkg in availpkgs:
5e9bef
                 for obsoleted_pkg in self._find_obsoletees(available_pkg):
5e9bef
+                    if not arch_specified and not self._valid_obsoleter_arch(available_pkg, obsoleted_pkg):
5e9bef
+                        continue
5e9bef
                     obsoleted = obsoleted_pkg.pkgtup
5e9bef
                     txmbr = self.tsInfo.addObsoleting(available_pkg, obsoleted_pkg)
5e9bef
                     if requiringPo: