[yum-commits] Branch 'yum-3_2_X' - 8 commits - test/operationstests.py test/testbase.py yum/__init__.py yum/packageSack.py yum/rpmsack.py

James Antill james at osuosl.org
Tue Jan 5 15:31:52 UTC 2010


 test/operationstests.py |   37 ++++++++++++++++++++++++
 test/testbase.py        |    2 +
 yum/__init__.py         |   74 ++++++++++++++++++++++++++----------------------
 yum/packageSack.py      |   13 +++++++-
 yum/rpmsack.py          |   45 ++++++++++++++++++++++++++---
 5 files changed, 133 insertions(+), 38 deletions(-)

New commits:
commit a7517e189b52ab03161762eb3ade0505d754683a
Author: James Antill <james at and.org>
Date:   Tue Jan 5 10:30:09 2010 -0500

     Don't emit extra warnings due to multiple cross arch pkgs, fix by
    always using the installed pkg arch.

diff --git a/yum/__init__.py b/yum/__init__.py
index 3e4c7b0..c1f40c4 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3634,6 +3634,9 @@ class YumBase(depsolve.Depsolve):
                 for tlipkg in latest_installed_n[pkg.name]:
                     if not canCoinstall(pkg.arch, tlipkg.arch):
                         lipkg = tlipkg
+                        #  Use this so we don't get confused when we have
+                        # different versions with different arches.
+                        na = (pkg.name, lipkg.arch)
                         break
 
             if lipkg is None:
commit c5dd819c127cf5f2be7da1c45faf55baaaa54ac2
Author: James Antill <james at and.org>
Date:   Tue Jan 5 10:28:36 2010 -0500

    Add searchNames() to packageSack so it can be used from unittests

diff --git a/yum/packageSack.py b/yum/packageSack.py
index 1e99661..95b278a 100644
--- a/yum/packageSack.py
+++ b/yum/packageSack.py
@@ -643,7 +643,6 @@ class PackageSack(PackageSackBase):
     def setCompatArchs(self, compatarchs):
         self.compatarchs = compatarchs
 
-        
     def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
         """return list of pkgobjects matching the nevra requested"""
         self._checkIndexes(failure='build')
@@ -667,6 +666,18 @@ class PackageSack(PackageSackBase):
             result.append(po)
         return result
         
+    def searchNames(self, names=[]):
+        """return list of pkgobjects matching the names requested"""
+        self._checkIndexes(failure='build')
+        result = []
+        done = set()
+        for name in names:
+            if name in done:
+                continue
+            done.add(name)
+            result.extend(self.nevra.get((name, None, None, None, None), []))
+        return result
+
     def getProvides(self, name, flags=None, version=(None, None, None)):
         """return dict { packages -> list of matching provides }"""
         self._checkIndexes(failure='build')
commit dc7c72919c79f20b1948f51c568422c4e1a2b1fc
Author: James Antill <james at and.org>
Date:   Tue Jan 5 10:28:06 2010 -0500

    Add tests for cross arch downgrades

diff --git a/test/operationstests.py b/test/operationstests.py
index dd85ed6..5a50439 100644
--- a/test/operationstests.py
+++ b/test/operationstests.py
@@ -234,3 +234,40 @@ class MultiLibTests(OperationsTests):
         res, msg = self.runOperation(['install', 'xbar'], p.inst, p.avail,
                                      {'multilib_policy' : 'all'})
         self.assertResult(ninst)
