import dnf-4.2.7-7.el8_1
This commit is contained in:
commit
a7216982e9
1
.dnf.metadata
Normal file
1
.dnf.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
5b789329d4fc3e54190e637f1f046232681c8f5f SOURCES/dnf-4.2.7.tar.gz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
SOURCES/dnf-4.2.7.tar.gz
|
277424
SOURCES/0002-Update-localizations-from-zanata-RhBug1689982.patch
Normal file
277424
SOURCES/0002-Update-localizations-from-zanata-RhBug1689982.patch
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,118 @@
|
|||||||
|
From 524950fb6c647194ad9e0d3b7b2195d671424d1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 9 Apr 2019 20:54:12 +0200
|
||||||
|
Subject: [PATCH] Accept multiple specs in repoquery options (RhBug:1667898,1656801)
|
||||||
|
|
||||||
|
It allows with repoquery command to use --what* options multiple times
|
||||||
|
(append option) or add multiple arguments separated by comma.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1667898
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1656801
|
||||||
|
---
|
||||||
|
dnf.spec | 2 +-
|
||||||
|
dnf/cli/commands/repoquery.py | 39 +++++++++++++++++++++++++--------------
|
||||||
|
tests/test_repoquery.py | 4 ++--
|
||||||
|
3 files changed, 28 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf.spec b/dnf.spec
|
||||||
|
index bbbe954..e3002db 100644
|
||||||
|
--- a/dnf.spec
|
||||||
|
+++ b/dnf.spec
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# default dependencies
|
||||||
|
-%global hawkey_version 0.35.1
|
||||||
|
+%global hawkey_version 0.35.2
|
||||||
|
%global libcomps_version 0.1.8
|
||||||
|
%global libmodulemd_version 1.4.0
|
||||||
|
%global rpm_version 4.14.0
|
||||||
|
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
|
||||||
|
index 0e5073f..c31501f 100644
|
||||||
|
--- a/dnf/cli/commands/repoquery.py
|
||||||
|
+++ b/dnf/cli/commands/repoquery.py
|
||||||
|
@@ -126,24 +126,33 @@ class RepoQueryCommand(commands.Command):
|
||||||
|
help=_('show only results from this ARCH'))
|
||||||
|
parser.add_argument('-f', '--file', metavar='FILE', nargs='+',
|
||||||
|
help=_('show only results that owns FILE'))
|
||||||
|
- parser.add_argument('--whatconflicts', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatconflicts', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that conflict REQ'))
|
||||||
|
- parser.add_argument('--whatdepends', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatdepends', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('shows results that requires, suggests, supplements, enhances,'
|
||||||
|
'or recommends package provides and files REQ'))
|
||||||
|
- parser.add_argument('--whatobsoletes', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatobsoletes', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that obsolete REQ'))
|
||||||
|
- parser.add_argument('--whatprovides', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatprovides', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that provide REQ'))
|
||||||
|
- parser.add_argument('--whatrequires', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatrequires', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('shows results that requires package provides and files REQ'))
|
||||||
|
- parser.add_argument('--whatrecommends', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatrecommends', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that recommend REQ'))
|
||||||
|
- parser.add_argument('--whatenhances', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatenhances', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that enhance REQ'))
|
||||||
|
- parser.add_argument('--whatsuggests', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatsuggests', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that suggest REQ'))
|
||||||
|
- parser.add_argument('--whatsupplements', metavar='REQ',
|
||||||
|
+ parser.add_argument('--whatsupplements', default=[], action=OptionParser._SplitCallback,
|
||||||
|
+ metavar='REQ',
|
||||||
|
help=_('show only results that supplement REQ'))
|
||||||
|
whatrequiresform = parser.add_mutually_exclusive_group()
|
||||||
|
whatrequiresform.add_argument("--alldeps", action="store_true",
|
||||||
|
@@ -354,10 +363,12 @@ class RepoQueryCommand(commands.Command):
|
||||||
|
return t.union(done)
|
||||||
|
|
||||||
|
def by_all_deps(self, requires_name, depends_name, query):
|
||||||
|
- name = requires_name or depends_name
|
||||||
|
- defaultquery = query.intersection(dnf.subject.Subject(name).get_best_query(
|
||||||
|
- self.base.sack, with_provides=False, with_filenames=False))
|
||||||
|
- requiresquery = query.filter(requires__glob=name)
|
||||||
|
+ names = requires_name or depends_name
|
||||||
|
+ defaultquery = self.base.sack.query().filter(empty=True)
|
||||||
|
+ for name in names:
|
||||||
|
+ defaultquery.union(query.intersection(dnf.subject.Subject(name).get_best_query(
|
||||||
|
+ self.base.sack, with_provides=False, with_filenames=False)))
|
||||||
|
+ requiresquery = query.filter(requires__glob=names)
|
||||||
|
if depends_name:
|
||||||
|
requiresquery = requiresquery.union(query.filter(recommends__glob=depends_name))
|
||||||
|
requiresquery = requiresquery.union(query.filter(enhances__glob=depends_name))
|
||||||
|
@@ -446,7 +457,7 @@ class RepoQueryCommand(commands.Command):
|
||||||
|
if self.opts.whatobsoletes:
|
||||||
|
q.filterm(obsoletes=self.opts.whatobsoletes)
|
||||||
|
if self.opts.whatprovides:
|
||||||
|
- query_for_provide = q.filter(provides__glob=[self.opts.whatprovides])
|
||||||
|
+ query_for_provide = q.filter(provides__glob=self.opts.whatprovides)
|
||||||
|
if query_for_provide:
|
||||||
|
q = query_for_provide
|
||||||
|
else:
|
||||||
|
diff --git a/tests/test_repoquery.py b/tests/test_repoquery.py
|
||||||
|
index 9e6cc7d..9182537 100644
|
||||||
|
--- a/tests/test_repoquery.py
|
||||||
|
+++ b/tests/test_repoquery.py
|
||||||
|
@@ -78,8 +78,8 @@ class ArgParseTest(tests.support.TestCase):
|
||||||
|
|
||||||
|
def test_parse(self):
|
||||||
|
tests.support.command_configure(self.cmd, ['--whatrequires', 'prudence'])
|
||||||
|
- self.assertIsNone(self.cmd.opts.whatprovides)
|
||||||
|
- self.assertEqual(self.cmd.opts.whatrequires, 'prudence')
|
||||||
|
+ self.assertEqual(self.cmd.opts.whatprovides, [])
|
||||||
|
+ self.assertEqual(self.cmd.opts.whatrequires, ['prudence'])
|
||||||
|
self.assertEqual(self.cmd.opts.queryformat,
|
||||||
|
dnf.cli.commands.repoquery.QFORMAT_DEFAULT)
|
||||||
|
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,99 @@
|
|||||||
|
From d53492bea1ed9c08710af75c54abea9a69f82757 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Wed, 19 Jun 2019 12:42:31 +0200
|
||||||
|
Subject: [PATCH] Prevent switching modules in all cases (RhBug:1706215)
|
||||||
|
|
||||||
|
The test moved into cli/do_transaction() allows to apply the restriction
|
||||||
|
for all commands.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1706215
|
||||||
|
---
|
||||||
|
dnf/cli/cli.py | 16 ++++++++++++++++
|
||||||
|
dnf/cli/commands/module.py | 23 -----------------------
|
||||||
|
2 files changed, 16 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
|
||||||
|
index 09642d1..6ac18fa 100644
|
||||||
|
--- a/dnf/cli/cli.py
|
||||||
|
+++ b/dnf/cli/cli.py
|
||||||
|
@@ -142,6 +142,13 @@ def print_versions(pkgs, base, output):
|
||||||
|
# sm_ui_date(pkg.committime)))
|
||||||
|
|
||||||
|
|
||||||
|
+def report_module_switch(switchedModules):
|
||||||
|
+ msg1 = _("The operation would result in switching of module '{0}' stream '{1}' to "
|
||||||
|
+ "stream '{2}'")
|
||||||
|
+ for moduleName, streams in switchedModules.items():
|
||||||
|
+ logger.warning(msg1.format(moduleName, streams[0], streams[1]))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
class BaseCli(dnf.Base):
|
||||||
|
"""This is the base class for yum cli."""
|
||||||
|
|
||||||
|
@@ -157,6 +164,15 @@ class BaseCli(dnf.Base):
|
||||||
|
:param display: `rpm.callback.TransactionProgress` object(s)
|
||||||
|
:return: history database transaction ID or None
|
||||||
|
"""
|
||||||
|
+ if dnf.base.WITH_MODULES:
|
||||||
|
+ switchedModules = dict(self._moduleContainer.getSwitchedStreams())
|
||||||
|
+ if switchedModules:
|
||||||
|
+ report_module_switch(switchedModules)
|
||||||
|
+ msg = _("It is not possible to switch enabled streams of a module.\n"
|
||||||
|
+ "It is recommended to remove all installed content from the module, and "
|
||||||
|
+ "reset the module using 'dnf module reset <module_name>' command. After "
|
||||||
|
+ "you reset the module, you can install the other stream.")
|
||||||
|
+ raise dnf.exceptions.Error(msg)
|
||||||
|
|
||||||
|
trans = self.transaction
|
||||||
|
pkg_str = self.output.list_transaction(trans)
|
||||||
|
diff --git a/dnf/cli/commands/module.py b/dnf/cli/commands/module.py
|
||||||
|
index 143bfaa..acaa42c 100644
|
||||||
|
--- a/dnf/cli/commands/module.py
|
||||||
|
+++ b/dnf/cli/commands/module.py
|
||||||
|
@@ -32,13 +32,6 @@ import dnf.module.module_base
|
||||||
|
import dnf.exceptions
|
||||||
|
|
||||||
|
|
||||||
|
-def report_module_switch(switchedModules):
|
||||||
|
- msg1 = _("The operation would result in switching of module '{0}' stream '{1}' to "
|
||||||
|
- "stream '{2}'")
|
||||||
|
- for moduleName, streams in switchedModules.items():
|
||||||
|
- logger.warning(msg1.format(moduleName, streams[0], streams[1]))
|
||||||
|
-
|
||||||
|
-
|
||||||
|
class ModuleCommand(commands.Command):
|
||||||
|
class SubCommand(commands.Command):
|
||||||
|
|
||||||
|
@@ -122,14 +115,6 @@ class ModuleCommand(commands.Command):
|
||||||
|
libdnf.module.ModulePackageContainer.ModuleErrorType_ERROR_IN_DEFAULTS:
|
||||||
|
raise e
|
||||||
|
logger.error(str(e))
|
||||||
|
- switchedModules = dict(self.base._moduleContainer.getSwitchedStreams())
|
||||||
|
- if switchedModules:
|
||||||
|
- report_module_switch(switchedModules)
|
||||||
|
- msg = _("It is not possible to switch enabled streams of a module.\n"
|
||||||
|
- "It is recommended to remove all installed content from the module, and "
|
||||||
|
- "reset the module using 'dnf module reset <module_name>' command. After "
|
||||||
|
- "you reset the module, you can enable the other stream.")
|
||||||
|
- raise dnf.exceptions.Error(msg)
|
||||||
|
|
||||||
|
class DisableSubCommand(SubCommand):
|
||||||
|
|
||||||
|
@@ -193,14 +178,6 @@ class ModuleCommand(commands.Command):
|
||||||
|
if e.no_match_group_specs or e.error_group_specs:
|
||||||
|
raise e
|
||||||
|
logger.error(str(e))
|
||||||
|
- switchedModules = dict(self.base._moduleContainer.getSwitchedStreams())
|
||||||
|
- if switchedModules:
|
||||||
|
- report_module_switch(switchedModules)
|
||||||
|
- msg = _("It is not possible to switch enabled streams of a module.\n"
|
||||||
|
- "It is recommended to remove all installed content from the module, and "
|
||||||
|
- "reset the module using 'dnf module reset <module_name>' command. After "
|
||||||
|
- "you reset the module, you can install the other stream.")
|
||||||
|
- raise dnf.exceptions.Error(msg)
|
||||||
|
|
||||||
|
class UpdateSubCommand(SubCommand):
|
||||||
|
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,435 @@
|
|||||||
|
From f6ffdce83004acdb2325d966ad348dfe63fb55f8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Mon, 3 Jun 2019 19:26:55 +0200
|
||||||
|
Subject: [PATCH 1/5] [transaction] Set an error for first tsi in unknown state
|
||||||
|
(RhBug:1737328)
|
||||||
|
|
||||||
|
It should prevent "TransactionItem state is not set" in case of multiple
|
||||||
|
same NEVRASs and single with an error.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1737328
|
||||||
|
---
|
||||||
|
dnf/yum/rpmtrans.py | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/yum/rpmtrans.py b/dnf/yum/rpmtrans.py
|
||||||
|
index 6a60b5a08..50d8b81cb 100644
|
||||||
|
--- a/dnf/yum/rpmtrans.py
|
||||||
|
+++ b/dnf/yum/rpmtrans.py
|
||||||
|
@@ -386,6 +386,10 @@ class RPMTransaction(object):
|
||||||
|
msg = "Error unpacking rpm package %s" % tsi.pkg
|
||||||
|
for display in self.displays:
|
||||||
|
display.error(msg)
|
||||||
|
+ for tsi1 in transaction_list:
|
||||||
|
+ if tsi1.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
+ tsi1.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
+ return
|
||||||
|
tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
|
||||||
|
def _scriptError(self, amount, total, key):
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From c07beb11b8f085a4ced74502c70d48b4db4e4099 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Mach <dmach@redhat.com>
|
||||||
|
Date: Wed, 5 Jun 2019 08:29:03 +0200
|
||||||
|
Subject: [PATCH 2/5] [history] Don't store failed transactions as succeeded.
|
||||||
|
(RhBug:1737328)
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/base.py | 7 ++++---
|
||||||
|
dnf/db/history.py | 16 ++++++++++------
|
||||||
|
2 files changed, 14 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index 7a388ecf4..add64036b 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -987,7 +987,7 @@ class Base(object):
|
||||||
|
# particular element failed and if not, decide that is the
|
||||||
|
# case.
|
||||||
|
failed = [el for el in self._ts if el.Failed()]
|
||||||
|
- if len(failed) > 0:
|
||||||
|
+ if failed:
|
||||||
|
for te in failed:
|
||||||
|
te_nevra = dnf.util._te_nevra(te)
|
||||||
|
for tsi in self._transaction:
|
||||||
|
@@ -996,6 +996,7 @@ class Base(object):
|
||||||
|
|
||||||
|
errstring = _('Errors occurred during transaction.')
|
||||||
|
logger.debug(errstring)
|
||||||
|
+ self.history.end(rpmdbv)
|
||||||
|
else:
|
||||||
|
login = dnf.util.get_effective_login()
|
||||||
|
msg = _("Failed to obtain the transaction lock "
|
||||||
|
@@ -1006,7 +1007,7 @@ class Base(object):
|
||||||
|
else:
|
||||||
|
if self._record_history():
|
||||||
|
herrors = [ucd(x) for x in errors]
|
||||||
|
- self.history.end(rpmdbv, 2, errors=herrors)
|
||||||
|
+ self.history.end(rpmdbv)
|
||||||
|
|
||||||
|
logger.critical(_("Transaction couldn't start:"))
|
||||||
|
for e in errors:
|
||||||
|
@@ -1069,7 +1070,7 @@ class Base(object):
|
||||||
|
count = display_banner(tsi.pkg, count)
|
||||||
|
|
||||||
|
rpmdbv = rpmdb_sack._rpmdb_version()
|
||||||
|
- self.history.end(rpmdbv, 0)
|
||||||
|
+ self.history.end(rpmdbv)
|
||||||
|
|
||||||
|
timer()
|
||||||
|
self._trans_success = True
|
||||||
|
diff --git a/dnf/db/history.py b/dnf/db/history.py
|
||||||
|
index dc9c53b70..7f22f97c1 100644
|
||||||
|
--- a/dnf/db/history.py
|
||||||
|
+++ b/dnf/db/history.py
|
||||||
|
@@ -486,14 +486,18 @@ class SwdbInterface(object):
|
||||||
|
self.swdb.log_error(self._tid, error)
|
||||||
|
'''
|
||||||
|
|
||||||
|
- # TODO: rename to end_transaction?
|
||||||
|
- def end(self, end_rpmdb_version="", return_code=0, errors=None):
|
||||||
|
- assert return_code or not errors
|
||||||
|
- # TODO: fix return_code
|
||||||
|
- return_code = not bool(return_code)
|
||||||
|
+ def end(self, end_rpmdb_version="", return_code=None, errors=None):
|
||||||
|
if not hasattr(self, '_tid'):
|
||||||
|
return # Failed at beg() time
|
||||||
|
|
||||||
|
+ if return_code is None:
|
||||||
|
+ # return_code/state auto-detection
|
||||||
|
+ return_code = libdnf.transaction.TransactionState_DONE
|
||||||
|
+ for tsi in self.rpm:
|
||||||
|
+ if tsi.state == libdnf.transaction.TransactionItemState_ERROR:
|
||||||
|
+ return_code = libdnf.transaction.TransactionState_ERROR
|
||||||
|
+ break
|
||||||
|
+
|
||||||
|
for file_descriptor, line in self._output:
|
||||||
|
self.swdb.addConsoleOutputLine(file_descriptor, line)
|
||||||
|
self._output = []
|
||||||
|
@@ -501,7 +505,7 @@ class SwdbInterface(object):
|
||||||
|
self.swdb.endTransaction(
|
||||||
|
int(time.time()),
|
||||||
|
str(end_rpmdb_version),
|
||||||
|
- bool(return_code)
|
||||||
|
+ return_code,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Closing and cleanup is done in the close() method.
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 5302f0fbf977e6447b5a00adabb34b1c01fe7e55 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Mach <dmach@redhat.com>
|
||||||
|
Date: Wed, 5 Jun 2019 21:10:05 +0200
|
||||||
|
Subject: [PATCH 3/5] [transaction] Add RPMCALLBACK_INST_{START,STOP} callback
|
||||||
|
handlers. (RhBug:1737328)
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/yum/rpmtrans.py | 23 ++++++++++++++++++-----
|
||||||
|
1 file changed, 18 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/yum/rpmtrans.py b/dnf/yum/rpmtrans.py
|
||||||
|
index 50d8b81cb..0834a8c82 100644
|
||||||
|
--- a/dnf/yum/rpmtrans.py
|
||||||
|
+++ b/dnf/yum/rpmtrans.py
|
||||||
|
@@ -262,6 +262,10 @@ class RPMTransaction(object):
|
||||||
|
return self._instOpenFile(key)
|
||||||
|
elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
|
||||||
|
self._instCloseFile(key)
|
||||||
|
+ elif what == rpm.RPMCALLBACK_INST_START:
|
||||||
|
+ self._inst_start(key)
|
||||||
|
+ elif what == rpm.RPMCALLBACK_INST_STOP:
|
||||||
|
+ self._inst_stop(key)
|
||||||
|
elif what == rpm.RPMCALLBACK_INST_PROGRESS:
|
||||||
|
self._instProgress(amount, total, key)
|
||||||
|
elif what == rpm.RPMCALLBACK_UNINST_START:
|
||||||
|
@@ -321,12 +325,17 @@ class RPMTransaction(object):
|
||||||
|
return self.fd.fileno()
|
||||||
|
|
||||||
|
def _instCloseFile(self, key):
|
||||||
|
- transaction_list = self._extract_cbkey(key)
|
||||||
|
self.fd.close()
|
||||||
|
self.fd = None
|
||||||
|
|
||||||
|
+ def _inst_start(self, key):
|
||||||
|
+ pass
|
||||||
|
+
|
||||||
|
+ def _inst_stop(self, key):
|
||||||
|
if self.test or not self.trans_running:
|
||||||
|
return
|
||||||
|
+
|
||||||
|
+ transaction_list = self._extract_cbkey(key)
|
||||||
|
for tsi in transaction_list:
|
||||||
|
if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
tsi.state = libdnf.transaction.TransactionItemState_DONE
|
||||||
|
@@ -376,6 +385,10 @@ class RPMTransaction(object):
|
||||||
|
|
||||||
|
def _cpioError(self, key):
|
||||||
|
transaction_list = self._extract_cbkey(key)
|
||||||
|
+ for tsi in transaction_list:
|
||||||
|
+ if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
+ tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
+ break
|
||||||
|
msg = "Error in cpio payload of rpm package %s" % transaction_list[0].pkg
|
||||||
|
for display in self.displays:
|
||||||
|
display.error(msg)
|
||||||
|
@@ -386,11 +399,11 @@ class RPMTransaction(object):
|
||||||
|
msg = "Error unpacking rpm package %s" % tsi.pkg
|
||||||
|
for display in self.displays:
|
||||||
|
display.error(msg)
|
||||||
|
- for tsi1 in transaction_list:
|
||||||
|
- if tsi1.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
- tsi1.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
+
|
||||||
|
+ for tsi in transaction_list:
|
||||||
|
+ if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
+ tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
return
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
|
||||||
|
def _scriptError(self, amount, total, key):
|
||||||
|
# "amount" carries the failed scriptlet tag,
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From a3cc8343ff418cca386a0a11f331ebe08e70bae6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Thu, 13 Jun 2019 12:02:07 +0200
|
||||||
|
Subject: [PATCH 4/5] Change synchronization of rpm transaction to swdb
|
||||||
|
(RhBug:1737328)
|
||||||
|
|
||||||
|
Originally the state of transaction element was changed by callbacks,
|
||||||
|
but this approach cannot ensure that all elements will be marked
|
||||||
|
correctly in case of error when rpm could skip some of elements.
|
||||||
|
|
||||||
|
The new approach only synchronize the states of all elements in
|
||||||
|
transaction after transaction is finished.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1737328
|
||||||
|
---
|
||||||
|
dnf/base.py | 21 +++++----------------
|
||||||
|
dnf/util.py | 36 ++++++++++++++++++++++++++++++++++++
|
||||||
|
dnf/yum/rpmtrans.py | 22 +++-------------------
|
||||||
|
3 files changed, 44 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index add64036b..237ad397d 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -978,6 +978,7 @@ class Base(object):
|
||||||
|
os.nice(onice)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
+ dnf.util._sync_rpm_trans_with_swdb(self._ts, self._transaction)
|
||||||
|
|
||||||
|
if errors is None:
|
||||||
|
pass
|
||||||
|
@@ -987,17 +988,7 @@ class Base(object):
|
||||||
|
# particular element failed and if not, decide that is the
|
||||||
|
# case.
|
||||||
|
failed = [el for el in self._ts if el.Failed()]
|
||||||
|
- if failed:
|
||||||
|
- for te in failed:
|
||||||
|
- te_nevra = dnf.util._te_nevra(te)
|
||||||
|
- for tsi in self._transaction:
|
||||||
|
- if str(tsi) == te_nevra:
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
-
|
||||||
|
- errstring = _('Errors occurred during transaction.')
|
||||||
|
- logger.debug(errstring)
|
||||||
|
- self.history.end(rpmdbv)
|
||||||
|
- else:
|
||||||
|
+ if not failed:
|
||||||
|
login = dnf.util.get_effective_login()
|
||||||
|
msg = _("Failed to obtain the transaction lock "
|
||||||
|
"(logged in as: %s).")
|
||||||
|
@@ -1005,13 +996,11 @@ class Base(object):
|
||||||
|
msg = _('Could not run transaction.')
|
||||||
|
raise dnf.exceptions.Error(msg)
|
||||||
|
else:
|
||||||
|
- if self._record_history():
|
||||||
|
- herrors = [ucd(x) for x in errors]
|
||||||
|
- self.history.end(rpmdbv)
|
||||||
|
-
|
||||||
|
logger.critical(_("Transaction couldn't start:"))
|
||||||
|
for e in errors:
|
||||||
|
- logger.critical(e[0]) # should this be 'to_unicoded'?
|
||||||
|
+ logger.critical(ucd(e[0]))
|
||||||
|
+ if self._record_history() and not self._ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST):
|
||||||
|
+ self.history.end(rpmdbv)
|
||||||
|
msg = _("Could not run transaction.")
|
||||||
|
raise dnf.exceptions.Error(msg)
|
||||||
|
|
||||||
|
diff --git a/dnf/util.py b/dnf/util.py
|
||||||
|
index 2f1abe626..9d0288e5a 100644
|
||||||
|
--- a/dnf/util.py
|
||||||
|
+++ b/dnf/util.py
|
||||||
|
@@ -396,6 +396,42 @@ def _te_nevra(te):
|
||||||
|
return nevra + te.V() + '-' + te.R() + '.' + te.A()
|
||||||
|
|
||||||
|
|
||||||
|
+def _sync_rpm_trans_with_swdb(rpm_transaction, swdb_transaction):
|
||||||
|
+ revert_actions = {libdnf.transaction.TransactionItemAction_DOWNGRADED,
|
||||||
|
+ libdnf.transaction.TransactionItemAction_OBSOLETED,
|
||||||
|
+ libdnf.transaction.TransactionItemAction_REMOVE,
|
||||||
|
+ libdnf.transaction.TransactionItemAction_UPGRADED,
|
||||||
|
+ libdnf.transaction.TransactionItemAction_REINSTALLED}
|
||||||
|
+ cached_tsi = [tsi for tsi in swdb_transaction]
|
||||||
|
+ el_not_found = False
|
||||||
|
+ error = False
|
||||||
|
+ for rpm_el in rpm_transaction:
|
||||||
|
+ te_nevra = _te_nevra(rpm_el)
|
||||||
|
+ tsi = rpm_el.Key()
|
||||||
|
+ if tsi is None or not hasattr(tsi, "pkg"):
|
||||||
|
+ for tsi_candidate in cached_tsi:
|
||||||
|
+ if tsi_candidate.state != libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
+ continue
|
||||||
|
+ if tsi_candidate.action not in revert_actions:
|
||||||
|
+ continue
|
||||||
|
+ if str(tsi_candidate) == te_nevra:
|
||||||
|
+ tsi = tsi_candidate
|
||||||
|
+ break
|
||||||
|
+ if tsi is None or not hasattr(tsi, "pkg"):
|
||||||
|
+ logger.critical(_("TransactionItem not found for key: {}").format(te_nevra))
|
||||||
|
+ el_not_found = True
|
||||||
|
+ continue
|
||||||
|
+ if rpm_el.Failed():
|
||||||
|
+ tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
+ error = True
|
||||||
|
+ else:
|
||||||
|
+ tsi.state = libdnf.transaction.TransactionItemState_DONE
|
||||||
|
+ if error:
|
||||||
|
+ logger.debug(_('Errors occurred during transaction.'))
|
||||||
|
+
|
||||||
|
+ return el_not_found
|
||||||
|
+
|
||||||
|
+
|
||||||
|
class tmpdir(object):
|
||||||
|
def __init__(self):
|
||||||
|
prefix = '%s-' % dnf.const.PREFIX
|
||||||
|
diff --git a/dnf/yum/rpmtrans.py b/dnf/yum/rpmtrans.py
|
||||||
|
index 0834a8c82..8a5bd4731 100644
|
||||||
|
--- a/dnf/yum/rpmtrans.py
|
||||||
|
+++ b/dnf/yum/rpmtrans.py
|
||||||
|
@@ -336,10 +336,7 @@ class RPMTransaction(object):
|
||||||
|
return
|
||||||
|
|
||||||
|
transaction_list = self._extract_cbkey(key)
|
||||||
|
- for tsi in transaction_list:
|
||||||
|
- if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_DONE
|
||||||
|
- break
|
||||||
|
+ tsi = transaction_list[0]
|
||||||
|
|
||||||
|
for display in self.displays:
|
||||||
|
display.filelog(tsi.pkg, tsi.action)
|
||||||
|
@@ -370,10 +367,7 @@ class RPMTransaction(object):
|
||||||
|
|
||||||
|
def _unInstStop(self, key):
|
||||||
|
transaction_list = self._extract_cbkey(key)
|
||||||
|
- for tsi in transaction_list:
|
||||||
|
- if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_DONE
|
||||||
|
- break
|
||||||
|
+ tsi = transaction_list[0]
|
||||||
|
|
||||||
|
for display in self.displays:
|
||||||
|
display.filelog(tsi.pkg, tsi.action)
|
||||||
|
@@ -385,26 +379,16 @@ class RPMTransaction(object):
|
||||||
|
|
||||||
|
def _cpioError(self, key):
|
||||||
|
transaction_list = self._extract_cbkey(key)
|
||||||
|
- for tsi in transaction_list:
|
||||||
|
- if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
- break
|
||||||
|
msg = "Error in cpio payload of rpm package %s" % transaction_list[0].pkg
|
||||||
|
for display in self.displays:
|
||||||
|
display.error(msg)
|
||||||
|
|
||||||
|
def _unpackError(self, key):
|
||||||
|
transaction_list = self._extract_cbkey(key)
|
||||||
|
- tsi = transaction_list[0]
|
||||||
|
- msg = "Error unpacking rpm package %s" % tsi.pkg
|
||||||
|
+ msg = "Error unpacking rpm package %s" % transaction_list[0].pkg
|
||||||
|
for display in self.displays:
|
||||||
|
display.error(msg)
|
||||||
|
|
||||||
|
- for tsi in transaction_list:
|
||||||
|
- if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
- tsi.state = libdnf.transaction.TransactionItemState_ERROR
|
||||||
|
- return
|
||||||
|
-
|
||||||
|
def _scriptError(self, amount, total, key):
|
||||||
|
# "amount" carries the failed scriptlet tag,
|
||||||
|
# "total" carries fatal/non-fatal status
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 91aa07fe7b7f01727f2eb5d231fdeb16bd82a872 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 25 Jun 2019 11:44:37 +0200
|
||||||
|
Subject: [PATCH 5/5] Add detailed debug login for swdb/rpm transaction
|
||||||
|
(RhBug:1737328)
|
||||||
|
|
||||||
|
The logging is required to investigate the issue with tsi.state unknown.
|
||||||
|
The logging will be triggered only when transaction element
|
||||||
|
synchronization failed.
|
||||||
|
---
|
||||||
|
dnf/util.py | 25 +++++++++++++++++++++++--
|
||||||
|
1 file changed, 23 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/util.py b/dnf/util.py
|
||||||
|
index 9d0288e5a..71f61ab52 100644
|
||||||
|
--- a/dnf/util.py
|
||||||
|
+++ b/dnf/util.py
|
||||||
|
@@ -396,6 +396,23 @@ def _te_nevra(te):
|
||||||
|
return nevra + te.V() + '-' + te.R() + '.' + te.A()
|
||||||
|
|
||||||
|
|
||||||
|
+def _log_rpm_trans_with_swdb(rpm_transaction, swdb_transaction):
|
||||||
|
+ logger.debug("Logging transaction elements")
|
||||||
|
+ for rpm_el in rpm_transaction:
|
||||||
|
+ tsi = rpm_el.Key()
|
||||||
|
+ tsi_state = None
|
||||||
|
+ if tsi is not None:
|
||||||
|
+ tsi_state = tsi.state
|
||||||
|
+ msg = "RPM element: '{}', Key(): '{}', Key state: '{}', Failed() '{}': ".format(
|
||||||
|
+ _te_nevra(rpm_el), tsi, tsi_state, rpm_el.Failed())
|
||||||
|
+ logger.debug(msg)
|
||||||
|
+ for tsi in swdb_transaction:
|
||||||
|
+ msg = "SWDB element: '{}', State: '{}', Action: '{}', From repo: '{}', Reason: '{}', " \
|
||||||
|
+ "Get reason: '{}'".format(str(tsi), tsi.state, tsi.action, tsi.from_repo, tsi.reason,
|
||||||
|
+ tsi.get_reason())
|
||||||
|
+ logger.debug(msg)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def _sync_rpm_trans_with_swdb(rpm_transaction, swdb_transaction):
|
||||||
|
revert_actions = {libdnf.transaction.TransactionItemAction_DOWNGRADED,
|
||||||
|
libdnf.transaction.TransactionItemAction_OBSOLETED,
|
||||||
|
@@ -426,10 +443,14 @@ def _sync_rpm_trans_with_swdb(rpm_transaction, swdb_transaction):
|
||||||
|
error = True
|
||||||
|
else:
|
||||||
|
tsi.state = libdnf.transaction.TransactionItemState_DONE
|
||||||
|
+ for tsi in cached_tsi:
|
||||||
|
+ if tsi.state == libdnf.transaction.TransactionItemState_UNKNOWN:
|
||||||
|
+ logger.critical(_("TransactionSWDBItem not found for key: {}").format(str(tsi)))
|
||||||
|
+ el_not_found = True
|
||||||
|
if error:
|
||||||
|
logger.debug(_('Errors occurred during transaction.'))
|
||||||
|
-
|
||||||
|
- return el_not_found
|
||||||
|
+ if el_not_found:
|
||||||
|
+ _log_rpm_trans_with_swdb(rpm_transaction, cached_tsi)
|
||||||
|
|
||||||
|
|
||||||
|
class tmpdir(object):
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
From 6a6ab3e12b4fe0f3fc402a6b99932640fabccc32 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Wed, 3 Jul 2019 10:49:20 +0200
|
||||||
|
Subject: [PATCH 1/2] Method to get catched rpm errors from RPMTransaction
|
||||||
|
(RhBug:1677199)
|
||||||
|
|
||||||
|
This method enables iterating through messages logged by underlaying
|
||||||
|
rpm. The messages could be then logged by dnf, printed to user...
|
||||||
|
---
|
||||||
|
dnf/yum/rpmtrans.py | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/yum/rpmtrans.py b/dnf/yum/rpmtrans.py
|
||||||
|
index 8a5bd4731..b0fd9b6eb 100644
|
||||||
|
--- a/dnf/yum/rpmtrans.py
|
||||||
|
+++ b/dnf/yum/rpmtrans.py
|
||||||
|
@@ -210,6 +210,12 @@ class RPMTransaction(object):
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
+ def messages(self):
|
||||||
|
+ messages = self._scriptOutput()
|
||||||
|
+ if messages:
|
||||||
|
+ for line in messages.splitlines():
|
||||||
|
+ yield ucd(line)
|
||||||
|
+
|
||||||
|
def _scriptout(self):
|
||||||
|
msgs = self._scriptOutput()
|
||||||
|
for display in self.displays:
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 61e0b7c553fe0c04dfeb3b6d4c16fa36e4eb26f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Wed, 3 Jul 2019 10:54:42 +0200
|
||||||
|
Subject: [PATCH 2/2] Print rpm error messages during transaction
|
||||||
|
(RhBug:1677199)
|
||||||
|
|
||||||
|
This patch lets the rpm error messages to be passed on to the user.
|
||||||
|
Original code basically considered all rpm errors as "Failed to obtain
|
||||||
|
the transaction lock", which is obviously not always the case. Now dnf
|
||||||
|
prints out original rpm messages so that user could find out what the
|
||||||
|
real problem is.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1677199
|
||||||
|
---
|
||||||
|
dnf/base.py | 16 ++++++++--------
|
||||||
|
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index 237ad397d..2c5d17e8b 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -983,16 +983,16 @@ class Base(object):
|
||||||
|
if errors is None:
|
||||||
|
pass
|
||||||
|
elif len(errors) == 0:
|
||||||
|
- # this is a particularly tricky case happening also when rpm failed
|
||||||
|
- # to obtain the transaction lock. We can only try to see if a
|
||||||
|
- # particular element failed and if not, decide that is the
|
||||||
|
- # case.
|
||||||
|
+ # If there is no failing element it means that some "global" error
|
||||||
|
+ # occured (like rpm failed to obtain the transaction lock). Just pass
|
||||||
|
+ # the rpm logs on to the user and raise an Error.
|
||||||
|
+ # If there are failing elements the problem is related to those
|
||||||
|
+ # elements and the Error is raised later, after saving the failure
|
||||||
|
+ # to the history and printing out the transaction table to user.
|
||||||
|
failed = [el for el in self._ts if el.Failed()]
|
||||||
|
if not failed:
|
||||||
|
- login = dnf.util.get_effective_login()
|
||||||
|
- msg = _("Failed to obtain the transaction lock "
|
||||||
|
- "(logged in as: %s).")
|
||||||
|
- logger.critical(msg, login)
|
||||||
|
+ for msg in cb.messages():
|
||||||
|
+ logger.critical(_('RPM: {}').format(msg))
|
||||||
|
msg = _('Could not run transaction.')
|
||||||
|
raise dnf.exceptions.Error(msg)
|
||||||
|
else:
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@ -0,0 +1,93 @@
|
|||||||
|
From 4662a3d342de4be584812267c5b59ed9c1f9c44e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 25 Jun 2019 18:54:54 +0200
|
||||||
|
Subject: [PATCH] Report missing default profile as an error (RhBug:1669527,1724564)
|
||||||
|
|
||||||
|
The behavior where module install command doesn't install any package
|
||||||
|
when there are no default profiles was recognized by users as an
|
||||||
|
unexpected behavior.
|
||||||
|
|
||||||
|
The patch allows DNF to fail when no default profile is available.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1669527
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1724564
|
||||||
|
---
|
||||||
|
dnf/module/module_base.py | 27 +++++++++++++++++++++++----
|
||||||
|
tests/test_modules.py | 12 ++----------
|
||||||
|
2 files changed, 25 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/module/module_base.py b/dnf/module/module_base.py
|
||||||
|
index 83e5e4a..ea56ad0 100644
|
||||||
|
--- a/dnf/module/module_base.py
|
||||||
|
+++ b/dnf/module/module_base.py
|
||||||
|
@@ -83,21 +83,40 @@ class ModuleBase(object):
|
||||||
|
if nsvcap.profile:
|
||||||
|
profiles.extend(latest_module.getProfiles(nsvcap.profile))
|
||||||
|
if not profiles:
|
||||||
|
- logger.error(_("Unable to match profile in argument {}").format(spec))
|
||||||
|
+ available_profiles = latest_module.getProfiles()
|
||||||
|
+ if available_profiles:
|
||||||
|
+ profile_names = ", ".join(
|
||||||
|
+ [profile.getName() for profile in available_profiles])
|
||||||
|
+ msg = _("Unable to match profile for argument {}. Available "
|
||||||
|
+ "profiles for '{}:{}': {}").format(
|
||||||
|
+ spec, name, stream, profile_names)
|
||||||
|
+ else:
|
||||||
|
+ msg = _("Unable to match profile for argument {}").format(spec)
|
||||||
|
+ logger.error(msg)
|
||||||
|
no_match_specs.append(spec)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
profiles_strings = self.base._moduleContainer.getDefaultProfiles(
|
||||||
|
name, stream)
|
||||||
|
if not profiles_strings:
|
||||||
|
- logger.error(_("No default profiles for module {}:{}").format(
|
||||||
|
- name, stream))
|
||||||
|
+ available_profiles = latest_module.getProfiles()
|
||||||
|
+ if available_profiles:
|
||||||
|
+ profile_names = ", ".join(
|
||||||
|
+ [profile.getName() for profile in available_profiles])
|
||||||
|
+ msg = _("No default profiles for module {}:{}. Available profiles"
|
||||||
|
+ ": {}").format(
|
||||||
|
+ name, stream, profile_names)
|
||||||
|
+ else:
|
||||||
|
+ msg = _("No default profiles for module {}:{}").format(name, stream)
|
||||||
|
+ logger.error(msg)
|
||||||
|
+ no_match_specs.append(spec)
|
||||||
|
for profile in set(profiles_strings):
|
||||||
|
module_profiles = latest_module.getProfiles(profile)
|
||||||
|
if not module_profiles:
|
||||||
|
logger.error(
|
||||||
|
- _("Profile {} not matched for module {}:{}").format(
|
||||||
|
+ _("Default profile {} not available in module {}:{}").format(
|
||||||
|
profile, name, stream))
|
||||||
|
+ no_match_specs.append(spec)
|
||||||
|
|
||||||
|
profiles.extend(module_profiles)
|
||||||
|
for profile in profiles:
|
||||||
|
diff --git a/tests/test_modules.py b/tests/test_modules.py
|
||||||
|
index d5fde4f..49e7718 100644
|
||||||
|
--- a/tests/test_modules.py
|
||||||
|
+++ b/tests/test_modules.py
|
||||||
|
@@ -274,16 +274,8 @@ class ModuleTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_install_implicit_empty_default_profile(self):
|
||||||
|
# install module without a 'default' profile
|
||||||
|
- # -> no packages should be installed, just module enablement
|
||||||
|
- self.module_base.install(["m4:1.4.18"])
|
||||||
|
-
|
||||||
|
- self.assertEqual(self.base._moduleContainer.getModuleState("m4"),
|
||||||
|
- libdnf.module.ModulePackageContainer.ModuleState_ENABLED)
|
||||||
|
- self.assertEqual(self.base._moduleContainer.getEnabledStream("m4"), "1.4.18")
|
||||||
|
- self.assertEqual(list(self.base._moduleContainer.getInstalledProfiles("m4")), [])
|
||||||
|
-
|
||||||
|
- self.base.resolve()
|
||||||
|
- self.assertInstalls([])
|
||||||
|
+ # -> It should raise an error
|
||||||
|
+ self.assertRaises(dnf.exceptions.MarkingErrors, self.module_base.install, ["m4:1.4.18"])
|
||||||
|
|
||||||
|
# dnf module upgrade / dnf upgrade @
|
||||||
|
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From c638887211b3d9c0b3b1fcb6eb6b62f384d2c263 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Mon, 22 Jul 2019 09:29:42 +0200
|
||||||
|
Subject: [PATCH] [doc] Describe a behavior when plugin is removed (RhBug:1700741)
|
||||||
|
|
||||||
|
When plugin is removed or obsoleted all hooks of removed plugins after
|
||||||
|
transaction are skipped. The behavior was added because some
|
||||||
|
of dependencies of the plugin could be also removed and unavailable in
|
||||||
|
memory. We apply the same behavior also for obsoleted plugins, because
|
||||||
|
we suggest that obsoleting plugin could have a different code base.
|
||||||
|
|
||||||
|
The behavior is not applicable for downgrades or upgrades.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1700741
|
||||||
|
---
|
||||||
|
doc/api_plugins.rst | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/doc/api_plugins.rst b/doc/api_plugins.rst
|
||||||
|
index f5d9829..5015e42 100644
|
||||||
|
--- a/doc/api_plugins.rst
|
||||||
|
+++ b/doc/api_plugins.rst
|
||||||
|
@@ -62,6 +62,7 @@ When DNF CLI runs it loads the plugins found in the paths during the CLI's initi
|
||||||
|
.. method:: transaction
|
||||||
|
|
||||||
|
Plugin can override this. This hook is called immediately after a successful transaction.
|
||||||
|
+ Plugins that were removed or obsoleted by the transaction will not run the transaction hook.
|
||||||
|
|
||||||
|
You may want to see the comparison with `yum plugin hook API`_.
|
||||||
|
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 60a8f5e3f0500720077b200ce3be46772db4f093 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aleš Matěj <amatej@redhat.com>
|
||||||
|
Date: Mon, 24 Jun 2019 16:13:28 +0200
|
||||||
|
Subject: [PATCH] Prevent printing empty Error Summary (RhBug: 1690414)
|
||||||
|
|
||||||
|
When test transaction fails we generate Error Summary but it contains
|
||||||
|
information only if the error happened because of lacking disk space
|
||||||
|
otherwise we get the headline "Error Summary" without any text this
|
||||||
|
commit prevents this.
|
||||||
|
---
|
||||||
|
dnf/base.py | 11 +++++++++--
|
||||||
|
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index 2c5d17e..0f8b77e 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -858,8 +858,12 @@ class Base(object):
|
||||||
|
for descr in tserrors:
|
||||||
|
errstring += ' %s\n' % ucd(descr)
|
||||||
|
|
||||||
|
- raise dnf.exceptions.Error(errstring + '\n' +
|
||||||
|
- self._trans_error_summary(errstring))
|
||||||
|
+ summary = self._trans_error_summary(errstring)
|
||||||
|
+ if summary:
|
||||||
|
+ errstring += '\n' + summary
|
||||||
|
+
|
||||||
|
+ raise dnf.exceptions.Error(errstring)
|
||||||
|
+
|
||||||
|
|
||||||
|
logger.info(_('Transaction test succeeded.'))
|
||||||
|
timer()
|
||||||
|
@@ -911,6 +915,9 @@ class Base(object):
|
||||||
|
'At least %dMB more space needed on the %s filesystem.',
|
||||||
|
disk[k]) % (disk[k], k) + '\n'
|
||||||
|
|
||||||
|
+ if not summary:
|
||||||
|
+ return None
|
||||||
|
+
|
||||||
|
summary = _('Error Summary') + '\n-------------\n' + summary
|
||||||
|
|
||||||
|
return summary
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
33
SOURCES/0010-Fix---setopt-and-repo-with-dots.patch
Normal file
33
SOURCES/0010-Fix---setopt-and-repo-with-dots.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 5b83b191574d43299bb6d3212df06c6f20c818e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Rohel <jrohel@redhat.com>
|
||||||
|
Date: Wed, 28 Aug 2019 09:52:40 +0200
|
||||||
|
Subject: [PATCH] Fix: --setopt and repo with dots
|
||||||
|
|
||||||
|
The "--setopt" have had a problem with repositories with dots in id.
|
||||||
|
Repository id may contain dots but option name can't. ->
|
||||||
|
So, the last dot is delimiter and not the first one.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
"--setopt=re.po.option=value " was parsed as repo id "re" and option
|
||||||
|
"po.option". Correct result would be repo id "re.po" and option
|
||||||
|
"option".
|
||||||
|
---
|
||||||
|
dnf/cli/option_parser.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/option_parser.py b/dnf/cli/option_parser.py
|
||||||
|
index 4b6599c..76fcb95 100644
|
||||||
|
--- a/dnf/cli/option_parser.py
|
||||||
|
+++ b/dnf/cli/option_parser.py
|
||||||
|
@@ -99,7 +99,7 @@ class OptionParser(argparse.ArgumentParser):
|
||||||
|
logger.warning(_("Setopt argument has no value: %s"), values)
|
||||||
|
return
|
||||||
|
k, v = vals
|
||||||
|
- period = k.find('.')
|
||||||
|
+ period = k.rfind('.')
|
||||||
|
if period != -1:
|
||||||
|
repo = k[:period]
|
||||||
|
k = k[period+1:]
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From a5c4a994f8ad2764ca8f971c39f189d5f9d7d337 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 3 Sep 2019 11:01:51 +0200
|
||||||
|
Subject: [PATCH] Keep installed packages in upgrade job (RhBug:1728252,1644241,1741381)
|
||||||
|
|
||||||
|
In combination with marking of job as TARGETED it prevents from
|
||||||
|
reinstalling of modified packages with same NEVRA.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1728252
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1644241
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1741381
|
||||||
|
|
||||||
|
Closes: #1474
|
||||||
|
Approved by: m-blaha
|
||||||
|
---
|
||||||
|
dnf/base.py | 3 ---
|
||||||
|
dnf/module/module_base.py | 2 +-
|
||||||
|
2 files changed, 1 insertion(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index b2ced61..628c154 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -1968,9 +1968,6 @@ class Base(object):
|
||||||
|
obsoletes=q.installed().union(q.upgrades()))
|
||||||
|
# add obsoletes into transaction
|
||||||
|
q = q.union(obsoletes)
|
||||||
|
- # provide only available packages to solver otherwise selection of available
|
||||||
|
- # possibilities will be ignored
|
||||||
|
- q = q.available()
|
||||||
|
if reponame is not None:
|
||||||
|
q.filterm(reponame=reponame)
|
||||||
|
q = self._merge_update_filters(q, pkg_spec=pkg_spec)
|
||||||
|
diff --git a/dnf/module/module_base.py b/dnf/module/module_base.py
|
||||||
|
index 976d730..ce70f63 100644
|
||||||
|
--- a/dnf/module/module_base.py
|
||||||
|
+++ b/dnf/module/module_base.py
|
||||||
|
@@ -214,7 +214,7 @@ class ModuleBase(object):
|
||||||
|
|
||||||
|
if not upgrade_package_set:
|
||||||
|
logger.error(_("Unable to match profile in argument {}").format(spec))
|
||||||
|
- query = self.base.sack.query().available().filterm(name=upgrade_package_set)
|
||||||
|
+ query = self.base.sack.query().filterm(name=upgrade_package_set)
|
||||||
|
if query:
|
||||||
|
sltr = dnf.selector.Selector(self.base.sack)
|
||||||
|
sltr.set(pkg=query)
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
2483
SPECS/dnf.spec
Normal file
2483
SPECS/dnf.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user