Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

53 changed files with 1468 additions and 14979 deletions

View File

@ -1 +0,0 @@
40f26a50a6605eacb1e9c4a443f01655fa461767 SOURCES/dnf-plugins-core-4.0.21.tar.gz

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

73
.gitignore vendored
View File

@ -1 +1,72 @@
SOURCES/dnf-plugins-core-4.0.21.tar.gz
/dnf-plugins-core-5bdfc96.tar.xz
/dnf-plugins-core-c897eac.tar.xz
/dnf-plugins-core-bc10258.tar.xz
/dnf-plugins-core-87e557d.tar.xz
/dnf-plugins-core-d8e8044.tar.xz
/dnf-plugins-core-c8940d0.tar.xz
/dnf-plugins-core-351e094.tar.xz
/dnf-plugins-core-f0f0cef.tar.xz
/dnf-plugins-core-0.1.6.tar.gz
/dnf-plugins-core-0.1.7.tar.gz
/dnf-plugins-core-0.1.8.tar.gz
/dnf-plugins-core-0.1.9.tar.gz
/dnf-plugins-core-0.1.10.tar.gz
/dnf-plugins-core-0.1.11.tar.gz
/dnf-plugins-core-0.1.12.tar.gz
/dnf-plugins-core-0.1.13.tar.gz
/dnf-plugins-core-0.1.14.tar.gz
/dnf-plugins-core-0.1.15.tar.gz
/dnf-plugins-core-0.1.16.tar.gz
/dnf-plugins-core-0.1.17.tar.gz
/dnf-plugins-core-0.1.18.tar.gz
/dnf-plugins-core-0.1.19.tar.gz
/dnf-plugins-core-0.1.20.tar.gz
/dnf-plugins-core-0.1.21.tar.gz
/dnf-plugins-core-1.0.0.tar.gz
/dnf-plugins-core-1.0.1.tar.gz
/dnf-plugins-core-1.0.2.tar.gz
/dnf-plugins-core-1.1.0.tar.gz
/dnf-plugins-core-2.0.0.tar.gz
/dnf-plugins-core-2.1.0.tar.gz
/dnf-plugins-core-2.1.1.tar.gz
/dnf-plugins-core-2.1.2.tar.gz
/dnf-plugins-core-2.1.3.tar.gz
/dnf-plugins-core-2.1.4.tar.gz
/dnf-plugins-core-2.1.5.tar.gz
/dnf-plugins-core-3.0.1.tar.gz
/dnf-plugins-core-3.0.2.tar.gz
/dnf-plugins-core-3.0.3.tar.gz
/dnf-plugins-core-3.0.4.tar.gz
/dnf-plugins-core-4.0.0.tar.gz
/dnf-plugins-core-4.0.2.tar.gz
/dnf-plugins-core-4.0.3.tar.gz
/dnf-plugins-core-4.0.4.tar.gz
/dnf-plugins-core-4.0.6.tar.gz
/dnf-plugins-core-4.0.7.tar.gz
/dnf-plugins-core-4.0.9.tar.gz
/dnf-plugins-core-4.0.10.tar.gz
/dnf-plugins-core-4.0.11.tar.gz
/dnf-plugins-core-4.0.12.tar.gz
/dnf-plugins-core-4.0.13.tar.gz
/dnf-plugins-core-4.0.14.tar.gz
/dnf-plugins-core-4.0.15.tar.gz
/dnf-plugins-core-4.0.16.tar.gz
/dnf-plugins-core-4.0.18.tar.gz
/dnf-plugins-core-4.0.19.tar.gz
/dnf-plugins-core-4.0.21.tar.gz
/dnf-plugins-core-4.0.22.tar.gz
/dnf-plugins-core-4.0.23.tar.gz
/dnf-plugins-core-4.0.24.tar.gz
/dnf-plugins-core-4.1.0.tar.gz
/dnf-plugins-core-4.2.0.tar.gz
/dnf-plugins-core-4.2.1.tar.gz
/dnf-plugins-core-4.3.0.tar.gz
/dnf-plugins-core-4.3.1.tar.gz
/dnf-plugins-core-4.4.0.tar.gz
/dnf-plugins-core-4.4.1.tar.gz
/dnf-plugins-core-4.4.2.tar.gz
/dnf-plugins-core-4.4.3.tar.gz
/dnf-plugins-core-4.4.4.tar.gz
/dnf-plugins-core-4.5.0.tar.gz
/dnf-plugins-core-4.6.0.tar.gz
/dnf-plugins-core-4.7.0.tar.gz

View File

