Blob Blame History Raw
From 087ad3d12ba307355dd66aba54faea97d227a3dd Mon Sep 17 00:00:00 2001
From: zhanghaolian <65838930+iWhy98@users.noreply.github.com>
Date: Tue, 25 Jan 2022 15:41:16 +0800
Subject: [PATCH 1/2] dnf:fix dnf mark error when history sqlite missing

---
 dnf/cli/commands/mark.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dnf/cli/commands/mark.py b/dnf/cli/commands/mark.py
index ec16b738d..cb1f91c13 100644
--- a/dnf/cli/commands/mark.py
+++ b/dnf/cli/commands/mark.py
@@ -89,7 +89,7 @@ class MarkCommand(commands.Command):
 
         old = self.base.history.last()
         if old is None:
-            rpmdb_version = self.sack._rpmdb_version()
+            rpmdb_version = self.base.sack._rpmdb_version()
         else:
             rpmdb_version = old.end_rpmdb_version
 
-- 
2.34.1


From bee5b97ad159af019deda4de0d80d0011dba4f7a Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 28 Jan 2022 16:53:50 +0100
Subject: [PATCH 2/2] Use rpm.TransactionSet.dbCookie() to determining if rpmdb
 has changed

DNF was using private method `hawkey.Sack._rpmdb_version()` from libdnf.
The method computes SHA1 hash from sorted list of hashes stored in
the headers of the instaled packages. And it adds prefix of the number
of installed packages to the computed hash. The result was stored
to the history database and used to detect changes in the rpm database.

The patch uses new oficial librpm API function
`rpm.TransactionSet.dbCookie()`. This is a cleaner solution.
It is also a step to remove the `._rpmdb_version()` method from libdnf.
It is an attempt to remove SHA1 calculations from libdnf.
Troubleshooting FIPS compatibility.

= changelog =
msg: Use rpm.TransactionSet.dbCookie() to determining if rpmdb has changed
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2043476
---
 dnf/base.py              |  6 +++---
 dnf/cli/commands/mark.py |  2 +-
 dnf/cli/output.py        |  2 +-
 dnf/rpm/transaction.py   | 16 ++++++++++++++++
 tests/test_sack.py       |  6 ------
 5 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/dnf/base.py b/dnf/base.py
index b0a536f7f..574e80f66 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -907,7 +907,7 @@ class Base(object):
                     cmdline = ' '.join(self.cmds)
                 old = self.history.last()
                 if old is None:
-                    rpmdb_version = self.sack._rpmdb_version()
+                    rpmdb_version = self._ts.dbCookie()
                 else:
                     rpmdb_version = old.end_rpmdb_version
 
@@ -1046,7 +1046,7 @@ class Base(object):
             using_pkgs_pats = list(self.conf.history_record_packages)
             installed_query = self.sack.query().installed()
             using_pkgs = installed_query.filter(name=using_pkgs_pats).run()
-            rpmdbv = self.sack._rpmdb_version()
+            rpmdbv = self._ts.dbCookie()
             lastdbv = self.history.last()
             if lastdbv is not None:
                 lastdbv = lastdbv.end_rpmdb_version
@@ -1163,7 +1163,7 @@ class Base(object):
         for tsi in transaction_items:
             count = display_banner(tsi.pkg, count)
 
-        rpmdbv = rpmdb_sack._rpmdb_version()
+        rpmdbv = self._ts.dbCookie()
         self.history.end(rpmdbv)
 
         timer()
diff --git a/dnf/cli/commands/mark.py b/dnf/cli/commands/mark.py
index cb1f91c13..36bf9d436 100644
--- a/dnf/cli/commands/mark.py
+++ b/dnf/cli/commands/mark.py
@@ -89,7 +89,7 @@ class MarkCommand(commands.Command):
 
         old = self.base.history.last()
         if old is None:
-            rpmdb_version = self.base.sack._rpmdb_version()
+            rpmdb_version = self.base._ts.dbCookie()
         else:
             rpmdb_version = old.end_rpmdb_version
 
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
index a4e9f6c8e..ecf05c2b0 100644
--- a/dnf/cli/output.py
+++ b/dnf/cli/output.py
@@ -1607,7 +1607,7 @@ Transaction Summary
             if lastdbv is not None and trans.tid == lasttid:
                 #  If this is the last transaction, is good and it doesn't
                 # match the current rpmdb ... then mark it as bad.
-                rpmdbv = self.sack._rpmdb_version()
+                rpmdbv = self.base._ts.dbCookie()
                 trans.compare_rpmdbv(str(rpmdbv))
             lastdbv = None
 
diff --git a/dnf/rpm/transaction.py b/dnf/rpm/transaction.py
index bcc2a7024..a11f36e7e 100644
--- a/dnf/rpm/transaction.py
+++ b/dnf/rpm/transaction.py
@@ -12,8 +12,10 @@
 from __future__ import absolute_import
 from __future__ import unicode_literals
 from dnf.i18n import _
+import logging
 import rpm
 
+_logger = logging.getLogger('dnf')
 read_ts = None
 ts = None
 
@@ -61,6 +63,20 @@ class TransactionWrapper(object):
             mi.pattern(tag, tp, pat)
         return mi
 
+    def dbCookie(self):
+        # dbCookie() does not support lazy opening of rpm database.
+        # The following line opens the database if it is not already open.
+        if self.ts.openDB() != 0:
+            _logger.error(_('The openDB() function connot open rpm database.'))
+            return ''
+
+        cookie = self.ts.dbCookie()
+        if not cookie:
+            _logger.error(_('The dbCookie() function did not return cookie of rpm database.'))
+            return ''
+
+        return cookie
+
     def __getattr__(self, attr):
         if attr in self._methods:
             return self.getMethod(attr)
diff --git a/tests/test_sack.py b/tests/test_sack.py
index 49a715924..2c6fe8e01 100644
--- a/tests/test_sack.py
+++ b/tests/test_sack.py
@@ -32,12 +32,6 @@ class SackTest(tests.support.DnfBaseTestCase):
 
     REPOS = []
 
-    def test_rpmdb_version(self):
-        version = self.sack._rpmdb_version()
-        self.assertIsNotNone(version)
-        expected = "%s:%s" % (tests.support.TOTAL_RPMDB_COUNT, tests.support.RPMDB_CHECKSUM)
-        self.assertEqual(version, expected)
-
     def test_excludepkgs(self):
         self.base.conf.excludepkgs = ['pepper']
         self.base._setup_excludes_includes()
-- 
2.34.1