Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package dnf-plugins-core for
openSUSE:Factory checked in at 2021-02-03 19:55:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dnf-plugins-core (Old)
and /work/SRC/openSUSE:Factory/.dnf-plugins-core.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dnf-plugins-core"
Wed Feb 3 19:55:53 2021 rev:15 rq:868795 version:4.0.19
Changes:
--------
--- /work/SRC/openSUSE:Factory/dnf-plugins-core/dnf-plugins-core.changes
2020-10-28 11:26:15.986902896 +0100
+++
/work/SRC/openSUSE:Factory/.dnf-plugins-core.new.28504/dnf-plugins-core.changes
2021-02-03 19:56:00.257694933 +0100
@@ -1,0 +2,11 @@
+Wed Feb 3 02:10:58 UTC 2021 - Neal Gompa <[email protected]>
+
+- Update to version 4.0.19
+ + copr: allow only 2 arguments with copr enable command
+ + [needs-restarting] fix -r in nspawn containers (rh#1913962, rh#1914251)
+ + Add --gpgcheck option to reposync (rh#1856818) (rh#1856818)
+ + Re-introduce yum-groups-manager functionality (rh#1826016)
+ + [repomanage] Don't use cached metadata (rh#1899852)
+ + [needs-restarting] add -s to list services (rh#1772939) (rh#1772939)
+
+-------------------------------------------------------------------
Old:
----
dnf-plugins-core-4.0.18.tar.gz
New:
----
dnf-plugins-core-4.0.19.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ dnf-plugins-core.spec ++++++
--- /var/tmp/diff_new_pack.68OkfZ/_old 2021-02-03 19:56:01.097695945 +0100
+++ /var/tmp/diff_new_pack.68OkfZ/_new 2021-02-03 19:56:01.097695945 +0100
@@ -2,7 +2,7 @@
# spec file for package dnf-plugins-core
#
# Copyright (c) 2020 SUSE LLC
-# Copyright (c) 2020 Neal Gompa <[email protected]>.
+# Copyright (c) 2020-2021 Neal Gompa <[email protected]>.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -56,7 +56,7 @@
#global prerel rc1
Name: dnf-plugins-core
-Version: 4.0.18
+Version: 4.0.19
Release: 0
Summary: Core Plugins for DNF
License: GPL-2.0-or-later
@@ -84,6 +84,7 @@
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(repodiff)
Provides: dnf-command(repograph)
@@ -101,6 +102,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-groups-manager = %{version}-%{release}
Provides: dnf-plugin-needs_restarting = %{version}-%{release}
Provides: dnf-plugin-repoclosure = %{version}-%{release}
Provides: dnf-plugin-repograph = %{version}-%{release}
@@ -111,18 +113,20 @@
%description
Core Plugins for DNF. This package enhances DNF with the builddep,
config-manager,
-%{?_with_copr_plugin:copr, }debug, debuginfo-install, download,
needs-restarting,
-repoclosure, repograph, repomanage, and reposync commands. Additionally, it
provides
-the generate_completion_cache passive plugin.
+%{?_with_copr_plugin:copr, }debug, debuginfo-install, download, groups-manager,
+needs-restarting, repoclosure, repograph, repomanage, and reposync commands.
+Additionally, it provides the generate_completion_cache passive plugin.
%package -n python3-dnf-plugins-core
Summary: Python 3 interface to core plugins for DNF
Group: System/Packages
BuildRequires: python3-Sphinx
+BuildRequires: python3-dbus-python
BuildRequires: python3-devel
BuildRequires: python3-dnf >= %{dnf_lowest_compatible}
BuildRequires: python3-pytest
Requires: python3-dateutil
+Requires: python3-dbus-python
Requires: python3-distro
Requires: python3-dnf >= %{dnf_lowest_compatible}
Requires: python3-hawkey >= %{hawkey_version}
@@ -145,7 +149,9 @@
%description -n python3-dnf-plugins-core
Core Plugins for DNF, Python 3 interface. This package enhances DNF with
the builddep, config-manager, %{?_with_copr_plugin:copr, }debug,
debuginfo-install,
-download, needs-restarting, repoclosure, repograph, repomanage, and reposync
commands.
+download, groups-manager, needs-restarting, repoclosure, repograph, repomanage,
+and reposync commands.
+
Additionally, it provides the generate_completion_cache passive plugin.
%package -n %{yum_utils_subpackage_name}
@@ -174,9 +180,9 @@
%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, builddep, config-manager, debug, and
-download that use new implementations using DNF.
+debuginfo-install, groups-manager, repograph, package-cleanup, repoclosure,
+repomanage, repoquery, reposync, repotrack, builddep, config-manager, debug,
+and download that use new implementations using DNF.
%package -n python3-dnf-plugin-leaves
@@ -316,6 +322,7 @@
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
%if %{with deconflict}
@@ -354,6 +361,7 @@
%{_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-repograph.*
@@ -382,6 +390,7 @@
%{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/repograph.py
@@ -420,6 +429,8 @@
%{_mandir}/man1/yum-debug-dump.1*
%{_bindir}/yum-debug-restore
%{_mandir}/man1/yum-debug-restore.1*
+%{_bindir}/yum-groups-manager
+%{_mandir}/man1/yum-groups-manager.1*
%{_bindir}/yumdownloader
%{_mandir}/man1/yumdownloader.1*
%{_mandir}/man1/yum-changelog.1*
++++++ dnf-plugins-core-4.0.18.tar.gz -> dnf-plugins-core-4.0.19.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/CMakeLists.txt
new/dnf-plugins-core-4.0.19/CMakeLists.txt
--- old/dnf-plugins-core-4.0.18/CMakeLists.txt 2020-10-06 18:54:52.000000000
+0200
+++ new/dnf-plugins-core-4.0.19/CMakeLists.txt 2021-01-28 18:02:06.000000000
+0100
@@ -29,4 +29,7 @@
ADD_SUBDIRECTORY (plugins)
ADD_SUBDIRECTORY (po)
+ENABLE_TESTING()
+ADD_SUBDIRECTORY (tests)
+
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/libexec/dnf-utils.in
${CMAKE_SOURCE_DIR}/libexec/dnf-utils-${PYTHON_VERSION_MAJOR} @ONLY)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/bors.toml
new/dnf-plugins-core-4.0.19/bors.toml
--- old/dnf-plugins-core-4.0.18/bors.toml 1970-01-01 01:00:00.000000000
+0100
+++ new/dnf-plugins-core-4.0.19/bors.toml 2021-01-28 18:02:06.000000000
+0100
@@ -0,0 +1,2 @@
+status = ["DNF CI"]
+timeout_sec = 10800 # 3 hours
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/dnf-plugins-core.spec
new/dnf-plugins-core-4.0.19/dnf-plugins-core.spec
--- old/dnf-plugins-core-4.0.18/dnf-plugins-core.spec 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/dnf-plugins-core.spec 2021-01-28
18:02:06.000000000 +0100
@@ -33,7 +33,7 @@
%endif
Name: dnf-plugins-core
-Version: 4.0.18
+Version: 4.0.19
Release: 1%{?dist}
Summary: Core Plugins for DNF
License: GPLv2+
@@ -58,6 +58,7 @@
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-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 @@
%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.
@@ -97,8 +99,10 @@
%{?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
@@ -108,8 +112,10 @@
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}
@@ -129,7 +135,8 @@
%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
@@ -137,12 +144,14 @@
%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
@@ -163,7 +172,8 @@
%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 +200,8 @@
%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 +468,7 @@
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.
@@ -468,10 +479,14 @@
%check
%if %{with python2}
-PYTHONPATH=./plugins nosetests-%{python2_version} -s tests/
+ pushd build-py2
+ ctest -VV
+ popd
%endif
%if %{with python3}
-PYTHONPATH=./plugins nosetests-%{python3_version} -s tests/
+ pushd build-py3
+ ctest -VV
+ popd
%endif
%files
@@ -483,6 +498,7 @@
%{_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 +529,7 @@
%{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 +555,7 @@
%{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 +570,7 @@
%{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 +598,7 @@
%{_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 +611,7 @@
%{_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 +633,7 @@
%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.*
@@ -744,6 +766,14 @@
%endif
%changelog
+* Thu Jan 28 2021 Nicola Sella <[email protected]> - 4.0.19-1
+- copr: allow only 2 arguments with copr enable command
+- [needs-restarting] fix -r in nspawn containers (RhBug:1913962,1914251)
+- Add --gpgcheck option to reposync (RhBug:1856818) (RhBug:1856818)
+- Re-introduce yum-groups-manager functionality (RhBug:1826016)
+- [repomanage] Don't use cached metadata (RhBug:1899852)
+- [needs-restarting] add -s to list services (RhBug:1772939) (RhBug:1772939)
+
* Tue Oct 06 2020 Nicola Sella <[email protected]> - 4.0.18-1
- [needs-restarting] Fix plugin fail if needs-restarting.d does not exist
- [needs-restarting] add kernel-rt to reboot list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/CMakeLists.txt
new/dnf-plugins-core-4.0.19/doc/CMakeLists.txt
--- old/dnf-plugins-core-4.0.18/doc/CMakeLists.txt 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/CMakeLists.txt 2021-01-28
18:02:06.000000000 +0100
@@ -26,6 +26,7 @@
${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 @@
${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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/conf.py
new/dnf-plugins-core-4.0.19/doc/conf.py
--- old/dnf-plugins-core-4.0.18/doc/conf.py 2020-10-06 18:54:52.000000000
+0200
+++ new/dnf-plugins-core-4.0.19/doc/conf.py 2021-01-28 18:02:06.000000000
+0100
@@ -251,6 +251,7 @@
('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 @@
('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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/groups-manager.rst
new/dnf-plugins-core-4.0.19/doc/groups-manager.rst
--- old/dnf-plugins-core-4.0.18/doc/groups-manager.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/dnf-plugins-core-4.0.19/doc/groups-manager.rst 2021-01-28
18:02:06.000000000 +0100
@@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/index.rst
new/dnf-plugins-core-4.0.19/doc/index.rst
--- old/dnf-plugins-core-4.0.18/doc/index.rst 2020-10-06 18:54:52.000000000
+0200
+++ new/dnf-plugins-core-4.0.19/doc/index.rst 2021-01-28 18:02:06.000000000
+0100
@@ -33,6 +33,7 @@
debuginfo-install
download
generate_completion_cache
+ groups-manager
leaves
local
migrate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/needs_restarting.rst
new/dnf-plugins-core-4.0.19/doc/needs_restarting.rst
--- old/dnf-plugins-core-4.0.18/doc/needs_restarting.rst 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/needs_restarting.rst 2021-01-28
18:02:06.000000000 +0100
@@ -48,3 +48,6 @@
``-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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dnf-plugins-core-4.0.18/doc/post-transaction-actions.rst
new/dnf-plugins-core-4.0.19/doc/post-transaction-actions.rst
--- old/dnf-plugins-core-4.0.18/doc/post-transaction-actions.rst
2020-10-06 18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/post-transaction-actions.rst
2021-01-28 18:02:06.000000000 +0100
@@ -76,7 +76,12 @@
The shell command will be evaluated for each package that matched the
``package_filter`` and
the ``transaction_state``. However, after variable substitution, any
duplicate commands will be
removed and each command will only be executed once per transaction. The
order of execution
- of the commands may differ from the order of packages in the transaction.
+ of the commands follows the order in the action files, but may differ from
the order of
+ packages in the transaction. In other words, when you define several
action lines for the
+ same ``package_filter`` these lines will be executed in the order they were
defined in the
+ action file when the ``package_filter`` matches a package during the
``trasaction_state`` state.
+ However, the order of when a particular ``package_filter`` is invoked
depends on the position
+ of the corresponding package in the transaction.
An example action file:
^^^^^^^^^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/release_notes.rst
new/dnf-plugins-core-4.0.19/doc/release_notes.rst
--- old/dnf-plugins-core-4.0.18/doc/release_notes.rst 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/release_notes.rst 2021-01-28
18:02:06.000000000 +0100
@@ -22,6 +22,34 @@
.. contents::
====================
+4.0.19 Release Notes
+====================
+
+- copr: allow only 2 arguments with copr enable command
+- [needs-restarting] fix -r in nspawn containers (RhBug:1913962,1914251)
+- Add --gpgcheck option to reposync (RhBug:1856818) (RhBug:1856818)
+- Re-introduce yum-groups-manager functionality (RhBug:1826016)
+- [repomanage] Don't use cached metadata (RhBug:1899852)
+- [needs-restarting] add -s to list services (RhBug:1772939) (RhBug:1772939)
+
+- New features:
+ - Add --gpgcheck option to reposync (RhBug:1856818) (RhBug:1856818)
+ - Re-introduce yum-groups-manager functionality (RhBug:1826016)
+
+- Bug fixes:
+ - [repomanage] Don't use cached metadata (RhBug:1899852)
+ - [repomanage] Fix ordering of modular stream versions
+ - [needs-restarting] add -s to list services (RhBug:1772939) (RhBug:1772939)
+
+Bugs fixed in 4.0.19:
+
+* :rhbug:`1913962`
+* :rhbug:`1772939`
+* :rhbug:`1914251`
+* :rhbug:`1899852`
+* :rhbug:`1856818`
+
+====================
4.0.18 Release Notes
====================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/reposync.rst
new/dnf-plugins-core-4.0.19/doc/reposync.rst
--- old/dnf-plugins-core-4.0.18/doc/reposync.rst 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/reposync.rst 2021-01-28
18:02:06.000000000 +0100
@@ -39,36 +39,40 @@
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).
+``-a <architecture>, --arch=<architecture>``
+ Download only packages of given architectures (default is all
architectures). Can be used multiple times.
+
+``--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.
-``-a <architecture>, --arch=<architecture>``
- Download only packages of given architectures (default is all
architectures). Can be used multiple times.
-
-``--source``
- Operate on source packages.
+``-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.
+``--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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/doc/summaries_cache
new/dnf-plugins-core-4.0.19/doc/summaries_cache
--- old/dnf-plugins-core-4.0.18/doc/summaries_cache 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/doc/summaries_cache 2021-01-28
18:02:06.000000000 +0100
@@ -586,5 +586,25 @@
[
1844925,
"when i execute \"dnf download\" failed i want to get return value 1
not 0 in shell."
+ ],
+ [
+ 1913962,
+ "\"dnf needs-restarting -r\" work incorrectly inside systemd-nspawn
containers"
+ ],
+ [
+ 1772939,
+ "For \"needs-restarting\" command. re-Include option (-s --services
-- \"List the affected systemd services only.\")"
+ ],
+ [
+ 1914251,
+ "\"dnf needs-restarting -r\" work incorrectly inside systemd-nspawn
containers"
+ ],
+ [
+ 1899852,
+ "repomanage is broken, reports not existing packages"
+ ],
+ [
+ 1856818,
+ "[RFE] add gpgcheck back to reposync"
]
-]
\ No newline at end of file
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/libexec/dnf-utils.in
new/dnf-plugins-core-4.0.19/libexec/dnf-utils.in
--- old/dnf-plugins-core-4.0.18/libexec/dnf-utils.in 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/libexec/dnf-utils.in 2021-01-28
18:02:06.000000000 +0100
@@ -37,6 +37,7 @@
'yum-config-manager': ['config-manager'],
'yum-debug-dump': ['debug-dump'],
'yum-debug-restore': ['debug-restore'],
+ 'yum-groups-manager': ['groups-manager'],
'yumdownloader': ['download']
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/CMakeLists.txt
new/dnf-plugins-core-4.0.19/plugins/CMakeLists.txt
--- old/dnf-plugins-core-4.0.18/plugins/CMakeLists.txt 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/plugins/CMakeLists.txt 2021-01-28
18:02:06.000000000 +0100
@@ -6,6 +6,7 @@
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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/copr.py
new/dnf-plugins-core-4.0.19/plugins/copr.py
--- old/dnf-plugins-core-4.0.18/plugins/copr.py 2020-10-06 18:54:52.000000000
+0200
+++ new/dnf-plugins-core-4.0.19/plugins/copr.py 2021-01-28 18:02:06.000000000
+0100
@@ -50,7 +50,7 @@
with open('/etc/os-release') as os_release_file:
os_release_data = {}
for line in os_release_file:
- os_release_key, os_release_value = line.rstrip.split('=')
+ os_release_key, os_release_value = line.rstrip().split('=')
os_release_data[os_release_key] =
os_release_value.strip('"')
return (os_release_data['NAME'],
os_release_data['VERSION_ID'], None)
@@ -223,8 +223,15 @@
'copr command are required'))
try:
chroot = self.opts.arg[1]
+ if len(self.opts.arg) > 2:
+ raise dnf.exceptions.Error(_('Too many arguments.'))
+ self.chroot_parts = chroot.split("-")
+ if len(self.chroot_parts) < 3:
+ raise dnf.exceptions.Error(_('Bad format of optional chroot.
The format is '
+
'distribution-version-architecture.'))
except IndexError:
chroot = self._guess_chroot()
+ self.chroot_parts = chroot.split("-")
# commands without defined copr_username/copr_projectname
if subcommand == "search":
@@ -267,7 +274,7 @@
copr_projectname])
msg = "Do you really want to enable {0}?".format(project)
self._ask_user(info, msg)
- self._download_repo(project_name, repo_filename, chroot)
+ self._download_repo(project_name, repo_filename)
logger.info(_("Repository successfully enabled."))
self._runtime_deps_warning(copr_username, copr_projectname)
elif subcommand == "disable":
@@ -453,11 +460,9 @@
chroot = ("epel-%s-x86_64" % dist[1].split(".", 1)[0])
return chroot
- def _download_repo(self, project_name, repo_filename, chroot=None):
- if chroot is None:
- chroot = self._guess_chroot()
- short_chroot = '-'.join(chroot.split('-')[:2])
- arch = chroot.split('-')[2]
+ def _download_repo(self, project_name, repo_filename):
+ short_chroot = '-'.join(self.chroot_parts[:-1])
+ arch = self.chroot_parts[-1]
api_path =
"/coprs/{0}/repo/{1}/dnf.repo?arch={2}".format(project_name, short_chroot, arch)
try:
@@ -660,7 +665,7 @@
f.close()
if (output2 and ("output" in output2)
and (output2["output"] == "ok")):
- self._download_repo(project_name, repo_filename, chroot)
+ self._download_repo(project_name, repo_filename)
except dnf.exceptions.Error:
# likely 404 and that repo does not exist
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/groups_manager.py
new/dnf-plugins-core-4.0.19/plugins/groups_manager.py
--- old/dnf-plugins-core-4.0.18/plugins/groups_manager.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dnf-plugins-core-4.0.19/plugins/groups_manager.py 2021-01-28
18:02:06.000000000 +0100
@@ -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
+
+
[email protected]_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))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/needs_restarting.py
new/dnf-plugins-core-4.0.19/plugins/needs_restarting.py
--- old/dnf-plugins-core-4.0.18/plugins/needs_restarting.py 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/plugins/needs_restarting.py 2021-01-28
18:02:06.000000000 +0100
@@ -29,6 +29,7 @@
import dnf
import dnf.cli
+import dbus
import functools
import os
import re
@@ -126,6 +127,30 @@
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:
@@ -174,11 +199,7 @@
@staticmethod
def get_boot_time():
- with open('/proc/stat') as stat_file:
- for line in stat_file.readlines():
- if not line.startswith('btime '):
- continue
- return int(line[len('btime '):].strip())
+ return int(os.stat('/proc/1/cmdline').st_mtime)
@staticmethod
def get_sc_clk_tck():
@@ -205,6 +226,8 @@
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 +274,11 @@
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)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dnf-plugins-core-4.0.18/plugins/post-transaction-actions.py
new/dnf-plugins-core-4.0.19/plugins/post-transaction-actions.py
--- old/dnf-plugins-core-4.0.18/plugins/post-transaction-actions.py
2020-10-06 18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/plugins/post-transaction-actions.py
2021-01-28 18:02:06.000000000 +0100
@@ -117,7 +117,7 @@
out_ts_items.append(ts_item)
all_ts_items.append(ts_item)
- commands_to_run = set()
+ commands_to_run = []
for (a_key, a_state, a_command) in action_tuples:
if a_state == "in":
ts_items = in_ts_items
@@ -141,7 +141,11 @@
if tsi.pkg == pkg and tsi.pkg.reponame ==
pkg.reponame]
ts_item = ts_item_list[0]
command = self._replace_vars(ts_item, a_command)
- commands_to_run.add(command)
+ commands_to_run.append(command)
+
+ # de-dup the list
+ seen = set()
+ commands_to_run = [x for x in commands_to_run if x not in seen and not
seen.add(x)]
for command in commands_to_run:
try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/repomanage.py
new/dnf-plugins-core-4.0.19/plugins/repomanage.py
--- old/dnf-plugins-core-4.0.18/plugins/repomanage.py 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/plugins/repomanage.py 2021-01-28
18:02:06.000000000 +0100
@@ -71,8 +71,11 @@
raise dnf.exceptions.Error(_("No files to process"))
try:
- this_repo = self.base.repos.add_new_repo("repomanage_repo",
self.base.conf, baseurl=[self.opts.path])
- self.base._add_repo_to_sack(this_repo)
+ 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
+ # for multiple runs even if the actual repo changed in the meantime
+ repo_conf._repo.expire()
+ self.base._add_repo_to_sack(repo_conf)
if dnf.base.WITH_MODULES:
self.base._setup_modular_excludes()
@@ -130,7 +133,7 @@
# modular packages
for streams_by_version in module_dict.values():
- sorted_stream_versions = sorted(streams_by_version.keys(),
reverse=True)
+ sorted_stream_versions = sorted(streams_by_version.keys())
new_sorted_stream_versions = sorted_stream_versions[-keepnum:]
@@ -153,7 +156,7 @@
# modular packages
for streams_by_version in module_dict.values():
- sorted_stream_versions = sorted(streams_by_version.keys(),
reverse=True)
+ sorted_stream_versions = sorted(streams_by_version.keys())
old_sorted_stream_versions = sorted_stream_versions[:-keepnum]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/plugins/reposync.py
new/dnf-plugins-core-4.0.19/plugins/reposync.py
--- old/dnf-plugins-core-4.0.18/plugins/reposync.py 2020-10-06
18:54:52.000000000 +0200
+++ new/dnf-plugins-core-4.0.19/plugins/reposync.py 2021-01-28
18:02:06.000000000 +0100
@@ -24,6 +24,7 @@
import hawkey
import os
import shutil
+import types
from dnfpluginscore import _, logger
from dnf.cli.option_parser import OptionParser
@@ -63,24 +64,27 @@
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('-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',
+ 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"))
@@ -114,6 +118,7 @@
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 @@
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,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dnf-plugins-core-4.0.18/tests/CMakeLists.txt
new/dnf-plugins-core-4.0.19/tests/CMakeLists.txt
--- old/dnf-plugins-core-4.0.18/tests/CMakeLists.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/dnf-plugins-core-4.0.19/tests/CMakeLists.txt 2021-01-28
18:02:06.000000000 +0100
@@ -0,0 +1,4 @@
+ADD_TEST(test ${PYTHON_EXECUTABLE} -m nose -s ${CMAKE_CURRENT_SOURCE_DIR})
+
+# ASAN_OPTIONS is for libdnf built with sanitizers, has no effect otherwise.
+SET_PROPERTY(TEST test PROPERTY ENVIRONMENT
"PYTHONPATH=${CMAKE_SOURCE_DIR}/plugins;ASAN_OPTIONS=verify_asan_link_order=0")