|
|
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)
|