import dnf-4.2.23-4.el8

This commit is contained in:
CentOS Sources 2020-11-03 06:47:17 -05:00 committed by Andrew Lukoshko
parent 553f17f763
commit ebe355c9b4
25 changed files with 10619 additions and 292777 deletions

View File

@ -1 +1 @@
535f46b9a5242a315e1269a59372362013a5a6f0 SOURCES/dnf-4.2.17.tar.gz 0da07a3e6ff19430ffe39699e474439eab63ee7d SOURCES/dnf-4.2.23.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/dnf-4.2.17.tar.gz SOURCES/dnf-4.2.23.tar.gz

View File

@ -1,101 +0,0 @@
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

View File

@ -0,0 +1,238 @@
From 3c758a4ea670fab1f4b55fa878ebf2b2ff4b678b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Tue, 28 Apr 2020 09:08:05 +0200
Subject: [PATCH] Handle empty comps group name (RhBug:1826198)
Don't crash on empty comps group/environment name. In outputs, use the
"<name-unset>" placeholder instead of the name.
https://bugzilla.redhat.com/show_bug.cgi?id=1826198
---
dnf/cli/commands/group.py | 4 ++--
dnf/cli/output.py | 16 ++++++++++------
dnf/comps.py | 11 ++++++++++-
dnf/db/group.py | 12 ++++++++----
tests/repos/main_comps.xml | 7 +++++++
tests/support.py | 2 +-
tests/test_comps.py | 6 +++---
tests/test_groups.py | 9 +++++++++
8 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/dnf/cli/commands/group.py b/dnf/cli/commands/group.py
index f535a50980..4ffd3b89c8 100644
--- a/dnf/cli/commands/group.py
+++ b/dnf/cli/commands/group.py
@@ -177,7 +177,7 @@ def _list(self, userlist):
def _out_grp(sect, group):
if not done:
print(sect)
- msg = ' %s' % group.ui_name
+ msg = ' %s' % (group.ui_name if group.ui_name is not None else _("<name-unset>"))
if print_ids:
msg += ' (%s)' % group.id
if group.lang_only:
@@ -188,7 +188,7 @@ def _out_env(sect, envs):
if envs:
print(sect)
for e in envs:
- msg = ' %s' % e.ui_name
+ msg = ' %s' % (e.ui_name if e.ui_name is not None else _("<name-unset>"))
if print_ids:
msg += ' (%s)' % e.id
print(msg)
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
index 67eab80b19..2585a5c773 100644
--- a/dnf/cli/output.py
+++ b/dnf/cli/output.py
@@ -1221,47 +1221,51 @@ def _add_line(lines, data, a_wid, po, obsoletes=[]):
lines.append((name, "", "", "", "", "", ""))
pkglist_lines.append((action, lines))
if self.base._history:
+ def format_line(group):
+ name = group.getName()
+ return (name if name else _("<name-unset>"), "", "", "", "", "", "")
+
install_env_group = self.base._history.env._installed
if install_env_group:
action = _("Installing Environment Groups")
lines = []
for group in install_env_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
upgrade_env_group = self.base._history.env._upgraded
if upgrade_env_group:
action = _("Upgrading Environment Groups")
lines = []
for group in upgrade_env_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
remove_env_group = self.base._history.env._removed
if remove_env_group:
action = _("Removing Environment Groups")
lines = []
for group in remove_env_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
install_group = self.base._history.group._installed
if install_group:
action = _("Installing Groups")
lines = []
for group in install_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
upgrade_group = self.base._history.group._upgraded
if upgrade_group:
action = _("Upgrading Groups")
lines = []
for group in upgrade_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
remove_group = self.base._history.group._removed
if remove_group:
action = _("Removing Groups")
lines = []
for group in remove_group.values():
- lines.append((group.getName(), "", "", "", "", "", ""))
+ lines.append(format_line(group))
pkglist_lines.append((action, lines))
# show skipped conflicting packages
if not self.conf.best and self.base._goal.actions & forward_actions:
diff --git a/dnf/comps.py b/dnf/comps.py
index 316d647087..4ca15b1e07 100644
--- a/dnf/comps.py
+++ b/dnf/comps.py
@@ -75,7 +75,16 @@ def _by_pattern(pattern, case_sensitive, sqn):
else:
match = re.compile(fnmatch.translate(pattern), flags=re.I).match
- return {g for g in sqn if match(g.name) or match(g.id) or match(g.ui_name)}
+ ret = set()
+ for g in sqn:
+ if match(g.id):
+ ret.add(g)
+ elif g.name is not None and match(g.name):
+ ret.add(g)
+ elif g.ui_name is not None and match(g.ui_name):
+ ret.add(g)
+
+ return ret
def _fn_display_order(group):
diff --git a/dnf/db/group.py b/dnf/db/group.py
index e3a087760b..5d7e18d1a8 100644
--- a/dnf/db/group.py
+++ b/dnf/db/group.py
@@ -78,8 +78,10 @@ def _get_obj_id(self, obj):
def new(self, obj_id, name, translated_name, pkg_types):
swdb_group = self.history.swdb.createCompsGroupItem()
swdb_group.setGroupId(obj_id)
- swdb_group.setName(name)
- swdb_group.setTranslatedName(translated_name)
+ if name is not None:
+ swdb_group.setName(name)
+ if translated_name is not None:
+ swdb_group.setTranslatedName(translated_name)
swdb_group.setPackageTypes(pkg_types)
return swdb_group
@@ -136,8 +138,10 @@ def _get_obj_id(self, obj):
def new(self, obj_id, name, translated_name, pkg_types):
swdb_env = self.history.swdb.createCompsEnvironmentItem()
swdb_env.setEnvironmentId(obj_id)
- swdb_env.setName(name)
- swdb_env.setTranslatedName(translated_name)
+ if name is not None:
+ swdb_env.setName(name)
+ if translated_name is not None:
+ swdb_env.setTranslatedName(translated_name)
swdb_env.setPackageTypes(pkg_types)
return swdb_env
diff --git a/tests/repos/main_comps.xml b/tests/repos/main_comps.xml
index 9e694d13a5..584bb25b3a 100644
--- a/tests/repos/main_comps.xml
+++ b/tests/repos/main_comps.xml
@@ -49,6 +49,13 @@
<packagereq type="optional">brokendeps</packagereq>
</packagelist>
</group>
+ <group>
+ <id>missing-name-group</id>
+ <name></name>
+ <packagelist>
+ <packagereq type="mandatory">meaning-of-life</packagereq>
+ </packagelist>
+ </group>
<category>
<id>base-system</id>
<display_order>99</display_order>
diff --git a/tests/support.py b/tests/support.py
index e549ba5b95..a7d6a8542c 100644
--- a/tests/support.py
+++ b/tests/support.py
@@ -94,7 +94,7 @@ def mock_open(mock=None, data=None):
MAIN_NSOLVABLES = 9
UPDATES_NSOLVABLES = 4
AVAILABLE_NSOLVABLES = MAIN_NSOLVABLES + UPDATES_NSOLVABLES
-TOTAL_GROUPS = 4
+TOTAL_GROUPS = 5
TOTAL_NSOLVABLES = SYSTEM_NSOLVABLES + AVAILABLE_NSOLVABLES
diff --git a/tests/test_comps.py b/tests/test_comps.py
index 30d468e3af..763218587f 100644
--- a/tests/test_comps.py
+++ b/tests/test_comps.py
@@ -107,7 +107,7 @@ def test_group_packages(self):
def test_iteration(self):
comps = self.comps
self.assertEqual([g.name for g in comps.groups_iter()],
- ['Base', 'Solid Ground', "Pepper's", "Broken Group"])
+ ['Base', 'Solid Ground', "Pepper's", "Broken Group", None])
self.assertEqual([c.name for c in comps.categories_iter()],
['Base System'])
g = dnf.util.first(comps.groups_iter())
@@ -115,7 +115,7 @@ def test_iteration(self):
def test_group_display_order(self):
self.assertEqual([g.name for g in self.comps.groups],
- ["Pepper's", 'Base', 'Solid Ground', 'Broken Group'])
+ ["Pepper's", 'Base', 'Solid Ground', 'Broken Group', None])
def test_packages(self):
comps = self.comps
@@ -127,7 +127,7 @@ def test_packages(self):
def test_size(self):
comps = self.comps
- self.assertLength(comps, 6)
+ self.assertLength(comps, 7)
self.assertLength(comps.groups, tests.support.TOTAL_GROUPS)
self.assertLength(comps.categories, 1)
self.assertLength(comps.environments, 1)
diff --git a/tests/test_groups.py b/tests/test_groups.py
index fe388f96c0..8972da687e 100644
--- a/tests/test_groups.py
+++ b/tests/test_groups.py
@@ -295,6 +295,15 @@ def test_group_install_broken_optional_nonstrict(self):
self.assertLength(inst, 1)
self.assertEmpty(removed)
+ def test_group_install_missing_name(self):
+ comps_group = self.base.comps.group_by_pattern('missing-name-group')
+
+ cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional'),
+ strict=False)
+ self._swdb_commit()
+ self.base.resolve()
+ self.assertEqual(cnt, 1)
+
class EnvironmentInstallTest(tests.support.ResultTestCase):
"""Set up a test where sugar is considered not installed."""

