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

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