+
+    def testDowngrade1(self):
+        p = self.pkgs
+        ninst = [p.i_foo_1_12_x, p.a_wbar_0_2_i]
+        res, msg = self.runOperation(['downgrade', 'wbar'], p.inst, p.avail)
+        self.assertResult(ninst)
+
+    def testDowngrade2(self):
+        p = self.pkgs
+        oinst = [p.i_foo_1_12_x, p.a_wbar_2_22_i]
+        ninst = [p.i_foo_1_12_x, p.i_wbar_1_12_i]
+        p.avail.append(p.i_wbar_1_12_i)
+        res, msg = self.runOperation(['downgrade', 'wbar'], oinst, p.avail)
+        self.assertResult(ninst)
+
+    def testDowngrade3(self):
+        p = self.pkgs
+        oinst = [p.i_foo_1_12_x, p.a_wbar_2_22_i]
+        ninst = [p.i_foo_1_12_x, p.a_wbar_0_2_i]
+        res, msg = self.runOperation(['downgrade', 'wbar'], oinst, p.avail)
+        self.assertResult(ninst)
+
+    def testDowngrade4(self):
+        p = self.pkgs
+        oinst = p.inst[:] + [p.a_ibar_2_22_x]
+        p.a_ibar_1_12_i.arch = 'noarch'
+        ninst = p.inst[:] + [p.a_ibar_1_12_i]
+        res, msg = self.runOperation(['downgrade', 'ibar'], oinst, p.avail)
+        self.assertResult(ninst)
+
+    def testDowngrade5(self):
+        p = self.pkgs
+        ninst = p.inst[:] + [p.a_xbar_1_12_x]
+        p.a_xbar_2_22_i.arch = 'noarch'
+        oinst = p.inst[:] + [p.a_xbar_2_22_i]
+        res, msg = self.runOperation(['downgrade', 'xbar'], oinst, p.avail)
+        self.assertResult(ninst)
commit 1f3ee900cb68ebadba909e1e7f20c4ccb58968ec
Author: James Antill <james at and.org>
Date:   Tue Jan 5 09:59:48 2010 -0500

    Add transactionReset() to FakeRpmDb, so tests don't fail

diff --git a/test/testbase.py b/test/testbase.py
index 28de577..0b05812 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -277,6 +277,8 @@ class FakeRpmDb(packageSack.PackageSack):
         return
     def transactionResultVersion(self, rpmdbv):
         return
+    def transactionReset(self):
+        return
 
     def getProvides(self, name, flags=None, version=(None, None, None)):
         """return dict { packages -> list of matching provides }"""
commit ffd42f091b4476d6fb83fae6225bde9a4d9e7623
Author: James Antill <james at and.org>
Date:   Mon Jan 4 18:04:11 2010 -0500

    Fix cross arch downgrades via. remove + install

diff --git a/yum/__init__.py b/yum/__init__.py
index 9e4a25e..3e4c7b0 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2954,7 +2954,8 @@ class YumBase(depsolve.Depsolve):
                     # and a remove, which also tries to remove the old version.
                     self.tsInfo.remove(ipkg.pkgtup)
                     break
-                if ipkg.verGT(po):
+            for ipkg in self.rpmdb.searchNevra(name=po.name):
+                if ipkg.verGT(po) and not canCoinstall(ipkg.arch, po.arch):
                     self._add_prob_flags(rpm.RPMPROB_FILTER_OLDPACKAGE)
                     break
             
commit 58abee5c7db221f59e97dcec8dc4282bf59fbc9d
Author: James Antill <james at and.org>
Date:   Mon Jan 4 17:53:05 2010 -0500

    Allow downgrades to go across arch changes better

diff --git a/yum/__init__.py b/yum/__init__.py
index d87c180..9e4a25e 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3610,49 +3610,56 @@ class YumBase(depsolve.Depsolve):
 
         latest_installed_na = {}
         latest_installed_n  = {}
-        for pkg in ipkgs:
-            latest_installed_n[pkg.name] = pkg
+        for pkg in sorted(ipkgs):
+            if (pkg.name not in latest_installed_n or
+                pkg.verGT(latest_installed_n[pkg.name][0])):
+                latest_installed_n[pkg.name] = [pkg]
+            elif pkg.verEQ(latest_installed_n[pkg.name][0]):
+                latest_installed_n[pkg.name].append(pkg)
             latest_installed_na[(pkg.name, pkg.arch)] = pkg
 
         #  Find "latest downgrade", ie. latest available pkg before
