[yum-commits] Branch 'yum-3_2_X' - 9 commits - docs/yum.8 test/depsolvetests.py test/simpleupdatetests.py yum/config.py yum/depsolve.py yum/history.py yum/__init__.py yum/misc.py

James Antill james at osuosl.org
Mon Oct 17 19:06:43 UTC 2011


 docs/yum.8                |    2 -
 test/depsolvetests.py     |    7 ++--
 test/simpleupdatetests.py |   69 ++++++++++++++++++++++++++++++++++++++++++++++
 yum/__init__.py           |   14 ++++++---
 yum/config.py             |    2 -
 yum/depsolve.py           |   31 +++++++++++++++++++-
 yum/history.py            |    6 +++-
 yum/misc.py               |   12 ++++++++
 8 files changed, 130 insertions(+), 13 deletions(-)

New commits:
commit de9bb4991938c56dfe70b1e343ea6650ca0e8ec5
Merge: e66bf77 ef4eda3
Author: James Antill <james at and.org>
Date:   Mon Oct 17 15:06:37 2011 -0400

    Merge branch 'yum-3_2_X' of ssh://yum.baseurl.org/srv/projects/yum/git/yum into yum-3_2_X
    
    * 'yum-3_2_X' of ssh://yum.baseurl.org/srv/projects/yum/git/yum: (2 commits)
      Improve history subcommand completion.
      ...

commit e66bf77b5845a64499cdbcc6ce20d8e1d0d49e26
Author: James Antill <james at and.org>
Date:   Fri Oct 14 16:27:13 2011 -0400

    Fix test "regression" in inst_require_obsoletes1 for ObsoletesOffPostAvail2+

diff --git a/test/depsolvetests.py b/test/depsolvetests.py
index 7af3f16..ea47b03 100644
--- a/test/depsolvetests.py
+++ b/test/depsolvetests.py
@@ -1130,9 +1130,10 @@ class DepsolveTests(DepsolveTests):
         # FIXME: Does it make sense to ignore the obsoletes here? esp. as we
         # don't ignore the conflicts above? ... I'm guessing ignoring it is
         # by accident too? bah.
-        # self.assertEquals('err', *self.resolveCode())
-        self.assertEquals('ok', *self.resolveCode())
-        self.assertResult((ipo1, po1))
+        self.assertEquals('err', *self.resolveCode())
+        # Old behaviour:
+        # self.assertEquals('ok', *self.resolveCode())
+        # self.assertResult((ipo1, po1))
 
     def testUpdate_so_req_diff_arch(self):
         rpo1 = FakePackage('foozoomer')
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 7e74880..c518311 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -849,6 +849,12 @@ class Depsolve(object):
                                 continue
                             if otxmbr.po.obsoletedBy([txmbr.po]):
                                 self.tsInfo.remove(otxmbr.pkgtup)
+                                #  We need to remove an obsoleted entry that
+                                # was maybe used to resolve something ... ?
+                                CheckDeps = True
+                                self._last_req = None
+                                self.pkgSack.delPackage(otxmbr.po)
+                                self.up.delPackage(otxmbr.pkgtup)
 
                 if CheckDeps:
                     if self.dsCallback: self.dsCallback.restartLoop()
commit a03ab5a673d051205a554098f64dd604eeb34cc7
Author: James Antill <james at and.org>
Date:   Fri Oct 14 15:38:52 2011 -0400

    Add fix for upgrade with same reqs. "Forces" upgrade, but oh well. BZ 745217.

diff --git a/yum/depsolve.py b/yum/depsolve.py
index 699a23c..7e74880 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -58,6 +58,9 @@ flags = {"GT": rpm.RPMSENSE_GREATER,
          "LE": rpm.RPMSENSE_LESS | rpm.RPMSENSE_EQUAL,
          "EQ": rpm.RPMSENSE_EQUAL,
          None: 0 }
+_rflags = {}
+for f in flags:
+    _rflags[flags[f]] = f
 
 class Depsolve(object):
     """A class for resolving dependencies."""
@@ -407,9 +410,27 @@ class Depsolve(object):
             self.conf.obsoletes = 0
             txmbrs = self.update(po=requiringPo, requiringPo=requiringPo)
             self.conf.obsoletes = origobs
-            if not txmbrs:
+
+            def _check_update_worked(txmbrs, obs=False):
+                #  Old code assumed that if there was an update, we were good:
+                #    if txmbrs: return True
+                # ..however we have a problem when foo-1 and foo-2 both require
+                # bar-1, and bar-2 is being installed. If the req. is identical
+                # then we'll skip checking it in _checkInstall(), so we need to
+                # check it here.
+                for txmbr in txmbrs:
+                    if obs or txmbr.name == requiringPo.name:
+                        n,f,v = requirement
+                        creq = (n, _rflags[f],
+                                rpmUtils.miscutils.stringToVersion(v))
+                        # If it's identical ... checkInstall will skip it.
+                        if creq not in txmbr.po.requires:
+                            return True
+                return False
+
+            if not _check_update_worked(txmbrs):
                 txmbrs = self.update(po=requiringPo, requiringPo=requiringPo)