View File

@ -0,0 +1,302 @@
From 9f9bfdfcb576846436f97275d6ee82004ceb4cb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
Date: Thu, 4 Jun 2020 16:02:58 +0200
Subject: [PATCH 1/3] Add logfilelevel configuration (RhBug:1802074)
https://bugzilla.redhat.com/show_bug.cgi?id=1802074
---
dnf.spec | 2 +-
dnf/logging.py | 17 +++++++++++------
doc/conf_ref.rst | 6 ++++++
3 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/dnf.spec b/dnf.spec
index 1423c6d5b5..27bae7aaa7 100644
--- a/dnf.spec
+++ b/dnf.spec
@@ -1,5 +1,5 @@
# default dependencies
-%global hawkey_version 0.48.0
+%global hawkey_version 0.50.0
%global libcomps_version 0.1.8
%global libmodulemd_version 1.4.0
%global rpm_version 4.14.0
diff --git a/dnf/logging.py b/dnf/logging.py
index bd660470a3..c578575e1c 100644
--- a/dnf/logging.py
+++ b/dnf/logging.py
@@ -70,11 +70,14 @@ def filter(self, record):
4 : logging.DEBUG,
5 : logging.DEBUG,
6 : logging.DEBUG, # verbose value
+ 7 : DDEBUG,
+ 8 : SUBDEBUG,
+ 9 : TRACE,
}
def _cfg_verbose_val2level(cfg_errval):
assert 0 <= cfg_errval <= 10
- return _VERBOSE_VAL_MAPPING.get(cfg_errval, DDEBUG)
+ return _VERBOSE_VAL_MAPPING.get(cfg_errval, TRACE)
# Both the DNF default and the verbose default are WARNING. Note that ERROR has
@@ -157,13 +160,14 @@ def _presetup(self):
self.stderr_handler = stderr
@only_once
- def _setup_file_loggers(self, verbose_level, logdir, log_size, log_rotate):
+ def _setup_file_loggers(self, logfile_level, 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)
+ handler.setLevel(logfile_level)
logger_dnf.addHandler(handler)
# put the marker in the file now:
_paint_mark(logger_dnf)
@@ -185,14 +189,14 @@ def _setup_file_loggers(self, verbose_level, logdir, log_size, log_rotate):
_paint_mark(logger_rpm)
@only_once
- def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate):
+ def _setup(self, verbose_level, error_level, logfile_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)
+ self._setup_file_loggers(logfile_level, verbose_level, logdir, log_size, log_rotate)
logger_warnings = logging.getLogger("py.warnings")
logger_warnings.addHandler(self.stderr_handler)
@@ -209,13 +213,14 @@ def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate):
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)
+ logfile_level_r = _cfg_verbose_val2level(conf.logfilelevel)
logdir = conf.logdir
log_size = conf.log_size
log_rotate = conf.log_rotate
if file_loggers_only:
- return self._setup_file_loggers(verbose_level_r, logdir, log_size, log_rotate)
+ return self._setup_file_loggers(logfile_level_r, verbose_level_r, logdir, log_size, log_rotate)
else:
- return self._setup(verbose_level_r, error_level_r, logdir, log_size, log_rotate)
+ return self._setup(verbose_level_r, error_level_r, logfile_level_r, logdir, log_size, log_rotate)
class Timer(object):
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
index cf442770c9..fed6efcec7 100644
--- a/doc/conf_ref.rst
+++ b/doc/conf_ref.rst
@@ -268,6 +268,12 @@ configuration file by your distribution to override the DNF defaults.
Directory where the log files will be stored. Default is ``/var/log``.
+``logfilelevel``
+ :ref:`integer <integer-label>`
+
+ Log file messages output level, in the range 0 to 10. The higher the number the
+ more debug output is put to logs. Default is 9.
+
.. _log_rotate-label:
``log_rotate``
From 1233d7da657ffbd03f9ffc274b648da0bb2898bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
Date: Fri, 5 Jun 2020 09:21:15 +0200
Subject: [PATCH 2/3] Update unit logging test to reflect logfilelevel addition
---
tests/test_logging.py | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/tests/test_logging.py b/tests/test_logging.py
index a7fee3e67c..80e219d882 100644
--- a/tests/test_logging.py
+++ b/tests/test_logging.py
@@ -88,7 +88,7 @@ def test_setup(self):
logger = logging.getLogger("dnf")
with tests.support.patch_std_streams() as (stdout, stderr):
self.logging._setup(
- logging.INFO, logging.ERROR, self.logdir, self.log_size, self.log_rotate)
+ logging.INFO, logging.ERROR, dnf.logging.TRACE, self.logdir, self.log_size, self.log_rotate)
self._bench(logger)
self.assertEqual("i\n", stdout.getvalue())
self.assertEqual("e\n", stderr.getvalue())
@@ -97,7 +97,7 @@ def test_setup_verbose(self):
logger = logging.getLogger("dnf")
with tests.support.patch_std_streams() as (stdout, stderr):
self.logging._setup(
- logging.DEBUG, logging.WARNING, self.logdir, self.log_size, self.log_rotate)
+ logging.DEBUG, logging.WARNING, dnf.logging.TRACE, self.logdir, self.log_size, self.log_rotate)
self._bench(logger)
self.assertEqual("d\ni\n", stdout.getvalue())
self.assertEqual("w\ne\n", stderr.getvalue())
@@ -105,20 +105,22 @@ def test_setup_verbose(self):
@mock.patch('dnf.logging.Logging._setup')
def test_setup_from_dnf_conf(self, setup_m):
conf = mock.Mock(
- debuglevel=2, errorlevel=3, logdir=self.logdir,
+ debuglevel=2, errorlevel=3, logfilelevel=2, logdir=self.logdir,
log_size=self.log_size, log_rotate=self.log_rotate)
self.logging._setup_from_dnf_conf(conf)
self.assertEqual(setup_m.call_args, mock.call(dnf.logging.INFO,
dnf.logging.WARNING,
+ dnf.logging.INFO,
self.logdir,
self.log_size,
self.log_rotate))
conf = mock.Mock(
- debuglevel=6, errorlevel=6, logdir=self.logdir,
+ debuglevel=6, errorlevel=6, logfilelevel=6, logdir=self.logdir,
log_size=self.log_size, log_rotate=self.log_rotate)
self.logging._setup_from_dnf_conf(conf)
self.assertEqual(setup_m.call_args, mock.call(dnf.logging.DEBUG,
dnf.logging.WARNING,
+ dnf.logging.DEBUG,
self.logdir,
self.log_size,
self.log_rotate))
@@ -126,7 +128,7 @@ def test_setup_from_dnf_conf(self, setup_m):
def test_file_logging(self):
# log nothing to the console:
self.logging._setup(
- dnf.logging.SUPERCRITICAL, dnf.logging.SUPERCRITICAL,
+ dnf.logging.SUPERCRITICAL, dnf.logging.SUPERCRITICAL, dnf.logging.TRACE,
self.logdir, self.log_size, self.log_rotate)
logger = logging.getLogger("dnf")
with tests.support.patch_std_streams() as (stdout, stderr):
@@ -145,7 +147,7 @@ def test_file_logging(self):
def test_rpm_logging(self):
# log everything to the console:
self.logging._setup(
- dnf.logging.SUBDEBUG, dnf.logging.SUBDEBUG,
+ dnf.logging.SUBDEBUG, dnf.logging.SUBDEBUG, dnf.logging.TRACE,
self.logdir, self.log_size, self.log_rotate)
logger = logging.getLogger("dnf.rpm")
with tests.support.patch_std_streams() as (stdout, stderr):
@@ -167,7 +169,7 @@ def test_setup_only_once(self):
logger = logging.getLogger("dnf")
self.assertLength(logger.handlers, 0)
self.logging._setup(
- dnf.logging.SUBDEBUG, dnf.logging.SUBDEBUG,
+ dnf.logging.SUBDEBUG, dnf.logging.SUBDEBUG, dnf.logging.TRACE,
self.logdir, self.log_size, self.log_rotate)
cnt = len(logger.handlers)
self.assertGreater(cnt, 0)
From 8a57da7229c67315d113b3c61cf981e1a7d81189 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
Date: Thu, 25 Jun 2020 14:03:02 +0200
Subject: [PATCH 3/3] Control hawkey and librepo log verbosity with
logfilelevel
= changelog =
msg: New config option 'logfilelevel' now controls logging to dnf.log, dnf.librepo.log and hawkey.log
type: enhancement
resolves: 1802074
---
dnf/logging.py | 11 +++++++----
dnf/sack.py | 2 +-
doc/conf_ref.rst | 3 +++
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/dnf/logging.py b/dnf/logging.py
index c578575e1c..b5196988f7 100644
--- a/dnf/logging.py
+++ b/dnf/logging.py
@@ -43,6 +43,7 @@
DDEBUG = 8 # used by anaconda (pyanaconda/payload/dnfpayload.py)
SUBDEBUG = 6
TRACE = 4
+ALL = 2
def only_once(func):
"""Method decorator turning the method into noop on second or later calls."""
@@ -73,6 +74,7 @@ def filter(self, record):
7 : DDEBUG,
8 : SUBDEBUG,
9 : TRACE,
+ 10: ALL, # more verbous librepo and hawkey
}
def _cfg_verbose_val2level(cfg_errval):
@@ -138,6 +140,7 @@ def __init__(self):
logging.addLevelName(DDEBUG, "DDEBUG")
logging.addLevelName(SUBDEBUG, "SUBDEBUG")
logging.addLevelName(TRACE, "TRACE")
+ logging.addLevelName(ALL, "ALL")
logging.captureWarnings(True)
logging.raiseExceptions = False
@@ -160,7 +163,7 @@ def _presetup(self):
self.stderr_handler = stderr
@only_once
- def _setup_file_loggers(self, logfile_level, verbose_level, logdir, log_size, log_rotate):
+ def _setup_file_loggers(self, logfile_level, logdir, log_size, log_rotate):
logger_dnf = logging.getLogger("dnf")
logger_dnf.setLevel(TRACE)
@@ -177,7 +180,7 @@ def _setup_file_loggers(self, logfile_level, verbose_level, logdir, log_size, lo
logger_warnings.addHandler(handler)
lr_logfile = os.path.join(logdir, dnf.const.LOG_LIBREPO)
- libdnf.repo.LibrepoLog.addHandler(lr_logfile, verbose_level <= DEBUG)
+ libdnf.repo.LibrepoLog.addHandler(lr_logfile, logfile_level <= ALL)
# setup RPM callbacks logger
logger_rpm = logging.getLogger("dnf.rpm")
@@ -196,7 +199,7 @@ def _setup(self, verbose_level, error_level, logfile_level, logdir, log_size, lo
self.stdout_handler.setLevel(SUPERCRITICAL)
self.stderr_handler.setLevel(SUPERCRITICAL)
- self._setup_file_loggers(logfile_level, verbose_level, logdir, log_size, log_rotate)
+ self._setup_file_loggers(logfile_level, logdir, log_size, log_rotate)
logger_warnings = logging.getLogger("py.warnings")
logger_warnings.addHandler(self.stderr_handler)
@@ -218,7 +221,7 @@ def _setup_from_dnf_conf(self, conf, file_loggers_only=False):
log_size = conf.log_size
log_rotate = conf.log_rotate
if file_loggers_only:
- return self._setup_file_loggers(logfile_level_r, verbose_level_r, logdir, log_size, log_rotate)
+ return self._setup_file_loggers(logfile_level_r, logdir, log_size, log_rotate)
else:
return self._setup(verbose_level_r, error_level_r, logfile_level_r, logdir, log_size, log_rotate)
diff --git a/dnf/sack.py b/dnf/sack.py
index fb8c70712f..3c6bc3bbe0 100644
--- a/dnf/sack.py
+++ b/dnf/sack.py
@@ -53,7 +53,7 @@ def _build_sack(base):
arch=base.conf.substitutions["arch"],
cachedir=cachedir, rootdir=base.conf.installroot,
logfile=os.path.join(base.conf.logdir, dnf.const.LOG_HAWKEY),
- logdebug=base.conf.debuglevel > 2)
+ logdebug=base.conf.logfilelevel > 9)
def _rpmdb_sack(base):
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
index fed6efcec7..fdb44a657d 100644
--- a/doc/conf_ref.rst
+++ b/doc/conf_ref.rst
@@ -274,6 +274,9 @@ configuration file by your distribution to override the DNF defaults.
Log file messages output level, in the range 0 to 10. The higher the number the
more debug output is put to logs. Default is 9.
+ This option controls dnf.log, dnf.librepo.log and hawkey.log. Although dnf.librepo.log
+ and hawkey.log are affected only by setting the logfilelevel to 10.
+
.. _log_rotate-label:
``log_rotate``