@ -0,0 +1,88 @@
From 78a541bff0eb234e77b64c058ef51b0650208c1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 6 Jun 2024 13:11:12 +0200
Subject: [PATCH] needs-restarting: Revert using systemd start time
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since commit a0ac8717219a1ec9f466162e87f40afa9aa65284 "dnf
needs-restarting -s" failed to spot services started withing few
seconds before updating their RPM package.
The cause was using systemd start time instead of a kernel boot time
when computing an absolute start time of processes.
This patch removes using the systemd start time until a proper fix is
found.
https://issues.redhat.com/browse/RHEL-39775
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
doc/needs_restarting.rst | 6 +-----
plugins/needs_restarting.py | 24 ------------------------
2 files changed, 1 insertion(+), 29 deletions(-)
diff --git a/doc/needs_restarting.rst b/doc/needs_restarting.rst
index 26f401b..be3cc03 100644
--- a/doc/needs_restarting.rst
+++ b/doc/needs_restarting.rst
@@ -36,12 +36,8 @@ Description
Note that in most cases a process should survive update of its binary and libraries it is using without requiring to be restarted for proper operation. There are however specific cases when this does not apply. Separately, processes often need to be restarted to reflect security updates.
.. note::
- Needs-restarting will try to guess the boot time using three different methods:
+ Needs-restarting will try to guess the boot time using two different methods:
- ``UnitsLoadStartTimestamp``
- D-Bus property on ``/org/freedesktop/systemd1``.
- Works unless the system was not booted with systemd,
- such as in (most) containers.
``st_mtime of /proc/1``
Reflects the time the first process was run after booting.
This works for all known cases except machines without
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 8a41753..86777a2 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -218,11 +218,6 @@ class ProcessStart(object):
We have two sources from which to derive the boot time. These values vary
depending on containerization, existence of a Real Time Clock, etc.
For our purposes we want the latest derived value.
- - UnitsLoadStartTimestamp property on /org/freedesktop/systemd1
- The start time of the service manager, according to systemd itself.
- Seems to be more reliable than UserspaceTimestamp when the RTC is
- in local time. Works unless the system was not booted with systemd,
- such as in (most) containers.
- st_mtime of /proc/1
Reflects the time the first process was run after booting
This works for all known cases except machines without
@@ -233,25 +228,6 @@ class ProcessStart(object):
Does not work on containers which share their kernel with the
host - there the host kernel uptime is returned
"""
- units_load_start_timestamp = None
- try:
- bus = dbus.SystemBus()
- systemd1 = bus.get_object(
- 'org.freedesktop.systemd1',
- '/org/freedesktop/systemd1'
- )
- props = dbus.Interface(
- systemd1,
- dbus.PROPERTIES_IFACE
- )
- units_load_start_timestamp = props.Get(
- 'org.freedesktop.systemd1.Manager',
- 'UnitsLoadStartTimestamp'
- )
- if units_load_start_timestamp != 0:
- return int(units_load_start_timestamp / (1000 * 1000))
- except dbus.exceptions.DBusException as e:
- logger.debug("D-Bus error getting boot time from systemd: {}".format(e))
proc_1_boot_time = int(os.stat('/proc/1').st_mtime)
if os.path.isfile('/proc/uptime'):
--
2.45.2

View File

@ -0,0 +1,105 @@
From 73ef31daf47fe0a90f0cda225c585ba4ceec9420 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 14 Jun 2024 17:46:04 +0200
Subject: [PATCH] spec: Fix symbolic links to packaged files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Upstream commit: 73ef31daf47fe0a90f0cda225c585ba4ceec9420
Some relative symlinks had an incorrect nesting:
$ rpm -qlv dnf-plugins-core-4.7.0-2.el10.noarch | grep dnf-offline
lrwxrwxrwx 1 root root 70 Jun 6 02:00 /usr/share/man/man8/dnf-offline-distrosync.8.gz -> ../../../../../../../../../usr/share/man/man8/dnf4-system-upgrade.8.gz
lrwxrwxrwx 1 root root 70 Jun 6 02:00 /usr/share/man/man8/dnf-offline-upgrade.8.gz -> ../../../../../../../../../usr/share/man/man8/dnf4-system-upgrade.8.gz
Also rpmlint and recenct rpmbuild complained on using absolute
symlinks:
dnf-plugins-core.noarch: W: symlink-should-be-relative /usr/share/man/man8/dnf4-offline-distrosync.8.gz /usr/share/man/man8/dnf4-system-upgrade.8.gz
dnf-plugins-core.noarch: W: symlink-should-be-relative /usr/share/man/man8/dnf4-offline-upgrade.8.gz /usr/share/man/man8/dnf4-system-upgrade.8.gz
This patch fixes all these issues.
Resolves: https://issues.redhat.com/browse/RHEL-40564
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
dnf-plugins-core.spec | 46 +++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index f0984dd..969233b 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -498,15 +498,15 @@ pushd %{buildroot}%{_unitdir}/system-update.target.wants/
ln -sr ../dnf-system-upgrade.service
popd
-ln -sf %{_mandir}/man8/dnf4-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf4-offline-upgrade.8.gz
-ln -sf %{_mandir}/man8/dnf4-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf4-offline-distrosync.8.gz
+ln -sf dnf4-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf4-offline-upgrade.8.gz
+ln -sf dnf4-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf4-offline-distrosync.8.gz
%endif
%if %{without dnf5_obsoletes_dnf}
for file in %{buildroot}%{_mandir}/man8/dnf4[-.]*; do
dir=$(dirname $file)
filename=$(basename $file)
- ln -sr $file $dir/${filename/dnf4/dnf}
+ ln -sf $filename $dir/${filename/dnf4/dnf}
done
%endif
@@ -522,28 +522,28 @@ rm -vf %{buildroot}%{_libexecdir}/dnf-utils-*
%if %{with yumutils}
mkdir -p %{buildroot}%{_bindir}
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/debuginfo-install
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/needs-restarting
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/find-repos-of-install
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repo-graph
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/package-cleanup
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repoclosure
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repodiff
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repomanage
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repoquery
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/reposync
-ln -sf %{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repotrack
-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
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/debuginfo-install
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/needs-restarting
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/find-repos-of-install
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repo-graph
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/package-cleanup
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repoclosure
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repodiff
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repomanage
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repoquery
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/reposync
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repotrack
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-builddep
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-config-manager
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-dump
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-restore
+ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-groups-manager
+ln -srf %{buildroot}%{_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.
-ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/find-repos-of-install.1.gz
-ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repoquery.1.gz
-ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1.gz
+ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/find-repos-of-install.1.gz
+ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repoquery.1.gz
+ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1.gz
%endif
%check
--
2.45.2

View File

@ -0,0 +1,334 @@
From 258ce716def8cf4e406da8eb4a80eace4865ac29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 14 Jun 2024 13:57:42 +0200
Subject: [PATCH] build: Disable debug plugin on Fedora > 40 and RHEL > 9
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Upstream commit: 918a17c540e69bd227a0534d3838c780341c600a
Upstream commit: 0ea22cfbd572d6ca188c6eac73d86287d1ceb17d
This adds -DWITHOUT_DEBUG:str=1 CMake option to disable installing
debug plugin (i.e. debug-dump and debug-restore).
The plugin is unhelp and broken.
https://issues.redhat.com/browse/RHEL-23706
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
CMakeLists.txt | 4 ++++
README.rst | 8 +++++++
dnf-plugins-core.spec | 50 +++++++++++++++++++++++++++++++++++++-----
doc/CMakeLists.txt | 14 +++++++++---
plugins/CMakeLists.txt | 2 ++
5 files changed, 69 insertions(+), 9 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1eea7b..a54e2c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,10 @@
PROJECT (dnf-plugins-core NONE)
CMAKE_MINIMUM_REQUIRED (VERSION 2.4)
+if (NOT WITHOUT_DEBUG)
+ set (WITHOUT_DEBUG "0")
+endif()
+
if (NOT WITHOUT_LOCAL)
set (WITHOUT_LOCAL "0")
endif()
diff --git a/README.rst b/README.rst
index 031c013..321abfe 100644
--- a/README.rst
+++ b/README.rst
@@ -26,6 +26,14 @@ From the DNF git checkout directory::
cmake .. && make;
popd;
+CMake optional switches::
+
+ -DWITHOUT_LOCAL:str=1
+ Differnt string value than "0" disables installing a local plugin.
+
+ -DWITHOUT_DEBUG:str=1
+ Differnt string value than "0" disables installing a debug plugin.
+
Then to run DNF::
PYTHONPATH=`readlink -f .` bin/dnf <arguments>
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 969233b..a2fe33f 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -10,6 +10,12 @@
%bcond dnf5_obsoletes_dnf %[0%{?fedora} > 40 || 0%{?rhel} > 11]
+%if (0%{?fedora} && 0%{?fedora} >= 41) || (0%{?rhel} && 0%{?rhel} >= 10)
+%bcond_with debug_plugin
+%else
+%bcond_without debug_plugin
+%endif
+
%if 0%{?rhel} && 0%{?rhel} <= 7
%bcond_with python3
%else
@@ -56,8 +62,10 @@ Provides: dnf-command(builddep)
Provides: dnf-command(changelog)
Provides: dnf-command(config-manager)
Provides: dnf-command(copr)
+%if %{with debug_plugin}
Provides: dnf-command(debug-dump)
Provides: dnf-command(debug-restore)
+%endif
Provides: dnf-command(debuginfo-install)
Provides: dnf-command(download)
Provides: dnf-command(groups-manager)
@@ -69,7 +77,9 @@ Provides: dnf-command(repodiff)
Provides: dnf-command(system-upgrade)
Provides: dnf-command(offline-upgrade)
Provides: dnf-command(offline-distrosync)
+%if %{with debug_plugin}
Provides: dnf-plugins-extras-debug = %{version}-%{release}
+%endif
Provides: dnf-plugins-extras-repoclosure = %{version}-%{release}
Provides: dnf-plugins-extras-repograph = %{version}-%{release}
Provides: dnf-plugins-extras-repomanage = %{version}-%{release}
@@ -95,7 +105,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, groups-manager, repoclosure,
+copr, %{?with_debug_plugin:debug, }debuginfo-install, download, needs-restarting, groups-manager, repoclosure,
repograph, repomanage, reposync, changelog and repodiff commands. Additionally
provides generate_completion_cache passive plugin.
@@ -122,11 +132,15 @@ Requires: python-dateutil
Requires: python2-dbus
Requires: python2-dateutil
%endif
+%if %{with debug_plugin}
Provides: python2-dnf-plugins-extras-debug = %{version}-%{release}
+%endif
Provides: python2-dnf-plugins-extras-repoclosure = %{version}-%{release}
Provides: python2-dnf-plugins-extras-repograph = %{version}-%{release}
Provides: python2-dnf-plugins-extras-repomanage = %{version}-%{release}
+%if %{with debug_plugin}
Obsoletes: python2-dnf-plugins-extras-debug < %{dnf_plugins_extra}
+%endif
Obsoletes: python2-dnf-plugins-extras-repoclosure < %{dnf_plugins_extra}
Obsoletes: python2-dnf-plugins-extras-repograph < %{dnf_plugins_extra}
Obsoletes: python2-dnf-plugins-extras-repomanage < %{dnf_plugins_extra}
@@ -138,7 +152,7 @@ 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,
+config-manager, copr, %{?with_debug_plugin:debug, }debuginfo-install, download, needs-restarting,
groups-manager, repoclosure, repograph, repomanage, reposync, changelog,
repodiff, system-upgrade, offline-upgrade and offline-distrosync commands.
Additionally provides generate_completion_cache passive plugin.
@@ -163,12 +177,16 @@ Requires: python3-dnf >= %{dnf_lowest_compatible}
Requires: python3-hawkey >= %{hawkey_version}
Requires: python3-dateutil
Requires: python3-systemd
+%if %{with debug_plugin}
Provides: python3-dnf-plugins-extras-debug = %{version}-%{release}
+%endif
Provides: python3-dnf-plugins-extras-repoclosure = %{version}-%{release}
Provides: python3-dnf-plugins-extras-repograph = %{version}-%{release}
Provides: python3-dnf-plugins-extras-repomanage = %{version}-%{release}
Provides: python3-dnf-plugin-system-upgrade = %{version}-%{release}
+%if %{with debug_plugin}
Obsoletes: python3-dnf-plugins-extras-debug < %{dnf_plugins_extra}
+%endif
Obsoletes: python3-dnf-plugins-extras-repoclosure < %{dnf_plugins_extra}
Obsoletes: python3-dnf-plugins-extras-repograph < %{dnf_plugins_extra}
Obsoletes: python3-dnf-plugins-extras-repomanage < %{dnf_plugins_extra}
@@ -181,7 +199,7 @@ 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,
+config-manager, copr, %{?with_debug_plugin:debug, }debuginfo-install, download, needs-restarting,
groups-manager, repoclosure, repograph, repomanage, reposync, changelog,
repodiff, system-upgrade, offline-upgrade and offline-distrosync commands.
Additionally provides generate_completion_cache passive plugin.
@@ -209,7 +227,7 @@ 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,
+repoquery, reposync, repotrack, repodiff, builddep, config-manager,%{?with_debug_plugin: debug,}
download and yum-groups-manager that use new implementations using DNF.
%endif
@@ -467,14 +485,18 @@ mkdir build-py3
%build
%if %{with python2}
pushd build-py2
- %cmake ../ -DPYTHON_DESIRED:FILEPATH=%{__python2} -DWITHOUT_LOCAL:str=0%{?rhel}
+ %cmake ../ -DPYTHON_DESIRED:FILEPATH=%{__python2} \
+ -DWITHOUT_DEBUG:str=0%{!?with_debug_plugin:1} \
+ -DWITHOUT_LOCAL:str=0%{?rhel}
%make_build
make doc-man
popd
%endif
%if %{with python3}
pushd build-py3
- %cmake ../ -DPYTHON_DESIRED:FILEPATH=%{__python3} -DWITHOUT_LOCAL:str=0%{?rhel}
+ %cmake ../ -DPYTHON_DESIRED:FILEPATH=%{__python3} \
+ -DWITHOUT_DEBUG:str=0%{!?with_debug_plugin:1} \
+ -DWITHOUT_LOCAL:str=0%{?rhel}
%make_build
make doc-man
popd
@@ -535,8 +557,10 @@ ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/reposync
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/repotrack
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-builddep
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-config-manager
++%if %{with debug_plugin}
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-dump
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-debug-restore
++%endif
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yum-groups-manager
ln -srf %{buildroot}%{_libexecdir}/dnf-utils %{buildroot}%{_bindir}/yumdownloader
# These commands don't have a dedicated man page, so let's just point them
@@ -563,7 +587,9 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_mandir}/man8/dnf*-changelog.*
%{_mandir}/man8/dnf*-config-manager.*
%{_mandir}/man8/dnf*-copr.*
+%if %{with debug_plugin}
%{_mandir}/man8/dnf*-debug.*
+%endif
%{_mandir}/man8/dnf*-debuginfo-install.*
%{_mandir}/man8/dnf*-download.*
%{_mandir}/man8/dnf*-generate_completion_cache.*
@@ -597,7 +623,9 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{python2_sitelib}/dnf-plugins/changelog.*
%{python2_sitelib}/dnf-plugins/config_manager.*
%{python2_sitelib}/dnf-plugins/copr.*
+%if %{with debug_plugin}
%{python2_sitelib}/dnf-plugins/debug.*
+%endif
%{python2_sitelib}/dnf-plugins/debuginfo-install.*
%{python2_sitelib}/dnf-plugins/download.*
%{python2_sitelib}/dnf-plugins/generate_completion_cache.*
@@ -623,7 +651,9 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{python3_sitelib}/dnf-plugins/changelog.py
%{python3_sitelib}/dnf-plugins/config_manager.py
%{python3_sitelib}/dnf-plugins/copr.py
+%if %{with debug_plugin}
%{python3_sitelib}/dnf-plugins/debug.py
+%endif
%{python3_sitelib}/dnf-plugins/debuginfo-install.py
%{python3_sitelib}/dnf-plugins/download.py
%{python3_sitelib}/dnf-plugins/generate_completion_cache.py
@@ -639,7 +669,9 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{python3_sitelib}/dnf-plugins/__pycache__/changelog.*
%{python3_sitelib}/dnf-plugins/__pycache__/config_manager.*
%{python3_sitelib}/dnf-plugins/__pycache__/copr.*
+%if %{with debug_plugin}
%{python3_sitelib}/dnf-plugins/__pycache__/debug.*
+%endif
%{python3_sitelib}/dnf-plugins/__pycache__/debuginfo-install.*
%{python3_sitelib}/dnf-plugins/__pycache__/download.*
%{python3_sitelib}/dnf-plugins/__pycache__/generate_completion_cache.*
@@ -673,8 +705,10 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_bindir}/repotrack
%{_bindir}/yum-builddep
%{_bindir}/yum-config-manager
+%if %{with debug_plugin}
%{_bindir}/yum-debug-dump
%{_bindir}/yum-debug-restore
+%endif
%{_bindir}/yum-groups-manager
%{_bindir}/yumdownloader
%{_mandir}/man1/debuginfo-install.*
@@ -686,8 +720,10 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_mandir}/man1/reposync.*
%{_mandir}/man1/yum-builddep.*
%{_mandir}/man1/yum-config-manager.*
+%if %{with debug_plugin}
%{_mandir}/man1/yum-debug-dump.*
%{_mandir}/man1/yum-debug-restore.*
+%endif
%{_mandir}/man1/yum-groups-manager.*
%{_mandir}/man1/yumdownloader.*
%{_mandir}/man1/package-cleanup.*
@@ -708,8 +744,10 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%exclude %{_mandir}/man1/reposync.*
%exclude %{_mandir}/man1/yum-builddep.*
%exclude %{_mandir}/man1/yum-config-manager.*
+%if %{with debug_plugin}
%exclude %{_mandir}/man1/yum-debug-dump.*
%exclude %{_mandir}/man1/yum-debug-restore.*
+%endif
%exclude %{_mandir}/man1/yum-groups-manager.*
%exclude %{_mandir}/man1/yumdownloader.*
%exclude %{_mandir}/man1/package-cleanup.*
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 9fd3f7c..143a26c 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -22,7 +22,6 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf4-builddep.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-changelog.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-config-manager.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-copr.8
- ${CMAKE_CURRENT_BINARY_DIR}/dnf4-debug.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-debuginfo-install.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-download.8
${CMAKE_CURRENT_BINARY_DIR}/dnf4-generate_completion_cache.8
@@ -48,6 +47,11 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-migrate.8
DESTINATION share/man/man8)
endif()
+if (${WITHOUT_DEBUG} STREQUAL "0")
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf4-debug.8
+ DESTINATION share/man/man8)
+endif()
+
if (${WITHOUT_LOCAL} STREQUAL "0")
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf4-local.8
DESTINATION share/man/man8)
@@ -63,8 +67,6 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/debuginfo-install.1
${CMAKE_CURRENT_BINARY_DIR}/yum-builddep.1
${CMAKE_CURRENT_BINARY_DIR}/yum-changelog.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
@@ -72,6 +74,12 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/debuginfo-install.1
${CMAKE_CURRENT_BINARY_DIR}/yum-utils.1
DESTINATION share/man/man1)
+if (${WITHOUT_DEBUG} STREQUAL "0")
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/yum-debug-dump.1
+ ${CMAKE_CURRENT_BINARY_DIR}/yum-debug-restore.1
+ DESTINATION share/man/man1)
+endif()
+
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/yum-versionlock.conf.5
DESTINATION share/man/man5)
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 6f4fa6e..d2383a5 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -1,6 +1,8 @@
INSTALL (FILES builddep.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES changelog.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+if (${WITHOUT_DEBUG} STREQUAL "0")
INSTALL (FILES debug.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+endif()
INSTALL (FILES debuginfo-install.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES config_manager.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES copr.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
--
2.45.2

View File

@ -0,0 +1,33 @@
From f0c08b4cae724057dc1183efacec45cb9032f1aa Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 18 Jun 2024 16:53:34 -0400
Subject: [PATCH] s/Differnt/Different
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
README.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.rst b/README.rst
index 321abfe..47410b2 100644
--- a/README.rst
+++ b/README.rst
@@ -29,10 +29,10 @@ From the DNF git checkout directory::
CMake optional switches::
-DWITHOUT_LOCAL:str=1
- Differnt string value than "0" disables installing a local plugin.
+ Different string value than "0" disables installing a local plugin.
-DWITHOUT_DEBUG:str=1
- Differnt string value than "0" disables installing a debug plugin.
+ Different string value than "0" disables installing a debug plugin.
Then to run DNF::
--
2.45.2

View File

@ -0,0 +1,117 @@
From 755a2a3cdbacfc1a5b632361c044be38164018fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Tue, 25 Jun 2024 12:36:55 +0200
Subject: [PATCH] Enable leaves and show-leaves plugins for RHEL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This effectively reverts commit
8a7a02b1e9573d86f5e6a430c61bf514e4856d31 because RHEL enebles these
plugins since RHEL 9.3.
Resolves: https://issues.redhat.com/browse/RHEL-44922
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
dnf-plugins-core.spec | 36 ++++--------------------------------
1 file changed, 4 insertions(+), 32 deletions(-)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 27933d1..bb06b8d 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -231,7 +231,7 @@ repoquery, reposync, repotrack, repodiff, builddep, config-manager,%{?with_debug
download and yum-groups-manager that use new implementations using DNF.
%endif
-%if 0%{?rhel} == 0 && %{with python2}
+%if %{with python2}
%package -n python2-dnf-plugin-leaves
Summary: Leaves Plugin for DNF
Requires: python2-%{name} = %{version}-%{release}
@@ -250,7 +250,7 @@ Leaves Plugin for DNF, Python 2 version. List all installed packages
not required by any other installed package.
%endif
-%if 0%{?rhel} == 0 && %{with python3}
+%if %{with python3}
%package -n python3-dnf-plugin-leaves
Summary: Leaves Plugin for DNF
Requires: python3-%{name} = %{version}-%{release}
@@ -376,7 +376,7 @@ Pre transaction actions Plugin for DNF, Python 3 version. Plugin runs actions
files.
%endif
-%if 0%{?rhel} == 0 && %{with python2}
+%if %{with python2}
%package -n python2-dnf-plugin-show-leaves
Summary: Leaves Plugin for DNF
Requires: python2-%{name} = %{version}-%{release}
@@ -397,7 +397,7 @@ packages that are no longer required by any other installed package
after a transaction.
%endif
-%if 0%{?rhel} == 0 && %{with python3}
+%if %{with python3}
%package -n python3-dnf-plugin-show-leaves
Summary: Show-leaves Plugin for DNF
Requires: python3-%{name} = %{version}-%{release}
@@ -755,8 +755,6 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%exclude %{_mandir}/man1/yum-utils.*
%endif
-%if 0%{?rhel} == 0
-
%if %{with python2}
%files -n python2-dnf-plugin-leaves
%{python2_sitelib}/dnf-plugins/leaves.*
@@ -770,18 +768,6 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_mandir}/man8/dnf*-leaves.*
%endif
-%else
-%exclude %{_mandir}/man8/dnf*-leaves.*
-%if %{with python2}
-%exclude %{python2_sitelib}/dnf-plugins/leaves.*
-%endif
-%if %{with python3}
-%exclude %{python3_sitelib}/dnf-plugins/leaves.*
-%exclude %{python3_sitelib}/dnf-plugins/__pycache__/leaves.*
-%endif
-%endif
-# endif 0%%{?rhel} == 0
-
%if 0%{?rhel} == 0 && %{with python2}
%files -n python2-dnf-plugin-local
%config(noreplace) %{_sysconfdir}/dnf/plugins/local.conf
@@ -839,8 +825,6 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_mandir}/man8/dnf*-pre-transaction-actions.*
%endif
-%if 0%{?rhel} == 0
-
%if %{with python2}
%files -n python2-dnf-plugin-show-leaves
%{python2_sitelib}/dnf-plugins/show_leaves.*
@@ -854,18 +838,6 @@ ln -sf %{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/man1/repotrack.1
%{_mandir}/man8/dnf*-show-leaves.*
%endif
-%else
-%exclude %{_mandir}/man8/dnf*-show-leaves.*
-%if %{with python2}
-%exclude %{python2_sitelib}/dnf-plugins/show_leaves.*
-%endif
-%if %{with python3}
-%exclude %{python3_sitelib}/dnf-plugins/show_leaves.*
-%exclude %{python3_sitelib}/dnf-plugins/__pycache__/show_leaves.*
-%endif
-%endif
-# endif 0%%{?rhel} == 0
-
%if %{with python2}
%files -n python2-dnf-plugin-versionlock
%config(noreplace) %{_sysconfdir}/dnf/plugins/versionlock.conf
--
2.45.2

View File

@ -0,0 +1,75 @@
From 204ad06c46b3389aff914528bcb4325bab8ef027 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 24 Sep 2024 21:43:46 +0000
Subject: [PATCH 1/2] needs-restarting: Add --exclude-services
For consumers of `dnf4 needs-restarting`'s output, it's useful to
separate the systemd services needing restart vs. the processes not
managed by systemd that need restarting. This new `dnf4 needs-restarting
--exclude-services` ONLY prints information about processes NOT managed
by systemd, and for listing systemd services that need to be restarted,
the existing `--services` flag can be used.
When both `--services` and `--exclude-services` are passed
`--exclude-services` is ignored.
For https://issues.redhat.com/browse/RHEL-56137.
---
plugins/needs_restarting.py | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 86777a2..cbb7a81 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -264,6 +264,8 @@ class NeedsRestartingCommand(dnf.cli.Command):
"(exit code 1) or not (exit code 0)"))
parser.add_argument('-s', '--services', action='store_true',
help=_("only report affected systemd services"))
+ parser.add_argument('--exclude-services', action='store_true',
+ help=_("don't list stale processes that correspond to a systemd service"))
def configure(self):
demands = self.cli.demands
@@ -303,19 +305,32 @@ class NeedsRestartingCommand(dnf.cli.Command):
return None
stale_pids = set()
+ stale_service_names = set()
uid = os.geteuid() if self.opts.useronly else None
for ofile in list_opened_files(uid):
pkg = owning_pkg_fn(ofile.presumed_name)
+ pid = ofile.pid
if pkg is None:
continue
- if pkg.installtime > process_start(ofile.pid):
- stale_pids.add(ofile.pid)
+ if pkg.installtime <= process_start(pid):
+ continue
+ if self.opts.services or self.opts.exclude_services:
+ service_name = get_service_dbus(pid)
+ if service_name is None:
+ stale_pids.add(pid)
+ else:
+ stale_service_names.add(service_name)
+ if not self.opts.exclude_services:
+ stale_pids.add(pid)
+ else:
+ # If neither --services nor --exclude-services is set, don't
+ # query D-Bus at all.
+ stale_pids.add(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)
+ for stale_service_name in sorted(stale_service_names):
+ print(stale_service_name)
return 0
+
for pid in sorted(stale_pids):
print_cmd(pid)
--
2.47.1

View File

@ -0,0 +1,26 @@
From d45b5ad95f5fa06d4cfb2a858c2c91cf1355ebd7 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Mon, 30 Sep 2024 12:47:57 +0000
Subject: [PATCH 2/2] needs-restarting: Add --exclude-services to man page
---
doc/needs_restarting.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/needs_restarting.rst b/doc/needs_restarting.rst
index be3cc03..e1fae48 100644
--- a/doc/needs_restarting.rst
+++ b/doc/needs_restarting.rst
@@ -72,6 +72,9 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det
``-s, --services``
Only list the affected systemd services.
+``--exclude-services``
+ Don't list stale processes that correspond to a systemd service.
+
-------------
Configuration
-------------
--
2.47.1

View File

@ -0,0 +1,159 @@
From 1966c63fcc99513603e06b8579cabfce15123b4f Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Thu, 3 Oct 2024 21:37:58 +0000
Subject: [PATCH 1/2] needs-restarting: Get boot time from systemd
UnitsLoadStartTimestamp
Resolves https://issues.redhat.com/browse/RHEL-35577.
Get the boot time from UnitsLoadStartTimestamp if systemd is available,
but make sure to use the kernel boot time for calculating process start
times using data from procfs. The previous attempt [1] at this failed to
do so and introduced a regression [2].
Also, get the kernel boot time from the btime field of /proc/stat instead of
calculating it from /proc/uptime, to be consistent with what procps-ng
does.
[1] https://github.com/rpm-software-management/dnf-plugins-core/pull/527
[2] https://issues.redhat.com/browse/RHEL-39775
---
plugins/needs_restarting.py | 106 +++++++++++++++++++++++++++---------
1 file changed, 81 insertions(+), 25 deletions(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index cbb7a81..8e01aba 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -206,36 +206,89 @@ class OpenedFile(object):
return match.group(1)
return self.name
-
class ProcessStart(object):
def __init__(self):
- self.boot_time = self.get_boot_time()
- self.sc_clk_tck = self.get_sc_clk_tck()
+ self.kernel_boot_time = ProcessStart.get_kernel_boot_time()
+ self.boot_time = ProcessStart.get_boot_time(self.kernel_boot_time)
+ self.sc_clk_tck = ProcessStart.get_sc_clk_tck()
+
+ @staticmethod
+ def get_kernel_boot_time():
+ try:
+ with open('/proc/stat', 'r') as file:
+ for line in file:
+ if line.startswith("btime "):
+ key, value = line.split()
+ return float(value)
+ except OSError as e:
+ logger.debug("Couldn't read /proc/stat: %s", e)
+ return 0
@staticmethod
- def get_boot_time():
+ def get_boot_time(kernel_boot_time):
"""
- We have two sources from which to derive the boot time. These values vary
+ We have three sources from which to derive the boot time. These values vary
depending on containerization, existence of a Real Time Clock, etc.
- For our purposes we want the latest derived value.
+ - UnitsLoadStartTimestamp property on /org/freedesktop/systemd1
+ The start time of the service manager, according to systemd itself.
+ Seems to be more reliable than UserspaceTimestamp when the RTC is
+ in local time. Works unless the system was not booted with systemd,
+ such as in (most) containers.
- st_mtime of /proc/1
- Reflects the time the first process was run after booting
- This works for all known cases except machines without
- a RTC - they awake at the start of the epoch.
- - /proc/uptime
- Seconds field of /proc/uptime subtracted from the current time
- Works for machines without RTC iff the current time is reasonably correct.
- Does not work on containers which share their kernel with the
- host - there the host kernel uptime is returned
+ Reflects the time the first process was run after booting. This
+ works for all known cases except machines without a RTC---they
+ awake at the start of the epoch.
+ - btime field of /proc/stat
+ Reflects the time when the kernel started. Works for machines
+ without RTC iff the current time is reasonably correct. Does not
+ work on containers which share their kernel with the host---there,
+ the host kernel uptime is returned.
"""
- proc_1_boot_time = int(os.stat('/proc/1').st_mtime)
- if os.path.isfile('/proc/uptime'):
- with open('/proc/uptime', 'rb') as f:
- uptime = f.readline().strip().split()[0].strip()
- proc_uptime_boot_time = int(time.time() - float(uptime))
- return max(proc_1_boot_time, proc_uptime_boot_time)
- return proc_1_boot_time
+ units_load_start_timestamp = None
+ try:
+ # systemd timestamps are the preferred method to determine boot
+ # time. max(proc_1_boot_time, kernel_boot_time) does not allow us
+ # to disambiguate between an unreliable RTC (e.g. the RTC is in
+ # UTC+1 instead of UTC) and a container with a proc_1_boot_time >
+ # kernel_boot_time. So we use UnitsLoadStartTimestamp if it's
+ # available, else fall back to the other methods.
+ bus = dbus.SystemBus()
+ systemd1 = bus.get_object(
+ 'org.freedesktop.systemd1',
+ '/org/freedesktop/systemd1'
+ )
+ props = dbus.Interface(
+ systemd1,
+ dbus.PROPERTIES_IFACE
+ )
+ units_load_start_timestamp = props.Get(
+ 'org.freedesktop.systemd1.Manager',
+ 'UnitsLoadStartTimestamp'
+ )
+ if units_load_start_timestamp != 0:
+ systemd_boot_time = units_load_start_timestamp / (1000 * 1000)
+ logger.debug("Got boot time from systemd: %s", systemd_boot_time)
+ return systemd_boot_time
+ except dbus.exceptions.DBusException as e:
+ logger.debug("D-Bus error getting boot time from systemd: %s", e)
+
+ logger.debug("Couldn't get boot time from systemd, checking st_mtime of /proc/1 and btime field of /proc/stat.")
+
+ try:
+ proc_1_boot_time = float(os.stat('/proc/1').st_mtime)
+ except OSError as e:
+ logger.debug("Couldn't stat /proc/1: %s", e)
+ proc_1_boot_time = 1
+ kernel_boot_time = kernel_boot_time
+
+ boot_time = max(proc_1_boot_time, kernel_boot_time)
+
+ logger.debug("st_mtime of /proc/1: %s", proc_1_boot_time)
+ logger.debug("btime field of /proc/stat: %s", kernel_boot_time)
+ logger.debug("Using %s as the system boot time.", boot_time)
+
+ return boot_time
@staticmethod
def get_sc_clk_tck():
@@ -244,10 +297,13 @@ class ProcessStart(object):
def __call__(self, pid):
stat_fn = '/proc/%d/stat' % pid
with open(stat_fn) as stat_file:
- stats = stat_file.read().strip().split()
- ticks_after_boot = int(stats[21])
- secs_after_boot = ticks_after_boot // self.sc_clk_tck
- return self.boot_time + secs_after_boot
+ stats = stat_file.read().split()
+ ticks_after_kernel_boot = int(stats[21])
+ secs_after_kernel_boot = ticks_after_kernel_boot / self.sc_clk_tck
+
+ # The process's start time is always measured relative to the kernel
+ # start time, not either of the other methods we use to get "boot time".
+ return self.kernel_boot_time + secs_after_kernel_boot
@dnf.plugin.register_command
--
2.48.1

View File

@ -0,0 +1,31 @@
From 54b9f83879dfb7bccfd610845ae9981c55f776b5 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Wed, 22 Jan 2025 16:46:52 +0000
Subject: [PATCH 2/2] doc: needs-restarting uses UnitsLoadStartTimestamp boot
time
---
doc/needs_restarting.rst | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/doc/needs_restarting.rst b/doc/needs_restarting.rst
index e1fae48..fea407e 100644
--- a/doc/needs_restarting.rst
+++ b/doc/needs_restarting.rst
@@ -36,8 +36,12 @@ Description
Note that in most cases a process should survive update of its binary and libraries it is using without requiring to be restarted for proper operation. There are however specific cases when this does not apply. Separately, processes often need to be restarted to reflect security updates.
.. note::
- Needs-restarting will try to guess the boot time using two different methods:
+ Needs-restarting will try to guess the boot time using three different methods:
+ ``UnitsLoadStartTimestamp``
+ D-Bus property on ``/org/freedesktop/systemd1``.
+ Works unless the system was not booted with systemd,
+ such as in (most) containers.
``st_mtime of /proc/1``
Reflects the time the first process was run after booting.
This works for all known cases except machines without
--
2.48.1

View File

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

@ -1,42 +0,0 @@
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,33 +0,0 @@
From ebacba86979d16cdb92ace9d7dc601a85c97b5db Mon Sep 17 00:00:00 2001
From: Jakub Kadlcik <frostyx@email.cz>
Date: Tue, 12 Oct 2021 18:30:47 +0200
Subject: [PATCH] copr: don't traceback on empty lines in /etc/os-release
Fix RHBZ 1994944
---
plugins/copr.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 4644495..8841f03 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -50,8 +50,13 @@ except ImportError:
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_data[os_release_key] = os_release_value.strip('"')
+ try:
+ os_release_key, os_release_value = line.rstrip().split('=')
+ os_release_data[os_release_key] = os_release_value.strip('"')
+ except ValueError:
+ # Skip empty lines and everything that is not a simple
+ # variable assignment
+ pass
return (os_release_data['NAME'], os_release_data['VERSION_ID'], None)
PLUGIN_CONF = 'copr'
--
libgit2 1.0.1

View File

@ -1,40 +0,0 @@
From b60f27006cdbdd14fb480aa22610fcd32bfe41e5 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Wed, 6 Oct 2021 13:40:55 +0200
Subject: [PATCH] reposync: Use fail_fast=False when downloading packages (RhBug:2009894)
= changelog =
msg: Reposync does not stop downloading packages on the first error
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2009894
---
dnf-plugins-core.spec | 2 +-
plugins/reposync.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 83ae6ae..cef836f 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -1,4 +1,4 @@
-%{?!dnf_lowest_compatible: %global dnf_lowest_compatible 4.2.22}
+%{?!dnf_lowest_compatible: %global dnf_lowest_compatible 4.9.2}
%global dnf_plugins_extra 2.0.0
%global hawkey_version 0.46.1
%global yum_utils_subpackage_name dnf-utils
diff --git a/plugins/reposync.py b/plugins/reposync.py
index 66c76a7..0ff936f 100644
--- a/plugins/reposync.py
+++ b/plugins/reposync.py
@@ -303,7 +303,7 @@ class RepoSyncCommand(dnf.cli.Command):
progress, 0)
payloads = [RPMPayloadLocation(pkg, progress, self.pkg_download_path(pkg))
for pkg in pkglist]
- base._download_remote_payloads(payloads, drpm, progress, None)
+ base._download_remote_payloads(payloads, drpm, progress, None, False)
def print_urls(self, pkglist):
for pkg in pkglist:
--
libgit2 1.0.1

View File

@ -1,101 +0,0 @@
From 54b7c5f91b4ad1db1f716f25cc7973ec7542f0d4 Mon Sep 17 00:00:00 2001
From: Jakub Kadlcik <frostyx@email.cz>
Date: Tue, 12 Oct 2021 12:54:05 +0200
Subject: [PATCH] copr: migrate all calls to APIv3
In the latest Copr release we dropped all APIv1 code from frontend.
https://docs.pagure.org/copr.copr/release-notes/2021-10-01.html
Unfortunatelly we frogot to migrate DNF copr plugin to APIv3 and
therefore the following commands started failing with 404.
dnf copr search tests
dnf copr list --available-by-user frostyx
---
plugins/copr.py | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 8841f03..7fc6c6f 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -355,51 +355,45 @@ Bugzilla. In case of problems, contact the owner of this repository.
"Re-enable the project to fix this."))
def _list_user_projects(self, user_name):
- # http://copr.fedorainfracloud.org/api/coprs/ignatenkobrain/
- api_path = "/api/coprs/{}/".format(user_name)
- res = self.base.urlopen(self.copr_url + api_path, mode='w+')
+ # https://copr.fedorainfracloud.org/api_3/project/list?ownername=ignatenkobrain
+ api_path = "/api_3/project/list?ownername={0}".format(user_name)
+ url = self.copr_url + api_path
+ res = self.base.urlopen(url, mode='w+')
try:
json_parse = json.loads(res.read())
except ValueError:
raise dnf.exceptions.Error(
_("Can't parse repositories for username '{}'.")
.format(user_name))
self._check_json_output(json_parse)
section_text = _("List of {} coprs").format(user_name)
self._print_match_section(section_text)
- i = 0
- while i < len(json_parse["repos"]):
- msg = "{0}/{1} : ".format(user_name,
- json_parse["repos"][i]["name"])
- desc = json_parse["repos"][i]["description"]
- if not desc:
- desc = _("No description given")
+
+ for item in json_parse["items"]:
+ msg = "{0}/{1} : ".format(user_name, item["name"])
+ desc = item["description"] or _("No description given")
msg = self.base.output.fmtKeyValFill(ucd(msg), desc)
print(msg)
- i += 1
def _search(self, query):
- # http://copr.fedorainfracloud.org/api/coprs/search/tests/
- api_path = "/api/coprs/search/{}/".format(query)
- res = self.base.urlopen(self.copr_url + api_path, mode='w+')
+ # https://copr.fedorainfracloud.org/api_3/project/search?query=tests
+ api_path = "/api_3/project/search?query={}".format(query)
+ url = self.copr_url + api_path
+ res = self.base.urlopen(url, mode='w+')
try:
json_parse = json.loads(res.read())
except ValueError:
raise dnf.exceptions.Error(_("Can't parse search for '{}'."
).format(query))
self._check_json_output(json_parse)
section_text = _("Matched: {}").format(query)
self._print_match_section(section_text)
- i = 0
- while i < len(json_parse["repos"]):
- msg = "{0}/{1} : ".format(json_parse["repos"][i]["username"],
- json_parse["repos"][i]["coprname"])
- desc = json_parse["repos"][i]["description"]
- if not desc:
- desc = _("No description given.")
+
+ for item in json_parse["items"]:
+ msg = "{0} : ".format(item["full_name"])
+ desc = item["description"] or _("No description given.")
msg = self.base.output.fmtKeyValFill(ucd(msg), desc)
print(msg)
- i += 1
def _print_match_section(self, text):
formatted = self.base.output.fmtSection(text)
@@ -624,7 +618,7 @@ Bugzilla. In case of problems, contact the owner of this repository.
@classmethod
def _check_json_output(cls, json_obj):
- if json_obj["output"] != "ok":
+ if "error" in json_obj:
raise dnf.exceptions.Error("{}".format(json_obj["error"]))
@classmethod
--
libgit2 1.0.1

View File

@ -1,31 +0,0 @@
From 5c8f753503be87e5d6237be12eec2330236d78ed Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Mon, 8 Nov 2021 16:51:56 +0100
Subject: [PATCH] groups-manager: More benevolent resolving of packages (RhBug:2013633)
= changelog =
msg: groups-manager uses for matching packages full NEVRA and not only name.
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2013633
---
plugins/groups_manager.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/plugins/groups_manager.py b/plugins/groups_manager.py
index 382df37..12da183 100644
--- a/plugins/groups_manager.py
+++ b/plugins/groups_manager.py
@@ -254,7 +254,9 @@ class GroupsManagerCommand(dnf.cli.Command):
# 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()
+ subj = dnf.subject.Subject(pkg_spec)
+ q = subj.get_best_query(self.base.sack, with_nevra=True,
+ with_provides=False, with_filenames=False).latest()
if not q:
logger.warning(_("No match for argument: {}").format(pkg_spec))
continue
--
libgit2 1.1.0

View File

@ -1,95 +0,0 @@
From 0030ea94dd261b66cac6f08c9dfa99e3d8ee3648 Mon Sep 17 00:00:00 2001
From: Nicola Sella <nsella@redhat.com>
Date: Mon, 1 Nov 2021 18:29:40 +0100
Subject: [PATCH] [versionlock] fix multi pkg lock (RhBug:2013324)
= changelog =
msg: [versionlock] Fix: Multiple package-name-spec arguments don't lock
correctly (RhBug:2001039)
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2013324
---
plugins/versionlock.py | 57 +++++++++++++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/plugins/versionlock.py b/plugins/versionlock.py
index c89a75d..77b7f91 100644
--- a/plugins/versionlock.py
+++ b/plugins/versionlock.py
@@ -167,25 +167,27 @@ class VersionLockCommand(dnf.cli.Command):
cmd = self.opts.subcommand
if cmd == 'add':
- (entry, entry_cmd) = _search_locklist(self.opts.package)
- if entry == '':
- _write_locklist(self.base, self.opts.package, self.opts.raw, True,
- "\n# Added lock on %s\n" % time.ctime(),
- ADDING_SPEC, '')
- elif cmd != entry_cmd:
- raise dnf.exceptions.Error(ALREADY_EXCLUDED.format(entry))
- else:
- logger.info("%s %s", EXISTING_SPEC, entry)
+ results = _search_locklist(self.opts.package)
+ for entry, entry_cmd in results:
+ if entry_cmd == '':
+ _write_locklist(self.base, [entry], self.opts.raw, True,
+ "\n# Added lock on %s\n" % time.ctime(),
+ ADDING_SPEC, '')
+ elif cmd != entry_cmd:
+ raise dnf.exceptions.Error(ALREADY_EXCLUDED.format(entry))
+ else:
+ logger.info("%s %s", EXISTING_SPEC, entry)
elif cmd == 'exclude':
- (entry, entry_cmd) = _search_locklist(self.opts.package)
- if entry == '':
- _write_locklist(self.base, self.opts.package, self.opts.raw, False,
- "\n# Added exclude on %s\n" % time.ctime(),
- EXCLUDING_SPEC, '!')
- elif cmd != entry_cmd:
- raise dnf.exceptions.Error(ALREADY_LOCKED.format(entry))
- else:
- logger.info("%s %s", EXISTING_SPEC, entry)
+ results = _search_locklist(self.opts.package)
+ for entry, entry_cmd in results:
+ if entry_cmd == '':
+ _write_locklist(self.base, [entry], self.opts.raw, False,
+ "\n# Added exclude on %s\n" % time.ctime(),
+ EXCLUDING_SPEC, '!')
+ elif cmd != entry_cmd:
+ raise dnf.exceptions.Error(ALREADY_LOCKED.format(entry))
+ else:
+ logger.info("%s %s", EXISTING_SPEC, entry)
elif cmd == 'list':
for pat in _read_locklist():
print(pat)
@@ -233,14 +235,21 @@ def _read_locklist():
def _search_locklist(package):
+ results = []
found = action = ''
locked_specs = _read_locklist()
- for ent in locked_specs:
- if _match(ent, package):
- found = ent
- action = 'exclude' if ent.startswith('!') else 'add'
- break
- return (found, action)
+ for pkg in package:
+ match = False
+ for ent in locked_specs:
+ found = action = ''
+ if _match(ent, [pkg]):
+ found = ent
+ action = 'exclude' if ent.startswith('!') else 'add'
+ results.append((found, action))
+ match = True
+ if not match:
+ results.append((pkg, action))
+ return results
def _write_locklist(base, args, raw, try_installed, comment, info, prefix):
--
libgit2 1.1.0

View File

@ -1,31 +0,0 @@
From ed05ce74cfb9151ea5218da0f8b9eccb70c00f70 Mon Sep 17 00:00:00 2001
From: Nicola Sella <nsella@redhat.com>
Date: Thu, 11 Nov 2021 13:48:39 +0100
Subject: [PATCH] Update documentation for adding specific version (RhBug:2013332)
=changelog=
msg: [versionlock] update documentation for adding specifi version
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2013332
---
doc/versionlock.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/doc/versionlock.rst b/doc/versionlock.rst
index 061ce80..1ac7196 100644
--- a/doc/versionlock.rst
+++ b/doc/versionlock.rst
@@ -97,6 +97,10 @@ Subcommands
Adding versionlock on: mutt-5:1.11.4-1.fc30.*
Adding versionlock on: mutt-5:1.12.1-3.fc30.*
+ .. note:: Be careful when adding specific versions
+
+ If you add a package specifying a version with ``dnf versionlock mutt-5:1.11.4-1.fc30.x86_64`` then, if you run ``dnf versionlock add mutt``
+ versionlock will not add ``mutt-5:1.12.1-3.fc30.x86_64``.
``dnf versionlock exclude <package-name-spec>``
Add an exclude (within versionlock) for the available packages matching the spec. It means that
--
libgit2 1.1.0

View File

@ -1,25 +0,0 @@
From dc13ed6bab62a38ef74b00376e2ba05c82115e47 Mon Sep 17 00:00:00 2001
From: Nicola Sella <nsella@redhat.com>
Date: Thu, 8 Jul 2021 15:54:21 +0200
Subject: [PATCH] [needs-restarting] Fix wrong boot time (RhBug:1960437)
---
plugins/needs_restarting.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 1fedb73..91dbe66 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -199,7 +199,7 @@ class ProcessStart(object):
@staticmethod
def get_boot_time():
- return int(os.stat('/proc/1/cmdline').st_mtime)
+ return int(os.stat('/proc/1').st_mtime)
@staticmethod
def get_sc_clk_tck():
--
libgit2 1.1.0

View File

@ -1,439 +0,0 @@
From 6ea94d9c768eb45975f314e11ab9dd88284fa380 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 27 Sep 2021 11:29:01 +0200
Subject: [PATCH] Add new command modulesync (RhBug:1868047)
It will download module metadata from all enabled repositories,
module artifacts and profiles of matching modules. Then it creates
a repository.
= changelog =
msg: Add a new subpackage with modulesync command. The command
downloads packages from modules and/or creates a repository with modular
data.
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1868047
---
dnf-plugins-core.spec | 20 ++++++++++++++++++++
doc/CMakeLists.txt | 1 +
doc/conf.py | 1 +
doc/index.rst | 1 +
doc/modulesync.rst | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
plugins/CMakeLists.txt | 1 +
plugins/modulesync.py | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 335 insertions(+)
create mode 100644 doc/modulesync.rst
create mode 100644 plugins/modulesync.py
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index cef836f..afdbcbb 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -402,6 +402,19 @@ versions of those packages. This allows you to e.g. protect packages from being
updated by newer versions.
%endif
+%if %{with python3}
+%package -n python3-dnf-plugin-modulesync
+Summary: Download module metadata and packages and create repository
+Requires: python3-%{name} = %{version}-%{release}
+Requires: createrepo_c >= 0.17.4
+Provides: dnf-plugin-modulesync = %{version}-%{release}
+Provides: dnf-command(modulesync)
+
+%description -n python3-dnf-plugin-modulesync
+Download module metadata from all enabled repositories, module artifacts and profiles of matching modules and create
+repository.
+%endif
+
%prep
%autosetup
%if %{with python2}
@@ -762,6 +775,13 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
%endif
%endif
+%if %{with python3}
+%files -n python3-dnf-plugin-modulesync
+%{python3_sitelib}/dnf-plugins/modulesync.*
+%{python3_sitelib}/dnf-plugins/__pycache__/modulesync.*
+%{_mandir}/man8/dnf-modulesync.*
+%endif
+
%changelog
* Mon Apr 12 2021 Nicola Sella <nsella@redhat.com> - 4.0.21-1
- Add missing command line option to documentation
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 3fb665d..ff84cf8 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -28,6 +28,7 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-builddep.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-modulesync.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-needs-restarting.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-repoclosure.8
${CMAKE_CURRENT_BINARY_DIR}/dnf-repodiff.8
diff --git a/doc/conf.py b/doc/conf.py
index 645185a..41d6936 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -254,6 +254,7 @@ man_pages = [
('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),
+ ('modulesync', 'dnf-modulesync', u'DNF modulesync Plugin', AUTHORS, 8),
('needs_restarting', 'dnf-needs-restarting', u'DNF needs_restarting Plugin', AUTHORS, 8),
('repoclosure', 'dnf-repoclosure', u'DNF repoclosure Plugin', AUTHORS, 8),
('repodiff', 'dnf-repodiff', u'DNF repodiff Plugin', AUTHORS, 8),
diff --git a/doc/index.rst b/doc/index.rst
index 7213253..07f6052 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -37,6 +37,7 @@ This documents core plugins of DNF:
leaves
local
migrate
+ modulesync
needs_restarting
post-transaction-actions
repoclosure
diff --git a/doc/modulesync.rst b/doc/modulesync.rst
new file mode 100644
index 0000000..2837287
--- /dev/null
+++ b/doc/modulesync.rst
@@ -0,0 +1,103 @@
+..
+ Copyright (C) 2015 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 modulesync Plugin
+====================
+
+Download packages from modules and/or create a repository with modular data.
+
+--------
+Synopsis
+--------
+
+``dnf modulesync [options] [<module-spec>...]``
+
+-----------
+Description
+-----------
+
+`modulesync` downloads packages from modules according to provided arguments and creates a repository with modular data
+in working directory. In environment with modules it is recommend to use the command for redistribution of packages,
+because DNF does not allow installation of modular packages without modular metadata on the system (Fail-safe
+mechanism). The command without an argument creates a repository like `createrepo_c` but with modular metadata collected
+from all available repositories.
+
+See examples.
+
+---------
+Arguments
+---------
+
+``<module-spec>``
+ Module specification for the package to download. The argument is an optional.
+
+-------
+Options
+-------
+
+All general DNF options are accepted. Namely, the ``--destdir`` option can be used to specify directory where packages
+will be downloaded and the new repository created. See `Options` in :manpage:`dnf(8)` for details.
+
+
+``-n, --newest-only``
+ Download only packages from the newest modules.
+
+``--enable_source_repos``
+ Enable repositories with source packages
+
+``--enable_debug_repos``
+ Enable repositories with debug-info and debug-source packages
+
+``--resolve``
+ Resolve and download needed dependencies
+
+--------
+Examples
+--------
+
+``dnf modulesync nodejs``
+ Download packages from `nodejs` module and crete a repository with modular metadata in working directory
+
+``dnf download nodejs``
+
+``dnf modulesync``
+ The first `download` command downloads nodejs package into working directory. In environment with modules `nodejs`
+ package can be a modular package therefore when I create a repository I have to insert also modular metadata
+ from available repositories to ensure 100% functionality. Instead of `createrepo_c` use `dnf modulesync`
+ to create a repository in working directory with nodejs package and modular metadata.
+
+``dnf --destdir=/tmp/my-temp modulesync nodejs:14/minimal --resolve``
+ Download package required for installation of `minimal` profile from module `nodejs` and stream `14` into directory
+ `/tmp/my-temp` and all required dependencies. Then it will create a repository in `/tmp/my-temp` directory with
+ previously downloaded packages and modular metadata from all available repositories.
+
+``dnf module install nodejs:14/minimal --downloadonly --destdir=/tmp/my-temp``
+
+``dnf modulesync --destdir=/tmp/my-temp``
+ The first `dnf module install` command downloads package from required for installation of `minimal` profile from module
+ `nodejs` and stream `14` into directory `/tmp/my-temp`. The second command `dnf modulesync` will create
+ a repository in `/tmp/my-temp` directory with previously downloaded packages and modular metadata from all
+ available repositories. In comparison to `dnf --destdir=/tmp/my-temp modulesync nodejs:14/minimal --resolve` it will
+ only download packages required for installation on current system.
+
+
+--------
+See Also
+--------
+
+* :manpage:`dnf(8)`, DNF Command Reference
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index f66d3df..59f148f 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -22,6 +22,7 @@ INSTALL (FILES repograph.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES repomanage.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES reposync.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES show_leaves.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+INSTALL (FILES modulesync.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
INSTALL (FILES versionlock.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
ADD_SUBDIRECTORY (dnfpluginscore)
diff --git a/plugins/modulesync.py b/plugins/modulesync.py
new file mode 100644
index 0000000..c1c33e4
--- /dev/null
+++ b/plugins/modulesync.py
@@ -0,0 +1,208 @@
+# Copyright (C) 2021 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
+from dnfpluginscore import _, P_, logger
+from dnf.cli.option_parser import OptionParser
+
+import os
+import shutil
+import subprocess
+
+import dnf
+import dnf.cli
+import dnf.i18n
+import hawkey
+
+
+@dnf.plugin.register_command
+class SyncToolCommand(dnf.cli.Command):
+
+ aliases = ['modulesync']
+ summary = _('Download packages from modules and/or create a repository with modular data')
+
+ def __init__(self, cli):
+ super(SyncToolCommand, self).__init__(cli)
+
+ @staticmethod
+ def set_argparser(parser):
+ parser.add_argument('module', nargs='*', metavar=_('MODULE'),
+ help=_('modules to download'))
+ parser.add_argument("--enable_source_repos", action='store_true',
+ help=_('enable repositories with source packages'))
+ parser.add_argument("--enable_debug_repos", action='store_true',
+ help=_('enable repositories with debug-info and debug-source packages'))
+ parser.add_argument('--resolve', action='store_true',
+ help=_('resolve and download needed dependencies'))
+ parser.add_argument('-n', '--newest-only', default=False, action='store_true',
+ help=_('download only packages from newest modules'))
+
+ def configure(self):
+ # setup sack and populate it with enabled repos
+ demands = self.cli.demands
+ demands.sack_activation = True
+ demands.available_repos = True
+
+ demands.load_system_repo = False
+
+ if self.opts.enable_source_repos:
+ self.base.repos.enable_source_repos()
+
+ if self.opts.enable_debug_repos:
+ self.base.repos.enable_debug_repos()
+
+ if self.opts.destdir:
+ self.base.conf.destdir = self.opts.destdir
+ else:
+ self.base.conf.destdir = dnf.i18n.ucd(os.getcwd())
+
+ def run(self):
+ """Execute the util action here."""
+
+ pkgs = self.base.sack.query().filterm(empty=True)
+ no_matched_spec = []
+ for module_spec in self.opts.module:
+ try:
+ pkgs = pkgs.union(self._get_packages_from_modules(module_spec))
+ except dnf.exceptions.Error:
+ no_matched_spec.append(module_spec)
+ if no_matched_spec:
+ msg = P_("Unable to find a match for argument: '{}'", "Unable to find a match for arguments: '{}'",
+ len(no_matched_spec)).format("' '".join(no_matched_spec))
+ raise dnf.exceptions.Error(msg)
+
+ if self.opts.resolve:
+ pkgs = pkgs.union(self._get_providers_of_requires(pkgs))
+
+ # download rpms
+ self._do_downloads(pkgs)
+
+ # Create a repository at destdir with modular data
+ remove_tmp_moduleyamls_files = []
+ for repo in self.base.repos.iter_enabled():
+ module_md_path = repo.get_metadata_path('modules')
+ if module_md_path:
+ filename = "".join([repo.id, "-", os.path.basename(module_md_path)])
+ dest_path = os.path.join(self.base.conf.destdir, filename)
+ shutil.copy(module_md_path, dest_path)
+ remove_tmp_moduleyamls_files.append(dest_path)
+ args = ["createrepo_c", "--update", "--unique-md-filenames", self.base.conf.destdir]
+ p = subprocess.run(args)
+ if p.returncode:
+ msg = _("Creation of repository failed with return code {}. All downloaded content was kept on the system")
+ msg = msg.format(p.returncode)
+ raise dnf.exceptions.Error(msg)
+ for file_path in remove_tmp_moduleyamls_files:
+ os.remove(file_path)
+
+ def _do_downloads(self, pkgs):
+ """
+ Perform the download for a list of packages
+ """
+ pkg_dict = {}
+ for pkg in pkgs:
+ pkg_dict.setdefault(str(pkg), []).append(pkg)
+
+ to_download = []
+
+ for pkg_list in pkg_dict.values():
+ pkg_list.sort(key=lambda x: (x.repo.priority, x.repo.cost))
+ to_download.append(pkg_list[0])
+ if to_download:
+ self.base.download_packages(to_download, self.base.output.progress)
+
+ def _get_packages_from_modules(self, module_spec):
+ """Gets packages from modules matching module spec
+ 1. From module artifacts
+ 2. From module profiles"""
+ result_query = self.base.sack.query().filterm(empty=True)
+ module_base = dnf.module.module_base.ModuleBase(self.base)
+ module_list, nsvcap = module_base.get_modules(module_spec)
+ if self.opts.newest_only:
+ module_list = self.base._moduleContainer.getLatestModules(module_list, False)
+ for module in module_list:
+ for artifact in module.getArtifacts():
+ query = self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(nevra_strict=artifact)
+ if query:
+ result_query = result_query.union(query)
+ else:
+ msg = _("No match for artifact '{0}' from module '{1}'").format(
+ artifact, module.getFullIdentifier())
+ logger.warning(msg)
+ if nsvcap.profile:
+ profiles_set = module.getProfiles(nsvcap.profile)
+ else:
+ profiles_set = module.getProfiles()
+ if profiles_set:
+ for profile in profiles_set:
+ for pkg_name in profile.getContent():
+ query = self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(name=pkg_name)
+ # Prefer to add modular providers selected by argument
+ if result_query.intersection(query):
+ continue
+ # Add all packages with the same name as profile described
+ elif query:
+ result_query = result_query.union(query)
+ else:
+ msg = _("No match for package name '{0}' in profile {1} from module {2}")\
+ .format(pkg_name, profile.getName(), module.getFullIdentifier())
+ logger.warning(msg)
+ if not module_list:
+ msg = _("No mach for argument '{}'").format(module_spec)
+ raise dnf.exceptions.Error(msg)
+
+ return result_query
+
+ def _get_providers_of_requires(self, to_test, done=None, req_dict=None):
+ done = done if done else to_test
+ # req_dict = {} {req : set(pkgs)}
+ if req_dict is None:
+ req_dict = {}
+ test_requires = []
+ for pkg in to_test:
+ for require in pkg.requires:
+ if require not in req_dict:
+ test_requires.append(require)
+ req_dict.setdefault(require, set()).add(pkg)
+
+ if self.opts.newest_only:
+ # Prepare cache with all packages related affected by modular filtering
+ names = set()
+ for module in self.base._moduleContainer.getModulePackages():
+ for artifact in module.getArtifacts():
+ name, __, __ = artifact.rsplit("-", 2)
+ names.add(name)
+ modular_related = self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(provides=names)
+
+ requires = self.base.sack.query().filterm(empty=True)
+ for require in test_requires:
+ q = self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(provides=require)
+
+ if not q:
+ # TODO(jmracek) Shell we end with an error or with RC 1?
+ logger.warning((_("Unable to satisfy require {}").format(require)))
+ else:
+ if self.opts.newest_only:
+ if not modular_related.intersection(q):
+ q.filterm(latest_per_arch_by_priority=1)
+ requires = requires.union(q.difference(done))
+ done = done.union(requires)
+ if requires:
+ done = self._get_providers_of_requires(requires, done=done, req_dict=req_dict)
+
+ return done
--
libgit2 1.1.0

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
From e80f79b2f5e17a20065617c0b614b272dd53c57c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
Date: Thu, 26 May 2022 07:21:45 +0200
Subject: [PATCH] repomanage: Use modules only from repo they are handling
(RhBug:2072441)
= changelog =
msg: [repomanage] Modules are used only when they belong to target repo
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2072441
---
plugins/repomanage.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/plugins/repomanage.py b/plugins/repomanage.py
index 989bd78..67a6fc7 100644
--- a/plugins/repomanage.py
+++ b/plugins/repomanage.py
@@ -66,7 +66,8 @@ class RepoManageCommand(dnf.cli.Command):
keepnum = int(self.opts.keep) # the number of items to keep
try:
- repo_conf = self.base.repos.add_new_repo("repomanage_repo", self.base.conf, baseurl=[self.opts.path])
+ REPOMANAGE_REPOID = "repomanage_repo"
+ repo_conf = self.base.repos.add_new_repo(REPOMANAGE_REPOID, 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()
@@ -78,9 +79,13 @@ class RepoManageCommand(dnf.cli.Command):
module_packages = self.base._moduleContainer.getModulePackages()
for module_package in module_packages:
- all_modular_artifacts.update(module_package.getArtifacts())
- module_dict.setdefault(module_package.getNameStream(), {}).setdefault(
- module_package.getVersionNum(), []).append(module_package)
+ # Even though we load only REPOMANAGE_REPOID other modules can be loaded from system
+ # failsafe data automatically, we don't want them affecting repomanage results so ONLY
+ # use modules from REPOMANAGE_REPOID.
+ if module_package.getRepoID() == REPOMANAGE_REPOID:
+ all_modular_artifacts.update(module_package.getArtifacts())
+ module_dict.setdefault(module_package.getNameStream(), {}).setdefault(
+ module_package.getVersionNum(), []).append(module_package)
except dnf.exceptions.RepoError:
rpm_list = []
--
2.36.1

View File

@ -1,117 +0,0 @@
From eb1d6edf55c167d575ce3d16bd6349e382d05600 Mon Sep 17 00:00:00 2001
From: Masahiro Matsuya <mmatsuya@redhat.com>
Date: Wed, 13 Apr 2022 18:42:03 +0900
Subject: [PATCH] feat(repomanage): Add new option --oldonly
= changelog =
msg: repomanage: Add new option --oldonly
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2034736
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2058676
---
doc/repomanage.rst | 3 +++
plugins/repomanage.py | 46 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/doc/repomanage.rst b/doc/repomanage.rst
index e3171ef..3c01289 100644
--- a/doc/repomanage.rst
+++ b/doc/repomanage.rst
@@ -47,6 +47,9 @@ The following options set what packages are displayed. These options are mutuall
``--old``
Show older packages (for a package or a stream show all versions except the newest one).
+``--oldonly``
+ Show older packages (same as --old, but exclude the newest packages even when it's included in the older stream versions).
+
``--new``
Show newest packages.
diff --git a/plugins/repomanage.py b/plugins/repomanage.py
index 67a6fc7..d23497a 100644
--- a/plugins/repomanage.py
+++ b/plugins/repomanage.py
@@ -57,6 +57,12 @@ class RepoManageCommand(dnf.cli.Command):
def run(self):
if self.opts.new and self.opts.old:
raise dnf.exceptions.Error(_("Pass either --old or --new, not both!"))
+ if self.opts.new and self.opts.oldonly:
+ raise dnf.exceptions.Error(_("Pass either --oldonly or --new, not both!"))
+ if self.opts.old and self.opts.oldonly:
+ raise dnf.exceptions.Error(_("Pass either --old or --oldonly, not both!"))
+ if not self.opts.old and not self.opts.oldonly:
+ self.opts.new = True
verfile = {}
pkgdict = {}
@@ -123,8 +129,7 @@ class RepoManageCommand(dnf.cli.Command):
# modular packages
keepnum_latest_stream_artifacts = set()
- # if new
- if not self.opts.old:
+ if self.opts.new:
# regular packages
for (n, a) in pkgdict.keys():
evrlist = pkgdict[(n, a)]
@@ -146,7 +151,6 @@ class RepoManageCommand(dnf.cli.Command):
for stream in streams_by_version[i]:
keepnum_latest_stream_artifacts.update(set(stream.getArtifacts()))
-
if self.opts.old:
# regular packages
for (n, a) in pkgdict.keys():
@@ -169,6 +173,40 @@ class RepoManageCommand(dnf.cli.Command):
for stream in streams_by_version[i]:
keepnum_latest_stream_artifacts.update(set(stream.getArtifacts()))
+ if self.opts.oldonly:
+ # regular packages
+ for (n, a) in pkgdict.keys():
+ evrlist = pkgdict[(n, a)]
+
+ oldevrs = evrlist[:-keepnum]
+
+ for package in oldevrs:
+ nevra = self._package_to_nevra(package)
+ for fpkg in verfile[nevra]:
+ outputpackages.append(fpkg)
+
+ # modular packages
+ keepnum_newer_stream_artifacts = set()
+
+ for streams_by_version in module_dict.values():
+ sorted_stream_versions = sorted(streams_by_version.keys())
+
+ new_sorted_stream_versions = sorted_stream_versions[-keepnum:]
+
+ for i in new_sorted_stream_versions:
+ for stream in streams_by_version[i]:
+ keepnum_newer_stream_artifacts.update(set(stream.getArtifacts()))
+
+ for streams_by_version in module_dict.values():
+ sorted_stream_versions = sorted(streams_by_version.keys())
+
+ old_sorted_stream_versions = sorted_stream_versions[:-keepnum]
+
+ for i in old_sorted_stream_versions:
+ for stream in streams_by_version[i]:
+ for artifact in stream.getArtifacts():
+ if artifact not in keepnum_newer_stream_artifacts:
+ keepnum_latest_stream_artifacts.add(artifact)
modular_packages = [self._package_to_path(x) for x in query.filter(pkg__eq=query.filter(nevra_strict=keepnum_latest_stream_artifacts)).available()]
outputpackages = outputpackages + modular_packages
@@ -183,6 +221,8 @@ class RepoManageCommand(dnf.cli.Command):
def set_argparser(parser):
parser.add_argument("-o", "--old", action="store_true",
help=_("Print the older packages"))
+ parser.add_argument("-O", "--oldonly", action="store_true",
+ help=_("Print the older packages. Exclude the newest packages."))
parser.add_argument("-n", "--new", action="store_true",
help=_("Print the newest packages"))
parser.add_argument("-s", "--space", action="store_true",
--
2.36.1

View File

@ -1,28 +0,0 @@
From b4e0cafe70680db24ab3611e0fd4dd95c8311ccc Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Tue, 26 Apr 2022 11:23:41 +0200
Subject: [PATCH] Skip all non rpm tsi for transaction_action plugins
(rhbug:2023652)
It prevent traceback in output when reason change is in transaction
---
plugins/post-transaction-actions.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/post-transaction-actions.py b/plugins/post-transaction-actions.py
index 05a7841..1520c26 100644
--- a/plugins/post-transaction-actions.py
+++ b/plugins/post-transaction-actions.py
@@ -115,6 +115,9 @@ class PostTransactionActions(dnf.Plugin):
in_ts_items.append(ts_item)
elif ts_item.action in dnf.transaction.BACKWARD_ACTIONS:
out_ts_items.append(ts_item)
+ else:
+ # The action is not rpm change. It can be a reason change, therefore we can skip that item
+ continue
all_ts_items.append(ts_item)
commands_to_run = []
--
2.36.1

View File

@ -1,28 +0,0 @@
From 76d7c9e2d2fa052cc6d9fab08af51c603d7e20e5 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <praiskup@redhat.com>
Date: Fri, 16 Jul 2021 12:52:03 +0200
Subject: [PATCH] Fix 'dnf copr enable' on Fedora 35
The output from linux_distribution() changed so it returns:
>>> distro.linux_distribution()
('Fedora Linux', '35', '')
---
plugins/copr.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 7fc6c6f..235989b 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -430,7 +430,7 @@ Bugzilla. In case of problems, contact the owner of this repository.
dist = linux_distribution()
# Get distribution architecture
distarch = self.base.conf.substitutions['basearch']
- if "Fedora" in dist:
+ if any([name in dist for name in ["Fedora", "Fedora Linux"]]):
if "Rawhide" in dist:
chroot = ("fedora-rawhide-" + distarch)
# workaround for enabling repos in Rawhide when VERSION in os-release
--
2.36.1

View File

@ -1,37 +0,0 @@
From 517f0093218e3c23097d7e7e3f3d65930059ef82 Mon Sep 17 00:00:00 2001
From: Silvie Chlupova <sisi.chlupova@gmail.com>
Date: Thu, 12 Aug 2021 16:24:56 +0200
Subject: [PATCH] Disable dnf playground command
= changelog =
msg: playground command doesn't work
type: bugfix
related: https://bugzilla.redhat.com/show_bug.cgi?id=1955907
---
plugins/copr.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/copr.py b/plugins/copr.py
index 235989b..e1e7018 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -122,6 +122,8 @@ class CoprCommand(dnf.cli.Command):
parser.add_argument('arg', nargs='*')
def configure(self):
+ if self.cli.command.opts.command != "copr":
+ return
copr_hub = None
copr_plugin_config = ConfigParser()
config_files = []
@@ -680,6 +682,7 @@ class PlaygroundCommand(CoprCommand):
choices=['enable', 'disable', 'upgrade'])
def run(self):
+ raise dnf.exceptions.Error("Playground is temporarily unsupported")
subcommand = self.opts.subcommand[0]
chroot = self._guess_chroot()
if subcommand == "enable":
--
2.36.1

View File

@ -1,29 +0,0 @@
From 7f9d6809f7cb9ac48f11ef02a4e7c0cadeef9594 Mon Sep 17 00:00:00 2001
From: Silvie Chlupova <sisi.chlupova@gmail.com>
Date: Wed, 22 Sep 2021 22:35:21 +0200
Subject: [PATCH] Fix baseurl for centos stream chroot
= changelog =
msg: dnf copr enable on CentOS Stream should enable centos stream chroot, not epel 8
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1994154
---
plugins/copr.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/plugins/copr.py b/plugins/copr.py
index e1e7018..c216408 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -457,6 +457,8 @@ Bugzilla. In case of problems, contact the owner of this repository.
chroot = ("opensuse-tumbleweed-{}".format(distarch))
else:
chroot = ("opensuse-leap-{0}-{1}".format(dist[1], distarch))
+ elif "CentOS Stream" in dist:
+ chroot = ("centos-stream-{0}-{1}".format(dist[1], distarch))
else:
chroot = ("epel-%s-x86_64" % dist[1].split(".", 1)[0])
return chroot
--
2.36.1

View File

@ -1,42 +0,0 @@
From a07db6dcd669eecb27b7ddbf1b85cd842bdcc35b Mon Sep 17 00:00:00 2001
From: Otto Urpelainen <oturpe@iki.fi>
Date: Wed, 6 Oct 2021 22:08:54 +0300
Subject: [PATCH] Silence a deprecation warning in plugins/copr.py
In version 1.6.0, the 'distro' package deprecated linux_distribution().
This causes a deprecation warning to printed to stdout
every time the user calls the copr plugin.
In order to avoid the printout
and to protect against possible removal in the future,
the function is reimplemented
using still supported functions from 'distro'.
= changelog =
msg: [copr] Avoid using deprecated function distro.linux_distribution()
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2011550
---
plugins/copr.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index c216408..9f597dd 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -38,7 +38,11 @@ import rpm
# If that fails, attempt to import the deprecated implementation
# from the platform module.
try:
- from distro import linux_distribution, os_release_attr
+ from distro import name, version, codename, os_release_attr
+
+ # Re-implement distro.linux_distribution() to avoid a deprecation warning
+ def linux_distribution():
+ return (name(), version(), codename())
except ImportError:
def os_release_attr(_):
return ""
--
2.36.1

View File

@ -1,49 +0,0 @@
From bf230d570763acc6ccd4f4b3951f4b8325a8e4b8 Mon Sep 17 00:00:00 2001
From: Silvie Chlupova <sisi.chlupova@gmail.com>
Date: Fri, 3 Sep 2021 15:45:43 +0200
Subject: [PATCH] Shorter verification that the project exists
---
plugins/copr.py | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 9f597dd..1539c0d 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -70,8 +70,10 @@ NO = set([_('no'), _('n'), ''])
if PY3:
from configparser import ConfigParser, NoOptionError, NoSectionError
+ from urllib.request import urlopen, HTTPError
else:
from ConfigParser import ConfigParser, NoOptionError, NoSectionError
+ from urllib2 import urlopen, HTTPError
@dnf.plugin.register_command
class CoprCommand(dnf.cli.Command):
@@ -478,17 +480,11 @@ Bugzilla. In case of problems, contact the owner of this repository.
if os.path.exists(repo_filename):
os.remove(repo_filename)
if '404' in str(e):
- if PY3:
- import urllib.request
- try:
- res = urllib.request.urlopen(self.copr_url + "/coprs/" + project_name)
- status_code = res.getcode()
- except urllib.error.HTTPError as e:
- status_code = e.getcode()
- else:
- import urllib
- res = urllib.urlopen(self.copr_url + "/coprs/" + project_name)
+ try:
+ res = urlopen(self.copr_url + "/coprs/" + project_name)
status_code = res.getcode()
+ except HTTPError as e:
+ status_code = e.getcode()
if str(status_code) != '404':
raise dnf.exceptions.Error(_("This repository does not have"
" any builds yet so you cannot enable it now."))
--
2.36.1

View File

@ -1,114 +0,0 @@
From 1d097d0e4ecfef78aec5d760278b44d5f3192cdc Mon Sep 17 00:00:00 2001
From: Silvie Chlupova <sisi.chlupova@gmail.com>
Date: Mon, 2 Aug 2021 15:04:17 +0200
Subject: [PATCH] Better error message for dnf copr enable
= changelog =
msg: show better error message if the command dnf copr enable fails
type: enhancement
---
plugins/copr.py | 63 +++++++++++++++++++++++++++++++------------------
1 file changed, 40 insertions(+), 23 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 1539c0d..721c010 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -27,6 +27,8 @@ import re
import shutil
import stat
import sys
+import base64
+import json
from dnfpluginscore import _, logger
import dnf
@@ -70,10 +72,10 @@ NO = set([_('no'), _('n'), ''])
if PY3:
from configparser import ConfigParser, NoOptionError, NoSectionError
- from urllib.request import urlopen, HTTPError
+ from urllib.request import urlopen, HTTPError, URLError
else:
from ConfigParser import ConfigParser, NoOptionError, NoSectionError
- from urllib2 import urlopen, HTTPError
+ from urllib2 import urlopen, HTTPError, URLError
@dnf.plugin.register_command
class CoprCommand(dnf.cli.Command):
@@ -475,28 +477,40 @@ Bugzilla. In case of problems, contact the owner of this repository.
api_path = "/coprs/{0}/repo/{1}/dnf.repo?arch={2}".format(project_name, short_chroot, arch)
try:
- f = self.base.urlopen(self.copr_url + api_path, mode='w+')
- except IOError as e:
+ response = urlopen(self.copr_url + api_path)
if os.path.exists(repo_filename):
os.remove(repo_filename)
- if '404' in str(e):
- try:
- res = urlopen(self.copr_url + "/coprs/" + project_name)
- status_code = res.getcode()
- except HTTPError as e:
- status_code = e.getcode()
- if str(status_code) != '404':
- raise dnf.exceptions.Error(_("This repository does not have"
- " any builds yet so you cannot enable it now."))
- else:
- raise dnf.exceptions.Error(_("Such repository does not exist."))
- raise
-
- for line in f:
- if re.match(r"\[copr:", line):
- repo_filename = os.path.join(self.base.conf.get_reposdir,
- "_" + line[1:-2] + ".repo")
- break
+ except HTTPError as e:
+ if e.code != 404:
+ error_msg = _("Request to {0} failed: {1} - {2}").format(self.copr_url + api_path, e.code, str(e))
+ raise dnf.exceptions.Error(error_msg)
+ error_msg = _("It wasn't possible to enable this project.\n")
+ error_data = e.headers.get("Copr-Error-Data")
+ if error_data:
+ error_data_decoded = base64.b64decode(error_data).decode('utf-8')
+ error_data_decoded = json.loads(error_data_decoded)
+ error_msg += _("Repository '{0}' does not exist in project '{1}'.").format(
+ '-'.join(self.chroot_parts), project_name)
+ if error_data_decoded.get("available chroots"):
+ error_msg += _("\nAvailable repositories: ") + ', '.join(
+ "'{}'".format(x) for x in error_data_decoded["available chroots"])
+ error_msg += _("\n\nIf you want to enable a non-default repository, use the following command:\n"
+ " 'dnf copr enable {0} <repository>'\n"
+ "But note that the installed repo file will likely need a manual "
+ "modification.").format(project_name)
+ raise dnf.exceptions.Error(error_msg)
+ else:
+ error_msg += _("Project {0} does not exist.").format(project_name)
+ raise dnf.exceptions.Error(error_msg)
+ except URLError as e:
+ error_msg = _("Failed to connect to {0}: {1}").format(self.copr_url + api_path, e.reason.strerror)
+ raise dnf.exceptions.Error(error_msg)
+
+ # Try to read the first line, and detect the repo_filename from that (override the repo_filename value).
+ first_line = response.readline()
+ line = first_line.decode("utf-8")
+ if re.match(r"\[copr:", line):
+ repo_filename = os.path.join(self.base.conf.get_reposdir, "_" + line[1:-2] + ".repo")
# if using default hub, remove possible old repofile
if self.copr_url == self.default_url:
@@ -507,7 +521,10 @@ Bugzilla. In case of problems, contact the owner of this repository.
if os.path.exists(old_repo_filename):
os.remove(old_repo_filename)
- shutil.copy2(f.name, repo_filename)
+ with open(repo_filename, 'wb') as f:
+ f.write(first_line)
+ for line in response.readlines():
+ f.write(line)
os.chmod(repo_filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
def _runtime_deps_warning(self, copr_username, copr_projectname):
--
2.36.1

View File

@ -1,33 +0,0 @@
From b2d019658ebb40606e1a9efcb2233a8e38834410 Mon Sep 17 00:00:00 2001
From: Alexander Sosedkin <asosedkin@redhat.com>
Date: Thu, 7 Oct 2021 19:08:47 +0200
Subject: [PATCH] copr: allow specifying protocol as part of --hub
This way it doesn't try to connect to
https://http//url if --hub started with http://.
---
plugins/copr.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 721c010..297210b 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -198,8 +198,12 @@ class CoprCommand(dnf.cli.Command):
self.copr_hostname += ":" + port
if not self.copr_url:
- self.copr_hostname = copr_hub
- self.copr_url = self.default_protocol + "://" + copr_hub
+ if '://' not in copr_hub:
+ self.copr_hostname = copr_hub
+ self.copr_url = self.default_protocol + "://" + copr_hub
+ else:
+ self.copr_hostname = copr_hub.split('://', 1)[1]
+ self.copr_url = copr_hub
def _read_config_item(self, config, hub, section, default):
try:
--
2.36.1

View File

@ -1,37 +0,0 @@
From 4b0001d0f13598369ec2e6a800af519e8c3a334c Mon Sep 17 00:00:00 2001
From: Carl George <carl@george.computer>
Date: Mon, 27 Jun 2022 23:12:05 -0500
Subject: [PATCH] copr: Guess EPEL chroots for CentOS Stream (RhBug:2058471)
Packages built in epel-9 chroots are almost always compatible with
CentOS Stream 9. Not having the copr plugin guess this chroot is
causing user friction. Users are creating epel-9 chroots expecting them
to work for both CentOS Stream 9 and RHEL 9. When they get reports
about `dnf copr enable` not working, they try to add a centos-stream-9
chroot, only to discover the dependencies they need from EPEL are not
available.
Instead of making the majority of CentOS Stream users include an
explicit chroot argument, let's reserve that workaround only for the
people that don't want their CentOS Stream systems picking the EPEL
chroot.
---
plugins/copr.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/plugins/copr.py b/plugins/copr.py
index 297210b..16946b7 100644
--- a/plugins/copr.py
+++ b/plugins/copr.py
@@ -469,8 +469,6 @@ Bugzilla. In case of problems, contact the owner of this repository.
chroot = ("opensuse-tumbleweed-{}".format(distarch))
else:
chroot = ("opensuse-leap-{0}-{1}".format(dist[1], distarch))
- elif "CentOS Stream" in dist:
- chroot = ("centos-stream-{0}-{1}".format(dist[1], distarch))
else:
chroot = ("epel-%s-x86_64" % dist[1].split(".", 1)[0])
return chroot
--
2.36.1

View File

@ -1,45 +0,0 @@
From 0afd47edc60fb7fe5c72fa64bca413bdce82d900 Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Thu, 11 Aug 2022 14:12:06 +0200
Subject: [PATCH] builddep: Warning when using macros with source rpms
(RhBug:2077820)
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2077820
---
doc/builddep.rst | 2 +-
plugins/builddep.py | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/doc/builddep.rst b/doc/builddep.rst
index 6e9bde6..97eb823 100644
--- a/doc/builddep.rst
+++ b/doc/builddep.rst
@@ -31,7 +31,7 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det
Show this help.
``-D <macro expr>, --define <macro expr>``
- Define the RPM macro named `macro` to the value `expr` when parsing spec files.
+ Define the RPM macro named `macro` to the value `expr` when parsing spec files. Does not apply for source rpm files.
``--spec``
Treat arguments as .spec files.
diff --git a/plugins/builddep.py b/plugins/builddep.py
index e3da012..e7dac43 100644
--- a/plugins/builddep.py
+++ b/plugins/builddep.py
@@ -204,6 +204,10 @@ class BuildDepCommand(dnf.cli.Command):
err = _("Not all dependencies satisfied")
raise dnf.exceptions.Error(err)
+ if self.opts.define:
+ logger.warning(_("Warning: -D or --define arguments have no meaning "
+ "for source rpm packages."))
+
def _spec_deps(self, spec_fn):
try:
spec = rpm.spec(spec_fn)
--
2.37.1

View File

@ -1,78 +0,0 @@
From e52655aa9c7c9ad334639990d612da574b57736b Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Fri, 30 Sep 2022 11:36:26 +0000
Subject: [PATCH 1/3] Add a warning when using `system-upgrade` on RHEL
---
dnf-plugins-core.spec | 3 +--
doc/system-upgrade.rst | 6 ++++--
plugins/system_upgrade.py | 4 ++++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 0e1c9e3..a5ec165 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -148,14 +148,13 @@ Summary: Core Plugins for DNF
%{?python_provide:%python_provide python3-%{name}}
BuildRequires: python3-dbus
BuildRequires: python3-devel
+BuildRequires: python3-distro
BuildRequires: python3-dnf >= %{dnf_lowest_compatible}
BuildRequires: python3-systemd
BuildRequires: pkgconfig(systemd)
BuildRequires: systemd
%{?systemd_ordering}
-%if 0%{?fedora}
Requires: python3-distro
-%endif
Requires: python3-dbus
Requires: python3-dnf >= %{dnf_lowest_compatible}
Requires: python3-hawkey >= %{hawkey_version}
diff --git a/doc/system-upgrade.rst b/doc/system-upgrade.rst
index 3110460..87b7319 100644
--- a/doc/system-upgrade.rst
+++ b/doc/system-upgrade.rst
@@ -27,13 +27,15 @@ DNF system-upgrades plugin provides three commands: ``system-upgrade``, ``offlin
``offline-distrosync``. Only ``system-upgrade`` command requires increase of distribution major
version (``--releasever``) compared to installed version.
-``dnf system-upgrade`` can be used to upgrade a Fedora system to a new major
-release. It replaces fedup (the old Fedora Upgrade tool). Before you proceed ensure that your system
+``dnf system-upgrade`` is a recommended way to upgrade a system to a new major release.
+It replaces fedup (the old Fedora Upgrade tool). Before you proceed ensure that your system
is fully upgraded (``dnf --refresh upgrade``).
The ``system-upgrade`` command also performes additional actions necessary for the upgrade of the
system, for example an upgrade of groups and environments.
+.. WARNING:: The ``system-upgrade`` command is not supported on the RHEL distribution.
+
--------
Synopsis
--------
diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py
index fee6762..0baf978 100644
--- a/plugins/system_upgrade.py
+++ b/plugins/system_upgrade.py
@@ -20,6 +20,7 @@
"""system_upgrade.py - DNF plugin to handle major-version system upgrades."""
from subprocess import call, Popen, check_output, CalledProcessError
+import distro
import json
import os
import os.path
@@ -451,6 +452,9 @@ class SystemUpgradeCommand(dnf.cli.Command):
def configure_download(self):
if 'system-upgrade' == self.opts.command or 'fedup' == self.opts.command:
+ if distro.id() == 'rhel':
+ logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. '
+ 'Proceed at your own risk.'))
help_url = get_url_from_os_release()
if help_url:
msg = _('Additional information for System Upgrade: {}')
--
2.38.1

View File

@ -1,61 +0,0 @@
From 3a18b7241708a3c5fd1b4b92a2f9908a826e815d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tarc=C3=ADsio=20Ladeia=20de=20Oliveira?=
<wyrquill@gmail.com>
Date: Thu, 20 Oct 2022 22:16:59 -0300
Subject: [PATCH 1/2] [offline-upgrade] Add security filters (RhBug:1939975)
Add support for security filter options that are available in the main
`dnf` commands, that is, `--advisory`, `--bugfix`, `--security`, and
`--enhancement`.
= changelog =
msg: [offline-upgrade] Add support for security filters
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1939975
---
plugins/system_upgrade.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py
index 0baf978..ef1de73 100644
--- a/plugins/system_upgrade.py
+++ b/plugins/system_upgrade.py
@@ -467,6 +467,9 @@ class SystemUpgradeCommand(dnf.cli.Command):
logger.error(_("Operation aborted."))
sys.exit(1)
check_release_ver(self.base.conf, target=self.opts.releasever)
+ elif 'offline-upgrade' == self.opts.command:
+ self.cli._populate_update_security_filter(self.opts)
+
self.cli.demands.root_user = True
self.cli.demands.resolving = True
self.cli.demands.available_repos = True
--
2.38.1
From dad20a478e100bd0ac3a8d7d51dad75baca90c7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tarc=C3=ADsio=20Ladeia=20de=20Oliveira?=
<wyrquill@gmail.com>
Date: Thu, 20 Oct 2022 22:27:22 -0300
Subject: [PATCH 2/2] Add myself as contributor in AUTHORS
---
AUTHORS | 1 +
1 file changed, 1 insertion(+)
diff --git a/AUTHORS b/AUTHORS
index 33512fd..cd4b5be 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,6 +32,7 @@ DNF-PLUGINS-CORE CONTRIBUTORS
Neal Gompa <ngompa13@gmail.com>
Paul Howarth <paul@city-fan.org>
Rickard Dybeck <r.dybeck@gmail.com>
+ Tarcísio Ladeia de Oliveira <wyrquill@gmail.com>
Tomas Babej <tomasbabej@gmail.com>
Vladan Kudlac <vladankudlac@gmail.com>
Wieland Hoffmann <themineo@gmail.com>
--
2.38.1

View File

@ -1,62 +0,0 @@
From dfbda502c5c46daf84e00179478de01e452f9dae Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Fri, 16 Dec 2022 05:55:19 +0000
Subject: [PATCH] system-upgrade: Show warning always for a downstream
As the distro package is not available in the BaseOS, the warning implementation will be shown always, but only in related downstreams.
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152846
---
dnf-plugins-core.spec | 3 ++-
plugins/system_upgrade.py | 6 ++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index a5ec165..0e1c9e3 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -148,13 +148,14 @@ Summary: Core Plugins for DNF
%{?python_provide:%python_provide python3-%{name}}
BuildRequires: python3-dbus
BuildRequires: python3-devel
-BuildRequires: python3-distro
BuildRequires: python3-dnf >= %{dnf_lowest_compatible}
BuildRequires: python3-systemd
BuildRequires: pkgconfig(systemd)
BuildRequires: systemd
%{?systemd_ordering}
+%if 0%{?fedora}
Requires: python3-distro
+%endif
Requires: python3-dbus
Requires: python3-dnf >= %{dnf_lowest_compatible}
Requires: python3-hawkey >= %{hawkey_version}
diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py
index ef1de73..4f7620f 100644
--- a/plugins/system_upgrade.py
+++ b/plugins/system_upgrade.py
@@ -20,7 +20,6 @@
"""system_upgrade.py - DNF plugin to handle major-version system upgrades."""
from subprocess import call, Popen, check_output, CalledProcessError
-import distro
import json
import os
import os.path
@@ -452,9 +451,8 @@ class SystemUpgradeCommand(dnf.cli.Command):
def configure_download(self):
if 'system-upgrade' == self.opts.command or 'fedup' == self.opts.command:
- if distro.id() == 'rhel':
- logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. '
- 'Proceed at your own risk.'))
+ logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. '
+ 'Proceed at your own risk.'))
help_url = get_url_from_os_release()
if help_url:
msg = _('Additional information for System Upgrade: {}')
--
2.39.0

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
From ee0e1ca0751d29adcc4788334ce8fd74b4d772c9 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Wed, 19 May 2021 16:52:57 +0200
Subject: [PATCH] versionlock: Store full NEVRA
---
plugins/versionlock.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/plugins/versionlock.py b/plugins/versionlock.py
index 77b7f91..8a3994e 100644
--- a/plugins/versionlock.py
+++ b/plugins/versionlock.py
@@ -312,5 +312,4 @@ def _match(ent, patterns):
def pkgtup2spec(name, arch, epoch, version, release):
# we ignore arch
- e = "" if epoch in (None, "") else "%s:" % epoch
- return "%s-%s%s-%s.*" % (name, e, version, release)
+ return "%s-%s:%s-%s.*" % (name, epoch or "0", version, release)
--
2.40.1
From da25d50a8753b0a648a2653e2fb9e33eb372f73f Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Wed, 19 May 2021 16:53:37 +0200
Subject: [PATCH] versionlock: Use only the most specific NEVRA (RhBug:1961217)
When matching patterns from versionlock.list file accept only the most
specific possible NEVRA.
The problem with current implementation (using of all possible variants)
is following (also see the referenced bug):
$ dnf repoquery procps-ng
procps-ng-0:3.3.17-1.fc34.1.x86_64
procps-ng-0:3.3.17-1.fc34.x86_64 <-- this one is installed
See the `.1` minorbump part of the release after %{dist} in
`procps-ng-0:3.3.17-1.fc34.1.x86_64`
$ dnf versionlock procps-ng
Adding versionlock on: procps-ng-0:3.3.17-1.fc34.*
Now both of the available procps-ng version could be matched by this
pattern:
- procps-ng-0:3.3.17-1.fc34.x86_64 (when `*` is considered arch)
- procps-ng-0:3.3.17-1.fc34.1.x86_64 (when `*` is matched against
release part, and arch is considered not present)
That results in versionlock allowing upgrade to a newer version than the
locked one.
= changelog =
msg: Versionlock works correctly with packages with minorbump part of release
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1961217
---
plugins/versionlock.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/plugins/versionlock.py b/plugins/versionlock.py
index 8a3994e..32c51da 100644
--- a/plugins/versionlock.py
+++ b/plugins/versionlock.py
@@ -89,7 +89,9 @@ class VersionLock(dnf.Plugin):
pat = pat[1:]
excl = 1
- possible_nevras = dnf.subject.Subject(pat).get_nevra_possibilities()
+ possible_nevras = dnf.subject.Subject(pat).get_nevra_possibilities(
+ forms=[hawkey.FORM_NEVRA, hawkey.FORM_NEVR, hawkey.FORM_NEV,
+ hawkey.FORM_NA, hawkey.FORM_NAME])
if possible_nevras:
count[excl] += 1
else:
@@ -102,6 +104,8 @@ class VersionLock(dnf.Plugin):
else:
locked_names.add(nevra.name)
locked_query = locked_query.union(pat_query)
+ if pat_query:
+ break
if count[1]:
logger.debug(APPLY_EXCLUDE.format(locklist_fn, count[1]))
--
2.40.1

View File

@ -1,55 +0,0 @@
From 23a6123348f0a387768ebdfdaaded900a083039e Mon Sep 17 00:00:00 2001
From: Todd Lewis <todd_lewis@unc.edu>
Date: Wed, 16 Nov 2022 10:45:39 -0500
Subject: [PATCH] Fix boot time derivation for systems with no rtc
That addresses https://bugzilla.redhat.com/show_bug.cgi?id=2137935
---
plugins/needs_restarting.py | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 91dbe66..03831fa 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -34,6 +34,7 @@ import functools
import os
import re
import stat
+import time
# For which package updates we should recommend a reboot
@@ -199,7 +200,28 @@ class ProcessStart(object):
@staticmethod
def get_boot_time():
- return int(os.stat('/proc/1').st_mtime)
+ """
+ We have two sources from which to derive the boot time. These values vary
+ depending on containerization, existence of a Real Time Clock, etc.
+ For our purposes we want the latest derived value.
+ - st_mtime of /proc/1
+ Reflects the time the first process was run after booting
+ This works for all known cases except machines without
+ a RTC - they awake at the start of the epoch.
+ - /proc/uptime
+ Seconds field of /proc/uptime subtracted from the current time
+ Works for machines without RTC iff the current time is reasonably correct.
+ Does not work on containers which share their kernel with the
+ host - there the host kernel uptime is returned
+ """
+
+ proc_1_boot_time = int(os.stat('/proc/1').st_mtime)
+ if os.path.isfile('/proc/uptime'):
+ with open('/proc/uptime', 'rb') as f:
+ uptime = f.readline().strip().split()[0].strip()
+ proc_uptime_boot_time = int(time.time() - float(uptime))
+ return max(proc_1_boot_time, proc_uptime_boot_time)
+ return proc_1_boot_time
@staticmethod
def get_sc_clk_tck():
--
libgit2 1.3.2

View File

@ -1,34 +0,0 @@
From a83af3db9f1aaf698be5455a01814849e39307d8 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 27 Mar 2023 10:24:59 +0200
Subject: [PATCH] Documentation update for reposync (RhBug:2132383,2182004)
The update describe the behavior when `-n` and `--download-metadata`
is used.
https://bugzilla.redhat.com/show_bug.cgi?id=2132383
https://bugzilla.redhat.com/show_bug.cgi?id=2182004
---
doc/reposync.rst | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/doc/reposync.rst b/doc/reposync.rst
index 0df00b9..bbf714c 100644
--- a/doc/reposync.rst
+++ b/doc/reposync.rst
@@ -46,7 +46,11 @@ All general DNF options are accepted. Namely, the ``--repoid`` option can be use
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.
+ Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c
+ on it. When the option is used with `--newest-only`, only latest packages will be downloaded, but metadata will
+ still contain older packages. It might be useful to update metadata using `createrepo_c --update` to remove
+ the packages with missing RPM files from metadata. Otherwise, DNF ends with an error due to the missing files
+ whenever it tries to download older packages.
``-g, --gpgcheck``
Remove packages that fail GPG signature checking after downloading. Exit code is ``1`` if at least one package was removed.
--
libgit2 1.3.2

View File

@ -1,88 +0,0 @@
From b086bfe09cf0eec67ea830e0e0f3482c6b6b2aa9 Mon Sep 17 00:00:00 2001
From: Andy Baugh <andy@troglodyne.net>
Date: Fri, 28 Apr 2023 10:52:16 -0500
Subject: [PATCH] Add fix and test assertion for "no systemd unit exists for
pid"
= changelog =
msg: Catch exception in needs-restarting.py when no systemd unit exists for pid
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2122587
related: None
---
plugins/needs_restarting.py | 18 ++++++++++++++----
tests/test_needs_restarting.py | 15 +++++++++++++--
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 03831fa..8dbc965 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -138,10 +138,20 @@ def get_service_dbus(pid):
systemd_manager_object,
'org.freedesktop.systemd1.Manager'
)
- service_proxy = bus.get_object(
- 'org.freedesktop.systemd1',
- systemd_manager_interface.GetUnitByPID(pid)
- )
+ service_proxy = None
+ try:
+ service_proxy = bus.get_object(
+ 'org.freedesktop.systemd1',
+ systemd_manager_interface.GetUnitByPID(pid)
+ )
+ except dbus.DBusException as e:
+ # There is no unit for the pid. Usually error is 'NoUnitForPid'.
+ # Considering what we do at the bottom (just return if not service)
+ # Then there's really no reason to exit here on that exception.
+ # Log what's happened then move on.
+ msg = str(e)
+ logger.warning("Failed to get systemd unit for PID {}: {}".format(pid, msg))
+ return
service_properties = dbus.Interface(
service_proxy, dbus_interface="org.freedesktop.DBus.Properties")
name = service_properties.Get(
diff --git a/tests/test_needs_restarting.py b/tests/test_needs_restarting.py
index 0ad70a5..7b629b4 100644
--- a/tests/test_needs_restarting.py
+++ b/tests/test_needs_restarting.py
@@ -20,6 +20,8 @@ from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
+from unittest.mock import patch, Mock
+import dbus
import needs_restarting
import tests.support
@@ -29,8 +31,6 @@ MM_FILE = '7fc4e1168000-7fc4e1169000 rw-s 1096dd000 00:05 7749' \
' /dev/dri/card0'
SO_FILE = '30efe06000-30efe07000 r--p 00006000 08:02 139936' \
' /usr/lib64/libSM.so.6.0.1'
-
-
class NeedsRestartingTest(tests.support.TestCase):
def test_smap2opened_file(self):
func = needs_restarting.smap2opened_file
@@ -46,6 +46,17 @@ class NeedsRestartingTest(tests.support.TestCase):
self.assertTrue(ofile.deleted)
self.assertEqual(ofile.name, '/usr/lib64/libXfont.so.1.4.1;5408628d')
+ def test_get_service_dbus_nounitforpid(self):
+ func = needs_restarting.get_service_dbus
+ # So, This is gonna look kinda screwy unless you are aware of what
+ # this proxies interface is actually doing. The GetUnitByPid function
+ # is normally "dynamically" defined by the get_dbus_method at runtime.
+ # As such there's no actual way to mock it out in any meaningful way
+ # without create=True.
+ with patch( "dbus.proxies.Interface.GetUnitByPID", create=True, side_effect=dbus.DBusException('org.freedesktop.systemd1.NoUnitForPID: PID 1234 does not belong to any loaded unit.') ), \
+ patch( "dbus.SystemBus", return_value=Mock(spec=dbus.Bus) ), \
+ patch( "dbus.bus.BusConnection.__new__", side_effect=dbus.DBusException("Never should hit this exception if mock above works")):
+ self.assertIsNone(func(1234))
class OpenedFileTest(tests.support.TestCase):
def test_presumed_name(self):
--
2.40.1

View File

@ -1,51 +0,0 @@
From b5e6219b12773b76f634641752fa6f194608e1ff Mon Sep 17 00:00:00 2001
From: Nicola Sella <nsella@redhat.com>
Date: Wed, 21 Jun 2023 15:21:57 +0200
Subject: [PATCH] Fix zlib reboot requirement (RhBug:2092033)
---
plugins/needs_restarting.py | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 8dbc965..3197fe1 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -42,6 +42,8 @@ import time
NEED_REBOOT = ['kernel', 'kernel-rt', 'glibc', 'linux-firmware',
'systemd', 'dbus', 'dbus-broker', 'dbus-daemon']
+NEED_REBOOT_DEPENDS_ON_DBUS = ['zlib']
+
def get_options_from_dir(filepath, base):
"""
Provide filepath as string if single dir or list of strings
@@ -277,15 +279,24 @@ class NeedsRestartingCommand(dnf.cli.Command):
NEED_REBOOT.extend(opt)
if self.opts.reboothint:
need_reboot = set()
+ need_reboot_depends_on_dbus = set()
installed = self.base.sack.query().installed()
for pkg in installed.filter(name=NEED_REBOOT):
if pkg.installtime > process_start.boot_time:
need_reboot.add(pkg.name)
- if need_reboot:
+
+ dbus_installed = installed.filter(name=['dbus', 'dbus-daemon', 'dbus-broker'])
+ if len(dbus_installed) != 0:
+ for pkg in installed.filter(name=NEED_REBOOT_DEPENDS_ON_DBUS):
+ if pkg.installtime > process_start.boot_time:
+ need_reboot_depends_on_dbus.add(pkg.name)
+ if need_reboot or need_reboot_depends_on_dbus:
print(_('Core libraries or services have been updated '
'since boot-up:'))
for name in sorted(need_reboot):
print(' * %s' % name)
+ for name in sorted(need_reboot_depends_on_dbus):
+ print(' * %s (dependency of dbus. Recommending reboot of dbus)' % name)
print()
print(_('Reboot is required to fully utilize these updates.'))
print(_('More information:'),
--
2.40.1

View File

@ -1,75 +0,0 @@
From 1a29f3ab2f4719f40510dc08f12f4795ad358e93 Mon Sep 17 00:00:00 2001
From: Andy Baugh <thomas.baugh@cpanel.net>
Date: Tue, 6 Jun 2023 16:37:42 +0000
Subject: [PATCH] Fix for strange issue with binary garbage in smaps files
= changelog =
msg: Avoid issue with garbage smaps chars in needs-restarting.py
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2212953
related: None
---
plugins/needs_restarting.py | 2 +-
tests/test_needs_restarting.py | 14 +++++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 3197fe1..64d4d0f 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -76,7 +76,7 @@ def list_opened_files(uid):
try:
if uid is not None and uid != owner_uid(smaps):
continue
- with open(smaps, 'r') as smaps_file:
+ with open(smaps, 'r', errors='replace') as smaps_file:
lines = smaps_file.readlines()
except EnvironmentError:
logger.warning("Failed to read PID %d's smaps.", pid)
diff --git a/tests/test_needs_restarting.py b/tests/test_needs_restarting.py
index 7b629b4..d7dd6d5 100644
--- a/tests/test_needs_restarting.py
+++ b/tests/test_needs_restarting.py
@@ -1,3 +1,4 @@
+# coding: utf-8
# Copyright (C) 2014 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
@@ -15,15 +16,15 @@
# Red Hat, Inc.
#
-
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from unittest.mock import patch, Mock
import dbus
import needs_restarting
import tests.support
+import tempfile
DEL_FILE = '3dcf000000-3dcf032000 r-xp 00000000 08:02 140759 ' \
' /usr/lib64/libXfont.so.1.4.1;5408628d (deleted)'
@@ -58,6 +59,17 @@ class NeedsRestartingTest(tests.support.TestCase):
patch( "dbus.bus.BusConnection.__new__", side_effect=dbus.DBusException("Never should hit this exception if mock above works")):
self.assertIsNone(func(1234))
+ def test_list_opened_files_garbage_filename(self):
+ tempObj = tempfile.NamedTemporaryFile()
+ tempFile = tempObj.name
+ with open(tempFile, 'wb') as bogusFile:
+ bogusFile.write(b'151e7f7b7000-151e7f7b8000 r--p 00006000 fd:01 14744 /usr/lib64/lib\xe5Evil-13.37.so')
+ smaps = [[1234,tempObj.name]]
+ with patch("needs_restarting.list_smaps", return_value=smaps):
+ ofiles = list(needs_restarting.list_opened_files(None));
+ self.assertEqual(ofiles[0].presumed_name, '/usr/lib64/lib<69>Evil-13.37.so')
+
+
class OpenedFileTest(tests.support.TestCase):
def test_presumed_name(self):
ofile = needs_restarting.OpenedFile(
--
libgit2 1.6.4

View File

@ -1,40 +0,0 @@
From e1af3642a7811229567284f6901d393a6ce28b62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 23 Nov 2023 16:26:06 +0100
Subject: [PATCH] needs-restarting: Add microcode_ctl to a reboot list
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 9f46488c6b1ac553989a3fd8a9ea18271451c5e8 upstream.
To fully update CPU microcode, a reboot is needed because the
microcode update should be applied before starting a kernel and other
process.
Therefore recommend a reboot after installing or updating
microcode_ctl package.
https://issues.redhat.com/browse/RHEL-17356
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
plugins/needs_restarting.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
index 64d4d0f..92cde0a 100644
--- a/plugins/needs_restarting.py
+++ b/plugins/needs_restarting.py
@@ -40,7 +40,8 @@ import time
# For which package updates we should recommend a reboot
# Mostly taken from https://access.redhat.com/solutions/27943
NEED_REBOOT = ['kernel', 'kernel-rt', 'glibc', 'linux-firmware',
- 'systemd', 'dbus', 'dbus-broker', 'dbus-daemon']
+ 'systemd', 'dbus', 'dbus-broker', 'dbus-daemon',
+ 'microcode_ctl']
NEED_REBOOT_DEPENDS_ON_DBUS = ['zlib']
--
2.43.0

1
ci.fmf Normal file
View File

@ -0,0 +1 @@
resultsdb-testcase: separate

File diff suppressed because it is too large Load Diff

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/internal/CI-Tier-1.functional}

View File

@ -0,0 +1,15 @@
summary: Internal CI-Tier-1 tests plan
discover:
- name: dnf-plugins-core
how: fmf
filter: 'tag: CI-Tier-1'
url: https://pkgs.devel.redhat.com/git/tests/dnf-plugins-core
- name: yum-utils
how: fmf
filter: 'tag: CI-Tier-1'
url: https://pkgs.devel.redhat.com/git/tests/yum-utils
execute:
how: tmt
adjust:
enabled: false
when: distro == centos-stream or distro == fedora

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (dnf-plugins-core-4.7.0.tar.gz) = 78c92429638c440005913578d7d91087ed329ea191cc35f4c5f58f1ac3f7b617b6f724aa9b96fb6e73f448d8a304a570fece3a834003a688e248bd24bc7acbfa