Blame SOURCES/0002-Fix-debug-restore-command-RhBug-1844533.patch

b1d886
From b94763c7f52dbbcc9920b4216d53fd8109e434c9 Mon Sep 17 00:00:00 2001
b1d886
From: Marek Blaha <mblaha@redhat.com>
b1d886
Date: Wed, 17 Jun 2020 15:49:50 +0200
b1d886
Subject: [PATCH] Fix debug-restore command
b1d886
b1d886
- correctly work with install-only packages (BZ#1844533)
b1d886
- do not remove current versions of packages that are supposed to be
b1d886
  replaced (downgraded / upgraded)
b1d886
---
b1d886
 plugins/debug.py | 108 ++++++++++++++++++++++++-----------------------
b1d886
 1 file changed, 56 insertions(+), 52 deletions(-)
b1d886
b1d886
diff --git a/plugins/debug.py b/plugins/debug.py
b1d886
index 6d00613d..29c5bf78 100644
b1d886
--- a/plugins/debug.py
b1d886
+++ b/plugins/debug.py
b1d886
@@ -201,10 +201,9 @@ def run(self):
b1d886
             self.opts.filter_types = set(
b1d886
                 self.opts.filter_types.replace(",", " ").split())
b1d886
 
b1d886
-        installed = self.base.sack.query().installed()
b1d886
         dump_pkgs = self.read_dump_file(self.opts.filename[0])
b1d886
 
b1d886
-        self.process_installed(installed, dump_pkgs, self.opts)
b1d886
+        self.process_installed(dump_pkgs, self.opts)
b1d886
 
b1d886
         self.process_dump(dump_pkgs, self.opts)
b1d886
 
b1d886
@@ -212,56 +211,63 @@ def run(self):
b1d886
             self.base.resolve()
b1d886
             self.base.do_transaction()
b1d886
 
b1d886
-    def process_installed(self, installed, dump_pkgs, opts):
b1d886
-        for pkg in sorted(installed):
b1d886
-            filtered = False
b1d886
+    def process_installed(self, dump_pkgs, opts):
b1d886
+        installed = self.base.sack.query().installed()
b1d886
+        installonly_pkgs = self.base._get_installonly_query(installed)
b1d886
+        for pkg in installed:
b1d886
+            pkg_remove = False
b1d886
             spec = pkgspec(pkg)
b1d886
-            action, dn, da, de, dv, dr = dump_pkgs.get((pkg.name, pkg.arch),
b1d886
-                                                       [None, None, None,
b1d886
-                                                        None, None, None])
b1d886
-            dump_naevr = (dn, da, de, dv, dr)
b1d886
-            if pkg.pkgtup == dump_naevr:
b1d886
-                # package unchanged
b1d886
-                del dump_pkgs[(pkg.name, pkg.arch)]
b1d886
-            else:
b1d886
-                if action == "install":
b1d886
-                    # already have some version
b1d886
-                    dump_pkgs[(pkg.name, pkg.arch)][0] = "replace"
b1d886
-                    if "replace" not in opts.filter_types:
b1d886
-                        filtered = True
b1d886
+            dumped_versions = dump_pkgs.get((pkg.name, pkg.arch), None)
b1d886
+            if dumped_versions is not None:
b1d886
+                evr = (pkg.epoch, pkg.version, pkg.release)
b1d886
+                if evr in dumped_versions:
b1d886
+                    # the correct version is already installed
b1d886
+                    dumped_versions[evr] = 'skip'
b1d886
                 else:
b1d886
-                    if "remove" not in opts.filter_types:
b1d886
-                        filtered = True
b1d886
-                if not filtered:
b1d886
-                    if opts.output:
b1d886
-                        print("remove    %s" % spec)
b1d886
+                    # other version is currently installed
b1d886
+                    if pkg in installonly_pkgs:
b1d886
+                        # package is install-only, should be removed
b1d886
+                        pkg_remove = True
b1d886
                     else:
b1d886
-                        self.base.package_remove(pkg)
b1d886
-
b1d886
-    def process_dump(self, dump_pkgs, opts):
b1d886
-        for (action, n, a, e, v, r) in sorted(dump_pkgs.values()):
b1d886
-            filtered = False
b1d886
-            if opts.ignore_arch:
b1d886
-                arch = ""
b1d886
-            else:
b1d886
-                arch = "." + a
b1d886
-            if opts.install_latest and action == "install":
b1d886
-                pkg_spec = "%s%s" % (n, arch)
b1d886
-                if "install" not in opts.filter_types:
b1d886
-                    filtered = True
b1d886
+                        # package should be upgraded / downgraded
b1d886
+                        if "replace" in opts.filter_types:
b1d886
+                            action = 'replace'
b1d886
+                        else:
b1d886
+                            action = 'skip'
b1d886
+                        for d_evr in dumped_versions.keys():
b1d886
+                            dumped_versions[d_evr] = action
b1d886
             else:
b1d886
-                pkg_spec = pkgtup2spec(n, arch, e, v, r)
b1d886
-                if (action == "replace" and
b1d886
-                        "replace" not in opts.filter_types):
b1d886
-                    filtered = True
b1d886
-            if not filtered:
b1d886
+                # package should not be installed
b1d886
+                pkg_remove = True
b1d886
+            if pkg_remove and "remove" in opts.filter_types:
b1d886
                 if opts.output:
b1d886
-                    print("install   %s" % pkg_spec)
b1d886
+                    print("remove    %s" % spec)
b1d886
                 else:
b1d886
-                    try:
b1d886
-                        self.base.install(pkg_spec)
b1d886
-                    except dnf.exceptions.MarkingError:
b1d886
-                        logger.error(_("Package %s is not available"), pkg_spec)
b1d886
+                    self.base.package_remove(pkg)
b1d886
+
b1d886
+    def process_dump(self, dump_pkgs, opts):
b1d886
+        for (n, a) in sorted(dump_pkgs.keys()):
b1d886
+            dumped_versions = dump_pkgs[(n, a)]
b1d886
+            for (e, v, r) in sorted(dumped_versions.keys()):
b1d886
+                action = dumped_versions[(e, v, r)]
b1d886
+                if action == 'skip':
b1d886
+                    continue
b1d886
+                if opts.ignore_arch:
b1d886
+                    arch = ""
b1d886
+                else:
b1d886
+                    arch = "." + a
b1d886
+                if opts.install_latest and action == "install":
b1d886
+                    pkg_spec = "%s%s" % (n, arch)
b1d886
+                else:
b1d886
+                    pkg_spec = pkgtup2spec(n, arch, e, v, r)
b1d886
+                if action in opts.filter_types:
b1d886
+                    if opts.output:
b1d886
+                        print("%s   %s" % (action, pkg_spec))
b1d886
+                    else:
b1d886
+                        try:
b1d886
+                            self.base.install(pkg_spec)
b1d886
+                        except dnf.exceptions.MarkingError:
b1d886
+                            logger.error(_("Package %s is not available"), pkg_spec)
b1d886
 
b1d886
     @staticmethod
b1d886
     def read_dump_file(filename):
b1d886
@@ -288,11 +294,9 @@ def read_dump_file(filename):
b1d886
 
b1d886
             pkg_spec = line.strip()
b1d886
             nevra = hawkey.split_nevra(pkg_spec)
b1d886
-            pkgs[(nevra.name, nevra.arch)] = ["install", ucd(nevra.name),
b1d886
-                                              ucd(nevra.arch),
b1d886
-                                              ucd(nevra.epoch),
b1d886
-                                              ucd(nevra.version),
b1d886
-                                              ucd(nevra.release)]
b1d886
+            # {(name, arch): {(epoch, version, release): action}}
b1d886
+            pkgs.setdefault((nevra.name, nevra.arch), {})[
b1d886
+                (nevra.epoch, nevra.version, nevra.release)] = "install"
b1d886
 
b1d886
         return pkgs
b1d886
 
b1d886
@@ -321,6 +325,6 @@ def pkgspec(pkg):
b1d886
 
b1d886
 
b1d886
 def pkgtup2spec(name, arch, epoch, version, release):
b1d886
-    a = "" if not arch else ".%s" % arch
b1d886
+    a = "" if not arch else ".%s" % arch.lstrip('.')
b1d886
     e = "" if epoch in (None, "") else "%s:" % epoch
b1d886
     return "%s-%s%s-%s%s" % (name, e, version, release, a)