-        # installed version.
+        # installed version. Indexed fromn the latest installed pkgtup.
         downgrade_apkgs = {}
         for pkg in sorted(apkgs):
             na  = (pkg.name, pkg.arch)
 
             # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386
             # but not .i386 => .x86_64 (similar to update).
-            key = na
-            latest_installed = latest_installed_na
-            if pkg.name in latest_installed_n and na not in latest_installed_na:
-                if not canCoinstall(pkg.arch,latest_installed_n[pkg.name].arch):
-                    key = pkg.name
-                    latest_installed = latest_installed_n
-
-            if key not in latest_installed:
+            lipkg = None
+            if na in latest_installed_na:
+                lipkg = latest_installed_na[na]
+            elif pkg.name in latest_installed_n:
+                for tlipkg in latest_installed_n[pkg.name]:
+                    if not canCoinstall(pkg.arch, tlipkg.arch):
+                        lipkg = tlipkg
+                        break
+
+            if lipkg is None:
                 if na not in warned_nas and not doing_group_pkgs:
                     msg = _('No Match for available package: %s') % pkg
                     self.logger.critical(msg)
                 warned_nas.add(na)
                 continue
-            if pkg.verGE(latest_installed[key]):
+
+            if pkg.verGE(lipkg):
                 if na not in warned_nas:
                     msg = _('Only Upgrade available on package: %s') % pkg
                     self.logger.critical(msg)
                 warned_nas.add(na)
                 continue
+
             warned_nas.add(na)
-            if (na in downgrade_apkgs and
-                pkg.verLE(downgrade_apkgs[na])):
+            if (lipkg.pkgtup in downgrade_apkgs and
+                pkg.verLE(downgrade_apkgs[lipkg.pkgtup])):
                 continue # Skip older than "latest downgrade"
-            downgrade_apkgs[na] = pkg
+            downgrade_apkgs[lipkg.pkgtup] = pkg
 
         tx_return = []
-        for po in ipkgs:
-            na = (po.name, po.arch)
-            if na not in downgrade_apkgs:
+        for ipkg in ipkgs:
+            if ipkg.pkgtup not in downgrade_apkgs:
                 continue
-            txmbrs = self.tsInfo.addDowngrade(downgrade_apkgs[na], po)
+            txmbrs = self.tsInfo.addDowngrade(downgrade_apkgs[ipkg.pkgtup],ipkg)
             if not txmbrs: # Fail?
                 continue
             self._add_prob_flags(rpm.RPMPROB_FILTER_OLDPACKAGE)
commit 4ee2e5a51fc35b8142a9279932bd0dffa9659b4c
Author: James Antill <james at and.org>
Date:   Mon Jan 4 13:27:57 2010 -0500

    Return objects from the rpmdb.check_* functions, so it's easier to add more

diff --git a/yum/__init__.py b/yum/__init__.py
index 48be3e8..d87c180 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1073,23 +1073,20 @@ class YumBase(depsolve.Depsolve):
             out(_('Warning: RPMDB altered outside of yum.'))
 
         rc = 0
+        probs = []
         if chkcmd in ('all', 'dependencies'):
             prob2ui = {'requires' : _('missing requires'),
                        'conflicts' : _('installed conflict')}
-            for (pkg, prob, ver, opkgs) in self.rpmdb.check_dependencies():
-                rc += 1
-                if opkgs:
-                    opkgs = ": " + ', '.join(map(str, opkgs))
-                else:
-                    opkgs = ''
-                out("%s %s %s%s" % (pkg, prob2ui[prob], ver, opkgs))
+            probs.extend(self.rpmdb.check_dependencies())
 
         if chkcmd in ('all', 'duplicates'):
             iopkgs = set(self.conf.installonlypkgs)
-            for (pkg, prob, opkg) in self.rpmdb.check_duplicates(iopkgs):
-                rc += 1
-                out(_("%s is a duplicate of %s") % (pkg, opkg))
-        return rc
+            probs.extend(self.rpmdb.check_duplicates(iopkgs))
+
+        for prob in sorted(probs):
+            out(prob)
+
+        return len(probs)
 
     def runTransaction(self, cb):
         """takes an rpm callback object, performs the transaction"""
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 229adaa..4f79fad 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -32,7 +32,7 @@ from packageSack import PackageSackBase, PackageSackVersion
 import fnmatch
 import re
 
