[Yum-devel] [PATCH] Add package checksums from yumdb to the data we store in the rpmdb cache

James Antill james at and.org
Mon Feb 22 19:32:32 UTC 2010


---
 yum/rpmsack.py         |   78 ++++++++++++++++++++++++++++++++++++++++++++++++
 yum/transactioninfo.py |    7 ++++
 2 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index adf70af..8289cd2 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -528,6 +528,10 @@ class RPMDBPackageSack(PackageSackBase):
             data = self._trans_cache_store['file-requires']
             self._write_file_requires(rpmdbv, data)
 
+        if 'yumdb-package-checksums' in self._trans_cache_store:
+            data = self._trans_cache_store['yumdb-package-checksums']
+            self._write_package_checksums(rpmdbv, data)
+
         self._trans_cache_store = {}
 
     def transactionReset(self):
@@ -699,6 +703,80 @@ class RPMDBPackageSack(PackageSackBase):
         os.rename(self._cachedir + '/file-requires.tmp',
                   self._cachedir + '/file-requires')
 
+    def preloadPackageChecksums(self):
+        """ As simpleVersion() et. al. requires it, we "cache" this yumdb data
+            as part of our rpmdb cache. We cache it with rpmdb data, even
+            though someone _could_ use yumdb to alter it without changing the
+            rpmdb ... don't do that. """
+        if not self.__cache_rpmdb__:
+            return
+
+        if not os.path.exists(self._cachedir + '/yumdb-package-checksums'):
+            return
+
+        def _read_str(fo):
+            return fo.readline()[:-1]
+
+        rpmdbv = self.simpleVersion(main_only=True)[0]
+        fo = open(self._cachedir + '/yumdb-package-checksums')
+        frpmdbv = fo.readline()
+        if not frpmdbv or rpmdbv != frpmdbv[:-1]:
+            return
+
+        checksum_data = {}
+        try:
+            # Read the checksums...
+            pkgtups_num = int(_read_str(fo))
+            while pkgtups_num > 0:
+                pkgtups_num -= 1
+
+                # n, a, e, v, r
+                pkgtup = (_read_str(fo), _read_str(fo),
+                          _read_str(fo), _read_str(fo), _read_str(fo))
+                int(pkgtup[2]) # Check epoch is valid
+
+                T = _read_str(fo)
+                D = _read_str(fo)
+                checksum_data[pkgtup] = (T, D)
+
+            if fo.readline() != '': # Should be EOF
+                return
+        except ValueError:
+            return
+
+        for pkgtup in checksum_data:
+            (n, a, e, v, r) = pkgtup
+            pkg = self.searchNevra(n, e, v, r, a)[0]
+            (T, D) = checksum_data[pkgtup]
+            if ('checksum_type' in pkg.yumdb_info._read_cached_data or
+                'checksum_data' in pkg.yumdb_info._read_cached_data):
+                continue
+            pkg.yumdb_info._read_cached_data['checksum_type'] = T
+            pkg.yumdb_info._read_cached_data['checksum_data'] = D
+
+    def transactionCachePackageChecksums(self, pkg_checksum_tups):
+        if not self.__cache_rpmdb__:
+            return
+
+        self._trans_cache_store['yumdb-package-checksums'] = pkg_checksum_tups
+
+    def _write_package_checksums(self, rpmdbversion, data):
+        if not os.access(self._cachedir, os.W_OK):
+            return
+
+        pkg_checksum_tups = data
+        fo = open(self._cachedir + '/yumdb-package-checksums.tmp', 'w')
+        fo.write("%s\n" % rpmdbversion)
+        fo.write("%u\n" % len(pkg_checksum_tups))
+        for pkgtup, TD in sorted(pkg_checksum_tups):
+            for var in pkgtup:
+                fo.write("%s\n" % var)
+            for var in TD:
+                fo.write("%s\n" % var)
+        fo.close()
+        os.rename(self._cachedir + '/yumdb-package-checksums.tmp',
+                  self._cachedir + '/yumdb-package-checksums')
+
     def _get_cached_simpleVersion_main(self):
         """ Return the cached string of the main rpmdbv. """
         if self._have_cached_rpmdbv_data is not None:
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index 30a2625..e7b60de 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -577,12 +577,15 @@ class TransactionData:
                 _reinstalled_pkgtups[txmbr.po.pkgtup] = txmbr.po
             pkgs.append(txmbr.po)
 
+        self.rpmdb.preloadPackageChecksums()
         main = PackageSackVersion()
+        pkg_checksum_tups = []
         for pkg in sorted(pkgs):
             if pkg.repoid != 'installed':
                 # Paste from PackageSackBase.simpleVersion()
                 csum = pkg.returnIdSum()
                 main.update(pkg, csum)
+                pkg_checksum_tups.append((pkg.pkgtup, csum))
                 continue
 
             # Installed pkg, see if it's about to die
@@ -597,7 +600,11 @@ class TransactionData:
             csum = None
             if 'checksum_type' in ydbi and 'checksum_data' in ydbi:
                 csum = (ydbi.checksum_type, ydbi.checksum_data)
+                pkg_checksum_tups.append((pkg.pkgtup, csum))
             main.update(pkg, csum)
+
+        self.rpmdb.transactionCachePackageChecksums(pkg_checksum_tups)
+
         return main
 
 class ConditionalTransactionData(TransactionData):
-- 
1.6.6



More information about the Yum-devel mailing list