View File

@ -1,67 +0,0 @@
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

View File

@ -0,0 +1,41 @@
From 03eac4f0b87bb9393e1662af76c433c996c702ab Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Tue, 14 Jul 2020 08:37:28 +0200
Subject: [PATCH] [doc] Enhance repo variables documentation
(RhBug:1848161,1848615)
- clarify DNF_VAR_XXX variables usage
- mention numeric variables
https://bugzilla.redhat.com/show_bug.cgi?id=1848615
https://bugzilla.redhat.com/show_bug.cgi?id=1848161
---
doc/conf_ref.rst | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
index fdb44a657d..a0362d0779 100644
--- a/doc/conf_ref.rst
+++ b/doc/conf_ref.rst
@@ -629,6 +629,21 @@ In addition to these hard coded variables, user-defined ones can also be used. T
$ DNF_VAR_MY_VARIABLE=value
+To use such variable in your repository configuration remove the prefix. E.g.::
+
+ [myrepo]
+ baseurl=https://example.site/pub/fedora/$MY_VARIABLE/releases/$releasever
+
+Note that it is not possible to override the ``arch`` and ``basearch`` variables using either variable files or environmental variables.
+
+Although users are encouraged to use named variables, the numbered environmental variables ``DNF0`` - ``DNF9`` are still supported::
+
+ $ DNF1=value
+
+ [myrepo]
+ baseurl=https://example.site/pub/fedora/$DNF1/releases/$releasever
+
+
.. _conf_main_and_repo_options-label:
==================================