-                if not txmbrs:
+                if not _check_update_worked(txmbrs, obs=True):
                     msg = self._err_missing_requires(requiringPo, requirement)
                     self.verbose_logger.log(logginglevels.DEBUG_2, _('No update paths found for %s. Failure!'), requiringPo)
                     return self._requiringFromTransaction(requiringPo, requirement, errorlist)
commit 9d0b5381c98855df0c7d56a023b455caba83f8aa
Author: James Antill <james at and.org>
Date:   Fri Oct 14 15:38:13 2011 -0400

    Add testcases for upgrade with same reqs. BZ 745217.

diff --git a/test/simpleupdatetests.py b/test/simpleupdatetests.py
index 6177fb1..2c8bcb3 100644
--- a/test/simpleupdatetests.py
+++ b/test/simpleupdatetests.py
@@ -990,3 +990,72 @@ class SimpleUpdateTests(OperationsTests):
         # Nothing to do...
         self.assert_(res==0, msg)
 
+    def testUpdateReqFail_1(self):
+        foo11 = FakePackage('foo', '1', '1', '0', 'i386')
+        foo11.addRequires('bar', 'EQ', ('0', '1', '1'))
+        foo12 = FakePackage('foo', '1', '2', '0', 'i386')
+        foo12.addRequires('bar', 'EQ', ('0', '1', '1'))
+
+        bar11 = FakePackage('bar', '1', '1', '0', 'i386')
+        bar12 = FakePackage('bar', '1', '2', '0', 'i386')
+
+        res, msg = self.runOperation(['update', 'bar'],
+                                     [foo11, bar11],
+                                     [foo11, foo12, bar11, bar12])
+        # Should fail...
+        self.assert_(res=='err', msg)
+
+    def testUpdateReqFail_2(self):
+        foo11 = FakePackage('foo', '1', '1', '0', 'i386')
+        foo11.addRequires('bar', 'EQ', ('0', '1', '1'))
+        foo12 = FakePackage('foo', '1', '2', '0', 'i386')
+        foo12.addRequires('bar', 'LE', ('0', '1', '1'))
+
+        bar11 = FakePackage('bar', '1', '1', '0', 'i386')
+        bar12 = FakePackage('bar', '1', '2', '0', 'i386')
+
+        res, msg = self.runOperation(['update', 'bar'],
+                                     [foo11, bar11],
+                                     [foo11, foo12, bar11, bar12])
+        # Should fail...
+        self.assert_(res=='err', msg)
+
+    def testUpdateReqFail_3(self):
+        foo11 = FakePackage('foo', '1', '1', '0', 'i386')
+        foo11.addRequires('bar', 'EQ', ('0', '1', '1'))
+        foo12 = FakePackage('foo', '1', '2', '0', 'i386')
+        foo12.addRequires('bar', 'EQ', ('0', '1', '1'))
+
+        bar11 = FakePackage('bar', '1', '1', '0', 'i386')
+        bar12 = FakePackage('bar', '1', '2', '0', 'i386')
+
+        cbar11 = FakePackage('compat-bar', '1', '1', '0', 'i386')
+        cbar11.addProvides('bar', 'EQ', ('0', '1', '1'))
+
+        res, msg = self.runOperation(['update', 'bar'],
+                                     [foo11, bar11],
+                                     [foo11, foo12, bar11, bar12, cbar11])
+        self.assert_(res=='ok', msg)
+        # Ideal:
+        # self.assertResult((foo11, bar12, cbar11))
+        self.assertResult((foo12, bar12, cbar11))
+
+    def testUpdateReqFail_4(self):
+        foo11 = FakePackage('foo', '1', '1', '0', 'i386')
+        foo11.addRequires('bar', 'EQ', ('0', '1', '1'))
+        foo12 = FakePackage('foo', '1', '2', '0', 'i386')
+        foo12.addRequires('bar', 'LE', ('0', '1', '1'))
+
+        bar11 = FakePackage('bar', '1', '1', '0', 'i386')
+        bar12 = FakePackage('bar', '1', '2', '0', 'i386')
+
+        cbar11 = FakePackage('compat-bar', '1', '1', '0', 'i386')
+        cbar11.addProvides('bar', 'EQ', ('0', '1', '1'))
+
+        res, msg = self.runOperation(['update', 'bar'],
+                                     [foo11, bar11],
+                                     [foo11, foo12, bar11, bar12, cbar11])
+        self.assert_(res=='ok', msg)
+        # Ideal:
+        # self.assertResult((foo11, bar12, cbar11))
+        self.assertResult((foo12, bar12, cbar11))
commit b070ced387a670b4fe1440f5e6ae086fe6e5ef3b
Author: James Antill <james at and.org>
Date:   Thu Oct 13 10:35:05 2011 -0400

    Ignore time skew by using sqlite IDs instead to order transactions. BZ 745635.

diff --git a/yum/history.py b/yum/history.py
index 8e62f50..d27fa44 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -1204,7 +1204,11 @@ class YumHistory:
         if tids and len(tids) <= yum.constants.PATTERNS_INDEXED_MAX:
             params = tids = list(set(tids))
             sql += " WHERE tid IN (%s)" % ", ".join(['?'] * len(tids))
