import dnf-plugins-core-4.0.21-2.el8

This commit is contained in:
CentOS Sources 2021-10-06 12:43:09 -04:00 committed by Stepan Oksanichenko
parent e1a3d6ce06
commit 3c83afcd73
9 changed files with 159 additions and 997 deletions

View File

@ -1 +1 @@
3b8638dec2cb91a13241106b9a57114ed037d2ca SOURCES/dnf-plugins-core-4.0.18.tar.gz 40f26a50a6605eacb1e9c4a443f01655fa461767 SOURCES/dnf-plugins-core-4.0.21.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/dnf-plugins-core-4.0.18.tar.gz SOURCES/dnf-plugins-core-4.0.21.tar.gz

View File

@ -1,653 +0,0 @@
From 40f08d7a22907e6292c314462c01de94584c0854 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Tue, 27 Oct 2020 15:46:03 +0100
Subject: [PATCH 1/2] [groups-manager] Re-introduce yum-groups-manager
functionality (RhBug:1826016)
Implements 'dnf groups-manager' command with features:
- read, merge, print and write groups metadata files
- edit group attributes name (with translated variants),
description (with translated variants), uservisible, displayorder
- add packgages to group
- remove packages from group
= changelog =
msg: Re-introduce yum-groups-manager functionality
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1826016
---
dnf-plugins-core.spec | 22 ++-
doc/CMakeLists.txt | 2 +
doc/conf.py | 2 +
doc/groups-manager.rst | 94 ++++++++++++
doc/index.rst | 1 +
libexec/dnf-utils.in | 1 +
plugins/CMakeLists.txt | 1 +
plugins/groups_manager.py | 314 ++++++++++++++++++++++++++++++++++++++
8 files changed, 432 insertions(+), 5 deletions(-)
create mode 100644 doc/groups-manager.rst
create mode 100644 plugins/groups_manager.py
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index d13a996..42d0884 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -58,6 +58,7 @@ Provides: dnf-command(debug-dump)
Provides: dnf-command(debug-restore)
Provides: dnf-command(debuginfo-install)
Provides: dnf-command(download)
+Provides: dnf-command(groups-manager)
Provides: dnf-command(repoclosure)
Provides: dnf-command(repograph)
Provides: dnf-command(repomanage)
@@ -73,6 +74,7 @@ Provides: dnf-plugin-debuginfo-install = %{version}-%{release}
Provides: dnf-plugin-download = %{version}-%{release}
Provides: dnf-plugin-generate_completion_cache = %{version}-%{release}
Provides: dnf-plugin-needs_restarting = %{version}-%{release}
+Provides: dnf-plugin-groups-manager = %{version}-%{release}
Provides: dnf-plugin-repoclosure = %{version}-%{release}
Provides: dnf-plugin-repodiff = %{version}-%{release}
Provides: dnf-plugin-repograph = %{version}-%{release}
@@ -87,7 +89,7 @@ Conflicts: dnf-plugins-extras-common-data < %{dnf_plugins_extra}
%description
Core Plugins for DNF. This package enhances DNF with builddep, config-manager,
-copr, debug, debuginfo-install, download, needs-restarting, repoclosure,
+copr, debug, debuginfo-install, download, needs-restarting, groups-manager, repoclosure,
repograph, repomanage, reposync, changelog and repodiff commands. Additionally
provides generate_completion_cache passive plugin.
@@ -129,7 +131,8 @@ Conflicts: python-%{name} < %{version}-%{release}
%description -n python2-%{name}
Core Plugins for DNF, Python 2 interface. This package enhances DNF with builddep,
config-manager, copr, degug, debuginfo-install, download, needs-restarting,
-repoclosure, repograph, repomanage, reposync, changelog and repodiff commands.
+groups-manager, repoclosure, repograph, repomanage, reposync, changelog
+and repodiff commands.
Additionally provides generate_completion_cache passive plugin.
%endif
@@ -163,7 +166,8 @@ Conflicts: python-%{name} < %{version}-%{release}
%description -n python3-%{name}
Core Plugins for DNF, Python 3 interface. This package enhances DNF with builddep,
config-manager, copr, debug, debuginfo-install, download, needs-restarting,
-repoclosure, repograph, repomanage, reposync, changelog and repodiff commands.
+groups-manager, repoclosure, repograph, repomanage, reposync, changelog
+and repodiff commands.
Additionally provides generate_completion_cache passive plugin.
%endif
@@ -190,8 +194,8 @@ Summary: Yum-utils CLI compatibility layer
%description -n %{yum_utils_subpackage_name}
As a Yum-utils CLI compatibility layer, supplies in CLI shims for
debuginfo-install, repograph, package-cleanup, repoclosure, repomanage,
-repoquery, reposync, repotrack, repodiff, builddep, config-manager, debug
-and download that use new implementations using DNF.
+repoquery, reposync, repotrack, repodiff, builddep, config-manager, debug,
+download and yum-groups-manager that use new implementations using DNF.
%endif
%if 0%{?rhel} == 0 && %{with python2}
@@ -458,6 +462,7 @@ ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-builddep
ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-config-manager
ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-dump
ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-restore
+ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-groups-manager
ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yumdownloader
# These commands don't have a dedicated man page, so let's just point them
# to the utils page which contains their descriptions.
@@ -483,6 +488,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{_mandir}/man8/dnf-debuginfo-install.*
%{_mandir}/man8/dnf-download.*
%{_mandir}/man8/dnf-generate_completion_cache.*
+%{_mandir}/man8/dnf-groups-manager.*
%{_mandir}/man8/dnf-needs-restarting.*
%{_mandir}/man8/dnf-repoclosure.*
%{_mandir}/man8/dnf-repodiff.*
@@ -513,6 +519,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{python2_sitelib}/dnf-plugins/debuginfo-install.*
%{python2_sitelib}/dnf-plugins/download.*
%{python2_sitelib}/dnf-plugins/generate_completion_cache.*
+%{python2_sitelib}/dnf-plugins/groups_manager.*
%{python2_sitelib}/dnf-plugins/needs_restarting.*
%{python2_sitelib}/dnf-plugins/repoclosure.*
%{python2_sitelib}/dnf-plugins/repodiff.*
@@ -538,6 +545,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{python3_sitelib}/dnf-plugins/debuginfo-install.py
%{python3_sitelib}/dnf-plugins/download.py
%{python3_sitelib}/dnf-plugins/generate_completion_cache.py
+%{python3_sitelib}/dnf-plugins/groups_manager.py
%{python3_sitelib}/dnf-plugins/needs_restarting.py
%{python3_sitelib}/dnf-plugins/repoclosure.py
%{python3_sitelib}/dnf-plugins/repodiff.py
@@ -552,6 +560,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{python3_sitelib}/dnf-plugins/__pycache__/debuginfo-install.*
%{python3_sitelib}/dnf-plugins/__pycache__/download.*
%{python3_sitelib}/dnf-plugins/__pycache__/generate_completion_cache.*
+%{python3_sitelib}/dnf-plugins/__pycache__/groups_manager.*
%{python3_sitelib}/dnf-plugins/__pycache__/needs_restarting.*
%{python3_sitelib}/dnf-plugins/__pycache__/repoclosure.*
%{python3_sitelib}/dnf-plugins/__pycache__/repodiff.*
@@ -579,6 +588,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{_bindir}/yum-config-manager
%{_bindir}/yum-debug-dump
%{_bindir}/yum-debug-restore
+%{_bindir}/yum-groups-manager
%{_bindir}/yumdownloader
%{_mandir}/man1/debuginfo-install.*
%{_mandir}/man1/needs-restarting.*
@@ -591,6 +601,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%{_mandir}/man1/yum-config-manager.*
%{_mandir}/man1/yum-debug-dump.*
%{_mandir}/man1/yum-debug-restore.*
+%{_mandir}/man1/yum-groups-manager.*
%{_mandir}/man1/yumdownloader.*
%{_mandir}/man1/package-cleanup.*
%{_mandir}/man1/dnf-utils.*
@@ -612,6 +623,7 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%exclude %{_mandir}/man1/yum-config-manager.*
%exclude %{_mandir}/man1/yum-debug-dump.*
%exclude %{_mandir}/man1/yum-debug-restore.*
+%exclude %{_mandir}/man1/yum-groups-manager.*
%exclude %{_mandir}/man1/yumdownloader.*
%exclude %{_mandir}/man1/package-cleanup.*
%exclude %{_mandir}/man1/dnf-utils.*
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index dd97eb2..3fb665d 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -26,6 +26,7 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-builddep.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-debuginfo-install.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-download.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-generate_completion_cache.8
+ ${CMAKE_CURRENT_BINARY_DIR}/dnf-groups-manager.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-leaves.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-needs-restarting.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-repoclosure.8
@@ -61,6 +62,7 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/debuginfo-install.1
${CMAKE_CURRENT_BINARY_DIR}/yum-config-manager.1
${CMAKE_CURRENT_BINARY_DIR}/yum-debug-dump.1
${CMAKE_CURRENT_BINARY_DIR}/yum-debug-restore.1
+ ${CMAKE_CURRENT_BINARY_DIR}/yum-groups-manager.1
${CMAKE_CURRENT_BINARY_DIR}/yumdownloader.1
${CMAKE_CURRENT_BINARY_DIR}/package-cleanup.1
${CMAKE_CURRENT_BINARY_DIR}/dnf-utils.1
diff --git a/doc/conf.py b/doc/conf.py
index d760ef3..645185a 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -251,6 +251,7 @@ man_pages = [
('download', 'dnf-download', u'DNF download Plugin', AUTHORS, 8),
('generate_completion_cache', 'dnf-generate_completion_cache',
u'DNF generate_completion_cache Plugin', AUTHORS, 8),
+ ('groups-manager', 'dnf-groups-manager', u'DNF groups-manager Plugin', AUTHORS, 8),
('leaves', 'dnf-leaves', u'DNF leaves Plugin', AUTHORS, 8),
('local', 'dnf-local', u'DNF local Plugin', AUTHORS, 8),
('needs_restarting', 'dnf-needs-restarting', u'DNF needs_restarting Plugin', AUTHORS, 8),
@@ -268,6 +269,7 @@ man_pages = [
('copr', 'yum-copr', u'redirecting to DNF copr Plugin', AUTHORS, 8),
('debuginfo-install', 'debuginfo-install', u'redirecting to DNF debuginfo-install Plugin',
AUTHORS, 1),
+ ('groups-manager', 'yum-groups-manager', u'redirecting to DNF groups-manager Plugin', AUTHORS, 1),
('needs_restarting', 'needs-restarting', u'redirecting to DNF needs-restarting Plugin',
AUTHORS, 1),
('repoclosure', 'repoclosure', u'redirecting to DNF repoclosure Plugin', AUTHORS, 1),
diff --git a/doc/groups-manager.rst b/doc/groups-manager.rst
new file mode 100644
index 0000000..f8f76a1
--- /dev/null
+++ b/doc/groups-manager.rst
@@ -0,0 +1,94 @@
+..
+ Copyright (C) 2020 Red Hat, Inc.
+
+ This copyrighted material is made available to anyone wishing to use,
+ modify, copy, or redistribute it subject to the terms and conditions of
+ the GNU General Public License v.2, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY expressed or implied, including the implied warranties of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ Public License for more details. You should have received a copy of the
+ GNU General Public License along with this program; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+ source code or documentation are not subject to the GNU General Public
+ License and may only be used or replicated with the express permission of
+ Red Hat, Inc.
+
+=========================
+DNF groups-manager Plugin
+=========================
+
+Create and edit groups repository metadata files.
+
+--------
+Synopsis
+--------
+
+``dnf groups-manager [options] [package-name-spec [package-name-spec ...]]``
+
+-----------
+Description
+-----------
+groups-manager plugin is used to create or edit a group metadata file for a repository. This is often much easier than writing/editing the XML by hand. The groups-manager can load an entire file of groups metadata and either create a new group or edit an existing group and then write all of the groups metadata back out.
+
+---------
+Arguments
+---------
+
+``<package-name-spec>``
+ Package to add to a group or remove from a group.
+
+-------
+Options
+-------
+
+All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for details.
+
+``--load=<path_to_comps.xml>``
+ Load the groups metadata information from the specified file before performing any operations. Metadata from all files are merged together if the option is specified multiple times.
+
+``--save=<path_to_comps.xml>``
+ Save the result to this file. You can specify the name of a file you are loading from as the data will only be saved when all the operations have been performed. This option can also be specified multiple times.
+
+``--merge=<path_to_comps.xml>``
+ This is the same as loading and saving a file, however the "merge" file is loaded before any others and saved last.
+
+``--print``
+ Also print the result to stdout.
+
+``--id=<id>``
+ The id to lookup/use for the group. If you don't specify an ``<id>``, but do specify a name that doesn't refer to an existing group, then an id for the group is generated based on the name.
+
+``-n <name>, --name=<name>``
+ The name to lookup/use for the group. If you specify an existing group id, then the group with that id will have it's name changed to this value.
+
+``--description=<description>``
+ The description to use for the group.
+
+``--display-order=<display_order>``
+ Change the integer which controls the order groups are presented in, for example in ``dnf grouplist``.
+
+``--translated-name=<lang:text>``
+ A translation of the group name in the given language. The syntax is ``lang:text``. Eg. ``en:my-group-name-in-english``
+
+``--translated-description=<lang:text>``
+ A translation of the group description in the given language. The syntax is ``lang:text``. Eg. ``en:my-group-description-in-english``.
+
+``--user-visible``
+ Make the group visible in ``dnf grouplist`` (this is the default).
+
+``--not-user-visible``
+ Make the group not visible in ``dnf grouplist``.
+
+``--mandatory``
+ Store the package names specified within the mandatory section of the specified group, the default is to use the default section.
+
+``--optional``
+ Store the package names specified within the optional section of the specified group, the default is to use the default section.
+
+``--remove``
+ Instead of adding packages remove them. Note that the packages are removed from all sections (default, mandatory and optional).
+
+``--dependencies``
+ Also include the names of the direct dependencies for each package specified.
diff --git a/doc/index.rst b/doc/index.rst
index 91bb36e..7213253 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -33,6 +33,7 @@ This documents core plugins of DNF:
debuginfo-install
download
generate_completion_cache
+ groups-manager
leaves
local
migrate
diff --git a/libexec/dnf-utils.in b/libexec/dnf-utils.in
index 667ce13..af1e893 100644
--- a/libexec/dnf-utils.in
+++ b/libexec/dnf-utils.in
@@ -37,6 +37,7 @@ MAPPING = {'debuginfo-install': ['debuginfo-install'],
'yum-config-manager': ['config-manager'],
'yum-debug-dump': ['debug-dump'],
'yum-debug-restore': ['debug-restore'],
+ 'yum-groups-manager': ['groups-manager'],
'yumdownloader': ['download']
}
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 7465e53..f66d3df 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -6,6 +6,7 @@ INSTALL (FILES config_manager.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES copr.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES download.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES generate_completion_cache.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+INSTALL (FILES groups_manager.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES leaves.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
if (${WITHOUT_LOCAL} STREQUAL "0")
INSTALL (FILES local.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
diff --git a/plugins/groups_manager.py b/plugins/groups_manager.py
new file mode 100644
index 0000000..382df37
--- /dev/null
+++ b/plugins/groups_manager.py
@@ -0,0 +1,314 @@
+# groups_manager.py
+# DNF plugin for managing comps groups metadata files
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+import argparse
+import gzip
+import libcomps
+import os
+import re
+import shutil
+import tempfile
+
+from dnfpluginscore import _, logger
+import dnf
+import dnf.cli
+
+
+RE_GROUP_ID_VALID = '-a-z0-9_.:'
+RE_GROUP_ID = re.compile(r'^[{}]+$'.format(RE_GROUP_ID_VALID))
+RE_LANG = re.compile(r'^[-a-zA-Z0-9_.@]+$')
+COMPS_XML_OPTIONS = {
+ 'default_explicit': True,
+ 'uservisible_explicit': True,
+ 'empty_groups': True}
+
+
+def group_id_type(value):
+ '''group id validator'''
+ if not RE_GROUP_ID.match(value):
+ raise argparse.ArgumentTypeError(_('Invalid group id'))
+ return value
+
+
+def translation_type(value):
+ '''translated texts validator'''
+ data = value.split(':', 2)
+ if len(data) != 2:
+ raise argparse.ArgumentTypeError(
+ _("Invalid translated data, should be in form 'lang:text'"))
+ lang, text = data
+ if not RE_LANG.match(lang):
+ raise argparse.ArgumentTypeError(_('Invalid/empty language for translated data'))
+ return lang, text
+
+
+def text_to_id(text):
+ '''generate group id based on its name'''
+ group_id = text.lower()
+ group_id = re.sub('[^{}]'.format(RE_GROUP_ID_VALID), '', group_id)
+ if not group_id:
+ raise dnf.cli.CliError(
+ _("Can't generate group id from '{}'. Please specify group id using --id.").format(
+ text))
+ return group_id
+
+
+@dnf.plugin.register_command
+class GroupsManagerCommand(dnf.cli.Command):
+ aliases = ('groups-manager',)
+ summary = _('create and edit groups metadata file')
+
+ def __init__(self, cli):
+ super(GroupsManagerCommand, self).__init__(cli)
+ self.comps = libcomps.Comps()
+
+ @staticmethod
+ def set_argparser(parser):
+ # input / output options
+ parser.add_argument('--load', action='append', default=[],
+ metavar='COMPS.XML',
+ help=_('load groups metadata from file'))
+ parser.add_argument('--save', action='append', default=[],
+ metavar='COMPS.XML',
+ help=_('save groups metadata to file'))
+ parser.add_argument('--merge', metavar='COMPS.XML',
+ help=_('load and save groups metadata to file'))
+ parser.add_argument('--print', action='store_true', default=False,
+ help=_('print the result metadata to stdout'))
+ # group options
+ parser.add_argument('--id', type=group_id_type,
+ help=_('group id'))
+ parser.add_argument('-n', '--name', help=_('group name'))
+ parser.add_argument('--description',
+ help=_('group description'))
+ parser.add_argument('--display-order', type=int,
+ help=_('group display order'))
+ parser.add_argument('--translated-name', action='append', default=[],
+ metavar='LANG:TEXT', type=translation_type,
+ help=_('translated name for the group'))
+ parser.add_argument('--translated-description', action='append', default=[],
+ metavar='LANG:TEXT', type=translation_type,
+ help=_('translated description for the group'))
+ visible = parser.add_mutually_exclusive_group()
+ visible.add_argument('--user-visible', dest='user_visible', action='store_true',
+ default=None,
+ help=_('make the group user visible (default)'))
+ visible.add_argument('--not-user-visible', dest='user_visible', action='store_false',
+ default=None,
+ help=_('make the group user invisible'))
+
+ # package list options
+ section = parser.add_mutually_exclusive_group()
+ section.add_argument('--mandatory', action='store_true',
+ help=_('add packages to the mandatory section'))
+ section.add_argument('--optional', action='store_true',
+ help=_('add packages to the optional section'))
+ section.add_argument('--remove', action='store_true', default=False,
+ help=_('remove packages from the group instead of adding them'))
+ parser.add_argument('--dependencies', action='store_true',
+ help=_('include also direct dependencies for packages'))
+
+ parser.add_argument("packages", nargs='*', metavar='PACKAGE',
+ help=_('package specification'))
+
+ def configure(self):
+ demands = self.cli.demands
+
+ if self.opts.packages:
+ demands.sack_activation = True
+ demands.available_repos = True
+ demands.load_system_repo = False
+
+ # handle --merge option (shortcut to --load and --save the same file)
+ if self.opts.merge:
+ self.opts.load.insert(0, self.opts.merge)
+ self.opts.save.append(self.opts.merge)
+
+ # check that group is specified when editing is attempted
+ if (self.opts.description
+ or self.opts.display_order
+ or self.opts.translated_name
+ or self.opts.translated_description
+ or self.opts.user_visible is not None
+ or self.opts.packages):
+ if not self.opts.id and not self.opts.name:
+ raise dnf.cli.CliError(
+ _("Can't edit group without specifying it (use --id or --name)"))
+
+ def load_input_files(self):
+ """
+ Loads all input xml files.
+ Returns True if at least one file was successfuly loaded
+ """
+ for file_name in self.opts.load:
+ file_comps = libcomps.Comps()
+ try:
+ if file_name.endswith('.gz'):
+ # libcomps does not support gzipped files - decompress to temporary
+ # location
+ with gzip.open(file_name) as gz_file:
+ temp_file = tempfile.NamedTemporaryFile(delete=False)
+ try:
+ shutil.copyfileobj(gz_file, temp_file)
+ # close temp_file to ensure the content is flushed to disk
+ temp_file.close()
+ file_comps.fromxml_f(temp_file.name)
+ finally:
+ os.unlink(temp_file.name)
+ else:
+ file_comps.fromxml_f(file_name)
+ except (IOError, OSError, libcomps.ParserError) as err:
+ # gzip module raises OSError on reading from malformed gz file
+ # get_last_errors() output often contains duplicit lines, remove them
+ seen = set()
+ for error in file_comps.get_last_errors():
+ if error in seen:
+ continue
+ logger.error(error.strip())
+ seen.add(error)
+ raise dnf.exceptions.Error(
+ _("Can't load file \"{}\": {}").format(file_name, err))
+ else:
+ self.comps += file_comps
+
+ def save_output_files(self):
+ for file_name in self.opts.save:
+ try:
+ # xml_f returns a list of errors / log entries
+ errors = self.comps.xml_f(file_name, xml_options=COMPS_XML_OPTIONS)
+ except libcomps.XMLGenError as err:
+ errors = [err]
+ if errors:
+ # xml_f() method could return more than one error. In this case
+ # raise the latest of them and log the others.
+ for err in errors[:-1]:
+ logger.error(err.strip())
+ raise dnf.exceptions.Error(_("Can't save file \"{}\": {}").format(
+ file_name, errors[-1].strip()))
+
+
+ def find_group(self, group_id, name):
+ '''
+ Try to find group according to command line parameters - first by id
+ then by name.
+ '''
+ group = None
+ if group_id:
+ for grp in self.comps.groups:
+ if grp.id == group_id:
+ group = grp
+ break
+ if group is None and name:
+ for grp in self.comps.groups:
+ if grp.name == name:
+ group = grp
+ break
+ return group
+
+ def edit_group(self, group):
+ '''
+ Set attributes and package lists for selected group
+ '''
+ def langlist_to_strdict(lst):
+ str_dict = libcomps.StrDict()
+ for lang, text in lst:
+ str_dict[lang] = text
+ return str_dict
+
+ # set group attributes
+ if self.opts.name:
+ group.name = self.opts.name
+ if self.opts.description:
+ group.desc = self.opts.description
+ if self.opts.display_order:
+ group.display_order = self.opts.display_order
+ if self.opts.user_visible is not None:
+ group.uservisible = self.opts.user_visible
+ if self.opts.translated_name:
+ group.name_by_lang = langlist_to_strdict(self.opts.translated_name)
+ if self.opts.translated_description:
+ group.desc_by_lang = langlist_to_strdict(self.opts.translated_description)
+
+ # edit packages list
+ if self.opts.packages:
+ # find packages according to specifications from command line
+ packages = set()
+ for pkg_spec in self.opts.packages:
+ q = self.base.sack.query().filterm(name__glob=pkg_spec).latest()
+ if not q:
+ logger.warning(_("No match for argument: {}").format(pkg_spec))
+ continue
+ packages.update(q)
+ if self.opts.dependencies:
+ # add packages that provide requirements
+ requirements = set()
+ for pkg in packages:
+ requirements.update(pkg.requires)
+ packages.update(self.base.sack.query().filterm(provides=requirements))
+
+ pkg_names = {pkg.name for pkg in packages}
+
+ if self.opts.remove:
+ for pkg_name in pkg_names:
+ for pkg in group.packages_match(name=pkg_name,
+ type=libcomps.PACKAGE_TYPE_UNKNOWN):
+ group.packages.remove(pkg)
+ else:
+ if self.opts.mandatory:
+ pkg_type = libcomps.PACKAGE_TYPE_MANDATORY
+ elif self.opts.optional:
+ pkg_type = libcomps.PACKAGE_TYPE_OPTIONAL
+ else:
+ pkg_type = libcomps.PACKAGE_TYPE_DEFAULT
+ for pkg_name in sorted(pkg_names):
+ if not group.packages_match(name=pkg_name, type=pkg_type):
+ group.packages.append(libcomps.Package(name=pkg_name, type=pkg_type))
+
+ def run(self):
+ self.load_input_files()
+
+ if self.opts.id or self.opts.name:
+ # we are adding / editing a group
+ group = self.find_group(group_id=self.opts.id, name=self.opts.name)
+ if group is None:
+ # create a new group
+ if self.opts.remove:
+ raise dnf.exceptions.Error(_("Can't remove packages from non-existent group"))
+ group = libcomps.Group()
+ if self.opts.id:
+ group.id = self.opts.id
+ group.name = self.opts.id
+ elif self.opts.name:
+ group_id = text_to_id(self.opts.name)
+ if self.find_group(group_id=group_id, name=None):
+ raise dnf.cli.CliError(
+ _("Group id '{}' generated from '{}' is duplicit. "
+ "Please specify group id using --id.").format(
+ group_id, self.opts.name))
+ group.id = group_id
+ self.comps.groups.append(group)
+ self.edit_group(group)
+
+ self.save_output_files()
+ if self.opts.print or (not self.opts.save):
+ print(self.comps.xml_str(xml_options=COMPS_XML_OPTIONS))
--
2.26.2

View File

@ -0,0 +1,38 @@
From a3b9e17628994b43080b8c03b9f665a0e6514cd6 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Tue, 11 May 2021 08:29:31 +0200
Subject: [PATCH] versionlock: Do not exclude locked obsoleters (RhBug:1957280)
The versionlock plugin excludes all obsoleters of locked packages. If
both versions (obsoleted package and its obsoleter) are locked, this
leads to the inability to install the obsoleter package. The patch
protects all locked packages from being excluded as obsoleters.
= changelog =
msg: versionlock: Locking obsoleted package does not make the obsoleter unavailable
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1957280
---
plugins/versionlock.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/plugins/versionlock.py b/plugins/versionlock.py
index d997130..c89a75d 100644
--- a/plugins/versionlock.py
+++ b/plugins/versionlock.py
@@ -113,8 +113,10 @@ class VersionLock(dnf.Plugin):
other_versions = all_versions.difference(locked_query)
excludes_query = excludes_query.union(other_versions)
# exclude also anything that obsoletes the locked versions of packages
- excludes_query = excludes_query.union(
- self.base.sack.query().filterm(obsoletes=locked_query))
+ obsoletes_query = self.base.sack.query().filterm(obsoletes=locked_query)
+ # leave out obsoleters that are also part of locked versions (otherwise the obsoleter package
+ # would not be installable at all)
+ excludes_query = excludes_query.union(obsoletes_query.difference(locked_query))
excludes_query.filterm(reponame__neq=hawkey.SYSTEM_REPO_NAME)
if excludes_query:
--
libgit2 1.0.1

View File

@ -1,138 +0,0 @@
From b2a912724d737ca7ac4350885b54117f5e043046 Mon Sep 17 00:00:00 2001
From: Nicola Sella <nsella@redhat.com>
Date: Thu, 5 Mar 2020 12:45:39 +0100
Subject: [PATCH 2/2] [needs-restarting] add -s to list services
(RhBug:1772939)
= changelog =
msg: [needs-restarting] add -s to list services (RhBug:1772939)
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1772939
Closes: #395
Approved by: kontura
---
dnf-plugins-core.spec | 6 ++++++
doc/needs_restarting.rst | 3 +++
plugins/needs_restarting.py | 33 +++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 42d0884..012dde8 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -99,8 +99,10 @@ Summary: Core Plugins for DNF
%{?python_provide:%python_provide python2-%{name}}
BuildRequires: python2-dnf >= %{dnf_lowest_compatible}
%if 0%{?rhel} && 0%{?rhel} <= 7
+BuildRequires: dbus-python
BuildRequires: python-nose
%else
+BuildRequires: python2-dbus
BuildRequires: python2-nose
%endif
BuildRequires: python2-devel
@@ -110,8 +112,10 @@ Requires: python2-distro
Requires: python2-dnf >= %{dnf_lowest_compatible}
Requires: python2-hawkey >= %{hawkey_version}
%if 0%{?rhel} && 0%{?rhel} <= 7
+Requires: dbus-python
Requires: python-dateutil
%else
+Requires: python2-dbus
Requires: python2-dateutil
%endif
Provides: python2-dnf-plugins-extras-debug = %{version}-%{release}
@@ -140,12 +144,14 @@ Additionally provides generate_completion_cache passive plugin.
%package -n python3-%{name}
Summary: Core Plugins for DNF
%{?python_provide:%python_provide python3-%{name}}
+BuildRequires: python3-dbus
BuildRequires: python3-devel
BuildRequires: python3-dnf >= %{dnf_lowest_compatible}
BuildRequires: python3-nose
%if 0%{?fedora}
Requires: python3-distro
%endif
+Requires: python3-dbus
Requires: python3-dnf >= %{dnf_lowest_compatible}
Requires: python3-hawkey >= %{hawkey_version}
Requires: python3-dateutil
diff --git a/doc/needs_restarting.rst b/doc/needs_restarting.rst
index e79b43f..1a3fbbe 100644
--- a/doc/needs_restarting.rst
+++ b/doc/needs_restarting.rst
@@ -48,3 +48,6 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det
``-r, --reboothint``
Only report whether a reboot is required (exit code 1) or not (exit code 0).
+
+``-s, --services``
+ Only list the affected systemd services.
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 69203f4..f6bf525 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -29,6 +29,7 @@ from dnfpluginscore import logger, _
import dnf
import dnf.cli
+import dbus
import functools
import os
import re
@@ -126,6 +127,30 @@ def print_cmd(pid):
print('%d : %s' % (pid, command))
+def get_service_dbus(pid):
+ bus = dbus.SystemBus()
+ systemd_manager_object = bus.get_object(
+ 'org.freedesktop.systemd1',
+ '/org/freedesktop/systemd1'
+ )
+ systemd_manager_interface = dbus.Interface(
+ systemd_manager_object,
+ 'org.freedesktop.systemd1.Manager'
+ )
+ service_proxy = bus.get_object(
+ 'org.freedesktop.systemd1',
+ systemd_manager_interface.GetUnitByPID(pid)
+ )
+ service_properties = dbus.Interface(
+ service_proxy, dbus_interface="org.freedesktop.DBus.Properties")
+ name = service_properties.Get(
+ "org.freedesktop.systemd1.Unit",
+ 'Id'
+ )
+ if name.endswith(".service"):
+ return name
+ return
+
def smap2opened_file(pid, line):
slash = line.find('/')
if slash < 0:
@@ -205,6 +230,8 @@ class NeedsRestartingCommand(dnf.cli.Command):
parser.add_argument('-r', '--reboothint', action='store_true',
help=_("only report whether a reboot is required "
"(exit code 1) or not (exit code 0)"))
+ parser.add_argument('-s', '--services', action='store_true',
+ help=_("only report affected systemd services"))
def configure(self):
demands = self.cli.demands
@@ -251,5 +278,11 @@ class NeedsRestartingCommand(dnf.cli.Command):
if pkg.installtime > process_start(ofile.pid):
stale_pids.add(ofile.pid)
+ if self.opts.services:
+ names = set([get_service_dbus(pid) for pid in sorted(stale_pids)])
+ for name in names:
+ if name is not None:
+ print(name)
+ return 0
for pid in sorted(stale_pids):
print_cmd(pid)
--
2.26.2

View File

@ -0,0 +1,49 @@
From 716c5978a8036df22d6f5b430ba38c35d034f3ea Mon Sep 17 00:00:00 2001
From: Aleš Matěj <amatej@redhat.com>
Date: Tue, 8 Jun 2021 10:25:55 +0200
Subject: [PATCH] [repomanage] Allow running only with metadata
Requiring some packages to be present even if there are repodata was
arbitrary because they are never used.
---
plugins/repomanage.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/plugins/repomanage.py b/plugins/repomanage.py
index 445006d..989bd78 100644
--- a/plugins/repomanage.py
+++ b/plugins/repomanage.py
@@ -58,18 +58,13 @@ class RepoManageCommand(dnf.cli.Command):
if self.opts.new and self.opts.old:
raise dnf.exceptions.Error(_("Pass either --old or --new, not both!"))
- rpm_list = []
- rpm_list = self._get_file_list(self.opts.path, ".rpm")
verfile = {}
pkgdict = {}
module_dict = {} # {NameStream: {Version: [modules]}}
all_modular_artifacts = set()
keepnum = int(self.opts.keep) # the number of items to keep
- if len(rpm_list) == 0:
- raise dnf.exceptions.Error(_("No files to process"))
-
try:
repo_conf = self.base.repos.add_new_repo("repomanage_repo", self.base.conf, baseurl=[self.opts.path])
# Always expire the repo, otherwise repomanage could use cached metadata and give identical results
@@ -88,6 +83,11 @@ class RepoManageCommand(dnf.cli.Command):
module_package.getVersionNum(), []).append(module_package)
except dnf.exceptions.RepoError:
+ rpm_list = []
+ rpm_list = self._get_file_list(self.opts.path, ".rpm")
+ if len(rpm_list) == 0:
+ raise dnf.exceptions.Error(_("No files to process"))
+
self.base.reset(sack=True, repos=True)
self.base.fill_sack(load_system_repo=False, load_available_repos=False)
try:
--
libgit2 1.0.1

View File

@ -0,0 +1,42 @@
From 1b432bada5a3627f729cb42b99b7a93f808e3a80 Mon Sep 17 00:00:00 2001
From: Aleš Matěj <amatej@redhat.com>
Date: Tue, 8 Jun 2021 11:48:07 +0200
Subject: [PATCH] [repomanage] Enhance repomanage documentation (RhBug:1898293)
= changelog =
msg: Enhance repomanage documentation
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1898293
---
doc/repomanage.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/doc/repomanage.rst b/doc/repomanage.rst
index e4da441..e3171ef 100644
--- a/doc/repomanage.rst
+++ b/doc/repomanage.rst
@@ -31,9 +31,10 @@ Synopsis
Description
-----------
-`repomanage` prints newest or oldest packages in a repository specified by <path> for easy piping to xargs or similar programs. In case <path> doesn't contain a valid repository it is searched for rpm packages which are then used instead.
+`repomanage` prints newest or older packages in a repository specified by <path> for easy piping to xargs or similar programs. In case <path> doesn't contain a valid repodata, it is searched for rpm packages which are then used instead.
+If the repodata are present, `repomanage` uses them as the source of truth, it doesn't verify that they match the present rpm packages. In fact, `repomanage` can run with just the repodata, no rpm packages are needed.
-In order to work correctly with modular packages <path> has to contain repodata with modular metadata. If modular content is present `repomanage` prints packages from newest or oldest versions of each stream in addition to newest or oldest non-modular packages.
+In order to work correctly with modular packages, <path> has to contain repodata with modular metadata. If modular content is present, `repomanage` prints packages from newest or older stream versions in addition to newest or older non-modular packages.
Options
@@ -44,7 +45,7 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det
The following options set what packages are displayed. These options are mutually exclusive, i.e. only one can be specified. If no option is specified, the newest packages are shown.
``--old``
- Show older packages.
+ Show older packages (for a package or a stream show all versions except the newest one).
``--new``
Show newest packages.
--
libgit2 1.0.1

View File

@ -1,194 +0,0 @@
From a4f21266a6dab9e77913d56c04aba1e579f0e0c1 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Fri, 23 Oct 2020 09:06:35 +0200
Subject: [PATCH 1/2] [reposync] Reorder options alphabetically
---
doc/reposync.rst | 30 +++++++++++++++---------------
plugins/reposync.py | 18 +++++++++---------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/doc/reposync.rst b/doc/reposync.rst
index 71a435dc..3b820f33 100644
--- a/doc/reposync.rst
+++ b/doc/reposync.rst
@@ -39,36 +39,36 @@ Options
All general DNF options are accepted. Namely, the ``--repoid`` option can be used to specify the repositories to synchronize. See `Options` in :manpage:`dnf(8)` for details.
-``-p <download-path>, --download-path=<download-path>``
- Root path under which the downloaded repositories are stored, relative to the current working directory. Defaults to the current working directory. Every downloaded repository has a subdirectory named after its ID under this path.
-
-``--norepopath``
- Don't add the reponame to the download path. Can only be used when syncing a single repository (default is to add the reponame).
-
-``--download-metadata``
- Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it.
-
``-a <architecture>, --arch=<architecture>``
Download only packages of given architectures (default is all architectures). Can be used multiple times.
-``--source``
- Operate on source packages.
+``--delete``
+ Delete local packages no longer present in repository.
+
+``--download-metadata``
+ Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it.
``-m, --downloadcomps``
Also download and uncompress comps.xml. Consider using ``--download-metadata`` option which will download all available repository metadata.
+``--metadata-path``
+ Root path under which the downloaded metadata are stored. It defaults to ``--download-path`` value if not given.
+
``-n, --newest-only``
Download only newest packages per-repo.
-``--delete``
- Delete local packages no longer present in repository.
+``--norepopath``
+ Don't add the reponame to the download path. Can only be used when syncing a single repository (default is to add the reponame).
-``--metadata-path``
- Root path under which the downloaded metadata are stored. It defaults to ``--download-path`` value if not given.
+``-p <download-path>, --download-path=<download-path>``
+ Root path under which the downloaded repositories are stored, relative to the current working directory. Defaults to the current working directory. Every downloaded repository has a subdirectory named after its ID under this path.
``--remote-time``
Try to set the timestamps of the downloaded files to those on the remote side.
+``--source``
+ Operate on source packages.
+
``-u, --urls``
Just print urls of what would be downloaded, don't download.
diff --git a/plugins/reposync.py b/plugins/reposync.py
index 7556e7eb..6f572cac 100644
--- a/plugins/reposync.py
+++ b/plugins/reposync.py
@@ -63,24 +63,24 @@ def set_argparser(parser):
help=_('download only packages for this ARCH'))
parser.add_argument('--delete', default=False, action='store_true',
help=_('delete local packages no longer present in repository'))
- parser.add_argument('-m', '--downloadcomps', default=False, action='store_true',
- help=_('also download and uncompress comps.xml'))
parser.add_argument('--download-metadata', default=False, action='store_true',
help=_('download all the metadata.'))
+ parser.add_argument('-m', '--downloadcomps', default=False, action='store_true',
+ help=_('also download and uncompress comps.xml'))
+ parser.add_argument('--metadata-path',
+ help=_('where to store downloaded repository metadata. '
+ 'Defaults to the value of --download-path.'))
parser.add_argument('-n', '--newest-only', default=False, action='store_true',
help=_('download only newest packages per-repo'))
- parser.add_argument('-p', '--download-path', default='./',
- help=_('where to store downloaded repositories'))
parser.add_argument('--norepopath', default=False, action='store_true',
help=_("Don't add the reponame to the download path."))
- parser.add_argument('--metadata-path',
- help=_('where to store downloaded repository metadata. '
- 'Defaults to the value of --download-path.'))
- parser.add_argument('--source', default=False, action='store_true',
- help=_('operate on source packages'))
+ parser.add_argument('-p', '--download-path', default='./',
+ help=_('where to store downloaded repositories'))
parser.add_argument('--remote-time', default=False, action='store_true',
help=_('try to set local timestamps of local files by '
'the one on the server'))
+ parser.add_argument('--source', default=False, action='store_true',
+ help=_('operate on source packages'))
parser.add_argument('-u', '--urls', default=False, action='store_true',
help=_("Just list urls of what would be downloaded, "
"don't download"))
From 978b7f2b1c654fed7b1b4cf45cb607143226804c Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Fri, 23 Oct 2020 09:14:02 +0200
Subject: [PATCH 2/2] [reposync] Check GPG signatures of downloaded packages
(RhBug:1856818)
YUMv3 reposync used to have --gpgcheck option to remove packages that fail GPG
signature checking after downloading.
This patch implements the option for DNF.
= changelog =
msg: Add --gpgcheck option to reposync (RhBug:1856818)
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1856818
---
doc/reposync.rst | 4 ++++
plugins/reposync.py | 21 +++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/doc/reposync.rst b/doc/reposync.rst
index 3b820f33..de40957f 100644
--- a/doc/reposync.rst
+++ b/doc/reposync.rst
@@ -48,6 +48,10 @@ All general DNF options are accepted. Namely, the ``--repoid`` option can be use
``--download-metadata``
Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it.
+``-g, --gpgcheck``
+ Remove packages that fail GPG signature checking after downloading. Exit code is ``1`` if at least one package was removed.
+ Note that for repositories with ``gpgcheck=0`` set in their configuration the GPG signature is not checked even with this option used.
+
``-m, --downloadcomps``
Also download and uncompress comps.xml. Consider using ``--download-metadata`` option which will download all available repository metadata.
diff --git a/plugins/reposync.py b/plugins/reposync.py
index 6f572cac..c891bfa2 100644
--- a/plugins/reposync.py
+++ b/plugins/reposync.py
@@ -24,6 +24,7 @@
import hawkey
import os
import shutil
+import types
from dnfpluginscore import _, logger
from dnf.cli.option_parser import OptionParser
@@ -65,6 +66,9 @@ def set_argparser(parser):
help=_('delete local packages no longer present in repository'))
parser.add_argument('--download-metadata', default=False, action='store_true',
help=_('download all the metadata.'))
+ parser.add_argument('-g', '--gpgcheck', default=False, action='store_true',
+ help=_('Remove packages that fail GPG signature checking '
+ 'after downloading'))
parser.add_argument('-m', '--downloadcomps', default=False, action='store_true',
help=_('also download and uncompress comps.xml'))
parser.add_argument('--metadata-path',
@@ -114,6 +118,7 @@ def configure(self):
def run(self):
self.base.conf.keepcache = True
+ gpgcheck_ok = True
for repo in self.base.repos.iter_enabled():
if self.opts.remote_time:
repo._repo.setPreserveRemoteTime(True)
@@ -150,8 +155,24 @@ def run(self):
self.print_urls(pkglist)
else:
self.download_packages(pkglist)
+ if self.opts.gpgcheck:
+ for pkg in pkglist:
+ local_path = self.pkg_download_path(pkg)
+ # base.package_signature_check uses pkg.localPkg() to determine
+ # the location of the package rpm file on the disk.
+ # Set it to the correct download path.
+ pkg.localPkg = types.MethodType(
+ lambda s, local_path=local_path: local_path, pkg)
+ result, error = self.base.package_signature_check(pkg)
+ if result != 0:
+ logger.warning(_("Removing {}: {}").format(
+ os.path.basename(local_path), error))
+ os.unlink(local_path)
+ gpgcheck_ok = False
if self.opts.delete:
self.delete_old_local_packages(repo, pkglist)
+ if not gpgcheck_ok:
+ raise dnf.exceptions.Error(_("GPG signature check failed."))
def repo_target(self, repo):
return _pkgdir(self.opts.destdir or self.opts.download_path,

View File

@ -6,6 +6,8 @@
%global yum_utils_subpackage_name yum-utils %global yum_utils_subpackage_name yum-utils
%endif %endif
%define __cmake_in_source_build 1
%if 0%{?rhel} && 0%{?rhel} <= 7 %if 0%{?rhel} && 0%{?rhel} <= 7
%bcond_with python3 %bcond_with python3
%else %else
@ -31,15 +33,16 @@
%endif %endif
Name: dnf-plugins-core Name: dnf-plugins-core
Version: 4.0.18 Version: 4.0.21
Release: 3%{?dist} Release: 2%{?dist}
Summary: Core Plugins for DNF Summary: Core Plugins for DNF
License: GPLv2+ License: GPLv2+
URL: https://github.com/rpm-software-management/dnf-plugins-core URL: https://github.com/rpm-software-management/dnf-plugins-core
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
Patch1: 0001-groups-manager-Re-introduce-yum-groups-manager-funct.patch Patch1: 0001-versionlock-Do-not-exclude-locked-obsoleters-RhBug1957280.patch
Patch2: 0002-needs-restarting-add-s-to-list-services-RhBug-177293.patch Patch2: 0002-repomanage-Allow-running-only-with-metadata.patch
Patch3: 0003-reposync-Check-GPG-signatures-of-downloaded-packages-RhBug-1856818.patch Patch3: 0003-repomanage-Enhance-repomanage-documentation-RhBug1898293.patch
BuildArch: noarch BuildArch: noarch
BuildRequires: cmake BuildRequires: cmake
BuildRequires: gettext BuildRequires: gettext
@ -101,10 +104,8 @@ Summary: Core Plugins for DNF
BuildRequires: python2-dnf >= %{dnf_lowest_compatible} BuildRequires: python2-dnf >= %{dnf_lowest_compatible}
%if 0%{?rhel} && 0%{?rhel} <= 7 %if 0%{?rhel} && 0%{?rhel} <= 7
BuildRequires: dbus-python BuildRequires: dbus-python
BuildRequires: python-nose
%else %else
BuildRequires: python2-dbus BuildRequires: python2-dbus
BuildRequires: python2-nose
%endif %endif
BuildRequires: python2-devel BuildRequires: python2-devel
%if 0%{?fedora} %if 0%{?fedora}
@ -147,7 +148,6 @@ Summary: Core Plugins for DNF
BuildRequires: python3-dbus BuildRequires: python3-dbus
BuildRequires: python3-devel BuildRequires: python3-devel
BuildRequires: python3-dnf >= %{dnf_lowest_compatible} BuildRequires: python3-dnf >= %{dnf_lowest_compatible}
BuildRequires: python3-nose
%if 0%{?fedora} %if 0%{?fedora}
Requires: python3-distro Requires: python3-distro
%endif %endif
@ -478,10 +478,14 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
%check %check
%if %{with python2} %if %{with python2}
PYTHONPATH=./plugins nosetests-%{python2_version} -s tests/ pushd build-py2
ctest -VV
popd
%endif %endif
%if %{with python3} %if %{with python3}
PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/ pushd build-py3
ctest -VV
popd
%endif %endif
%files %files
@ -761,6 +765,20 @@ PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
%endif %endif
%changelog %changelog
* Tue Jul 27 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-2
- [versionlock] Locking obsoleted package does not make the obsoleter unavailable (RhBug:1957280)
- [repomanage] Allow running with metadata only
- [repomanage] Enhance repomanage documentation (RhBug:1898293)
* Wed May 19 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-1
- Update to 4.0.21
- [repomanage] Don't use cached metadata (RhBug:1899852)
- [needs-restarting] fix -r in nspawn containers (RhBug:1913962,1914251)
- doc: add packages to needs-restarting conf
- Set blacklist subcommand as deprecated
- Removed dependency on dnf.yum.misc.Checksum class (RhBug:1935465)
- Bugs fixed (RhBug:1914827,1916782)
* Fri Jan 15 2021 Nicola Sella <nsella@redhat.com> - 4.0.18-3 * Fri Jan 15 2021 Nicola Sella <nsella@redhat.com> - 4.0.18-3
- [reposync] Check GPG signatures of downloaded packages (RhBug:1856818) - [reposync] Check GPG signatures of downloaded packages (RhBug:1856818)