View File

@ -1,32 +0,0 @@
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

View File

@ -1,157 +0,0 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -1,106 +0,0 @@
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):

View File

@ -1,125 +0,0 @@
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.

View File

@ -1,111 +0,0 @@
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()

View File

@ -1,115 +0,0 @@
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"))

View File

@ -1,33 +0,0 @@
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

View File

@ -1,61 +0,0 @@
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)

View File

@ -1,50 +0,0 @@
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,

View File

@ -1,32 +0,0 @@
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 it is too large Load Diff

View File

@ -1,82 +0,0 @@
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)

View File

@ -1,57 +0,0 @@
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(

View File

@ -1,26 +0,0 @@
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
====================================================

View File

@ -1,138 +0,0 @@
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)

View File

@ -1,441 +0,0 @@
From bfd04883c44ad31407f0b5a48e06fa597c46d727 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Fri, 12 Jul 2019 17:14:00 +0200
Subject: [PATCH 1/6] repoquery: move the alldeps/exactdeps check to
configure()
Moves the check for alldeps/exactdeps switches to the configure() method
along with the other checks.
Raises dnf.cli.CliError instead of dnf.exceptions.Error.
---
dnf/cli/commands/repoquery.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
index 7334ddcd90..dc09bf4403 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -303,6 +303,12 @@ def configure(self):
"(optionally with '--alldeps', but not with '--exactdeps'), or with "
"'--requires <REQ> --resolve'"))
+ if self.opts.alldeps or self.opts.exactdeps:
+ if not (self.opts.whatrequires or self.opts.whatdepends):
+ raise dnf.cli.CliError(
+ _("argument {} requires --whatrequires or --whatdepends option".format(
+ '--alldeps' if self.opts.alldeps else '--exactdeps')))
+
if self.opts.srpm:
self.base.repos.enable_source_repos()
@@ -496,10 +502,6 @@ def run(self):
else:
q.filterm(file__glob=self.opts.whatprovides)
if self.opts.alldeps or self.opts.exactdeps:
- if not (self.opts.whatrequires or self.opts.whatdepends):
- raise dnf.exceptions.Error(
- _("argument {} requires --whatrequires or --whatdepends option".format(
- '--alldeps' if self.opts.alldeps else '--exactdeps')))
if self.opts.alldeps:
q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
else:
From d9492fef24989085011047dd561fef1dfa1e31d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Fri, 12 Jul 2019 17:22:05 +0200
Subject: [PATCH 2/6] repoquery: fix calling by_all_deps() for --tree
Fixes a bug introduced in bd00c044, where the by_all_deps() arguments
were changed to an array, but in tree_seed() it still passes a single
string.
Untested, I have actually no idea what the code does there, it looks
kind of suspect.
---
dnf/cli/commands/repoquery.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
index dc09bf4403..db174b3bba 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -674,7 +674,7 @@ def tree_seed(self, query, aquery, opts, level=-1, usedpkgs=None):
ar[querypkg.name + "." + querypkg.arch] = querypkg
pkgquery = self.base.sack.query().filterm(pkg=list(ar.values()))
else:
- pkgquery = self.by_all_deps(pkg.name, None, aquery) if opts.alldeps \
+ pkgquery = self.by_all_deps((pkg.name, ), None, aquery) if opts.alldeps \
else aquery.filter(requires__glob=pkg.name)
self.tree_seed(pkgquery, aquery, opts, level + 1, usedpkgs)
From f2f31452876b37b54150cba1bf08fc46ecaf72f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Fri, 12 Jul 2019 17:44:38 +0200
Subject: [PATCH 3/6] repoquery: simplify handling of whatrequires and
whatdepends
Separates whatrequires and whatdepends handling into two separate code
branches, the original was overly complex, confusing and presented
multiple unnecessary corner cases.
The by_all_deps() arguments now also have a much better defined role.
---
dnf/cli/commands/repoquery.py | 59 +++++++++++++++++------------------
1 file changed, 29 insertions(+), 30 deletions(-)
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
index db174b3bba..f5e951c9c8 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -350,7 +350,7 @@ def build_format_fn(self, opts, pkg):
raise dnf.exceptions.Error(str(e))
def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False,
- all_deps=False):
+ all_dep_types=False):
done = done if done else self.base.sack.query().filterm(empty=True)
t = self.base.sack.query().filterm(empty=True)
set_requires = set()
@@ -360,7 +360,7 @@ def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive
pkg_provides = pkg.provides
set_requires.update(pkg_provides)
set_requires.update(pkg.files)
- if all_deps:
+ if all_dep_types:
set_all_deps.update(pkg_provides)
t = t.union(query_in.filter(requires=set_requires))
@@ -373,29 +373,29 @@ def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive
query_select = t.difference(done)
if query_select:
done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done),
- recursive=recursive, all_deps=all_deps)
+ recursive=recursive,
+ all_dep_types=all_dep_types)
return t.union(done)
- def by_all_deps(self, requires_name, depends_name, query):
- names = requires_name or depends_name
+ def by_all_deps(self, names, query, all_dep_types=False):
defaultquery = self.base.sack.query().filterm(empty=True)
for name in names:
defaultquery = 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))
- requiresquery = requiresquery.union(query.filter(supplements__glob=depends_name))
- requiresquery = requiresquery.union(query.filter(suggests__glob=depends_name))
+ if all_dep_types:
+ requiresquery = requiresquery.union(query.filter(recommends__glob=names))
+ requiresquery = requiresquery.union(query.filter(enhances__glob=names))
+ requiresquery = requiresquery.union(query.filter(supplements__glob=names))
+ requiresquery = requiresquery.union(query.filter(suggests__glob=names))
done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery,
- all_deps=depends_name))
+ all_dep_types=all_dep_types))
if self.opts.recursive:
done = done.union(self._get_recursive_deps_query(query, done,
recursive=self.opts.recursive,
- all_deps=depends_name))
+ all_dep_types=all_dep_types))
return done
def _get_recursive_providers_query(self, query_in, providers, done=None):
@@ -501,24 +501,23 @@ def run(self):
q = query_for_provide
else:
q.filterm(file__glob=self.opts.whatprovides)
- if self.opts.alldeps or self.opts.exactdeps:
- if self.opts.alldeps:
- q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
+
+ if self.opts.whatrequires:
+ if (self.opts.exactdeps):
+ q.filterm(requires__glob=self.opts.whatrequires)
else:
- if self.opts.whatrequires:
- q.filterm(requires__glob=self.opts.whatrequires)
- else:
- dependsquery = q.filter(requires__glob=self.opts.whatdepends)
- dependsquery = dependsquery.union(
- q.filter(recommends__glob=self.opts.whatdepends))
- dependsquery = dependsquery.union(
- q.filter(enhances__glob=self.opts.whatdepends))
- dependsquery = dependsquery.union(
- q.filter(supplements__glob=self.opts.whatdepends))
- q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends))
-
- elif self.opts.whatrequires or self.opts.whatdepends:
- q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
+ q = self.by_all_deps(self.opts.whatrequires, q)
+
+ if self.opts.whatdepends:
+ if (self.opts.exactdeps):
+ dependsquery = q.filter(requires__glob=self.opts.whatdepends)
+ dependsquery = dependsquery.union(q.filter(recommends__glob=self.opts.whatdepends))
+ dependsquery = dependsquery.union(q.filter(enhances__glob=self.opts.whatdepends))
+ dependsquery = dependsquery.union(q.filter(supplements__glob=self.opts.whatdepends))
+ q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends))
+ else:
+ q = self.by_all_deps(self.opts.whatdepends, q, True)
+
if self.opts.whatrecommends:
q.filterm(recommends__glob=self.opts.whatrecommends)
if self.opts.whatenhances:
@@ -674,7 +673,7 @@ def tree_seed(self, query, aquery, opts, level=-1, usedpkgs=None):
ar[querypkg.name + "." + querypkg.arch] = querypkg
pkgquery = self.base.sack.query().filterm(pkg=list(ar.values()))
else:
- pkgquery = self.by_all_deps((pkg.name, ), None, aquery) if opts.alldeps \
+ pkgquery = self.by_all_deps((pkg.name, ), aquery) if opts.alldeps \
else aquery.filter(requires__glob=pkg.name)
self.tree_seed(pkgquery, aquery, opts, level + 1, usedpkgs)
From a1bdbfa498438c2710aecd607a82face05a1bdfd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Tue, 9 Jul 2019 17:30:58 +0200
Subject: [PATCH 4/6] repoquery: rework "alldeps" dependency search
(RhBug:1534123,1698034)
Uses the new feature of filtering by solvables to properly resolve rich
dependencies for packages. The new code now, along with serching for the
arguments as reldeps, also searches for them as NEVRAs and then looks up
the dependencies for the packages it found.
https://bugzilla.redhat.com/show_bug.cgi?id=1534123
https://bugzilla.redhat.com/show_bug.cgi?id=1698034
---
dnf.spec | 2 +-
dnf/cli/commands/repoquery.py | 93 +++++++++++++++++++----------------
2 files changed, 51 insertions(+), 44 deletions(-)
diff --git a/dnf.spec b/dnf.spec
index 79e4d27dab..578baccac4 100644
--- a/dnf.spec
+++ b/dnf.spec
@@ -1,5 +1,5 @@
# default dependencies
-%global hawkey_version 0.41.0
+%global hawkey_version 0.44.0
%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 f5e951c9c8..d86d32ffcd 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -349,54 +349,61 @@ def build_format_fn(self, opts, pkg):
# there don't exist on the dnf Package object.
raise dnf.exceptions.Error(str(e))
- def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False,
- all_dep_types=False):
- done = done if done else self.base.sack.query().filterm(empty=True)
- t = self.base.sack.query().filterm(empty=True)
- set_requires = set()
- set_all_deps = set()
-
- for pkg in query_select.run():
- pkg_provides = pkg.provides
- set_requires.update(pkg_provides)
- set_requires.update(pkg.files)
- if all_dep_types:
- set_all_deps.update(pkg_provides)
-
- t = t.union(query_in.filter(requires=set_requires))
- if set_all_deps:
- t = t.union(query_in.filter(recommends=set_all_deps))
- t = t.union(query_in.filter(enhances=set_all_deps))
- t = t.union(query_in.filter(supplements=set_all_deps))
- t = t.union(query_in.filter(suggests=set_all_deps))
- if recursive:
- query_select = t.difference(done)
- if query_select:
- done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done),
- recursive=recursive,
- all_dep_types=all_dep_types)
- return t.union(done)
+ def _resolve_nevras(self, nevras, base_query):
+ resolved_nevras_query = self.base.sack.query().filterm(empty=True)
+ for nevra in nevras:
+ resolved_nevras_query = resolved_nevras_query.union(base_query.intersection(
+ dnf.subject.Subject(nevra).get_best_query(
+ self.base.sack,
+ with_provides=False,
+ with_filenames=False
+ )
+ ))
+
+ return resolved_nevras_query
+
+ def _do_recursive_deps(self, query_in, query_select, done=None):
+ done = done if done else query_select
+
+ query_required = query_in.filter(requires=query_select)
+
+ query_select = query_required.difference(done)
+ done = query_required.union(done)
+
+ if query_select:
+ done = self._do_recursive_deps(query_in, query_select, done=done)
+
+ return done
def by_all_deps(self, names, query, all_dep_types=False):
- defaultquery = self.base.sack.query().filterm(empty=True)
- for name in names:
- defaultquery = 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)
+ # in case of arguments being NEVRAs, resolve them to packages
+ resolved_nevras_query = self._resolve_nevras(names, query)
+
+ # filter the arguments directly as reldeps
+ depquery = query.filter(requires__glob=names)
+
+ # filter the resolved NEVRAs as packages
+ depquery = depquery.union(query.filter(requires=resolved_nevras_query))
+
if all_dep_types:
- requiresquery = requiresquery.union(query.filter(recommends__glob=names))
- requiresquery = requiresquery.union(query.filter(enhances__glob=names))
- requiresquery = requiresquery.union(query.filter(supplements__glob=names))
- requiresquery = requiresquery.union(query.filter(suggests__glob=names))
+ # TODO this is very inefficient, as it resolves the `names` glob to
+ # reldeps four more times, which in a reasonably wide glob like
+ # `dnf repoquery --whatdepends "libdnf*"` can take roughly 50% of
+ # the total execution time.
+ depquery = depquery.union(query.filter(recommends__glob=names))
+ depquery = depquery.union(query.filter(enhances__glob=names))
+ depquery = depquery.union(query.filter(supplements__glob=names))
+ depquery = depquery.union(query.filter(suggests__glob=names))
+
+ depquery = depquery.union(query.filter(recommends=resolved_nevras_query))
+ depquery = depquery.union(query.filter(enhances=resolved_nevras_query))
+ depquery = depquery.union(query.filter(supplements=resolved_nevras_query))
+ depquery = depquery.union(query.filter(suggests=resolved_nevras_query))
- done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery,
- all_dep_types=all_dep_types))
if self.opts.recursive:
- done = done.union(self._get_recursive_deps_query(query, done,
- recursive=self.opts.recursive,
- all_dep_types=all_dep_types))
- return done
+ depquery = self._do_recursive_deps(query, depquery)
+
+ return depquery
def _get_recursive_providers_query(self, query_in, providers, done=None):
done = done if done else self.base.sack.query().filterm(empty=True)
From 60cd14aae7fe3d9ae75d5e5665fc311ef3b04402 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Fri, 1 Nov 2019 18:33:13 +0100
Subject: [PATCH 5/6] repoquery: resolve NEVRAs to packages for most of --what*
arguments (RhBug:1534123,1698034)
To properly list the conflicts, suggests, recommends, enhances and
supplements dependencies of packages defined through provides or even
rich dependencies, it is required to resolve them to packages and query
for them, because that's where the dependencies are defined.
https://bugzilla.redhat.com/show_bug.cgi?id=1534123
https://bugzilla.redhat.com/show_bug.cgi?id=1698034
---
dnf/cli/commands/repoquery.py | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
index d86d32ffcd..d0521432be 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -499,7 +499,8 @@ def run(self):
if self.opts.file:
q.filterm(file__glob=self.opts.file)
if self.opts.whatconflicts:
- q.filterm(conflicts=self.opts.whatconflicts)
+ rels = q.filter(conflicts__glob=self.opts.whatconflicts)
+ q = rels.union(q.filter(conflicts=self._resolve_nevras(self.opts.whatconflicts, q)))
if self.opts.whatobsoletes:
q.filterm(obsoletes=self.opts.whatobsoletes)
if self.opts.whatprovides:
@@ -526,13 +527,18 @@ def run(self):
q = self.by_all_deps(self.opts.whatdepends, q, True)
if self.opts.whatrecommends:
- q.filterm(recommends__glob=self.opts.whatrecommends)
+ rels = q.filter(recommends__glob=self.opts.whatrecommends)
+ q = rels.union(q.filter(recommends=self._resolve_nevras(self.opts.whatrecommends, q)))
if self.opts.whatenhances:
- q.filterm(enhances__glob=self.opts.whatenhances)
+ rels = q.filter(enhances__glob=self.opts.whatenhances)
+ q = rels.union(q.filter(enhances=self._resolve_nevras(self.opts.whatenhances, q)))
if self.opts.whatsupplements:
- q.filterm(supplements__glob=self.opts.whatsupplements)
+ rels = q.filter(supplements__glob=self.opts.whatsupplements)
+ q = rels.union(q.filter(supplements=self._resolve_nevras(self.opts.whatsupplements, q)))
if self.opts.whatsuggests:
- q.filterm(suggests__glob=self.opts.whatsuggests)
+ rels = q.filter(suggests__glob=self.opts.whatsuggests)
+ q = rels.union(q.filter(suggests=self._resolve_nevras(self.opts.whatsuggests, q)))
+
if self.opts.latest_limit:
q = q.latest(self.opts.latest_limit)
# reduce a query to security upgrades if they are specified
From 757f9ad4f26c5a0fee9a6a3620eea94dd6004a73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
Date: Tue, 14 Jan 2020 16:44:07 +0100
Subject: [PATCH 6/6] [doc] Update documentation for the query filter API
Add the new types of arguments supported for dependency filtering.
---
doc/api_queries.rst | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/doc/api_queries.rst b/doc/api_queries.rst
index 5c8804e52a..98907d95a6 100644
--- a/doc/api_queries.rst
+++ b/doc/api_queries.rst
@@ -101,17 +101,20 @@
release string match against packages' releases
reponame string match against packages repositories' names
version string match against packages' versions
- obsoletes Query match packages that obsolete any package from query
pkg Query match against packages in query
pkg* list match against hawkey.Packages in list
provides string match against packages' provides
provides* Hawkey.Reldep match against packages' provides
- requires string match against packages' requirements
- requires* Hawkey.Reldep match against packages' requirements
+ <DEP> string match against packages' <DEP>
+ <DEP>* Hawkey.Reldep match a reldep against packages' <DEP>
+ <DEP>* Query match the result of a query against packages' <DEP>
+ <DEP>* list(Package) match the list of hawkey.Packages against packages' <DEP>
sourcerpm string match against packages' source rpm
upgrades boolean see :meth:`upgrades`. Defaults to ``False``.
=============== ============== ======================================================
+ ``<DEP>`` can be any of: requires, conflicts, obsoletes, enhances, recomments, suggests, supplements
+
\* The key can also accept a list of values with specified type.
The key name can be supplemented with a relation-specifying suffix, separated by ``__``:
@@ -133,6 +136,8 @@
q = base.sack.query().filter(name__substr="club")
+ Note that using packages or queries for dependency filtering performs a more advanced resolution than using a string or a reldep. When a package list or a query is used, rich dependencies are resolved in a more precise way than what is possible when a string or a reldep is used.
+
.. method:: filterm(\*\*kwargs)
Similar to :meth:`dnf.query.Query.filter` but it modifies the query in place.

