yifengyou / rpms / yum

Forked from rpms/yum 3 years ago
Clone

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

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