-from yum.i18n import to_unicode
+from yum.i18n import to_unicode, _
 import constants
 
 import yum.depsolve
@@ -80,6 +80,40 @@ class RPMInstalledPackage(YumInstalledPackage):
         return val
 
 
+class RPMDBProblem:
+    '''
+    Represents a problem in the rpmdb, from the check_*() functions.
+    '''
+    def __init__(self, pkg, problem, **kwargs):
+        self.pkg = pkg
+        self.problem = problem
+        for kwarg in kwargs:
+            setattr(self, kwarg, kwargs[kwarg])
+
+    def __cmp__(self, other):
+        if other is None:
+            return 1
+        return cmp(self.pkg, other.pkg) or cmp(self.problem, problem)
+
+
+class RPMDBProblemDependency(RPMDBProblem):
+    def __str__(self):
+        if self.problem == 'requires':
+            return "%s %s %s" % (self.pkg, _('has missing requires of'),
+                                 self.missing)
+
+        return "%s %s %s: %s" % (self.pkg, _('has installed conflicts'),
+                                 self.found,', '.join(map(str, self.conflicts)))
+
+
+class RPMDBProblemDuplicate(RPMDBProblem):
+    def __init__(self, pkg, **kwargs):
+        RPMDBProblem.__init__(self, pkg, "duplicate", **kwargs)
+
+    def __str__(self):
+        return _("%s is a duplicate with %s") % (self.pkg, self.duplicate)
+
+
 class RPMDBPackageSack(PackageSackBase):
     '''
     Represent rpmdb as a packagesack
@@ -1072,7 +1106,8 @@ class RPMDBPackageSack(PackageSackBase):
                     continue
                 flags = yum.depsolve.flags.get(flags, flags)
                 missing = miscutils.formatRequire(req, ver, flags)
-                problems.append((pkg, "requires", missing, []))
+                prob = RPMDBProblemDependency(pkg, "requires", missing=missing)
+                problems.append(prob)
 
             for creq in pkg.conflicts:
                 if creq[0].startswith('rpmlib'): continue
@@ -1083,7 +1118,9 @@ class RPMDBPackageSack(PackageSackBase):
                     continue
                 flags = yum.depsolve.flags.get(flags, flags)
                 found = miscutils.formatRequire(req, ver, flags)
-                problems.append((pkg, "conflicts", found, res))
+                prob = RPMDBProblemDependency(pkg, "conflicts", found=found,
+                                              conflicts=res)
+                problems.append(prob)
         return problems
 
     def _iter_two_pkgs(self, ignore):
@@ -1111,7 +1148,7 @@ class RPMDBPackageSack(PackageSackBase):
                     continue
 
             # More than one pkg, they aren't version equal, or aren't multiarch
-            problems.append((pkg, "dup", last))
+            problems.append(RPMDBProblemDuplicate(pkg, duplicate=last))
         return problems
 
 
commit 7d875cbb8e7d5198e052183e34eed55850e17012
Author: James Antill <james at and.org>
Date:   Mon Jan 4 11:24:19 2010 -0500

    Cleanup the comment about the fix for skip-broken and rpmdb-cache

diff --git a/yum/__init__.py b/yum/__init__.py
index b8244ca..48be3e8 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -868,8 +868,8 @@ class YumBase(depsolve.Depsolve):
         while (len(self.po_with_problems) > 0 and rescode == 1):
             count += 1
             #  Remove all the rpmdb cache data, this is somewhat heavy handed
-            # but easier than removing it ... and skip-broken shouldn't care
-            # too much about speed.
+            # but easier than removing/altering specific bits of the cache ...
+            # and skip-broken shouldn't care too much about speed.
             self.rpmdb.transactionReset()
             self.verbose_logger.debug(_("Skip-broken round %i"), count)
             self._printTransaction()        


More information about the Yum-commits mailing list