View File

@ -1,11 +1,11 @@
# default dependencies # default dependencies
%global hawkey_version 0.39.1-6 %global hawkey_version 0.48.0-3
%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.2-35 %global rpm_version 4.14.2-35
# conflicts # conflicts
%global conflicts_dnf_plugins_core_version 4.0.12 %global conflicts_dnf_plugins_core_version 4.0.16
%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
@ -81,31 +81,17 @@
It supports RPMs, modules and comps groups & environments. It supports RPMs, modules and comps groups & environments.
Name: dnf Name: dnf
Version: 4.2.17 Version: 4.2.23
Release: 7%{?dist} Release: 4%{?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
Patch1: 0001-Do-a-substitution-of-variables-in-repo_id-RhBug1748841.patch Patch1: 0001-Handle-empty-comps-group-name-RhBug1826198.patch
Patch2: 0002-Fix-and-document-order-of-config-files-in-aliasesd-RhBug1680489.patch Patch2: 0002-Add-logfilelevel-configuration-RhBug-1802074.patch
Patch3: 0003-doc-Remove-note-about-whitelist.patch Patch3: 0003-Enhance-repo-variables-documentation-RhBug-1848161-1848615.patch
Patch4: 0004-Fix-detection-of-the-latest-module-RhBug1781769.patch Patch4: 0004-Update-translations-RhBug-1820544.patch
Patch5: 0005-Unify-downgrade-exit-codes-with-upgrade-RhBug1759847.patch
Patch6: 0006-Restore-functionality-of-remove-oldinstallonly.patch
Patch7: 0007-Shell-restriction-with-local-packages.patch
Patch8: 0008-Improve-help-for-dnf-module-command-RhBug1758447.patch
Patch9: 0009-Fix-alias-processing-with-backslash-escaping-RhBug1680482.patch
Patch10: 0010-Honor-priority-with-check-update-RhBug1769466.patch
Patch11: 0011-Better-descriptions-for-infinite-aliases-recursion-RhBug1680488.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
Patch18: 0018-repoquery-fix-rich-deps-matching-by-using-provide-expansion-from-libdn-RhBug-1819172.patch
BuildArch: noarch BuildArch: noarch
BuildRequires: cmake BuildRequires: cmake
@ -156,8 +142,8 @@ Provides: dnf-command(upgrade)
Provides: dnf-command(upgrade-to) Provides: dnf-command(upgrade-to)
Conflicts: python2-dnf-plugins-core < %{conflicts_dnf_plugins_core_version} Conflicts: python2-dnf-plugins-core < %{conflicts_dnf_plugins_core_version}
Conflicts: python3-dnf-plugins-core < %{conflicts_dnf_plugins_core_version} Conflicts: python3-dnf-plugins-core < %{conflicts_dnf_plugins_core_version}
Conflicts: python2-dnf-plugins-extras < %{conflicts_dnf_plugins_extras_version} Conflicts: python2-dnf-plugins-extras-common < %{conflicts_dnf_plugins_extras_version}
Conflicts: python3-dnf-plugins-extras < %{conflicts_dnf_plugins_extras_version} Conflicts: python3-dnf-plugins-extras-common < %{conflicts_dnf_plugins_extras_version}
%description %description
%{pkg_description} %{pkg_description}
@ -212,11 +198,9 @@ Requires: python2-enum34
Requires: %{name}-data = %{version}-%{release} Requires: %{name}-data = %{version}-%{release}
%if 0%{?fedora} %if 0%{?fedora}
Recommends: deltarpm Recommends: deltarpm
# required for DNSSEC main.gpgkey_dns_verification https://dnf.readthedocs.io/en/latest/conf_ref.html
Recommends: python2-unbound Recommends: python2-unbound
%endif %endif
%if 0%{?centos}
Requires: deltarpm
%endif
Requires: python2-hawkey >= %{hawkey_version} Requires: python2-hawkey >= %{hawkey_version}
Requires: python2-libdnf >= %{hawkey_version} Requires: python2-libdnf >= %{hawkey_version}
Requires: python2-libcomps >= %{libcomps_version} Requires: python2-libcomps >= %{libcomps_version}
@ -254,15 +238,13 @@ Requires: %{name}-data = %{version}-%{release}
%if 0%{?fedora} %if 0%{?fedora}
Recommends: deltarpm Recommends: deltarpm
%endif %endif
%if 0%{?centos}
Requires: deltarpm
%endif
Requires: python3-hawkey >= %{hawkey_version} Requires: python3-hawkey >= %{hawkey_version}
Requires: python3-libdnf >= %{hawkey_version} Requires: python3-libdnf >= %{hawkey_version}
Requires: python3-libcomps >= %{libcomps_version} Requires: python3-libcomps >= %{libcomps_version}
Requires: python3-libdnf Requires: python3-libdnf
BuildRequires: python3-rpm >= %{rpm_version} BuildRequires: python3-rpm >= %{rpm_version}
Requires: python3-rpm >= %{rpm_version} Requires: python3-rpm >= %{rpm_version}
# required for DNSSEC main.gpgkey_dns_verification https://dnf.readthedocs.io/en/latest/conf_ref.html
Recommends: python3-unbound Recommends: python3-unbound
%if 0%{?rhel} && 0%{?rhel} <= 7 %if 0%{?rhel} && 0%{?rhel} <= 7
Requires: rpm-plugin-systemd-inhibit Requires: rpm-plugin-systemd-inhibit
@ -293,7 +275,7 @@ mkdir build-py3
%build %build
%if %{with python2} %if %{with python2}
pushd build-py2 pushd build-py2
%cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python2} %cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python2} -DDNF_VERSION=%{version}
%make_build %make_build
make doc-man make doc-man
popd popd
@ -301,7 +283,7 @@ mkdir build-py3
%if %{with python3} %if %{with python3}
pushd build-py3 pushd build-py3
%cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python3} %cmake .. -DPYTHON_DESIRED:FILEPATH=%{__python3} -DDNF_VERSION=%{version}
%make_build %make_build
make doc-man make doc-man
popd popd
@ -529,8 +511,71 @@ ln -sr %{buildroot}%{confdir}/vars %{buildroot}%{_sysconfdir}/yum/vars
%endif %endif
%changelog %changelog
* Wed May 06 2020 Nicola Sella <nsella@redhat.com> - 4.2.17-7 * Tue Jul 28 2020 Marek Blaha <mblaha@redhat.com> - 4.2.23-4
- repoquery: fix rich deps matching by using provide expansion from libdnf (RhBug:1819172) - Update translations
* Fri Jul 17 2020 Nicola Sella <nsella@redhat.com> - 4.2.23-3
- Add logfilelevel configuration (RhBug:1802074)
- [doc] Enhance repo variables documentation (RhBug:1848161,1848615)
* Wed Jun 10 2020 Ales Matej <amatej@redhat.com> - 4.2.23-2
- Handle empty comps group name (RhBug:1826198)
* Tue Jun 02 2020 Nicola Sella <nsella@redhat.com> - 4.2.23-1
- Update to 4.2.23
- Fix behavior of `install-n` command
- Fix behavior of `localinstall` command
- Fix behavior of `autoremove-n` command
- Fix behavior of `remove-n` command
- Fix behavior of `repoquery-n` command
- Fix behavior of `list-updateinfo` and related aliases
- Refactor code in `repoinfo` to use opts.command correctly.
- Add myself to list of contributors
- Add updated to verbose output of updateinfo list (RhBug: 1801092)
- Fix a couple of missed grammatical errors in updateinfo docs.
- Add comment option (RhBug:1773679)
- Better wording of dnssec email parsing error.
- Print nicer DnssecErrors (RhBug:1813244)
- Add new API for handling gpg signatures (RhBug:1339617)
- Verify GPG signatures (RhBug:1793298)
- Fix a syntax typo
- Fix up Conflicts: on python-dnf-plugins-extras so it actually works
- [doc] Move yum-plugin-post-transaction-actions to dnf-plugins-core
- Remove args "--set-enabled", "--set-disabled" from DNF (RhBug:1727882)
- Search command is now alphabetical (RhBug:1811802)
- Fix downloading packages with full URL as their location
- repo: catch libdnf.error.Error in addition to RuntimeError in load() (RhBug:1788182)
- History tbl to max size when redirect to file (RhBug:1786335,1786316)
* Mon Apr 06 2020 Ales Matej <amatej@redhat.com> - 4.2.21-1
- Update to 4.2.21
- Running with tsflags=test doesn't update log files
- Allow disabling individual aliases config files (RhBug:1680566)
- List arguments: only first empty value is used (RhBug:1788154)
- Report missing profiles or default as broken module (RhBug:1790967)
- Format history table to use actual terminal width (RhBug:1786316)
- Handle custom exceptions from libdnf
- Fix _skipped_packages to return only skipped (RhBug:1774617)
- Add setter for tsi.reason
- Add new hook for commands: Run_resolved
- Clean also .yaml repository metadata
- Use WantedBy=timers.target for all dnf timers (RhBug:1798475)
- Fix completion helper if solv files not in roon cache (RhBug:1714376)
- Add bash completion for 'dnf module' (RhBug:1565614)
- Check command no longer reports missing %pre and %post deps (RhBug:1543449)
- Check if arguments can be encoded in 'utf-8'
- Fix crash with "dnf -d 6 repolist" (RhBug:1812682)
- Do not print the first empty line for repoinfo
- Redirect logger and repo download progress when --verbose
- Respect repo priority when listing packages (RhBug:1800342)
- Remove misleading green color from the "broken dependencies" lines (RhBug:1814192)
- [repoquery] Fix rich deps matching by using provide expansion from libdnf (RhBug:1534123)
- [repoquery] Do not protect running kernel for --unsafisfied (RhBug:1750745)
- [doc] Document the retries config option only works for packages (RhBug:1783041)
- [doc] repoquery --what* with multiple arguments (RhBug:1790262)
- [doc] Remove incorrect information about includepkgs (RhBug:1813460)
- [doc] Document that list and info commands respect repo priority
- [doc] Document color options
* Tue Feb 18 2020 Ales Matej <amatej@redhat.com> - 4.2.17-6 * Tue Feb 18 2020 Ales Matej <amatej@redhat.com> - 4.2.17-6
- Sort packages in transaction output by nevra (RhBug:1773436) - Sort packages in transaction output by nevra (RhBug:1773436)