import dnf-4.2.17-6.el8
This commit is contained in:
parent
a7216982e9
commit
4c31b89508
@ -1 +1 @@
|
|||||||
5b789329d4fc3e54190e637f1f046232681c8f5f SOURCES/dnf-4.2.7.tar.gz
|
535f46b9a5242a315e1269a59372362013a5a6f0 SOURCES/dnf-4.2.17.tar.gz
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/dnf-4.2.7.tar.gz
|
SOURCES/dnf-4.2.17.tar.gz
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
From 8bcd196fd95e70fd1f0be16d2c274e39a1cabe2e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Rohel <jrohel@redhat.com>
|
||||||
|
Date: Thu, 21 Nov 2019 11:45:03 +0100
|
||||||
|
Subject: [PATCH] Do a substitution of variables in repo_id (RhBug:1748841)
|
||||||
|
|
||||||
|
Example of repo file:
|
||||||
|
[test-$basearch-$releasever]
|
||||||
|
Name=Test-$basearch-$releasever
|
||||||
|
baseurl=file:///mnt/
|
||||||
|
gpgcheck=0
|
||||||
|
enabled=1
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1748841
|
||||||
|
---
|
||||||
|
dnf/conf/read.py | 40 +++++++++++++++++++++++++++-------------
|
||||||
|
1 file changed, 27 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/conf/read.py b/dnf/conf/read.py
|
||||||
|
index a526a71..1efac22 100644
|
||||||
|
--- a/dnf/conf/read.py
|
||||||
|
+++ b/dnf/conf/read.py
|
||||||
|
@@ -43,7 +43,7 @@ class RepoReader(object):
|
||||||
|
|
||||||
|
# read .repo files from directories specified by conf.reposdir
|
||||||
|
for repofn in (repofn for reposdir in self.conf.reposdir
|
||||||
|
- for repofn in sorted(glob.glob('%s/*.repo' % reposdir))):
|
||||||
|
+ for repofn in sorted(glob.glob('{}/*.repo'.format(reposdir)))):
|
||||||
|
try:
|
||||||
|
for r in self._get_repos(repofn):
|
||||||
|
yield r
|
||||||
|
@@ -54,17 +54,38 @@ class RepoReader(object):
|
||||||
|
def _build_repo(self, parser, id_, repofn):
|
||||||
|
"""Build a repository using the parsed data."""
|
||||||
|
|
||||||
|
- repo = dnf.repo.Repo(id_, self.conf)
|
||||||
|
+ substituted_id = libdnf.conf.ConfigParser.substitute(id_, self.conf.substitutions)
|
||||||
|
+
|
||||||
|
+ # Check the repo.id against the valid chars
|
||||||
|
+ invalid = dnf.repo.repo_id_invalid(substituted_id)
|
||||||
|
+ if invalid is not None:
|
||||||
|
+ if substituted_id != id_:
|
||||||
|
+ msg = _("Bad id for repo: {} ({}), byte = {} {}").format(substituted_id, id_,
|
||||||
|
+ substituted_id[invalid],
|
||||||
|
+ invalid)
|
||||||
|
+ else:
|
||||||
|
+ msg = _("Bad id for repo: {}, byte = {} {}").format(id_, id_[invalid], invalid)
|
||||||
|
+ raise dnf.exceptions.ConfigError(msg)
|
||||||
|
+
|
||||||
|
+ repo = dnf.repo.Repo(substituted_id, self.conf)
|
||||||
|
try:
|
||||||
|
repo._populate(parser, id_, repofn, dnf.conf.PRIO_REPOCONFIG)
|
||||||
|
except ValueError as e:
|
||||||
|
- msg = _("Repository '%s': Error parsing config: %s") % (id_, e)
|
||||||
|
+ if substituted_id != id_:
|
||||||
|
+ msg = _("Repository '{}' ({}): Error parsing config: {}").format(substituted_id,
|
||||||
|
+ id_, e)
|
||||||
|
+ else:
|
||||||
|
+ msg = _("Repository '{}': Error parsing config: {}").format(id_, e)
|
||||||
|
raise dnf.exceptions.ConfigError(msg)
|
||||||
|
|
||||||
|
# Ensure that the repo name is set
|
||||||
|
if repo._get_priority('name') == dnf.conf.PRIO_DEFAULT:
|
||||||
|
- msg = _("Repository '%s' is missing name in configuration, using id.")
|
||||||
|
- logger.warning(msg, id_)
|
||||||
|
+ if substituted_id != id_:
|
||||||
|
+ msg = _("Repository '{}' ({}) is missing name in configuration, using id.").format(
|
||||||
|
+ substituted_id, id_)
|
||||||
|
+ else:
|
||||||
|
+ msg = _("Repository '{}' is missing name in configuration, using id.").format(id_)
|
||||||
|
+ logger.warning(msg)
|
||||||
|
repo.name = ucd(repo.name)
|
||||||
|
repo._substitutions.update(self.conf.substitutions)
|
||||||
|
repo.cfg = parser
|
||||||
|
@@ -80,23 +101,16 @@ class RepoReader(object):
|
||||||
|
try:
|
||||||
|
parser.read(repofn)
|
||||||
|
except RuntimeError as e:
|
||||||
|
- raise dnf.exceptions.ConfigError(_('Parsing file "%s" failed: %s') % (repofn, e))
|
||||||
|
+ raise dnf.exceptions.ConfigError(_('Parsing file "{}" failed: {}').format(repofn, e))
|
||||||
|
except IOError as e:
|
||||||
|
logger.warning(e)
|
||||||
|
|
||||||
|
# Check sections in the .repo file that was just slurped up
|
||||||
|
for section in parser.getData():
|
||||||
|
|
||||||
|
if section == 'main':
|
||||||
|
continue
|
||||||
|
|
||||||
|
- # Check the repo.id against the valid chars
|
||||||
|
- invalid = dnf.repo.repo_id_invalid(section)
|
||||||
|
- if invalid is not None:
|
||||||
|
- logger.warning(_("Bad id for repo: %s, byte = %s %d"), section,
|
||||||
|
- section[invalid], invalid)
|
||||||
|
- continue
|
||||||
|
-
|
||||||
|
try:
|
||||||
|
thisrepo = self._build_repo(parser, ucd(section), repofn)
|
||||||
|
except (dnf.exceptions.RepoError, dnf.exceptions.ConfigError) as e:
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,67 @@
|
|||||||
|
From ba3615c600532a0ce8693a626a9cbe71a458399a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 14:48:29 +0200
|
||||||
|
Subject: [PATCH 1/2] Respect order of config files in aliases.d
|
||||||
|
(RhBug:1680489)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1680489
|
||||||
|
The aliases config files were read in arbitrary order (os.listdir does not
|
||||||
|
give sorted output). It is better to define clear order (i.e. all config files
|
||||||
|
except USER.conf are ordered alphabetically, USER.conf is the last).
|
||||||
|
|
||||||
|
Closes: #1542
|
||||||
|
Approved by: kontura
|
||||||
|
---
|
||||||
|
dnf/cli/aliases.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/aliases.py b/dnf/cli/aliases.py
|
||||||
|
index 0b3ba8f6b..b5283d0f3 100644
|
||||||
|
--- a/dnf/cli/aliases.py
|
||||||
|
+++ b/dnf/cli/aliases.py
|
||||||
|
@@ -143,7 +143,7 @@ class Aliases(object):
|
||||||
|
try:
|
||||||
|
if not os.path.exists(ALIASES_DROPIN_DIR):
|
||||||
|
os.mkdir(ALIASES_DROPIN_DIR)
|
||||||
|
- for fn in os.listdir(ALIASES_DROPIN_DIR):
|
||||||
|
+ for fn in sorted(os.listdir(ALIASES_DROPIN_DIR)):
|
||||||
|
if _ignore_filename(fn):
|
||||||
|
continue
|
||||||
|
filenames.append(os.path.join(ALIASES_DROPIN_DIR, fn))
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From e292de84fcdec844530099a6c37ef29e1a330003 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 15:04:34 +0200
|
||||||
|
Subject: [PATCH 2/2] [doc] Describe priorities of config files in aliases.d
|
||||||
|
(RhBug:1680489)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1680489
|
||||||
|
|
||||||
|
Closes: #1542
|
||||||
|
Approved by: kontura
|
||||||
|
---
|
||||||
|
doc/command_ref.rst | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
|
||||||
|
index 7141fc2aa..637ccf96b 100644
|
||||||
|
--- a/doc/command_ref.rst
|
||||||
|
+++ b/doc/command_ref.rst
|
||||||
|
@@ -424,7 +424,10 @@ for aliases. The alias processing stops when the first found command is not a na
|
||||||
|
Also, like in shell aliases, if the result starts with a ``\``, the alias processing will stop.
|
||||||
|
|
||||||
|
All aliases are defined in configuration files in the ``/etc/dnf/aliases.d/`` directory in the [aliases] section,
|
||||||
|
-and aliases created by the alias command are written to the ``USER.conf`` file.
|
||||||
|
+and aliases created by the alias command are written to the ``USER.conf`` file. In case of conflicts,
|
||||||
|
+the ``USER.conf`` has the highest priority, and alphabetical ordering is used for the rest of the
|
||||||
|
+configuration files.
|
||||||
|
+
|
||||||
|
Optionally, there is the ``enabled`` option in the ``[main]`` section defaulting to True. This can be set for each
|
||||||
|
file separately in the respective file, or globally for all aliases in the ``ALIASES.conf`` file.
|
||||||
|
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@ -1,118 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
32
SOURCES/0003-doc-Remove-note-about-whitelist.patch
Normal file
32
SOURCES/0003-doc-Remove-note-about-whitelist.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 3c473306e5e1b630a3030791fb1ef7ea0c0cd823 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Tue, 26 Nov 2019 13:22:15 +0100
|
||||||
|
Subject: [PATCH] [doc] Remove note about whitelist
|
||||||
|
|
||||||
|
The whitelist mechanism has been recently removed from libdnf.
|
||||||
|
|
||||||
|
Closes: #1543
|
||||||
|
Approved by: Conan-Kudo
|
||||||
|
---
|
||||||
|
doc/conf_ref.rst | 5 -----
|
||||||
|
1 file changed, 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
|
||||||
|
index d3ea11d..cb95e47 100644
|
||||||
|
--- a/doc/conf_ref.rst
|
||||||
|
+++ b/doc/conf_ref.rst
|
||||||
|
@@ -806,11 +806,6 @@ configuration.
|
||||||
|
|
||||||
|
libdnf (Fedora 31; server; Linux.x86_64)
|
||||||
|
|
||||||
|
- To avoid leaking identifiable data, the variant in the above string will be
|
||||||
|
- replaced by "generic" if the value is not an official Fedora variant.
|
||||||
|
- Likewise, the whole OS part (enclosed in parenthesis) will be omitted if
|
||||||
|
- this is a non-Fedora system.
|
||||||
|
-
|
||||||
|
=================
|
||||||
|
Types of Options
|
||||||
|
=================
|
||||||
|
--
|
||||||
|
libgit2 0.28.2
|
||||||
|
|
@ -0,0 +1,157 @@
|
|||||||
|
From c8d79c0b9956aeeb8cd3a0422656b030d4656578 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Mon, 9 Dec 2019 12:32:18 +0100
|
||||||
|
Subject: [PATCH 1/2] Fix detection of the latest module (RhBug:1781769)
|
||||||
|
|
||||||
|
The code originally compared module version as a string, but it should
|
||||||
|
be compared as a int.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1781769
|
||||||
|
|
||||||
|
Closes: #1548
|
||||||
|
Approved by: m-blaha
|
||||||
|
---
|
||||||
|
dnf/module/module_base.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/module/module_base.py b/dnf/module/module_base.py
|
||||||
|
index 8093ab443..64bad84b6 100644
|
||||||
|
--- a/dnf/module/module_base.py
|
||||||
|
+++ b/dnf/module/module_base.py
|
||||||
|
@@ -285,7 +285,7 @@ class ModuleBase(object):
|
||||||
|
if module_list:
|
||||||
|
latest = module_list[0]
|
||||||
|
for module in module_list[1:]:
|
||||||
|
- if module.getVersion() > latest.getVersion():
|
||||||
|
+ if module.getVersionNum() > latest.getVersionNum():
|
||||||
|
latest = module
|
||||||
|
return latest
|
||||||
|
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 44e9095404569dbf8a19726eb79be8e580bed60c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Wed, 11 Dec 2019 09:52:16 +0100
|
||||||
|
Subject: [PATCH 2/2] Improve transaction table formatting
|
||||||
|
|
||||||
|
It improves formatting of transaction table in case when terminal has
|
||||||
|
unknown width.
|
||||||
|
|
||||||
|
Closes: #1548
|
||||||
|
Approved by: m-blaha
|
||||||
|
---
|
||||||
|
dnf/cli/output.py | 45 ++++++++++++++++++++++++---------------------
|
||||||
|
1 file changed, 24 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
|
||||||
|
index a03df610c..2ff41b625 100644
|
||||||
|
--- a/dnf/cli/output.py
|
||||||
|
+++ b/dnf/cli/output.py
|
||||||
|
@@ -224,16 +224,32 @@ class Output(object):
|
||||||
|
if total_width is None:
|
||||||
|
total_width = self.term.real_columns
|
||||||
|
|
||||||
|
+ # We start allocating 1 char to everything but the last column, and a
|
||||||
|
+ # space between each (again, except for the last column). Because
|
||||||
|
+ # at worst we are better with:
|
||||||
|
+ # |one two three|
|
||||||
|
+ # | four |
|
||||||
|
+ # ...than:
|
||||||
|
+ # |one two three|
|
||||||
|
+ # | f|
|
||||||
|
+ # |our |
|
||||||
|
+ # ...the later being what we get if we pre-allocate the last column, and
|
||||||
|
+ # thus. the space, due to "three" overflowing it's column by 2 chars.
|
||||||
|
+ if columns is None:
|
||||||
|
+ columns = [1] * (cols - 1)
|
||||||
|
+ columns.append(0)
|
||||||
|
+
|
||||||
|
# i'm not able to get real terminal width so i'm probably
|
||||||
|
# running in non interactive terminal (pipe to grep, redirect to file...)
|
||||||
|
# avoid splitting lines to enable filtering output
|
||||||
|
if not total_width:
|
||||||
|
full_columns = []
|
||||||
|
- for col in data:
|
||||||
|
+ for d in xrange(0, cols):
|
||||||
|
+ col = data[d]
|
||||||
|
if col:
|
||||||
|
full_columns.append(col[-1][0])
|
||||||
|
else:
|
||||||
|
- full_columns.append(0)
|
||||||
|
+ full_columns.append(columns[d] + 1)
|
||||||
|
full_columns[0] += len(indent)
|
||||||
|
# if possible, try to keep default width (usually 80 columns)
|
||||||
|
default_width = self.term.columns
|
||||||
|
@@ -241,20 +257,6 @@ class Output(object):
|
||||||
|
return full_columns
|
||||||
|
total_width = default_width
|
||||||
|
|
||||||
|
- # We start allocating 1 char to everything but the last column, and a
|
||||||
|
- # space between each (again, except for the last column). Because
|
||||||
|
- # at worst we are better with:
|
||||||
|
- # |one two three|
|
||||||
|
- # | four |
|
||||||
|
- # ...than:
|
||||||
|
- # |one two three|
|
||||||
|
- # | f|
|
||||||
|
- # |our |
|
||||||
|
- # ...the later being what we get if we pre-allocate the last column, and
|
||||||
|
- # thus. the space, due to "three" overflowing it's column by 2 chars.
|
||||||
|
- if columns is None:
|
||||||
|
- columns = [1] * (cols - 1)
|
||||||
|
- columns.append(0)
|
||||||
|
|
||||||
|
total_width -= (sum(columns) + (cols - 1) + exact_width(indent))
|
||||||
|
if not columns[-1]:
|
||||||
|
@@ -1273,7 +1275,7 @@ class Output(object):
|
||||||
|
skip_str = skip_str % _(" or part of a group")
|
||||||
|
|
||||||
|
pkglist_lines.append((skip_str, lines))
|
||||||
|
-
|
||||||
|
+ output_width = self.term.columns
|
||||||
|
if not data['n'] and not self.base._moduleContainer.isChanged() and not \
|
||||||
|
(self.base._history and (self.base._history.group or self.base._history.env)):
|
||||||
|
return u''
|
||||||
|
@@ -1283,6 +1285,8 @@ class Output(object):
|
||||||
|
columns = self.calcColumns(data, indent=" ", columns=columns,
|
||||||
|
remainder_column=2, total_width=total_width)
|
||||||
|
(n_wid, a_wid, v_wid, r_wid, s_wid) = columns
|
||||||
|
+ real_width = sum(columns) + 5
|
||||||
|
+ output_width = output_width if output_width >= real_width else real_width
|
||||||
|
|
||||||
|
# Do not use 'Package' without context. Using context resolves
|
||||||
|
# RhBug 1302935 as a side effect.
|
||||||
|
@@ -1325,13 +1329,13 @@ class Output(object):
|
||||||
|
# Translators: This is the full (unabbreviated) term 'Size'.
|
||||||
|
C_('long', 'Size'))
|
||||||
|
|
||||||
|
- out = [u"%s\n%s\n%s\n" % ('=' * self.term.columns,
|
||||||
|
+ out = [u"%s\n%s\n%s\n" % ('=' * output_width,
|
||||||
|
self.fmtColumns(((msg_package, -n_wid),
|
||||||
|
(msg_arch, -a_wid),
|
||||||
|
(msg_version, -v_wid),
|
||||||
|
(msg_repository, -r_wid),
|
||||||
|
(msg_size, s_wid)), u" "),
|
||||||
|
- '=' * self.term.columns)]
|
||||||
|
+ '=' * output_width)]
|
||||||
|
|
||||||
|
for (action, lines) in pkglist_lines:
|
||||||
|
if lines:
|
||||||
|
@@ -1349,11 +1353,10 @@ class Output(object):
|
||||||
|
|
||||||
|
if lines:
|
||||||
|
out.append(totalmsg)
|
||||||
|
-
|
||||||
|
out.append(_("""
|
||||||
|
Transaction Summary
|
||||||
|
%s
|
||||||
|
-""") % ('=' * self.term.columns))
|
||||||
|
+""") % ('=' * output_width))
|
||||||
|
summary_data = (
|
||||||
|
(_('Install'), len(list_bunch.installed) +
|
||||||
|
len(list_bunch.installed_group) +
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@ -1,99 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,435 +0,0 @@
|
|||||||
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,106 @@
|
|||||||
|
From 4c2f0dbd2ffecec35c9df09190a5eeb8c4abce73 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Fri, 22 Nov 2019 08:02:45 +0100
|
||||||
|
Subject: [PATCH 1/2] Remove misleading comments
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/cli/cli.py | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
|
||||||
|
index 80df950c8d..9fbe7d3ada 100644
|
||||||
|
--- a/dnf/cli/cli.py
|
||||||
|
+++ b/dnf/cli/cli.py
|
||||||
|
@@ -405,13 +405,9 @@ def downgradePkgs(self, specs=[], file_pkgs=[], strict=False):
|
||||||
|
for pkg in file_pkgs:
|
||||||
|
try:
|
||||||
|
self.package_downgrade(pkg, strict=strict)
|
||||||
|
- continue # it was something on disk and it ended in rpm
|
||||||
|
- # no matter what we don't go looking at repos
|
||||||
|
except dnf.exceptions.MarkingError as e:
|
||||||
|
logger.info(_('No match for argument: %s'),
|
||||||
|
self.output.term.bold(pkg.location))
|
||||||
|
- # it was something on disk and it ended in rpm
|
||||||
|
- # no matter what we don't go looking at repos
|
||||||
|
|
||||||
|
for arg in specs:
|
||||||
|
try:
|
||||||
|
|
||||||
|
From 09b035f5d71c86b88da2d6ea117282fab5e87caa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Tue, 19 Nov 2019 07:08:21 +0100
|
||||||
|
Subject: [PATCH 2/2] Unify downgrade exit codes with upgrade (RhBug:1759847)
|
||||||
|
|
||||||
|
Now the dnf downgrade/upgrade commands behave consistently
|
||||||
|
in case the lowest/highest available version was already
|
||||||
|
installed. On top of that the behaviour is now compatible with
|
||||||
|
yum-3.
|
||||||
|
|
||||||
|
Behaviour of upgrade command in case that the latest version of
|
||||||
|
acpi is already installed:
|
||||||
|
$ dnf upgrade acpi
|
||||||
|
Dependencies resolved.
|
||||||
|
Nothing to do.
|
||||||
|
Complete!
|
||||||
|
|
||||||
|
The exit code of dnf upgrade is 0
|
||||||
|
|
||||||
|
In case that the lowest version of acpi is installed:
|
||||||
|
|
||||||
|
Previous behaviour:
|
||||||
|
$ dnf downgrade acpi
|
||||||
|
Package acpi of lowest version already installed, cannot downgrade it.
|
||||||
|
Error: No packages marked for downgrade.
|
||||||
|
|
||||||
|
The exit code of dnf downgrade was 1
|
||||||
|
|
||||||
|
New behaviour:
|
||||||
|
$ dnf downgrade acpi
|
||||||
|
Package acpi of lowest version already installed, cannot downgrade it.
|
||||||
|
Dependencies resolved.
|
||||||
|
Nothing to do.
|
||||||
|
Complete!
|
||||||
|
|
||||||
|
The exit code of dnf downgrade is 0
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1759847
|
||||||
|
---
|
||||||
|
dnf/cli/cli.py | 8 +++++---
|
||||||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
|
||||||
|
index 9fbe7d3ada..7a8d9e3b27 100644
|
||||||
|
--- a/dnf/cli/cli.py
|
||||||
|
+++ b/dnf/cli/cli.py
|
||||||
|
@@ -401,10 +401,11 @@ def downgradePkgs(self, specs=[], file_pkgs=[], strict=False):
|
||||||
|
:param file_pkgs: a list of pkg objects from local files
|
||||||
|
"""
|
||||||
|
|
||||||
|
- oldcount = self._goal.req_length()
|
||||||
|
+ result = False
|
||||||
|
for pkg in file_pkgs:
|
||||||
|
try:
|
||||||
|
self.package_downgrade(pkg, strict=strict)
|
||||||
|
+ result = True
|
||||||
|
except dnf.exceptions.MarkingError as e:
|
||||||
|
logger.info(_('No match for argument: %s'),
|
||||||
|
self.output.term.bold(pkg.location))
|
||||||
|
@@ -412,6 +413,7 @@ def downgradePkgs(self, specs=[], file_pkgs=[], strict=False):
|
||||||
|
for arg in specs:
|
||||||
|
try:
|
||||||
|
self.downgrade_to(arg, strict=strict)
|
||||||
|
+ result = True
|
||||||
|
except dnf.exceptions.PackageNotFoundError as err:
|
||||||
|
msg = _('No package %s available.')
|
||||||
|
logger.info(msg, self.output.term.bold(arg))
|
||||||
|
@@ -420,8 +422,8 @@ def downgradePkgs(self, specs=[], file_pkgs=[], strict=False):
|
||||||
|
self.output.term.bold(err.pkg_spec))
|
||||||
|
except dnf.exceptions.MarkingError:
|
||||||
|
assert False
|
||||||
|
- cnt = self._goal.req_length() - oldcount
|
||||||
|
- if cnt <= 0:
|
||||||
|
+
|
||||||
|
+ if not result:
|
||||||
|
raise dnf.exceptions.Error(_('No packages marked for downgrade.'))
|
||||||
|
|
||||||
|
def output_packages(self, basecmd, pkgnarrow='all', patterns=(), reponame=None):
|
@ -1,82 +0,0 @@
|
|||||||
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,125 @@
|
|||||||
|
From ee670a94b7f53716ac8db4a7ee1723d886378d6f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Fri, 22 Nov 2019 18:24:37 +0100
|
||||||
|
Subject: [PATCH 1/3] Restore functionality of remove --oldinstallonly
|
||||||
|
|
||||||
|
Additionally it also starts to protect running kernel.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1774666
|
||||||
|
---
|
||||||
|
dnf/cli/commands/remove.py | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/commands/remove.py b/dnf/cli/commands/remove.py
|
||||||
|
index f8059e4634..7b53dafcc4 100644
|
||||||
|
--- a/dnf/cli/commands/remove.py
|
||||||
|
+++ b/dnf/cli/commands/remove.py
|
||||||
|
@@ -110,8 +110,14 @@ def run(self):
|
||||||
|
|
||||||
|
if self.opts.oldinstallonly:
|
||||||
|
q = self.base.sack.query()
|
||||||
|
- instonly = self.base._get_installonly_query(q.installed()).latest(
|
||||||
|
- - self.base.conf.installonly_limit)
|
||||||
|
+ instonly = self.base._get_installonly_query(q.installed()).latest(-1)
|
||||||
|
+ # also remove running kernel from the set
|
||||||
|
+ kernel = self.base.sack.get_running_kernel()
|
||||||
|
+ if kernel is not None:
|
||||||
|
+ running_installonly = instonly.filter(
|
||||||
|
+ epoch=kernel.epoch, version=kernel.version, release=kernel.release)
|
||||||
|
+ if running_installonly:
|
||||||
|
+ instonly = instonly.difference(running_installonly)
|
||||||
|
if instonly:
|
||||||
|
for pkg in instonly:
|
||||||
|
self.base.package_remove(pkg)
|
||||||
|
|
||||||
|
From 031b424e3cf944f7585308ddda024ca6d2031c08 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Fri, 6 Dec 2019 13:50:37 +0100
|
||||||
|
Subject: [PATCH 2/3] Keep installed packages in upgrade transaction
|
||||||
|
|
||||||
|
In some cases missing installed packages could lead in an alternative
|
||||||
|
decision.
|
||||||
|
---
|
||||||
|
dnf/base.py | 8 +++++---
|
||||||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index 8091ca0366..f9d31b3f34 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -1975,17 +1975,19 @@ def package_upgrade(self, pkg):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _upgrade_internal(self, query, obsoletes, reponame, pkg_spec=None):
|
||||||
|
- installed = self.sack.query().installed()
|
||||||
|
- q = query.intersection(self.sack.query().filterm(name=[pkg.name for pkg in installed]))
|
||||||
|
+ installed_all = self.sack.query().installed()
|
||||||
|
+ q = query.intersection(self.sack.query().filterm(name=[pkg.name for pkg in installed_all]))
|
||||||
|
+ installed_query = q.installed()
|
||||||
|
if obsoletes:
|
||||||
|
obsoletes = self.sack.query().available().filterm(
|
||||||
|
- obsoletes=q.installed().union(q.upgrades()))
|
||||||
|
+ obsoletes=installed_query.union(q.upgrades()))
|
||||||
|
# add obsoletes into transaction
|
||||||
|
q = q.union(obsoletes)
|
||||||
|
if reponame is not None:
|
||||||
|
q.filterm(reponame=reponame)
|
||||||
|
q = self._merge_update_filters(q, pkg_spec=pkg_spec)
|
||||||
|
if q:
|
||||||
|
+ q = q.available().union(installed_query.latest())
|
||||||
|
sltr = dnf.selector.Selector(self.sack)
|
||||||
|
sltr.set(pkg=q)
|
||||||
|
self._goal.upgrade(select=sltr)
|
||||||
|
|
||||||
|
From 7cba81e129944b8b610895d24df1c4dbaa23b6a1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Fri, 6 Dec 2019 13:51:11 +0100
|
||||||
|
Subject: [PATCH 3/3] [doc] Update documentation of remove --oldinstallonly
|
||||||
|
|
||||||
|
---
|
||||||
|
doc/cli_vs_yum.rst | 18 +++++++++---------
|
||||||
|
doc/command_ref.rst | 2 +-
|
||||||
|
2 files changed, 10 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/cli_vs_yum.rst b/doc/cli_vs_yum.rst
|
||||||
|
index 56945869c9..bb379ab03e 100644
|
||||||
|
--- a/doc/cli_vs_yum.rst
|
||||||
|
+++ b/doc/cli_vs_yum.rst
|
||||||
|
@@ -387,15 +387,15 @@ Original YUM tool New DNF command Pack
|
||||||
|
|
||||||
|
Detailed table for ``package-cleanup`` replacement:
|
||||||
|
|
||||||
|
-================================== =====================================
|
||||||
|
-``package-cleanup --dupes`` ``dnf repoquery --duplicates``
|
||||||
|
-``package-cleanup --leaves`` ``dnf repoquery --unneeded``
|
||||||
|
-``package-cleanup --orphans`` ``dnf repoquery --extras``
|
||||||
|
-``package-cleanup --oldkernels`` ``dnf repoquery --installonly``
|
||||||
|
-``package-cleanup --problems`` ``dnf repoquery --unsatisfied``
|
||||||
|
-``package-cleanup --cleandupes`` ``dnf remove --duplicates``
|
||||||
|
-``package-cleanup --oldkernels`` ``dnf remove --oldinstallonly``
|
||||||
|
-================================== =====================================
|
||||||
|
+========================================== ===============================================================
|
||||||
|
+``package-cleanup --dupes`` ``dnf repoquery --duplicates``
|
||||||
|
+``package-cleanup --leaves`` ``dnf repoquery --unneeded``
|
||||||
|
+``package-cleanup --orphans`` ``dnf repoquery --extras``
|
||||||
|
+``package-cleanup --problems`` ``dnf repoquery --unsatisfied``
|
||||||
|
+``package-cleanup --cleandupes`` ``dnf remove --duplicates``
|
||||||
|
+``package-cleanup --oldkernels`` ``dnf remove --oldinstallonly``
|
||||||
|
+``package-cleanup --oldkernels --keep=2`` ``dnf remove $(dnf repoquery --installonly --latest-limit=-2)``
|
||||||
|
+========================================== ===============================================================
|
||||||
|
|
||||||
|
=============================
|
||||||
|
yum-updateonboot and yum-cron
|
||||||
|
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
|
||||||
|
index 7141fc2aae..134cc3d546 100644
|
||||||
|
--- a/doc/command_ref.rst
|
||||||
|
+++ b/doc/command_ref.rst
|
||||||
|
@@ -1061,7 +1061,7 @@ Remove Command
|
||||||
|
dnf-shell sub-commands could help.
|
||||||
|
|
||||||
|
``dnf [options] remove --oldinstallonly``
|
||||||
|
- Removes old installonly packages, keeping only ``installonly_limit`` latest versions.
|
||||||
|
+ Removes old installonly packages, keeping only latest versions and version of running kernel.
|
||||||
|
|
||||||
|
There are also a few specific remove commands ``remove-n``, ``remove-na`` and ``remove-nevra``
|
||||||
|
that allow the specification of an exact argument in the NEVRA format.
|
@ -1,93 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
111
SOURCES/0007-Shell-restriction-with-local-packages.patch
Normal file
111
SOURCES/0007-Shell-restriction-with-local-packages.patch
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
From 2e78e3006ca8b640028b98afd2ccaa5d26ead7e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 3 Dec 2019 09:09:20 +0100
|
||||||
|
Subject: [PATCH 1/3] [doc] Add note about limitation of the shell command
|
||||||
|
|
||||||
|
---
|
||||||
|
doc/command_ref.rst | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
|
||||||
|
index 24e08efdb2..cc27f57bba 100644
|
||||||
|
--- a/doc/command_ref.rst
|
||||||
|
+++ b/doc/command_ref.rst
|
||||||
|
@@ -1515,6 +1515,11 @@ Shell Command
|
||||||
|
* reset: reset the transaction
|
||||||
|
* run: resolve and run the transaction
|
||||||
|
|
||||||
|
+ Note that all local packages must be used in the first shell transaction subcommand (e.g.
|
||||||
|
+ `install /tmp/nodejs-1-1.x86_64.rpm /tmp/acpi-1-1.noarch.rpm`) otherwise an error will occur.
|
||||||
|
+ Any `disable`, `enable`, and `reset` module operations (e.g. `module enable nodejs`) must also
|
||||||
|
+ be performed before any other shell transaction subcommand is used.
|
||||||
|
+
|
||||||
|
.. _swap_command-label:
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
From 9e1958f3695b50f3c49f9aa2a8a113bbf660d62c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Tue, 3 Dec 2019 09:31:49 +0100
|
||||||
|
Subject: [PATCH 2/3] Prevent adding remote packages when goal is not empty
|
||||||
|
(RhBug:1773483)
|
||||||
|
|
||||||
|
Adding remote packages by add_remote_rpms() when goal is not empty
|
||||||
|
results in transaction that is completely broken, because elements in
|
||||||
|
transaction get different meaning.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1773483
|
||||||
|
---
|
||||||
|
dnf/base.py | 3 +++
|
||||||
|
tests/test_base.py | 1 +
|
||||||
|
2 files changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index 8091ca0366..c4ea04181a 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -1162,6 +1162,9 @@ def add_remote_rpms(self, path_list, strict=True, progress=None):
|
||||||
|
pkgs = []
|
||||||
|
if not path_list:
|
||||||
|
return pkgs
|
||||||
|
+ if self._goal.req_length():
|
||||||
|
+ raise dnf.exceptions.Error(
|
||||||
|
+ _("Cannot add local packages, because transaction job already exists"))
|
||||||
|
pkgs_error = []
|
||||||
|
for path in path_list:
|
||||||
|
if not os.path.exists(path) and '://' in path:
|
||||||
|
diff --git a/tests/test_base.py b/tests/test_base.py
|
||||||
|
index 0d50516d2f..8f807b7c13 100644
|
||||||
|
--- a/tests/test_base.py
|
||||||
|
+++ b/tests/test_base.py
|
||||||
|
@@ -168,6 +168,7 @@ class MockBaseTest(tests.support.DnfBaseTestCase):
|
||||||
|
"""Test the Base methods that need a Sack."""
|
||||||
|
|
||||||
|
REPOS = ["main"]
|
||||||
|
+ INIT_SACK = True
|
||||||
|
|
||||||
|
def test_add_remote_rpms(self):
|
||||||
|
pkgs = self.base.add_remote_rpms([tests.support.TOUR_50_PKG_PATH])
|
||||||
|
|
||||||
|
From 575ef19433909d3bf7d90e5e4b36f912a472b517 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Wed, 4 Dec 2019 13:17:26 +0100
|
||||||
|
Subject: [PATCH 3/3] [doc] Describe the new behavior of Base.add_remote_rpms()
|
||||||
|
|
||||||
|
---
|
||||||
|
doc/api_base.rst | 15 ++++++++++-----
|
||||||
|
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/api_base.rst b/doc/api_base.rst
|
||||||
|
index 5fd5b4cc99..618886d0cd 100644
|
||||||
|
--- a/doc/api_base.rst
|
||||||
|
+++ b/doc/api_base.rst
|
||||||
|
@@ -33,6 +33,10 @@
|
||||||
|
|
||||||
|
An instance of :class:`dnf.conf.Conf`, concentrates all the different configuration options. :meth:`__init__` initializes this to usable defaults.
|
||||||
|
|
||||||
|
+ .. attribute:: goal
|
||||||
|
+
|
||||||
|
+ An instance of :class:`dnf.goal.Goal` that this :class:`Base<dnf.Base>` object is using.
|
||||||
|
+
|
||||||
|
.. attribute:: repos
|
||||||
|
|
||||||
|
A :class:`dnf.repodict.RepoDict` instance, this member object contains all the repositories available.
|
||||||
|
@@ -51,11 +55,12 @@
|
||||||
|
|
||||||
|
.. method:: add_remote_rpms(path_list, strict=True, progress=None)
|
||||||
|
|
||||||
|
- Add RPM files at list `path_list` to the :attr:`sack` and return the list of respective
|
||||||
|
- :class:`dnf.package.Package` instances. Does the download to a temporary files for each path if
|
||||||
|
- `path` is a remote URL. Raises :exc:`IOError` if there are problems obtaining during reading
|
||||||
|
- files and `strict=True`. `progress`, if given, should be a :class:`.DownloadProgress` and can be
|
||||||
|
- used by the caller to monitor the progress of the download.
|
||||||
|
+ This function must be called before anything is added to the :attr:`goal`. Adds RPM files
|
||||||
|
+ in path_list to the :attr:`sack` and return the list of respective :class:`dnf.package.Package`
|
||||||
|
+ instances. Downloads the RPMs to a temporary file for each path if it is a remote URL.
|
||||||
|
+ Raises :exc:`IOError` if there are `IO` problems with files and `strict=True`. Raises
|
||||||
|
+ :exc:`dnf.exceptions.Error` if the :attr:`goal` is not empty. `progress`, if given, should be a
|
||||||
|
+ :class:`.DownloadProgress` instance which can be used to monitor the progress of the download.
|
||||||
|
|
||||||
|
.. method:: close()
|
||||||
|
|
@ -0,0 +1,115 @@
|
|||||||
|
From 27d2957e5051cc2edbea3a0d28a630e7eabfd673 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Fri, 6 Dec 2019 09:19:11 +0100
|
||||||
|
Subject: [PATCH] Improve help for 'dnf module' command (RhBug:1758447)
|
||||||
|
|
||||||
|
Added short summary for each subcommand of the 'dnf module' command.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1758447
|
||||||
|
---
|
||||||
|
dnf/cli/commands/module.py | 22 ++++++++++++++++++----
|
||||||
|
1 file changed, 18 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/commands/module.py b/dnf/cli/commands/module.py
|
||||||
|
index 07883af6a3..5a6c0069fb 100644
|
||||||
|
--- a/dnf/cli/commands/module.py
|
||||||
|
+++ b/dnf/cli/commands/module.py
|
||||||
|
@@ -74,6 +74,7 @@ def _get_module_artifact_names(self, use_modules, skip_modules):
|
||||||
|
class ListSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('list',)
|
||||||
|
+ summary = _('list all module streams, profiles and states')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -107,6 +108,7 @@ def run_on_module(self):
|
||||||
|
class InfoSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('info',)
|
||||||
|
+ summary = _('print detailed information about a module')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -128,6 +130,7 @@ def run_on_module(self):
|
||||||
|
class EnableSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('enable',)
|
||||||
|
+ summary = _('enable a module stream')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -151,6 +154,7 @@ def run_on_module(self):
|
||||||
|
class DisableSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('disable',)
|
||||||
|
+ summary = _('disable a module with all its streams')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -174,6 +178,7 @@ def run_on_module(self):
|
||||||
|
class ResetSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('reset',)
|
||||||
|
+ summary = _('reset a module')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -194,6 +199,7 @@ def run_on_module(self):
|
||||||
|
class InstallSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('install',)
|
||||||
|
+ summary = _('install a module profile including its packages')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -214,6 +220,7 @@ def run_on_module(self):
|
||||||
|
class UpdateSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('update',)
|
||||||
|
+ summary = _('update packages associated with an active stream')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -230,6 +237,7 @@ def run_on_module(self):
|
||||||
|
class RemoveSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ('remove', 'erase',)
|
||||||
|
+ summary = _('remove installed module profiles and their packages')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -266,6 +274,7 @@ def run_on_module(self):
|
||||||
|
class ProvidesSubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ("provides", )
|
||||||
|
+ summary = _('list modular packages')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -280,6 +289,7 @@ def run_on_module(self):
|
||||||
|
class RepoquerySubCommand(SubCommand):
|
||||||
|
|
||||||
|
aliases = ("repoquery", )
|
||||||
|
+ summary = _('list packages belonging to a module')
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
demands = self.cli.demands
|
||||||
|
@@ -342,10 +352,14 @@ def set_argparser(self, parser):
|
||||||
|
narrows.add_argument('--all', dest='all',
|
||||||
|
action='store_true',
|
||||||
|
help=_("remove all modular packages"))
|
||||||
|
-
|
||||||
|
- subcommand_help = [subcmd.aliases[0] for subcmd in self.SUBCMDS]
|
||||||
|
- parser.add_argument('subcmd', nargs=1, choices=subcommand_help,
|
||||||
|
- help=_("Modular command"))
|
||||||
|
+ subcommand_choices = []
|
||||||
|
+ subcommand_help = []
|
||||||
|
+ for subcmd in sorted(self.SUBCMDS, key=lambda x: x.aliases[0]):
|
||||||
|
+ subcommand_choices.append(subcmd.aliases[0])
|
||||||
|
+ subcommand_help.append('{}: {}'.format(subcmd.aliases[0], subcmd.summary or ''))
|
||||||
|
+ parser.add_argument('subcmd', nargs=1, choices=subcommand_choices,
|
||||||
|
+ metavar='<modular command>',
|
||||||
|
+ help='\n'.join(subcommand_help))
|
||||||
|
parser.add_argument('module_spec', metavar='module-spec', nargs='*',
|
||||||
|
help=_("Module specification"))
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
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,33 @@
|
|||||||
|
From 32f331724cc8b473073fa0f29ad93044b1dde824 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Brandon Bennett <bennetb@gmail.com>
|
||||||
|
Date: Mon, 16 Dec 2019 09:37:24 -0700
|
||||||
|
Subject: [PATCH] Strip '\' from aliases when processing (RhBug:1680482)
|
||||||
|
|
||||||
|
de40e3f7e910d5533dfbcc377807caaae115ed3e reworked the alias resolution
|
||||||
|
to detect infinate recursion, however it broke how the '\' works during
|
||||||
|
resolution. Before the '\\' was stripped but now it is no longer.
|
||||||
|
|
||||||
|
This just adds a check to see if '\\' is in the first part of the
|
||||||
|
arguments and strips it.
|
||||||
|
---
|
||||||
|
dnf/cli/aliases.py | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/aliases.py b/dnf/cli/aliases.py
|
||||||
|
index b5283d0f33..364aab6d21 100644
|
||||||
|
--- a/dnf/cli/aliases.py
|
||||||
|
+++ b/dnf/cli/aliases.py
|
||||||
|
@@ -176,8 +176,13 @@ def subresolve(args):
|
||||||
|
suffix[0].startswith('\\')): # End resolving
|
||||||
|
try:
|
||||||
|
stack.pop()
|
||||||
|
+
|
||||||
|
+ # strip the '\' if it exists
|
||||||
|
+ if suffix[0].startswith('\\'):
|
||||||
|
+ suffix[0] = suffix[0][1:]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
+
|
||||||
|
return suffix
|
||||||
|
|
||||||
|
if suffix[0] in stack: # Infinite recursion detected
|
@ -1,45 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
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,61 @@
|
|||||||
|
From 505e534817d076c5190b211983a8a2c930cbe560 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Mon, 16 Dec 2019 11:14:33 +0100
|
||||||
|
Subject: [PATCH] Honor priority with check-update (RhBug:1769466)
|
||||||
|
|
||||||
|
Check update is going to use the new query filter that honors repo
|
||||||
|
priority.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1769466
|
||||||
|
---
|
||||||
|
dnf.spec | 2 +-
|
||||||
|
dnf/base.py | 4 ++--
|
||||||
|
dnf/cli/commands/__init__.py | 2 +-
|
||||||
|
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf.spec b/dnf.spec
|
||||||
|
index e20be1e241..57bfd778d4 100644
|
||||||
|
--- a/dnf.spec
|
||||||
|
+++ b/dnf.spec
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# default dependencies
|
||||||
|
-%global hawkey_version 0.39.1
|
||||||
|
+%global hawkey_version 0.41.0
|
||||||
|
%global libcomps_version 0.1.8
|
||||||
|
%global libmodulemd_version 1.4.0
|
||||||
|
%global rpm_version 4.14.0
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index c4ea04181a..1ed01c37a9 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -1365,7 +1365,7 @@ def query_for_repo(query):
|
||||||
|
|
||||||
|
# produce the updates list of tuples
|
||||||
|
elif pkgnarrow == 'upgrades':
|
||||||
|
- updates = query_for_repo(q).upgrades()
|
||||||
|
+ updates = query_for_repo(q).filterm(upgrades_by_priority=True)
|
||||||
|
# reduce a query to security upgrades if they are specified
|
||||||
|
updates = self._merge_update_filters(updates)
|
||||||
|
# reduce a query to latest packages
|
||||||
|
@@ -1417,7 +1417,7 @@ def query_for_repo(query):
|
||||||
|
elif pkgnarrow == 'obsoletes':
|
||||||
|
inst = q.installed()
|
||||||
|
obsoletes = query_for_repo(
|
||||||
|
- self.sack.query()).filter(obsoletes=inst)
|
||||||
|
+ self.sack.query()).filter(obsoletes_by_priority=inst)
|
||||||
|
# reduce a query to security upgrades if they are specified
|
||||||
|
obsoletes = self._merge_update_filters(obsoletes, warning=False)
|
||||||
|
obsoletesTuples = []
|
||||||
|
diff --git a/dnf/cli/commands/__init__.py b/dnf/cli/commands/__init__.py
|
||||||
|
index 2a0726b654..d71a97f910 100644
|
||||||
|
--- a/dnf/cli/commands/__init__.py
|
||||||
|
+++ b/dnf/cli/commands/__init__.py
|
||||||
|
@@ -279,7 +279,7 @@ def configure(self):
|
||||||
|
_checkEnabledRepo(self.base)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
- query = self.base.sack.query().upgrades()
|
||||||
|
+ query = self.base.sack.query().filterm(upgrades_by_priority=True)
|
||||||
|
if self.base.conf.obsoletes:
|
||||||
|
obsoleted = query.union(self.base.sack.query().installed())
|
||||||
|
obsoletes = self.base.sack.query().filter(obsoletes=obsoleted)
|
@ -0,0 +1,50 @@
|
|||||||
|
From f89ac56ef0ee7a349e0389913a510ba194022e95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 14:32:32 +0200
|
||||||
|
Subject: [PATCH 1/2] Print the whole alias definition in case of infinite
|
||||||
|
recursion (RhBug:1680488)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1680488
|
||||||
|
---
|
||||||
|
dnf/cli/commands/alias.py | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/commands/alias.py b/dnf/cli/commands/alias.py
|
||||||
|
index 10f58867ca..d3e6e4326e 100644
|
||||||
|
--- a/dnf/cli/commands/alias.py
|
||||||
|
+++ b/dnf/cli/commands/alias.py
|
||||||
|
@@ -151,7 +151,8 @@ def list_alias(self, cmd):
|
||||||
|
try:
|
||||||
|
args = self.aliases_base._resolve(args)
|
||||||
|
except dnf.exceptions.Error as e:
|
||||||
|
- logger.error(_('%s, alias %s'), e, cmd)
|
||||||
|
+ logger.error(
|
||||||
|
+ _('%s, alias %s="%s"'), e, cmd, (' ').join(self.aliases_base.aliases[cmd]))
|
||||||
|
else:
|
||||||
|
print(_("Alias %s='%s'") % (cmd, " ".join(args)))
|
||||||
|
|
||||||
|
|
||||||
|
From ccd4213da366d49f6f84847fa2ccdb890d257930 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 14:39:19 +0200
|
||||||
|
Subject: [PATCH 2/2] [doc] Document aliases behavior in case of infinite
|
||||||
|
recursion (RhBug:1680488)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1680488
|
||||||
|
---
|
||||||
|
doc/command_ref.rst | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
|
||||||
|
index ba22453055..ab72b66f8f 100644
|
||||||
|
--- a/doc/command_ref.rst
|
||||||
|
+++ b/doc/command_ref.rst
|
||||||
|
@@ -423,6 +423,8 @@ To use an alias (name=value), the name must be placed as the first "command" (e.
|
||||||
|
that is not an option). It is then replaced by its value and the resulting sequence is again searched
|
||||||
|
for aliases. The alias processing stops when the first found command is not a name of any alias.
|
||||||
|
|
||||||
|
+In case the processing would result in an infinite recursion, the original arguments are used instead.
|
||||||
|
+
|
||||||
|
Also, like in shell aliases, if the result starts with a ``\``, the alias processing will stop.
|
||||||
|
|
||||||
|
All aliases are defined in configuration files in the ``/etc/dnf/aliases.d/`` directory in the [aliases] section,
|
@ -1,49 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 3a332e3eba6230d7da7472db654d50b8070570d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 11:07:37 +0200
|
||||||
|
Subject: [PATCH] [doc] Explain the backslash notation also near the example
|
||||||
|
(RhBug:1680482)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1680482
|
||||||
|
The backslash notation is mentioned before, but this adds an explanation
|
||||||
|
directly to the example where it is used.
|
||||||
|
---
|
||||||
|
doc/command_ref.rst | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
|
||||||
|
index ba22453055..84bad4b2b3 100644
|
||||||
|
--- a/doc/command_ref.rst
|
||||||
|
+++ b/doc/command_ref.rst
|
||||||
|
@@ -454,10 +454,12 @@ Alias Examples
|
||||||
|
Lists all defined aliases.
|
||||||
|
|
||||||
|
``dnf alias add rm=remove``
|
||||||
|
- Adds new alias command called "rm" which does the same thing as the command "remove".
|
||||||
|
+ Adds a new command alias called ``rm`` which works the same as the ``remove`` command.
|
||||||
|
|
||||||
|
``dnf alias add update="\update --skip-broken --disableexcludes=all --obsoletes"``
|
||||||
|
- Adds new alias command called "update" which does the same thing as the command "update", but with options ``--skip-broken --disableexcludes=all --obsoletes``.
|
||||||
|
+ Adds a new command alias called ``update`` which works the same as the ``update`` command,
|
||||||
|
+ with additional options. Note that the original ``update`` command is prefixed with a ``\``
|
||||||
|
+ to prevent an infinite loop in alias processing.
|
||||||
|
|
||||||
|
.. _alias_processing_examples-label:
|
||||||
|
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,82 @@
|
|||||||
|
From fa6afad083ffc19438603f43d17785f5741505b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Rohel <jrohel@redhat.com>
|
||||||
|
Date: Mon, 16 Dec 2019 12:52:41 +0100
|
||||||
|
Subject: [PATCH 1/2] Sort packages in transaction output by nevra
|
||||||
|
(RhBug:1773436)
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/cli/output.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
|
||||||
|
index 2ff41b6255..1d3eb1e94a 100644
|
||||||
|
--- a/dnf/cli/output.py
|
||||||
|
+++ b/dnf/cli/output.py
|
||||||
|
@@ -1147,7 +1147,7 @@ def _add_line(lines, data, a_wid, po, obsoletes=[]):
|
||||||
|
for i in tsi._item.getReplacedBy():
|
||||||
|
replaces.setdefault(i, set()).add(tsi)
|
||||||
|
|
||||||
|
- for tsi in pkglist:
|
||||||
|
+ for tsi in sorted(pkglist, key=lambda x: x.pkg):
|
||||||
|
if tsi.action not in dnf.transaction.FORWARD_ACTIONS + [libdnf.transaction.TransactionItemAction_REMOVE]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
From 0779b458ca30e895b72bcfb2d513c13b12f605df Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Rohel <jrohel@redhat.com>
|
||||||
|
Date: Mon, 16 Dec 2019 14:53:00 +0100
|
||||||
|
Subject: [PATCH 2/2] Sort packages in post transaction output by nevra
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/cli/output.py | 20 ++++++++++++++++++--
|
||||||
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
|
||||||
|
index 1d3eb1e94a..5dc0af6f4b 100644
|
||||||
|
--- a/dnf/cli/output.py
|
||||||
|
+++ b/dnf/cli/output.py
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
|
import fnmatch
|
||||||
|
+import functools
|
||||||
|
import hawkey
|
||||||
|
import itertools
|
||||||
|
import libdnf.transaction
|
||||||
|
@@ -1449,11 +1450,26 @@ def _fits_in_cols(msgs, num):
|
||||||
|
col_lens[col] *= -1
|
||||||
|
return col_lens
|
||||||
|
|
||||||
|
+ def _tsi_or_pkg_nevra_cmp(item1, item2):
|
||||||
|
+ """Compares two transaction items or packages by nevra.
|
||||||
|
+ Used as a fallback when tsi does not contain package object.
|
||||||
|
+ """
|
||||||
|
+ ret = (item1.name > item2.name) - (item1.name < item2.name)
|
||||||
|
+ if ret != 0:
|
||||||
|
+ return ret
|
||||||
|
+ nevra1 = hawkey.NEVRA(name=item1.name, epoch=item1.epoch, version=item1.version,
|
||||||
|
+ release=item1.release, arch=item1.arch)
|
||||||
|
+ nevra2 = hawkey.NEVRA(name=item2.name, epoch=item2.epoch, version=item2.version,
|
||||||
|
+ release=item2.release, arch=item2.arch)
|
||||||
|
+ ret = nevra1.evr_cmp(nevra2, self.sack)
|
||||||
|
+ if ret != 0:
|
||||||
|
+ return ret
|
||||||
|
+ return (item1.arch > item2.arch) - (item1.arch < item2.arch)
|
||||||
|
+
|
||||||
|
out = ''
|
||||||
|
list_bunch = _make_lists(transaction, self.base._goal)
|
||||||
|
skipped_conflicts, skipped_broken = self._skipped_packages(report_problems=False)
|
||||||
|
skipped = skipped_conflicts.union(skipped_broken)
|
||||||
|
- skipped = sorted(set([str(pkg) for pkg in skipped]))
|
||||||
|
|
||||||
|
for (action, tsis) in [(_('Upgraded'), list_bunch.upgraded),
|
||||||
|
(_('Downgraded'), list_bunch.downgraded),
|
||||||
|
@@ -1471,7 +1487,7 @@ def _fits_in_cols(msgs, num):
|
||||||
|
continue
|
||||||
|
msgs = []
|
||||||
|
out += '\n%s:\n' % action
|
||||||
|
- for tsi in tsis:
|
||||||
|
+ for tsi in sorted(tsis, key=functools.cmp_to_key(_tsi_or_pkg_nevra_cmp)):
|
||||||
|
msgs.append(str(tsi))
|
||||||
|
for num in (8, 7, 6, 5, 4, 3, 2):
|
||||||
|
cols = _fits_in_cols(msgs, num)
|
@ -0,0 +1,57 @@
|
|||||||
|
From bcfb9e8998a87f5737b6dbce5edd206f56d732eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||||
|
Date: Fri, 3 Jan 2020 10:57:59 +0100
|
||||||
|
Subject: [PATCH] Add support of commandline packages in repoquery
|
||||||
|
(RhBug:1784148)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1784148
|
||||||
|
---
|
||||||
|
dnf/cli/commands/repoquery.py | 21 +++++++++++++++++++++
|
||||||
|
1 file changed, 21 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
|
||||||
|
index f5cb36fe57..7334ddcd90 100644
|
||||||
|
--- a/dnf/cli/commands/repoquery.py
|
||||||
|
+++ b/dnf/cli/commands/repoquery.py
|
||||||
|
@@ -402,6 +402,20 @@ def _get_recursive_providers_query(self, query_in, providers, done=None):
|
||||||
|
done = self._get_recursive_providers_query(query_in, query_select, done=t.union(done))
|
||||||
|
return t.union(done)
|
||||||
|
|
||||||
|
+ def _add_add_remote_packages(self):
|
||||||
|
+ rpmnames = []
|
||||||
|
+ remote_packages = []
|
||||||
|
+ for key in self.opts.key:
|
||||||
|
+ schemes = dnf.pycomp.urlparse.urlparse(key)[0]
|
||||||
|
+ if key.endswith('.rpm'):
|
||||||
|
+ rpmnames.append(key)
|
||||||
|
+ elif schemes and schemes in ('http', 'ftp', 'file', 'https'):
|
||||||
|
+ rpmnames.append(key)
|
||||||
|
+ if rpmnames:
|
||||||
|
+ remote_packages = self.base.add_remote_rpms(
|
||||||
|
+ rpmnames, strict=False, progress=self.base.output.progress)
|
||||||
|
+ return remote_packages
|
||||||
|
+
|
||||||
|
def run(self):
|
||||||
|
if self.opts.querytags:
|
||||||
|
print(_('Available query-tags: use --queryformat ".. %{tag} .."'))
|
||||||
|
@@ -416,6 +430,8 @@ def run(self):
|
||||||
|
else hawkey.APPLY_EXCLUDES
|
||||||
|
)
|
||||||
|
if self.opts.key:
|
||||||
|
+ remote_packages = self._add_add_remote_packages()
|
||||||
|
+
|
||||||
|
kwark = {}
|
||||||
|
forms = [self.nevra_forms[command] for command in self.opts.command
|
||||||
|
if command in list(self.nevra_forms.keys())]
|
||||||
|
@@ -423,6 +439,11 @@ def run(self):
|
||||||
|
kwark["forms"] = forms
|
||||||
|
pkgs = []
|
||||||
|
query_results = q.filter(empty=True)
|
||||||
|
+
|
||||||
|
+ if remote_packages:
|
||||||
|
+ query_results = query_results.union(
|
||||||
|
+ self.base.sack.query().filterm(pkg=remote_packages))
|
||||||
|
+
|
||||||
|
for key in self.opts.key:
|
||||||
|
query_results = query_results.union(
|
||||||
|
dnf.subject.Subject(key, ignore_case=True).get_best_query(
|
26
SOURCES/0016-Documentation-changes-RhBug-1786072.patch
Normal file
26
SOURCES/0016-Documentation-changes-RhBug-1786072.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 8df2ca3485b0c758d2030b096ecc6acac0d2d462 Mon Sep 17 00:00:00 2001
|
||||||
|
From: nsella <nsella@redhat.com>
|
||||||
|
Date: Thu, 9 Jan 2020 11:13:48 +0100
|
||||||
|
Subject: [PATCH] Add doc entry: include url (RhBug 1786072)
|
||||||
|
|
||||||
|
---
|
||||||
|
doc/cli_vs_yum.rst | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/doc/cli_vs_yum.rst b/doc/cli_vs_yum.rst
|
||||||
|
index 5c03b598f3..199ef2fefb 100644
|
||||||
|
--- a/doc/cli_vs_yum.rst
|
||||||
|
+++ b/doc/cli_vs_yum.rst
|
||||||
|
@@ -93,6 +93,12 @@ following will work::
|
||||||
|
|
||||||
|
``include`` directive name of [main] and Repo configuration is a more logical and better named counterpart of ``exclude`` in DNF.
|
||||||
|
|
||||||
|
+=======================================
|
||||||
|
+The ``include`` option has been removed
|
||||||
|
+=======================================
|
||||||
|
+
|
||||||
|
+Inclusion of other configuration files in the main configuration file is no longer supported.
|
||||||
|
+
|
||||||
|
====================================================
|
||||||
|
``dnf provides /bin/<file>`` is not fully supported
|
||||||
|
====================================================
|
@ -0,0 +1,138 @@
|
|||||||
|
From 9d19491f52cad798ce995f3f8d1c13e2dc54cb0c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Sun, 12 Jan 2020 15:52:16 +0100
|
||||||
|
Subject: [PATCH 1/2] Split loggers setup so that file loggers could be set
|
||||||
|
separately
|
||||||
|
|
||||||
|
---
|
||||||
|
dnf/logging.py | 46 +++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 31 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dnf/logging.py b/dnf/logging.py
|
||||||
|
index df355efa57..bd660470a3 100644
|
||||||
|
--- a/dnf/logging.py
|
||||||
|
+++ b/dnf/logging.py
|
||||||
|
@@ -132,12 +132,14 @@ def _paint_mark(logger):
|
||||||
|
class Logging(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.stdout_handler = self.stderr_handler = None
|
||||||
|
-
|
||||||
|
- @only_once
|
||||||
|
- def _presetup(self):
|
||||||
|
logging.addLevelName(DDEBUG, "DDEBUG")
|
||||||
|
logging.addLevelName(SUBDEBUG, "SUBDEBUG")
|
||||||
|
logging.addLevelName(TRACE, "TRACE")
|
||||||
|
+ logging.captureWarnings(True)
|
||||||
|
+ logging.raiseExceptions = False
|
||||||
|
+
|
||||||
|
+ @only_once
|
||||||
|
+ def _presetup(self):
|
||||||
|
logger_dnf = logging.getLogger("dnf")
|
||||||
|
logger_dnf.setLevel(TRACE)
|
||||||
|
|
||||||
|
@@ -155,24 +157,19 @@ def _presetup(self):
|
||||||
|
self.stderr_handler = stderr
|
||||||
|
|
||||||
|
@only_once
|
||||||
|
- def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate):
|
||||||
|
- self._presetup()
|
||||||
|
+ def _setup_file_loggers(self, verbose_level, logdir, log_size, log_rotate):
|
||||||
|
logger_dnf = logging.getLogger("dnf")
|
||||||
|
+ logger_dnf.setLevel(TRACE)
|
||||||
|
|
||||||
|
# setup file logger
|
||||||
|
logfile = os.path.join(logdir, dnf.const.LOG)
|
||||||
|
handler = _create_filehandler(logfile, log_size, log_rotate)
|
||||||
|
logger_dnf.addHandler(handler)
|
||||||
|
- # temporarily turn off stdout/stderr handlers:
|
||||||
|
- self.stdout_handler.setLevel(SUPERCRITICAL)
|
||||||
|
- self.stderr_handler.setLevel(SUPERCRITICAL)
|
||||||
|
# put the marker in the file now:
|
||||||
|
_paint_mark(logger_dnf)
|
||||||
|
|
||||||
|
# setup Python warnings
|
||||||
|
- logging.captureWarnings(True)
|
||||||
|
logger_warnings = logging.getLogger("py.warnings")
|
||||||
|
- logger_warnings.addHandler(self.stderr_handler)
|
||||||
|
logger_warnings.addHandler(handler)
|
||||||
|
|
||||||
|
lr_logfile = os.path.join(logdir, dnf.const.LOG_LIBREPO)
|
||||||
|
@@ -184,22 +181,41 @@ def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate):
|
||||||
|
logger_rpm.setLevel(SUBDEBUG)
|
||||||
|
logfile = os.path.join(logdir, dnf.const.LOG_RPM)
|
||||||
|
handler = _create_filehandler(logfile, log_size, log_rotate)
|
||||||
|
- logger_rpm.addHandler(self.stdout_handler)
|
||||||
|
- logger_rpm.addHandler(self.stderr_handler)
|
||||||
|
logger_rpm.addHandler(handler)
|
||||||
|
_paint_mark(logger_rpm)
|
||||||
|
+
|
||||||
|
+ @only_once
|
||||||
|
+ def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate):
|
||||||
|
+ self._presetup()
|
||||||
|
+
|
||||||
|
+ # temporarily turn off stdout/stderr handlers:
|
||||||
|
+ self.stdout_handler.setLevel(SUPERCRITICAL)
|
||||||
|
+ self.stderr_handler.setLevel(SUPERCRITICAL)
|
||||||
|
+
|
||||||
|
+ self._setup_file_loggers(verbose_level, logdir, log_size, log_rotate)
|
||||||
|
+
|
||||||
|
+ logger_warnings = logging.getLogger("py.warnings")
|
||||||
|
+ logger_warnings.addHandler(self.stderr_handler)
|
||||||
|
+
|
||||||
|
+ # setup RPM callbacks logger
|
||||||
|
+ logger_rpm = logging.getLogger("dnf.rpm")
|
||||||
|
+ logger_rpm.addHandler(self.stdout_handler)
|
||||||
|
+ logger_rpm.addHandler(self.stderr_handler)
|
||||||
|
+
|
||||||
|
# bring std handlers to the preferred level
|
||||||
|
self.stdout_handler.setLevel(verbose_level)
|
||||||
|
self.stderr_handler.setLevel(error_level)
|
||||||
|
- logging.raiseExceptions = False
|
||||||
|
|
||||||
|
- def _setup_from_dnf_conf(self, conf):
|
||||||
|
+ def _setup_from_dnf_conf(self, conf, file_loggers_only=False):
|
||||||
|
verbose_level_r = _cfg_verbose_val2level(conf.debuglevel)
|
||||||
|
error_level_r = _cfg_err_val2level(conf.errorlevel)
|
||||||
|
logdir = conf.logdir
|
||||||
|
log_size = conf.log_size
|
||||||
|
log_rotate = conf.log_rotate
|
||||||
|
- return self._setup(verbose_level_r, error_level_r, logdir, log_size, log_rotate)
|
||||||
|
+ if file_loggers_only:
|
||||||
|
+ return self._setup_file_loggers(verbose_level_r, logdir, log_size, log_rotate)
|
||||||
|
+ else:
|
||||||
|
+ return self._setup(verbose_level_r, error_level_r, logdir, log_size, log_rotate)
|
||||||
|
|
||||||
|
|
||||||
|
class Timer(object):
|
||||||
|
|
||||||
|
From e43eaba4148446523eaf3e8ff1549c7576d00f1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Blaha <mblaha@redhat.com>
|
||||||
|
Date: Sun, 12 Jan 2020 15:53:09 +0100
|
||||||
|
Subject: [PATCH 2/2] New API function base.setup_loggers() (RhBug:1788212)
|
||||||
|
|
||||||
|
Gives API users ability to setup DNF loggers.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1788212
|
||||||
|
---
|
||||||
|
dnf/base.py | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dnf/base.py b/dnf/base.py
|
||||||
|
index b2c17bba30..56a9dfb478 100644
|
||||||
|
--- a/dnf/base.py
|
||||||
|
+++ b/dnf/base.py
|
||||||
|
@@ -2536,6 +2536,14 @@ def _raise_package_not_installed_error(self, pkg_spec, forms, reponame):
|
||||||
|
msg = _('All matches were filtered out by exclude filtering for argument')
|
||||||
|
raise dnf.exceptions.PackagesNotInstalledError(msg, pkg_spec)
|
||||||
|
|
||||||
|
+ def setup_loggers(self):
|
||||||
|
+ # :api
|
||||||
|
+ """
|
||||||
|
+ Setup DNF file loggers based on given configuration file. The loggers are set the same
|
||||||
|
+ way as if DNF was run from CLI.
|
||||||
|
+ """
|
||||||
|
+ self._logging._setup_from_dnf_conf(self.conf, file_loggers_only=True)
|
||||||
|
+
|
||||||
|
|
||||||
|
def _msg_installed(pkg):
|
||||||
|
name = ucd(pkg)
|
134
SPECS/dnf.spec
134
SPECS/dnf.spec
@ -1,11 +1,11 @@
|
|||||||
# default dependencies
|
# default dependencies
|
||||||
%global hawkey_version 0.35.1-9
|
%global hawkey_version 0.39.1
|
||||||
%global libcomps_version 0.1.8
|
%global libcomps_version 0.1.8
|
||||||
%global libmodulemd_version 1.4.0
|
%global libmodulemd_version 1.4.0
|
||||||
%global rpm_version 4.14.0
|
%global rpm_version 4.14.2-35
|
||||||
|
|
||||||
# conflicts
|
# conflicts
|
||||||
%global conflicts_dnf_plugins_core_version 4.0.6
|
%global conflicts_dnf_plugins_core_version 4.0.12
|
||||||
%global conflicts_dnf_plugins_extras_version 4.0.4
|
%global conflicts_dnf_plugins_extras_version 4.0.4
|
||||||
%global conflicts_dnfdaemon_version 0.3.19
|
%global conflicts_dnfdaemon_version 0.3.19
|
||||||
|
|
||||||
@ -47,6 +47,8 @@
|
|||||||
%global yum_compat_level full
|
%global yum_compat_level full
|
||||||
%global yum_subpackage_name yum
|
%global yum_subpackage_name yum
|
||||||
%if 0%{?fedora}
|
%if 0%{?fedora}
|
||||||
|
# Avoid file conflict with yum < 4 in all Fedoras
|
||||||
|
# It can be resolved by pretrans scriptlet but they are not recommended in Fedora
|
||||||
%global yum_compat_level minimal
|
%global yum_compat_level minimal
|
||||||
%if 0%{?fedora} < 31
|
%if 0%{?fedora} < 31
|
||||||
# Avoid name conflict with yum < 4
|
# Avoid name conflict with yum < 4
|
||||||
@ -79,25 +81,30 @@
|
|||||||
It supports RPMs, modules and comps groups & environments.
|
It supports RPMs, modules and comps groups & environments.
|
||||||
|
|
||||||
Name: dnf
|
Name: dnf
|
||||||
Version: 4.2.7
|
Version: 4.2.17
|
||||||
Release: 7%{?dist}
|
Release: 6%{?dist}
|
||||||
Summary: %{pkg_summary}
|
Summary: %{pkg_summary}
|
||||||
# For a breakdown of the licensing, see PACKAGE-LICENSING
|
# For a breakdown of the licensing, see PACKAGE-LICENSING
|
||||||
License: GPLv2+ and GPLv2 and GPL
|
License: GPLv2+ and GPLv2 and GPL
|
||||||
URL: https://github.com/rpm-software-management/dnf
|
URL: https://github.com/rpm-software-management/dnf
|
||||||
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
|
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
|
||||||
# Temporary patch to not fail on modular RPMs without modular metadata
|
Patch1: 0001-Do-a-substitution-of-variables-in-repo_id-RhBug1748841.patch
|
||||||
# until the infrastructure is ready
|
Patch2: 0002-Fix-and-document-order-of-config-files-in-aliasesd-RhBug1680489.patch
|
||||||
Patch2: 0002-Update-localizations-from-zanata-RhBug1689982.patch
|
Patch3: 0003-doc-Remove-note-about-whitelist.patch
|
||||||
Patch3: 0003-Accept-multiple-specs-in-repoquery-options-RhBug16678981656801.patch
|
Patch4: 0004-Fix-detection-of-the-latest-module-RhBug1781769.patch
|
||||||
Patch4: 0004-Prevent-switching-modules-in-all-cases-RhBug1706215.patch
|
Patch5: 0005-Unify-downgrade-exit-codes-with-upgrade-RhBug1759847.patch
|
||||||
Patch5: 0005-Change-synchronization-of-rpm-transaction-to-swdb-RhBug1737328.patch
|
Patch6: 0006-Restore-functionality-of-remove-oldinstallonly.patch
|
||||||
Patch6: 0006-Print-rpm-error-messages-during-transaction-RhBug1677199.patch
|
Patch7: 0007-Shell-restriction-with-local-packages.patch
|
||||||
Patch7: 0007-Report-missing-default-profile-as-an-error-RhBug16695271724564.patch
|
Patch8: 0008-Improve-help-for-dnf-module-command-RhBug1758447.patch
|
||||||
Patch8: 0008-doc-Describe-a-behavior-when-plugin-is-removed-RhBug1700741.patch
|
Patch9: 0009-Fix-alias-processing-with-backslash-escaping-RhBug1680482.patch
|
||||||
Patch9: 0009-Prevent-printing-empty-Error-Summary-RhBug-1690414.patch
|
Patch10: 0010-Honor-priority-with-check-update-RhBug1769466.patch
|
||||||
Patch10: 0010-Fix---setopt-and-repo-with-dots.patch
|
Patch11: 0011-Better-descriptions-for-infinite-aliases-recursion-RhBug1680488.patch
|
||||||
Patch11: 0011-Keep-installed-packages-in-upgrade-job-RhBug172825216442411741381.patch
|
Patch12: 0012-doc-Explain-the-backslash-notation-also-near-the-example-RhBug1680482.patch
|
||||||
|
Patch13: 0013-Update-translations-from-zanata-RhBug-1754959.patch
|
||||||
|
Patch14: 0014-Sort-packages-in-transaction-output-by-nevra-RhBug-1773436.patch
|
||||||
|
Patch15: 0015-Add-support-of-commandline-packages-by-repoquery-RhBug-1784148.patch
|
||||||
|
Patch16: 0016-Documentation-changes-RhBug-1786072.patch
|
||||||
|
Patch17: 0017-New-API-function-for-setting-loggers-RhBug-1788212.patch
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
@ -123,7 +130,6 @@ Recommends: (python2-dbus if NetworkManager)
|
|||||||
%endif
|
%endif
|
||||||
Recommends: (%{_bindir}/sqlite3 if bash-completion)
|
Recommends: (%{_bindir}/sqlite3 if bash-completion)
|
||||||
%endif
|
%endif
|
||||||
%{?systemd_requires}
|
|
||||||
Provides: dnf-command(alias)
|
Provides: dnf-command(alias)
|
||||||
Provides: dnf-command(autoremove)
|
Provides: dnf-command(autoremove)
|
||||||
Provides: dnf-command(check-update)
|
Provides: dnf-command(check-update)
|
||||||
@ -170,7 +176,7 @@ Summary: %{pkg_summary}
|
|||||||
%if 0%{?fedora}
|
%if 0%{?fedora}
|
||||||
%if 0%{?fedora} >= 31
|
%if 0%{?fedora} >= 31
|
||||||
Provides: %{name}-yum = %{version}-%{release}
|
Provides: %{name}-yum = %{version}-%{release}
|
||||||
Obsoletes: %{name}-yum < %{version}-%{release}
|
Obsoletes: %{name}-yum < 5
|
||||||
%else
|
%else
|
||||||
Conflicts: yum < 3.4.3-505
|
Conflicts: yum < 3.4.3-505
|
||||||
%endif
|
%endif
|
||||||
@ -338,6 +344,13 @@ mv %{buildroot}%{_bindir}/dnf-automatic-2 %{buildroot}%{_bindir}/dnf-automatic
|
|||||||
%endif
|
%endif
|
||||||
rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
|
rm -vf %{buildroot}%{_bindir}/dnf-automatic-*
|
||||||
|
|
||||||
|
# Strict conf distribution
|
||||||
|
%if 0%{?rhel}
|
||||||
|
mv -f %{buildroot}%{confdir}/%{name}-strict.conf %{buildroot}%{confdir}/%{name}.conf
|
||||||
|
%else
|
||||||
|
rm -vf %{buildroot}%{confdir}/%{name}-strict.conf
|
||||||
|
%endif
|
||||||
|
|
||||||
# YUM compat layer
|
# YUM compat layer
|
||||||
ln -sr %{buildroot}%{confdir}/%{name}.conf %{buildroot}%{_sysconfdir}/yum.conf
|
ln -sr %{buildroot}%{confdir}/%{name}.conf %{buildroot}%{_sysconfdir}/yum.conf
|
||||||
%if %{with python3}
|
%if %{with python3}
|
||||||
@ -515,6 +528,89 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Feb 18 2020 Ales Matej <amatej@redhat.com> - 4.2.17-6
|
||||||
|
- Sort packages in transaction output by nevra (RhBug:1773436)
|
||||||
|
- Add support of commandline packages by repoquery (RhBug:1784148)
|
||||||
|
- [doc] Document that the include option was removed (RhBug:1786072)
|
||||||
|
- New API function for setting loggers (RhBug:1788212)
|
||||||
|
|
||||||
|
* Fri Jan 31 2020 Marek Blaha <mblaha@redhat.com> - 4.2.17-5
|
||||||
|
- [translations] Update translations from zanata (RhBug:1754959)
|
||||||
|
|
||||||
|
* Mon Jan 13 2020 Ales Matej <amatej@redhat.com> - 4.2.17-4
|
||||||
|
- Fix alias processing with '\' escaping (RhBug:1680482)
|
||||||
|
- [doc] Explain the backslash notation also near the example (RhBug:1680482)
|
||||||
|
- Better descriptions for infinite aliases recursion (RhBug:1680488)
|
||||||
|
- Improve help for 'dnf module' command (RhBug:1758447)
|
||||||
|
- Unify downgrade exit codes with upgrade (RhBug:1759847)
|
||||||
|
- Honor priority with check-update (RhBug:1769466)
|
||||||
|
- Add shell restriction with local packages (RhBug:1773483)
|
||||||
|
- Restore functionality of remove --oldinstallonly (RhBug:1774670)
|
||||||
|
|
||||||
|
* Thu Dec 12 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.2.17-3
|
||||||
|
- Do a substitution of variables in repo_id (RhBug:1748841)
|
||||||
|
- Respect order of config files in aliases.d (RhBug:1680489)
|
||||||
|
- [doc] Remove note about user-agent whitelist (RhBug:1777255)
|
||||||
|
- Fix detection of the latest module (RhBug:1781769)
|
||||||
|
|
||||||
|
* Mon Nov 25 2019 Ales Matej <amatej@redhat.com> - 4.2.17-2
|
||||||
|
- Update to 4.2.17
|
||||||
|
- Enable versionlock for check-update command (RhBug:1750620)
|
||||||
|
- Add error message when no active modules matched (RhBug:1696204)
|
||||||
|
- Log mirror failures as warning when repo load fails (RhBug:1713627)
|
||||||
|
- dnf-automatic: Change all systemd timers to a fixed time of day (RhBug:1754609)
|
||||||
|
- DNF can use config from the remote location (RhBug:1721091)
|
||||||
|
- [doc] update reference to plugin documentation (RhBug:1706386)
|
||||||
|
- [yum compatibility] Report all packages in repoinfo
|
||||||
|
- [doc] Add definition of active/inactive module stream
|
||||||
|
- repoquery: Add a switch to disable modular excludes
|
||||||
|
- Report more informative messages when no match for argument (RhBug:1709563)
|
||||||
|
- [doc] Add description of excludes in dnf
|
||||||
|
- Report more descriptive message when removed package is excluded
|
||||||
|
- Add module repoquery command
|
||||||
|
- Fix assumptions about ARMv8 and the way the rpm features work (RhBug:1691430)
|
||||||
|
- Add Requires information into module info commands
|
||||||
|
- Enhance inheritance of transaction reasons (RhBug:1672618,1769788)
|
||||||
|
|
||||||
|
* Wed Nov 13 2019 Ales Matej <amatej@redhat.com> - 4.2.16-1
|
||||||
|
- Update to 4.2.16
|
||||||
|
- Fix downloading local packages into destdir (RhBug:1727137)
|
||||||
|
- Report skipped packages with identical nevra only once (RhBug:1643109)
|
||||||
|
- Restore functionality of dnf remove --duplicates (RhBug:1674296)
|
||||||
|
- Improve API documentation
|
||||||
|
- Document NEVRA parsing in the man page
|
||||||
|
- Do not wrap output when no terminal (RhBug:1577889)
|
||||||
|
- Allow to ship alternative dnf.conf (RhBug:1752249)
|
||||||
|
- Don't check if repo is expired if it doesn't have loaded metadata (RhBug:1745170)
|
||||||
|
- Remove duplicate entries from "dnf search" output (RhBug:1742926)
|
||||||
|
- Set default value of repo name attribute to repo id (RhBug:1669711)
|
||||||
|
- Allow searching in disabled modules using "dnf module provides" (RhBug:1629667)
|
||||||
|
- Group install takes obsoletes into account (RhBug:1761137)
|
||||||
|
- Improve handling of vars
|
||||||
|
- Do not load metadata for repolist commands (RhBug:1697472,1713055,1728894)
|
||||||
|
- Fix messages for starting and failing scriptlets (RhBug:1724779)
|
||||||
|
- Don't show older install-only pkgs updates in updateinfo (RhBug:1649383,1728004)
|
||||||
|
- Add --ids option to the group command (RhBug:1706382)
|
||||||
|
- Add --with_cve and --with_bz options to the updateinfo command (RhBug:1750528)
|
||||||
|
|
||||||
|
* Tue Oct 22 2019 Ales Matej <amatej@redhat.com> - 4.2.11-1
|
||||||
|
- Update to 4.2.11
|
||||||
|
- Improve modularity documentation (RhBug:1730162,1730162,1730807,1734081)
|
||||||
|
- Fix detection whether system is running on battery (used by metadata caching timer) (RhBug:1498680)
|
||||||
|
- New repoquery queryformat: %{reason}
|
||||||
|
- Print rpm errors during test transaction (RhBug:1730348)
|
||||||
|
- Fix incorrectly marked profile and stream after failed rpm transaction check (RhBug:1719679)
|
||||||
|
- Show transaction errors inside dnf shell (RhBug:1743644)
|
||||||
|
- dnf-automatic now respects versionlock excludes (RhBug:1746562)
|
||||||
|
- [doc] Add user_agent and countme options
|
||||||
|
- [history] Don't store failed transactions as succeeded
|
||||||
|
- [history] Do not require root for informative commands
|
||||||
|
- [dnssec] Fix UnicodeWarning when using new rpm (RhBug:1699650)
|
||||||
|
- Apply excludes before modular excludes (RhBug:1709453)
|
||||||
|
- Improve help for command line arguments (RhBug:1659328)
|
||||||
|
- Add new modular API method ModuleBase.get_modules
|
||||||
|
- Mark features used by ansible, anaconda and subscription-manager as an API
|
||||||
|
|
||||||
* Mon Oct 21 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.2.7-7
|
* Mon Oct 21 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.2.7-7
|
||||||
- Prevent reinstalling modified packages with same NEVRA (RhBug:1728252,1644241,1760825)
|
- Prevent reinstalling modified packages with same NEVRA (RhBug:1728252,1644241,1760825)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user