-        sql += " ORDER BY beg_ts DESC, tid ASC"
+        #  This relies on the fact that the PRIMARY KEY in sqlite will always
+        # increase with each transaction. In theory we can use:
+        # ORDER BY beg_ts DESC ... except sometimes people do installs with a
+        # system clock that is very broken, and using that screws them forever.
+        sql += " ORDER BY tid DESC"
         if limit is not None:
             sql += " LIMIT " + str(limit)
         executeSQL(cur, sql, params)
commit fe6da5db71bd1c9ede9f58311297d693b45cb914
Author: James Antill <james at and.org>
Date:   Thu Oct 13 10:31:31 2011 -0400

    Output the GPG fingerprint when showing the GPG key, BZ 745715.

diff --git a/yum/__init__.py b/yum/__init__.py
index 1807d61..53043de 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -5093,17 +5093,21 @@ class YumBase(depsolve.Depsolve):
             if pkgs:
                 pkgs = sorted(pkgs)[-1]
                 msg = (_('Importing %s key 0x%s:\n'
-                         ' Userid : %s\n'
-                         ' Package: %s (%s)\n'
-                         ' From   : %s') %
+                         ' Userid     : "%s"\n'
+                         ' Fingerprint: %s\n'
+                         ' Package    : %s (%s)\n'
+                         ' From       : %s') %
                        (keytype, info['hexkeyid'], to_unicode(info['userid']),
+                        misc.gpgkey_fingerprint_ascii(info),
                         pkgs, pkgs.ui_from_repo,
                         keyurl.replace("file://","")))
         if msg is None:
             msg = (_('Importing %s key 0x%s:\n'
-                     ' Userid: "%s"\n'
-                     ' From  : %s') %
+                     ' Userid     : "%s"\n'
+                     ' Fingerprint: %s\n'
+                     ' From       : %s') %
                    (keytype, info['hexkeyid'], to_unicode(info['userid']),
+                    misc.gpgkey_fingerprint_ascii(info),
                     keyurl.replace("file://","")))
         self.logger.critical("%s", msg)
 
commit f1704597a2fdeb05c781399d1c5c70bd9878f393
Author: James Antill <james at and.org>
Date:   Thu Oct 13 10:30:40 2011 -0400

    Add helper function to access the fingerprint in the GPG key info data.

diff --git a/yum/misc.py b/yum/misc.py
index 04490a6..5321003 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -8,6 +8,7 @@ import os
 import os.path
 from cStringIO import StringIO
 import base64
+import binascii
 import struct
 import re
 import errno
@@ -410,6 +411,17 @@ def procgpgkey(rawkey):
     # Decode and return
     return base64.decodestring(block.getvalue())
 
+def gpgkey_fingerprint_ascii(info, chop=4):
+    ''' Given a key_info data from getgpgkeyinfo(), return an ascii
+    fingerprint. Chop every 4 ascii values, as that is what GPG does. '''
+    # First "duh" ... it's a method...
+    fp = info['fingerprint']()
+    fp = binascii.hexlify(fp)
+    if chop:
+        fp = [fp[i:i+chop] for i in range(0, len(fp), chop)]
+        fp = " ".join(fp)
+    return fp
+
 def getgpgkeyinfo(rawkey, multiple=False):
     '''Return a dict of info for the given ASCII armoured key text
 
commit f7b2c265a4488b2db2350ba97fa11c3baa5bf596
Author: Ken Dreyer <ktdreyer at ktdreyer.com>
Date:   Tue Oct 11 14:58:38 2011 -0600

    Man page grammar fix

diff --git a/docs/yum.8 b/docs/yum.8
index 5d6e3d4..499da41 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -264,7 +264,7 @@ on groups, files, provides and filelists just like the "install" command\&.
 Will try and downgrade a package from the version currently installed to the
 previously highest version (or the specified version).
 The depsolver will not necessarily work, but if you specify all the packages it
-should work (and thus. all the simple cases will work). Also this does not
+should work (thus, all the simple cases will work). Also this does not
 work for "installonly" packages, like Kernels. downgrade operates
 on groups, files, provides, filelists and rpm files just like the "install" command\&.
 .IP
commit e2c197e6802da74b0c8568204cfec3ba8f1ce903
Author: James Antill <james at and.org>
Date:   Thu Oct 6 09:36:21 2011 -0400

    Update bugtracker URL back to redhat, as trac. is now offline.

diff --git a/yum/config.py b/yum/config.py
index ef1b9e1..fffd0d1 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -795,7 +795,7 @@ class YumConf(StartupConf):
                  # all == install any/all arches you can
                  # best == use the 'best  arch' for the system
                  
-    bugtracker_url = Option('http://yum.baseurl.org/report')
+    bugtracker_url = Option('https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&version=rawhide&component=yum')
 
     color = SelectionOption('auto', ('auto', 'never', 'always'),
                             mapper={'on' : 'always', 'yes' : 'always',


More information about the Yum-commits mailing list