Compare commits
No commits in common. "c8" and "c9-beta" have entirely different histories.
@ -1 +1 @@
|
||||
40f26a50a6605eacb1e9c4a443f01655fa461767 SOURCES/dnf-plugins-core-4.0.21.tar.gz
|
||||
d9a1561a5c4d238340b3db6d081c70b86841c291 SOURCES/dnf-plugins-core-4.3.0.tar.gz
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/dnf-plugins-core-4.0.21.tar.gz
|
||||
SOURCES/dnf-plugins-core-4.3.0.tar.gz
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From 54eba8059b07b31b2caa27b48269e74da959eaa6 Mon Sep 17 00:00:00 2001
|
||||
From 75e92678bfb687d23594c3ecef299cddca657c3e Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kolarik <jkolarik@redhat.com>
|
||||
Date: Thu, 22 Sep 2022 16:02:55 +0000
|
||||
Subject: [PATCH] Move system-upgrade plugin to core (RhBug:2054235)
|
||||
Subject: [PATCH 1/4] Move system-upgrade plugin to core (RhBug:2054235)
|
||||
|
||||
= changelog =
|
||||
type: bugfix
|
||||
@ -29,7 +29,7 @@ resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2054235
|
||||
create mode 100644 tests/test_system_upgrade.py
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index f143905..bd5f35b 100644
|
||||
index 59c4f2a..a1eea7b 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -23,6 +23,21 @@ MESSAGE(STATUS "Python install dir is ${PYTHON_INSTALL_DIR}")
|
||||
@ -55,7 +55,7 @@ index f143905..bd5f35b 100644
|
||||
ADD_SUBDIRECTORY (doc)
|
||||
ADD_SUBDIRECTORY (etc)
|
||||
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
|
||||
index afdbcbb..0e1c9e3 100644
|
||||
index c37dda8..4df6e44 100644
|
||||
--- a/dnf-plugins-core.spec
|
||||
+++ b/dnf-plugins-core.spec
|
||||
@@ -64,6 +64,9 @@ Provides: dnf-command(repograph)
|
||||
@ -1707,5 +1707,5 @@ index 0000000..6ef4c21
|
||||
+ self.command.run_log()
|
||||
+ show_log.assert_called_once_with(-2)
|
||||
--
|
||||
2.37.3
|
||||
2.38.1
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From e52655aa9c7c9ad334639990d612da574b57736b Mon Sep 17 00:00:00 2001
|
||||
From 307641a869134de4ebd496d1a78e5ff128a26293 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
|
||||
Subject: [PATCH 2/4] Add a warning when using `system-upgrade` on RHEL
|
||||
|
||||
---
|
||||
dnf-plugins-core.spec | 3 +--
|
||||
@ -10,7 +10,7 @@ Subject: [PATCH 1/3] Add a warning when using `system-upgrade` on RHEL
|
||||
3 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
|
||||
index 0e1c9e3..a5ec165 100644
|
||||
index 4df6e44..1ee87a1 100644
|
||||
--- a/dnf-plugins-core.spec
|
||||
+++ b/dnf-plugins-core.spec
|
||||
@@ -148,14 +148,13 @@ Summary: Core Plugins for DNF
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From 3a18b7241708a3c5fd1b4b92a2f9908a826e815d Mon Sep 17 00:00:00 2001
|
||||
From eef927ac825c1a07082e10ffbf11e16ecbd7688c 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
|
||||
@ -34,7 +34,7 @@ index 0baf978..ef1de73 100644
|
||||
2.38.1
|
||||
|
||||
|
||||
From dad20a478e100bd0ac3a8d7d51dad75baca90c7f Mon Sep 17 00:00:00 2001
|
||||
From 7e5d3028caa743f3e5ac7bf921c3ec39a4d2c85b 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
|
||||
@ -45,7 +45,7 @@ Subject: [PATCH 2/2] Add myself as contributor in AUTHORS
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index 33512fd..cd4b5be 100644
|
||||
index 352e195..f098cb6 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -32,6 +32,7 @@ DNF-PLUGINS-CORE CONTRIBUTORS
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From dfbda502c5c46daf84e00179478de01e452f9dae Mon Sep 17 00:00:00 2001
|
||||
From e04aff1e65fb260912e7e0feeb201e17fa5abda4 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
|
||||
@ -14,7 +14,7 @@ resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152846
|
||||
2 files changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
|
||||
index a5ec165..0e1c9e3 100644
|
||||
index 1ee87a1..4df6e44 100644
|
||||
--- a/dnf-plugins-core.spec
|
||||
+++ b/dnf-plugins-core.spec
|
||||
@@ -148,13 +148,14 @@ Summary: Core Plugins for DNF
|
||||
2782
SOURCES/0005-Update-translations.patch
Normal file
2782
SOURCES/0005-Update-translations.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From 23a6123348f0a387768ebdfdaaded900a083039e Mon Sep 17 00:00:00 2001
|
||||
From f65bb02d8c6fb6569c3e1db43c3b0e9f2a0ab283 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
|
||||
@ -50,6 +50,6 @@ index 91dbe66..03831fa 100644
|
||||
|
||||
@staticmethod
|
||||
def get_sc_clk_tck():
|
||||
--
|
||||
libgit2 1.3.2
|
||||
--
|
||||
2.40.1
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,241 @@
|
||||
From d5f5883623ada37b4cec5909a1032c4bc3123a9a Mon Sep 17 00:00:00 2001
|
||||
From: Cameron Rodriguez <rod.cam2014+dev@gmail.com>
|
||||
Date: Tue, 1 Nov 2022 02:25:52 -0400
|
||||
Subject: [PATCH] [system-upgrade] Add --poweroff option to reboot subcommand
|
||||
|
||||
= changelog =
|
||||
msg: Add --poweroff option to system-upgrade reboot
|
||||
type: enhancement
|
||||
---
|
||||
doc/system-upgrade.rst | 10 ++++++++++
|
||||
plugins/system_upgrade.py | 28 ++++++++++++++++++++++------
|
||||
tests/test_system_upgrade.py | 18 +++++++++++++++++-
|
||||
3 files changed, 49 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/doc/system-upgrade.rst b/doc/system-upgrade.rst
|
||||
index 87b7319..6a7785b 100644
|
||||
--- a/doc/system-upgrade.rst
|
||||
+++ b/doc/system-upgrade.rst
|
||||
@@ -44,6 +44,8 @@ Synopsis
|
||||
|
||||
``dnf system-upgrade reboot``
|
||||
|
||||
+``dnf system-upgrade reboot --poweroff``
|
||||
+
|
||||
``dnf system-upgrade clean``
|
||||
|
||||
``dnf system-upgrade log``
|
||||
@@ -54,6 +56,8 @@ Synopsis
|
||||
|
||||
``dnf offline-upgrade reboot``
|
||||
|
||||
+``dnf offline-upgrade reboot --poweroff``
|
||||
+
|
||||
``dnf offline-upgrade clean``
|
||||
|
||||
``dnf offline-upgrade log``
|
||||
@@ -64,6 +68,8 @@ Synopsis
|
||||
|
||||
``dnf offline-distrosync reboot``
|
||||
|
||||
+``dnf offline-distrosync reboot --poweroff``
|
||||
+
|
||||
``dnf offline-distrosync clean``
|
||||
|
||||
``dnf offline-distrosync log``
|
||||
@@ -116,6 +122,10 @@ Options
|
||||
``--distro-sync``. If both are specified, the last option will be used. The option cannot be
|
||||
used with the ``offline-distrosync`` command.
|
||||
|
||||
+``--poweroff``
|
||||
+ When applied with the ``reboot`` subcommand, the system will power off after
|
||||
+ upgrades are completed, instead of restarting.
|
||||
+
|
||||
``--number``
|
||||
Applied with ``log`` subcommand will show the log specified by the number.
|
||||
|
||||
diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py
|
||||
index 4f7620f..b99dd8a 100644
|
||||
--- a/plugins/system_upgrade.py
|
||||
+++ b/plugins/system_upgrade.py
|
||||
@@ -61,16 +61,19 @@ DOWNLOAD_FINISHED_MSG = _( # Translators: do not change "reboot" here
|
||||
CANT_RESET_RELEASEVER = _(
|
||||
"Sorry, you need to use 'download --releasever' instead of '--network'")
|
||||
|
||||
-STATE_VERSION = 2
|
||||
+STATE_VERSION = 3
|
||||
|
||||
# --- Miscellaneous helper functions ------------------------------------------
|
||||
|
||||
|
||||
-def reboot():
|
||||
+def reboot(poweroff = False):
|
||||
if os.getenv("DNF_SYSTEM_UPGRADE_NO_REBOOT", default=False):
|
||||
logger.info(_("Reboot turned off, not rebooting."))
|
||||
else:
|
||||
- Popen(["systemctl", "reboot"])
|
||||
+ if poweroff:
|
||||
+ Popen(["systemctl", "poweroff"])
|
||||
+ else:
|
||||
+ Popen(["systemctl", "reboot"])
|
||||
|
||||
|
||||
def get_url_from_os_release():
|
||||
@@ -183,6 +186,7 @@ class State(object):
|
||||
upgrade_status = _prop("upgrade_status")
|
||||
upgrade_command = _prop("upgrade_command")
|
||||
distro_sync = _prop("distro_sync")
|
||||
+ poweroff_after = _prop("poweroff_after")
|
||||
enable_disable_repos = _prop("enable_disable_repos")
|
||||
module_platform_id = _prop("module_platform_id")
|
||||
|
||||
@@ -359,6 +363,10 @@ class SystemUpgradeCommand(dnf.cli.Command):
|
||||
action='store_false',
|
||||
help=_("keep installed packages if the new "
|
||||
"release's version is older"))
|
||||
+ parser.add_argument('--poweroff', dest='poweroff_after',
|
||||
+ action='store_true',
|
||||
+ help=_("power off system after the operation "
|
||||
+ "is completed"))
|
||||
parser.add_argument('tid', nargs=1, choices=CMDS,
|
||||
metavar="[%s]" % "|".join(CMDS))
|
||||
parser.add_argument('--number', type=int, help=_('which logs to show'))
|
||||
@@ -566,8 +574,13 @@ class SystemUpgradeCommand(dnf.cli.Command):
|
||||
if not self.opts.tid[0] == "reboot":
|
||||
return
|
||||
|
||||
+ self.state.poweroff_after = self.opts.poweroff_after
|
||||
+
|
||||
self.log_status(_("Rebooting to perform upgrade."),
|
||||
REBOOT_REQUESTED_ID)
|
||||
+
|
||||
+ # Explicit write since __exit__ doesn't seem to get called when rebooting
|
||||
+ self.state.write()
|
||||
reboot()
|
||||
|
||||
def run_download(self):
|
||||
@@ -686,12 +699,15 @@ class SystemUpgradeCommand(dnf.cli.Command):
|
||||
self.log_status(_("Download finished."), DOWNLOAD_FINISHED_ID)
|
||||
|
||||
def transaction_upgrade(self):
|
||||
- Plymouth.message(_("Upgrade complete! Cleaning up and rebooting..."))
|
||||
- self.log_status(_("Upgrade complete! Cleaning up and rebooting..."),
|
||||
+ power_op = "powering off" if self.state.poweroff_after else "rebooting"
|
||||
+
|
||||
+ Plymouth.message(_("Upgrade complete! Cleaning up and " + power_op + "..."))
|
||||
+ self.log_status(_("Upgrade complete! Cleaning up and " + power_op + "..."),
|
||||
UPGRADE_FINISHED_ID)
|
||||
+
|
||||
self.run_clean()
|
||||
if self.opts.tid[0] == "upgrade":
|
||||
- reboot()
|
||||
+ reboot(self.state.poweroff_after)
|
||||
|
||||
|
||||
class OfflineUpgradeCommand(SystemUpgradeCommand):
|
||||
diff --git a/tests/test_system_upgrade.py b/tests/test_system_upgrade.py
|
||||
index 6ef4c21..769720d 100644
|
||||
--- a/tests/test_system_upgrade.py
|
||||
+++ b/tests/test_system_upgrade.py
|
||||
@@ -322,7 +322,7 @@ class RebootCheckCommandTestCase(CommandTestCaseBase):
|
||||
def check_reboot(self, status='complete', lexists=False, command='system-upgrade',
|
||||
state_command='system-upgrade'):
|
||||
with patch('system_upgrade.os.path.lexists') as lexists_func:
|
||||
- self.command.state.state_version = 2
|
||||
+ self.command.state.state_version = 3
|
||||
self.command.state.download_status = status
|
||||
self.command.opts = mock.MagicMock()
|
||||
self.command.opts.command = command
|
||||
@@ -356,6 +356,7 @@ class RebootCheckCommandTestCase(CommandTestCaseBase):
|
||||
@patch('system_upgrade.reboot')
|
||||
def test_run_reboot(self, reboot, log_status, run_prepare):
|
||||
self.command.opts = mock.MagicMock()
|
||||
+ self.command.opts.poweroff_after = False
|
||||
self.command.opts.tid = ["reboot"]
|
||||
self.command.run_reboot()
|
||||
run_prepare.assert_called_once_with()
|
||||
@@ -363,6 +364,21 @@ class RebootCheckCommandTestCase(CommandTestCaseBase):
|
||||
log_status.call_args[0][1])
|
||||
self.assertTrue(reboot.called)
|
||||
|
||||
+ @patch('system_upgrade.SystemUpgradeCommand.run_prepare')
|
||||
+ @patch('system_upgrade.SystemUpgradeCommand.log_status')
|
||||
+ @patch('system_upgrade.reboot')
|
||||
+ def test_reboot_poweroff_after(self, reboot, log_status, run_prepare):
|
||||
+ self.command.opts = mock.MagicMock()
|
||||
+ self.command.opts.tid = ["reboot"]
|
||||
+ self.command.opts.poweroff_after = True
|
||||
+ self.command.run_reboot()
|
||||
+ run_prepare.assert_called_with()
|
||||
+ self.assertEqual(system_upgrade.REBOOT_REQUESTED_ID,
|
||||
+ log_status.call_args[0][1])
|
||||
+ self.assertTrue(self.command.state.poweroff_after)
|
||||
+ self.assertTrue(reboot.called)
|
||||
+
|
||||
+
|
||||
@patch('system_upgrade.SystemUpgradeCommand.run_prepare')
|
||||
@patch('system_upgrade.SystemUpgradeCommand.log_status')
|
||||
@patch('system_upgrade.reboot')
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
From 52aec32ef129874dc28fc93947e5d32c78baff0c Mon Sep 17 00:00:00 2001
|
||||
From: Cameron Rodriguez <rod.cam2014+dev@gmail.com>
|
||||
Date: Tue, 1 Nov 2022 02:29:29 -0400
|
||||
Subject: [PATCH] Add Cameron Rodriguez to AUTHORS file
|
||||
|
||||
---
|
||||
AUTHORS | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index f098cb6..a6102ec 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -20,6 +20,7 @@ DNF-PLUGINS-CORE CONTRIBUTORS
|
||||
Adam Salih <salih.max@gmail.com>
|
||||
Alexander Todorov <atodorov@otb.bg>
|
||||
Anders Blomdell <anders.blomdell@gmail.com>
|
||||
+ Cameron Rodriguez <rod.cam2014+dev@gmail.com>
|
||||
Cyril Jouve <jv.cyril@gmail.com>
|
||||
David Michael <fedora.dm0@gmail.com>
|
||||
François Rigault <francois.rigault@amadeus.com>
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
From dd081ebd4c46a79688f81ef639628189f8b78db3 Mon Sep 17 00:00:00 2001
|
||||
From: Cameron Rodriguez <rod.cam2014+dev@gmail.com>
|
||||
Date: Sun, 4 Dec 2022 10:06:08 -0500
|
||||
Subject: [PATCH] [offline-upgrade] Fix strings for l10n
|
||||
|
||||
---
|
||||
plugins/system_upgrade.py | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py
|
||||
index b99dd8a..64195fd 100644
|
||||
--- a/plugins/system_upgrade.py
|
||||
+++ b/plugins/system_upgrade.py
|
||||
@@ -699,11 +699,13 @@ class SystemUpgradeCommand(dnf.cli.Command):
|
||||
self.log_status(_("Download finished."), DOWNLOAD_FINISHED_ID)
|
||||
|
||||
def transaction_upgrade(self):
|
||||
- power_op = "powering off" if self.state.poweroff_after else "rebooting"
|
||||
+ if self.state.poweroff_after:
|
||||
+ upgrade_complete_msg = _("Upgrade complete! Cleaning up and powering off...")
|
||||
+ else:
|
||||
+ upgrade_complete_msg = _("Upgrade complete! Cleaning up and rebooting...")
|
||||
|
||||
- Plymouth.message(_("Upgrade complete! Cleaning up and " + power_op + "..."))
|
||||
- self.log_status(_("Upgrade complete! Cleaning up and " + power_op + "..."),
|
||||
- UPGRADE_FINISHED_ID)
|
||||
+ Plymouth.message(upgrade_complete_msg)
|
||||
+ self.log_status(upgrade_complete_msg, UPGRADE_FINISHED_ID)
|
||||
|
||||
self.run_clean()
|
||||
if self.opts.tid[0] == "upgrade":
|
||||
--
|
||||
2.40.1
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From a83af3db9f1aaf698be5455a01814849e39307d8 Mon Sep 17 00:00:00 2001
|
||||
From 52c980f191993b61a42438a478d1e5629ea36c9f 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)
|
||||
@ -29,6 +29,6 @@ index 0df00b9..bbf714c 100644
|
||||
|
||||
``-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
|
||||
--
|
||||
2.40.1
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From b086bfe09cf0eec67ea830e0e0f3482c6b6b2aa9 Mon Sep 17 00:00:00 2001
|
||||
From 169a79922d7cb8968ffd378b1c98959185ee417f 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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From 7475f8df6d903764eaf8baaa87ec7a3a1a4d888c Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kolarik <jkolarik@redhat.com>
|
||||
Date: Fri, 9 Jun 2023 11:57:33 +0000
|
||||
Subject: [PATCH] system-upgrade: Wait until the upgrade is done before
|
||||
poweroff (RhBug:2211844)
|
||||
|
||||
Add a systemd dependency to wait until upgrade service is finished before executing the poweroff when passing the `--poweroff` option in `system-upgrade` plugin.
|
||||
|
||||
= changelog =
|
||||
msg: Fix systemd dependencies when using --poweroff option in system-upgrade plugin
|
||||
type: bugfix
|
||||
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2211844
|
||||
---
|
||||
etc/systemd/dnf-system-upgrade.service | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/etc/systemd/dnf-system-upgrade.service b/etc/systemd/dnf-system-upgrade.service
|
||||
index 2d23cfe..3e15920 100644
|
||||
--- a/etc/systemd/dnf-system-upgrade.service
|
||||
+++ b/etc/systemd/dnf-system-upgrade.service
|
||||
@@ -6,7 +6,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates
|
||||
DefaultDependencies=no
|
||||
Requires=sysinit.target
|
||||
After=sysinit.target systemd-journald.socket system-update-pre.target
|
||||
-Before=shutdown.target system-update.target
|
||||
+Before=poweroff.target reboot.target shutdown.target system-update.target
|
||||
OnFailure=dnf-system-upgrade-cleanup.service
|
||||
|
||||
[Service]
|
||||
--
|
||||
2.40.1
|
||||
|
||||
@ -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
|
||||
|
||||
3214
SOURCES/0011-Update-translations-RHEL-9.3.patch
Normal file
3214
SOURCES/0011-Update-translations-RHEL-9.3.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
||||
From 824aee8b6ace0df2fedc2cbee1dff4a0c0bc51b1 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Blaha <mblaha@redhat.com>
|
||||
Date: Fri, 22 Sep 2023 08:36:59 +0200
|
||||
Subject: [PATCH] RHEL-6394: Fix incorrect spanish translation file
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-6394
|
||||
---
|
||||
po/es.po | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/po/es.po b/po/es.po
|
||||
index c0268e5..ae4ad0a 100644
|
||||
--- a/po/es.po
|
||||
+++ b/po/es.po
|
||||
@@ -150,7 +150,7 @@ msgstr "Registros de cambios para {}"
|
||||
#: plugins/config_manager.py:38
|
||||
#, python-brace-format
|
||||
msgid "manage {prog} configuration options and repositories"
|
||||
-msgstr "Dirige {*prog} opciones de configuración y repositorios"
|
||||
+msgstr "Dirige {prog} opciones de configuración y repositorios"
|
||||
|
||||
#: plugins/config_manager.py:45
|
||||
msgid "repo to modify"
|
||||
--
|
||||
libgit2 1.6.4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
From 1a29f3ab2f4719f40510dc08f12f4795ad358e93 Mon Sep 17 00:00:00 2001
|
||||
From a8f5a8e7a33e39c393fb94cc47f65d46907b4261 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
|
||||
@ -14,10 +14,10 @@ related: None
|
||||
2 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py
|
||||
index 3197fe1..64d4d0f 100644
|
||||
index 8dbc965..baadde0 100644
|
||||
--- a/plugins/needs_restarting.py
|
||||
+++ b/plugins/needs_restarting.py
|
||||
@@ -76,7 +76,7 @@ def list_opened_files(uid):
|
||||
@@ -74,7 +74,7 @@ def list_opened_files(uid):
|
||||
try:
|
||||
if uid is not None and uid != owner_uid(smaps):
|
||||
continue
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From e1af3642a7811229567284f6901d393a6ce28b62 Mon Sep 17 00:00:00 2001
|
||||
From b4b3affd654f53d5f1a808e1ed7ea004fe875f96 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
|
||||
@ -15,14 +15,14 @@ process.
|
||||
Therefore recommend a reboot after installing or updating
|
||||
microcode_ctl package.
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-17356
|
||||
https://issues.redhat.com/browse/RHEL-4600
|
||||
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
|
||||
index baadde0..309a216 100644
|
||||
--- a/plugins/needs_restarting.py
|
||||
+++ b/plugins/needs_restarting.py
|
||||
@@ -40,7 +40,8 @@ import time
|
||||
@ -33,8 +33,8 @@ index 64d4d0f..92cde0a 100644
|
||||
+ 'systemd', 'dbus', 'dbus-broker', 'dbus-daemon',
|
||||
+ 'microcode_ctl']
|
||||
|
||||
NEED_REBOOT_DEPENDS_ON_DBUS = ['zlib']
|
||||
|
||||
def get_options_from_dir(filepath, base):
|
||||
"""
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 1880f968aa323226a70d058c64ee50c104536b88 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Goode <mail@evangoo.de>
|
||||
Date: Mon, 10 Jul 2023 13:09:36 +0000
|
||||
Subject: [PATCH] system-upgrade: change http to https in unit file
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Upstream commit: 4615b3213659351d9933ac91e595bd236618f649
|
||||
Resolves Rhbug:2219233
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-13053
|
||||
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
etc/systemd/dnf-system-upgrade.service | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/etc/systemd/dnf-system-upgrade.service b/etc/systemd/dnf-system-upgrade.service
|
||||
index 3e15920..f4f0dac 100644
|
||||
--- a/etc/systemd/dnf-system-upgrade.service
|
||||
+++ b/etc/systemd/dnf-system-upgrade.service
|
||||
@@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=System Upgrade using DNF
|
||||
ConditionPathExists=/system-update
|
||||
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates
|
||||
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates
|
||||
|
||||
DefaultDependencies=no
|
||||
Requires=sysinit.target
|
||||
--
|
||||
2.45.0
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From 1177f339dc3c428d57aef9ec6ae5d1db09ff7b95 Mon Sep 17 00:00:00 2001
|
||||
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||
Date: Wed, 24 Jul 2024 11:05:18 +0200
|
||||
Subject: [PATCH] reposync: Respect --norepopath with --metadata-path
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-40914
|
||||
---
|
||||
plugins/reposync.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/reposync.py b/plugins/reposync.py
|
||||
index 0ff936f..ab513e7 100644
|
||||
--- a/plugins/reposync.py
|
||||
+++ b/plugins/reposync.py
|
||||
@@ -180,7 +180,7 @@ class RepoSyncCommand(dnf.cli.Command):
|
||||
|
||||
def metadata_target(self, repo):
|
||||
if self.opts.metadata_path:
|
||||
- return _pkgdir(self.opts.metadata_path, repo.id)
|
||||
+ return _pkgdir(self.opts.metadata_path, repo.id if not self.opts.norepopath else '')
|
||||
else:
|
||||
return self.repo_target(repo)
|
||||
|
||||
--
|
||||
2.46.2
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,159 @@
|
||||
From 8cf40027b920b3760d6d1df9eb280b4f3772f290 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Goode <mail@evangoo.de>
|
||||
Date: Thu, 3 Oct 2024 21:37:58 +0000
|
||||
Subject: [PATCH] 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 309a216..9c77af7 100644
|
||||
--- a/plugins/needs_restarting.py
|
||||
+++ b/plugins/needs_restarting.py
|
||||
@@ -203,36 +203,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():
|
||||
@@ -241,10 +294,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.47.0
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From 275b858c8b90f880fe71c99bd07aeb76637a0926 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Curtin <ecurtin@redhat.com>
|
||||
Date: Wed, 7 Jun 2023 20:04:25 +0100
|
||||
Subject: [PATCH] "dnf copr enable" on "Asahi Fedora Linux Remix" guesses
|
||||
epel..x86_64
|
||||
|
||||
Resolves https://issues.redhat.com/browse/RHEL-56143.
|
||||
|
||||
On Asahi Fedora Linux Remix, this can occur when doing a dnf copr
|
||||
enable:
|
||||
|
||||
Repository 'epel-37-x86_64' does not exist in project '@asahi/mesa'
|
||||
|
||||
There are two bugs here, the code doesn't recongize this as a Fedora
|
||||
distro and defaults to x86_64 when in this case it's actually an aarch64
|
||||
system.
|
||||
---
|
||||
plugins/copr.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/copr.py b/plugins/copr.py
|
||||
index 16946b7..ae4f2e0 100644
|
||||
--- a/plugins/copr.py
|
||||
+++ b/plugins/copr.py
|
||||
@@ -444,7 +444,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 any([name in dist for name in ["Fedora", "Fedora Linux"]]):
|
||||
+ if "Fedora" in dist[0]:
|
||||
if "Rawhide" in dist:
|
||||
chroot = ("fedora-rawhide-" + distarch)
|
||||
# workaround for enabling repos in Rawhide when VERSION in os-release
|
||||
@@ -470,7 +470,7 @@ Bugzilla. In case of problems, contact the owner of this repository.
|
||||
else:
|
||||
chroot = ("opensuse-leap-{0}-{1}".format(dist[1], distarch))
|
||||
else:
|
||||
- chroot = ("epel-%s-x86_64" % dist[1].split(".", 1)[0])
|
||||
+ chroot = ("epel-{}-{}".format(dist[1].split(".", 1)[0], distarch if distarch else "x86_64"))
|
||||
return chroot
|
||||
|
||||
def _download_repo(self, project_name, repo_filename):
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 43d07e2b385b069b1f851e5a16f1b7d8bbed1195 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Blaha <mblaha@redhat.com>
|
||||
Date: Mon, 4 Nov 2024 10:35:08 +0100
|
||||
Subject: [PATCH] reposync: Avoid multiple downloads of duplicate packages
|
||||
|
||||
Download each package only once if it would have been saved to the same
|
||||
location. This can occur if the repository metadata contains duplicate
|
||||
entries for the same package.
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-64320
|
||||
|
||||
Upstream commit: 17e36ed
|
||||
---
|
||||
plugins/reposync.py | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/reposync.py b/plugins/reposync.py
|
||||
index ab513e7..19f5440 100644
|
||||
--- a/plugins/reposync.py
|
||||
+++ b/plugins/reposync.py
|
||||
@@ -292,7 +292,15 @@ class RepoSyncCommand(dnf.cli.Command):
|
||||
query.filterm(arch='src')
|
||||
elif self.opts.arches:
|
||||
query.filterm(arch=self.opts.arches)
|
||||
- return query
|
||||
+ # skip packages that would have been downloaded to the same location
|
||||
+ pkglist = []
|
||||
+ seen_paths = set()
|
||||
+ for pkg in query:
|
||||
+ download_path = self.pkg_download_path(pkg)
|
||||
+ if download_path not in seen_paths:
|
||||
+ pkglist.append(pkg)
|
||||
+ seen_paths.add(download_path)
|
||||
+ return pkglist
|
||||
|
||||
def download_packages(self, pkglist):
|
||||
base = self.base
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,617 @@
|
||||
From 37c4cd7014f4b3c5db64a0a900761e53caf645be Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||
Date: Tue, 25 Mar 2025 12:34:34 +0100
|
||||
Subject: [PATCH] multisig: A new plugin for verifying extraordinary RPM
|
||||
signatures
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This plugin executes a dedicated rpmkeys(8) tool of pqrpm for
|
||||
verifying RPM packages bound into a transaction.
|
||||
|
||||
The dedicated tool is supposed to understand signatures in RPM version
|
||||
6 format. One feature of that format is that you can have multiple
|
||||
signatures on a single RPM package.
|
||||
|
||||
This plugin takes public keys from a default key store of pqrpm, which
|
||||
is separate from the native RPM database. A reason is that the native
|
||||
database might reject storing OpenPGP keys with an unsupported key
|
||||
schema. A downside is that "dnf --installroot" places the keyring to
|
||||
a directory which is ununowned in the installroot.
|
||||
|
||||
XXX: This plugin does not report which keys required for the
|
||||
verification are missing (NOKEY case in _process_rpm_output()).
|
||||
Implementing that would require changing too many function interfaces.
|
||||
Classical single-signature verification does not do that either.
|
||||
|
||||
XXX: The plugin is packaged into a package which requires pqrpm which
|
||||
will only be available in RHEL 9. Next RHEL version will support the
|
||||
extraordinary signatures natively. Thus this patch only makes sense in
|
||||
RHEL 9.
|
||||
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
dnf-plugins-core.spec | 19 ++
|
||||
doc/CMakeLists.txt | 5 +
|
||||
doc/conf.py | 3 +
|
||||
doc/index.rst | 1 +
|
||||
doc/multisig.rst | 62 +++++++
|
||||
plugins/CMakeLists.txt | 3 +
|
||||
plugins/multisig.py | 402 +++++++++++++++++++++++++++++++++++++++++
|
||||
7 files changed, 495 insertions(+)
|
||||
create mode 100644 doc/multisig.rst
|
||||
create mode 100644 plugins/multisig.py
|
||||
|
||||
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
|
||||
index f2d1bc4..cb3b1b8 100644
|
||||
--- a/dnf-plugins-core.spec
|
||||
+++ b/dnf-plugins-core.spec
|
||||
@@ -301,6 +301,18 @@ Obsoletes: python-dnf-plugins-extras-migrate < %{dnf_plugins_extra}
|
||||
Migrate Plugin for DNF, Python 2 version. Migrates history, group and yumdb data from yum to dnf.
|
||||
%endif
|
||||
|
||||
+%if %{with python3}
|
||||
+%package -n python3-dnf-plugin-multisig
|
||||
+Summary: Multisig Plugin for DNF
|
||||
+Requires: pqrpm
|
||||
+Requires: python3-%{name} = %{version}-%{release}
|
||||
+Provides: dnf-plugin-multisig = %{version}-%{release}
|
||||
+
|
||||
+%description -n python3-dnf-plugin-multisig
|
||||
+Multisig Plugin for DNF, Python 3 version. The plugin verifies multiple RPMv6
|
||||
+signatures on RPMv4 packages by using an external rpmkeys program.
|
||||
+%endif
|
||||
+
|
||||
%if %{with python2}
|
||||
%package -n python2-dnf-plugin-post-transaction-actions
|
||||
Summary: Post transaction actions Plugin for DNF
|
||||
@@ -716,6 +728,13 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%exclude %{_mandir}/man8/dnf-migrate.*
|
||||
%endif
|
||||
|
||||
+%if %{with python3}
|
||||
+%files -n python3-dnf-plugin-multisig
|
||||
+%{python3_sitelib}/dnf-plugins/multisig.*
|
||||
+%{python3_sitelib}/dnf-plugins/__pycache__/multisig.*
|
||||
+%{_mandir}/man8/dnf*-multisig.*
|
||||
+%endif
|
||||
+
|
||||
%if %{with python2}
|
||||
%files -n python2-dnf-plugin-post-transaction-actions
|
||||
%config(noreplace) %{_sysconfdir}/dnf/plugins/post-transaction-actions.conf
|
||||
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
|
||||
index 79472a5..297506a 100644
|
||||
--- a/doc/CMakeLists.txt
|
||||
+++ b/doc/CMakeLists.txt
|
||||
@@ -47,6 +47,11 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-migrate.8
|
||||
DESTINATION share/man/man8)
|
||||
endif()
|
||||
|
||||
+if (${PYTHON_VERSION_MAJOR} STREQUAL "3")
|
||||
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf4-multisig.8
|
||||
+ DESTINATION share/man/man8)
|
||||
+endif()
|
||||
+
|
||||
if (${WITHOUT_LOCAL} STREQUAL "0")
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-local.8
|
||||
DESTINATION share/man/man8)
|
||||
diff --git a/doc/conf.py b/doc/conf.py
|
||||
index 327ac07..2845d18 100644
|
||||
--- a/doc/conf.py
|
||||
+++ b/doc/conf.py
|
||||
@@ -300,6 +300,9 @@ man_pages = [
|
||||
if sys.version_info[0] < 3:
|
||||
man_pages.append(('migrate', 'dnf-migrate', u'DNF migrate Plugin', AUTHORS, 8))
|
||||
|
||||
+if sys.version_info[0] == 3:
|
||||
+ man_pages.append(('multisig', 'dnf4-multisig', u'DNF multisig Plugin', AUTHORS, 8))
|
||||
+
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
diff --git a/doc/index.rst b/doc/index.rst
|
||||
index 251a24e..32984a5 100644
|
||||
--- a/doc/index.rst
|
||||
+++ b/doc/index.rst
|
||||
@@ -37,6 +37,7 @@ This documents core plugins of DNF:
|
||||
leaves
|
||||
local
|
||||
migrate
|
||||
+ multisig
|
||||
modulesync
|
||||
needs_restarting
|
||||
post-transaction-actions
|
||||
diff --git a/doc/multisig.rst b/doc/multisig.rst
|
||||
new file mode 100644
|
||||
index 0000000..21b9436
|
||||
--- /dev/null
|
||||
+++ b/doc/multisig.rst
|
||||
@@ -0,0 +1,62 @@
|
||||
+===================
|
||||
+DNF multisig Plugin
|
||||
+===================
|
||||
+
|
||||
+-----------
|
||||
+Description
|
||||
+-----------
|
||||
+
|
||||
+This plugin verifies extraordinary RPMv6 signatures when installing,
|
||||
+reinstalling, upgrading, or downgrading packages from a repository. If the
|
||||
+verification fails, the RPM operation will be aborted.
|
||||
+
|
||||
+The verification is achieved by executing a dedicated rpmkeys(8) tool which is
|
||||
+supposed to understand package signatures in RPM version 6 format. One feature
|
||||
+of that format is that you can have multiple signatures on a single RPM
|
||||
+package. If the package has no RPMv6 signature a signature in version 4 format
|
||||
+will be verified instead. If there is no signature, the verification will be
|
||||
+handled as failed.
|
||||
+
|
||||
+The dedicated rpmkeys(8) tool trusts public keys in a key store separate from
|
||||
+the native RPM database because the native database might reject storing
|
||||
+OpenPGP keys with an unsupported key schema which is foreseen to be used in
|
||||
+RPMv6 signatures.
|
||||
+
|
||||
+Public keys missing from the separate key store are attempted to be imported
|
||||
+from URLs listed in ``gpgkey`` configuration field of a repository the package
|
||||
+belongs to. Before importing, a user is asked for a confirmation with the
|
||||
+import, unless DNF was invoked with ``--assumeyes`` or ``--assumeno`` options.
|
||||
+
|
||||
+The key store can be inspected with ``/usr/lib/pqrpm/bin/rpmkeys -D --list``
|
||||
+command. A key can be deleted from the key store with
|
||||
+``/usr/lib/pqrpm/bin/rpmkeys -D --erase KEY_ID`` command. The ``KEY_ID`` is
|
||||
+the first word in an output of the ``--list`` command.
|
||||
+
|
||||
+Users who do not wish to verify the extraordinary RPMv6 signatures should
|
||||
+uninstall this plugin.
|
||||
+
|
||||
+-------------
|
||||
+Configuration
|
||||
+-------------
|
||||
+
|
||||
+Hard-coded path to the rpmkeys(8) tool is ``/usr/lib/pqrpm/bin/rpmkeys``.
|
||||
+
|
||||
+This plugin respects ``gpgkey`` and ``gpgcheck`` fields in a repository
|
||||
+configuration. See dnf.conf(5) for more details.
|
||||
+
|
||||
+-----
|
||||
+Files
|
||||
+-----
|
||||
+
|
||||
+``/usr/lib/pqrpm/lib/sysimage/rpm``
|
||||
+ A location of the key store defined by ``/usr/lib/pqrpm/bin/rpmkeys``
|
||||
+ tool.
|
||||
+
|
||||
+--------
|
||||
+See Also
|
||||
+--------
|
||||
+
|
||||
+* :manpage:`dnf.conf(5)`
|
||||
+* :manpage:`dnf(8)`
|
||||
+* :manpage:`rpmkeys(8)`
|
||||
+
|
||||
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
|
||||
index d004e5e..a84a786 100644
|
||||
--- a/plugins/CMakeLists.txt
|
||||
+++ b/plugins/CMakeLists.txt
|
||||
@@ -14,6 +14,9 @@ endif()
|
||||
if (${PYTHON_VERSION_MAJOR} STREQUAL "2")
|
||||
INSTALL (FILES migrate.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
|
||||
endif()
|
||||
+if (${PYTHON_VERSION_MAJOR} STREQUAL "3")
|
||||
+INSTALL (FILES multisig.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
|
||||
+endif()
|
||||
INSTALL (FILES needs_restarting.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
|
||||
INSTALL (FILES post-transaction-actions.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
|
||||
INSTALL (FILES repoclosure.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
|
||||
diff --git a/plugins/multisig.py b/plugins/multisig.py
|
||||
new file mode 100644
|
||||
index 0000000..8735a26
|
||||
--- /dev/null
|
||||
+++ b/plugins/multisig.py
|
||||
@@ -0,0 +1,402 @@
|
||||
+from __future__ import print_function, absolute_import, unicode_literals
|
||||
+import dnf
|
||||
+import dnf.crypto
|
||||
+import dnf.dnssec
|
||||
+import dnf.exceptions
|
||||
+from dnf.i18n import ucd
|
||||
+import dnf.rpm.transaction
|
||||
+import dnf.transaction
|
||||
+from dnfpluginscore import _, logger
|
||||
+import os
|
||||
+import subprocess
|
||||
+import sys
|
||||
+
|
||||
+class MultiSig(dnf.Plugin):
|
||||
+ """
|
||||
+ This plugin verifies signatures of RPM packages by executing an
|
||||
+ extraordinary "rpmkeys" tool. That tool can, for example, support multiple
|
||||
+ RPM v6 signatures, or signature schemata uknown to the ordinary,
|
||||
+ system-wide rpmkeys tool.
|
||||
+
|
||||
+ This verification is perfmored in addition to the standard verification
|
||||
+ performed by DNF.
|
||||
+ """
|
||||
+
|
||||
+ name = "multisig"
|
||||
+
|
||||
+ def __init__(self, base, cli):
|
||||
+ super(MultiSig, self).__init__(base, cli)
|
||||
+ # Path to the rpmkeys executable
|
||||
+ self.rpmkeys_executable = "/usr/lib/pqrpm/bin/rpmkeys"
|
||||
+ # List of repositories whose keys we have tried importing so far
|
||||
+ # during a run of this plugin.
|
||||
+ self._repo_set_imported_gpg_keys = [];
|
||||
+
|
||||
+ def pre_transaction(self):
|
||||
+ inbound_packages = []
|
||||
+ for ts_item in self.base.transaction:
|
||||
+ if ts_item.action in dnf.transaction.FORWARD_ACTIONS:
|
||||
+ inbound_packages.append(ts_item.pkg);
|
||||
+ self.gpgsigcheck(inbound_packages)
|
||||
+
|
||||
+ def _process_rpm_output(self, data):
|
||||
+ # No signatures or digests = corrupt package.
|
||||
+ # There is at least one line for -: and another (empty) entry after the
|
||||
+ # last newline.
|
||||
+ if len(data) < 3 or data[0] != b'-:' or data[-1]:
|
||||
+ return 2
|
||||
+ seen_sig, missing_key, not_trusted, not_signed = False, False, False, False
|
||||
+ for i in data[1:-1]:
|
||||
+ if b': BAD' in i:
|
||||
+ return 2
|
||||
+ elif i.endswith(b': NOKEY'):
|
||||
+ missing_key = True
|
||||
+ elif i.endswith(b': NOTTRUSTED'):
|
||||
+ not_trusted = True
|
||||
+ elif i.endswith(b': NOTFOUND'):
|
||||
+ not_signed = True
|
||||
+ elif not i.endswith(b': OK'):
|
||||
+ return 2
|
||||
+ if not_trusted:
|
||||
+ return 3
|
||||
+ elif missing_key:
|
||||
+ return 1
|
||||
+ elif not_signed:
|
||||
+ return 4
|
||||
+ # we still check return code, so this is safe
|
||||
+ return 0
|
||||
+
|
||||
+ def _verifyPackageUsingRpmkeys(self, package, installroot):
|
||||
+ # "--define=_pkgverify_level signature" enforces signature checking;
|
||||
+ # "--define=_pkgverify_flags 0x0" ensures that all signatures are checked.
|
||||
+ args = (self.rpmkeys_executable,
|
||||
+ '--checksig', '--root', installroot, '--verbose',
|
||||
+ '--define=_pkgverify_level signature', '--define=_pkgverify_flags 0x0',
|
||||
+ '-')
|
||||
+ env = dict(os.environ)
|
||||
+ env['LC_ALL'] = 'C'
|
||||
+ with subprocess.Popen(
|
||||
+ args=args,
|
||||
+ executable=self.rpmkeys_executable,
|
||||
+ env=env,
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ cwd='/',
|
||||
+ stdin=package) as p:
|
||||
+ data = p.communicate()[0]
|
||||
+ returncode = p.returncode
|
||||
+ if type(returncode) is not int:
|
||||
+ raise AssertionError('Popen set return code to non-int')
|
||||
+ # rpmkeys can return something other than 0 or 1 in the case of a
|
||||
+ # fatal error (OOM, abort() called, SIGSEGV, etc)
|
||||
+ if returncode >= 2 or returncode < 0:
|
||||
+ return 2
|
||||
+ ret = self._process_rpm_output(data.split(b'\n'))
|
||||
+ if ret:
|
||||
+ return ret
|
||||
+ return 2 if returncode else 0
|
||||
+
|
||||
+ def _checkSig(self, installroot, package):
|
||||
+ """Takes a transaction set and a package, check it's sigs,
|
||||
+ return 0 if they are all fine
|
||||
+ return 1 if the gpg key can't be found
|
||||
+ return 2 if the header is in someway damaged
|
||||
+ return 3 if the key is not trusted
|
||||
+ return 4 if the pkg is not gpg or pgp signed"""
|
||||
+
|
||||
+ fdno = os.open(package, os.O_RDONLY|os.O_NOCTTY|os.O_CLOEXEC)
|
||||
+ try:
|
||||
+ value = self._verifyPackageUsingRpmkeys(fdno, installroot)
|
||||
+ finally:
|
||||
+ os.close(fdno)
|
||||
+ return value
|
||||
+
|
||||
+ def _sig_check_pkg(self, po):
|
||||
+ """Verify the GPG signature of the given package object.
|
||||
+
|
||||
+ :param po: the package object to verify the signature of
|
||||
+ :return: (result, error_string)
|
||||
+ where result is::
|
||||
+
|
||||
+ 0 = GPG signature verifies ok or verification is not required.
|
||||
+ 1 = GPG verification failed but installation of the right GPG key
|
||||
+ might help.
|
||||
+ 2 = Fatal GPG verification error, give up.
|
||||
+ """
|
||||
+ if po._from_cmdline:
|
||||
+ check = self.base.conf.localpkg_gpgcheck
|
||||
+ hasgpgkey = 0
|
||||
+ else:
|
||||
+ repo = self.base.repos[po.repoid]
|
||||
+ check = repo.gpgcheck
|
||||
+ hasgpgkey = not not repo.gpgkey
|
||||
+
|
||||
+ localfn = os.path.basename(po.localPkg())
|
||||
+ if check:
|
||||
+ logger.debug(_("Multisig: verifying: {}").format(po.localPkg()))
|
||||
+ sigresult = self._checkSig(self.base.conf.installroot, po.localPkg())
|
||||
+ if sigresult == 0:
|
||||
+ result = 0
|
||||
+ msg = _('All signatures for %s successfully verified') % localfn
|
||||
+
|
||||
+ elif sigresult == 1:
|
||||
+ if hasgpgkey:
|
||||
+ result = 1
|
||||
+ else:
|
||||
+ result = 2
|
||||
+ msg = _('Public key for %s is not installed') % localfn
|
||||
+
|
||||
+ elif sigresult == 2:
|
||||
+ result = 2
|
||||
+ msg = _('Problem opening package %s') % localfn
|
||||
+
|
||||
+ elif sigresult == 3:
|
||||
+ if hasgpgkey:
|
||||
+ result = 1
|
||||
+ else:
|
||||
+ result = 2
|
||||
+ result = 1
|
||||
+ msg = _('Public key for %s is not trusted') % localfn
|
||||
+
|
||||
+ elif sigresult == 4:
|
||||
+ result = 2
|
||||
+ msg = _('Package %s is not signed') % localfn
|
||||
+
|
||||
+ else:
|
||||
+ result = 0
|
||||
+ msg = _('Signature verification for %s is disabled') % localfn
|
||||
+
|
||||
+ logger.debug(_("Multisig: verification result: {} (code={})").format(msg, result))
|
||||
+ return result, msg
|
||||
+
|
||||
+ def keyInstalled(self, fingerprint):
|
||||
+ '''
|
||||
+ Return if the GPG key described by the given fingerprint is installed
|
||||
+ in the multisig keyring.
|
||||
+
|
||||
+ Return values:
|
||||
+ - True key is installed
|
||||
+ - False otherwise
|
||||
+ Trows: If rpmkeys program could not been executed.
|
||||
+
|
||||
+ No effort is made to handle duplicates.
|
||||
+ '''
|
||||
+ # XXX: rpmkeys expects lowercase
|
||||
+ # <https://github.com/rpm-software-management/rpm/issues/3721>
|
||||
+ logger.debug(_("Multisig: Checking a presence of key={}").format(fingerprint))
|
||||
+ args = (self.rpmkeys_executable,
|
||||
+ '--root', self.base.conf.installroot,
|
||||
+ '--list', fingerprint.lower())
|
||||
+ p = subprocess.run(
|
||||
+ args=args,
|
||||
+ executable=self.rpmkeys_executable,
|
||||
+ cwd='/',
|
||||
+ stdin=subprocess.DEVNULL,
|
||||
+ stdout=subprocess.DEVNULL,
|
||||
+ stderr=subprocess.DEVNULL)
|
||||
+ return p.returncode == 0
|
||||
+
|
||||
+ def importKey(self, key):
|
||||
+ '''
|
||||
+ Import given Key object into the multisig keyring.
|
||||
+
|
||||
+ Return values:
|
||||
+ - True key imported successfully
|
||||
+ - False otherwise
|
||||
+ Trows: If rpmkeys program could not been executed.
|
||||
+
|
||||
+ What happens if a key's raw_string contains multiple public key
|
||||
+ packets, or if the key was already in the keyring is unspecified and
|
||||
+ it depends on rpmkeys behavior. Current rpmkeys implementation
|
||||
+ gracefully ignores (or updates?) existing keys.
|
||||
+ '''
|
||||
+ args = (self.rpmkeys_executable,
|
||||
+ '--root', self.base.conf.installroot,
|
||||
+ '--import', '-')
|
||||
+ env = dict(os.environ)
|
||||
+ env['LC_ALL'] = 'C'
|
||||
+ with subprocess.Popen(
|
||||
+ executable=self.rpmkeys_executable,
|
||||
+ args=args,
|
||||
+ env=env,
|
||||
+ cwd='/',
|
||||
+ # XXX: rpmkeys used to fail reading from a pipe. Fix at
|
||||
+ # <https://github.com/rpm-software-management/rpm/pull/3706>.
|
||||
+ stdin=subprocess.PIPE,
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ stderr=subprocess.PIPE) as p:
|
||||
+ stdout, stderr = p.communicate(input=key.raw_key)
|
||||
+ returncode = p.returncode
|
||||
+ if type(returncode) is not int:
|
||||
+ raise AssertionError('Popen set return code to non-int')
|
||||
+ logger.debug(_("Multisig: Key import result: exitcode={}, stdout={}, stderr={}").format(
|
||||
+ returncode, stdout, stderr))
|
||||
+ return returncode == 0
|
||||
+
|
||||
+ def _get_key_for_package(self, po, askcb=None, fullaskcb=None):
|
||||
+ """Retrieve a key for a package. If needed, use the given
|
||||
+ callback to prompt whether the key should be imported.
|
||||
+
|
||||
+ :param po: the package object to retrieve the key of
|
||||
+ :param askcb: Callback function to use to ask permission to
|
||||
+ import a key. The arguments *askcb* should take are the
|
||||
+ package object, the userid of the key, and the keyid
|
||||
+ :param fullaskcb: Callback function to use to ask permission to
|
||||
+ import a key. This differs from *askcb* in that it gets
|
||||
+ passed a dictionary so that we can expand the values passed.
|
||||
+ :raises: :class:`dnf.exceptions.Error` if there are errors
|
||||
+ retrieving the keys
|
||||
+ """
|
||||
+ if po._from_cmdline:
|
||||
+ # raise an exception, because po.repoid is not in self.repos
|
||||
+ msg = _('Unable to retrieve a key for a commandline package: %s')
|
||||
+ raise ValueError(msg % po)
|
||||
+
|
||||
+ repo = self.base.repos[po.repoid]
|
||||
+ key_installed = repo.id in self._repo_set_imported_gpg_keys
|
||||
+ keyurls = [] if key_installed else repo.gpgkey
|
||||
+
|
||||
+ def _prov_key_data(msg):
|
||||
+ msg += _('. Failing package is: %s') % (po) + '\n '
|
||||
+ msg += _('GPG Keys are configured as: %s') % \
|
||||
+ (', '.join(repo.gpgkey))
|
||||
+ return msg
|
||||
+
|
||||
+ user_cb_fail = False
|
||||
+ self._repo_set_imported_gpg_keys.append(repo.id)
|
||||
+ for keyurl in keyurls:
|
||||
+ keys = dnf.crypto.retrieve(keyurl, repo)
|
||||
+
|
||||
+ for info in keys:
|
||||
+ # Check if key is already installed
|
||||
+ if self.keyInstalled(info.fingerprint):
|
||||
+ msg = _('GPG key at %s (0x%s) is already installed')
|
||||
+ logger.info(msg, keyurl, info.short_id)
|
||||
+ continue
|
||||
+
|
||||
+ # DNS Extension: create a key object, pass it to the verification class
|
||||
+ # and print its result as an advice to the user.
|
||||
+ if self.base.conf.gpgkey_dns_verification:
|
||||
+ dns_input_key = dnf.dnssec.KeyInfo.from_rpm_key_object(info.userid,
|
||||
+ info.raw_key)
|
||||
+ dns_result = dnf.dnssec.DNSSECKeyVerification.verify(dns_input_key)
|
||||
+ logger.info(dnf.dnssec.nice_user_msg(dns_input_key, dns_result))
|
||||
+
|
||||
+ # Try installing/updating GPG key
|
||||
+ info.url = keyurl
|
||||
+ if self.base.conf.gpgkey_dns_verification:
|
||||
+ dnf.crypto.log_dns_key_import(info, dns_result)
|
||||
+ else:
|
||||
+ dnf.crypto.log_key_import(info)
|
||||
+ rc = False
|
||||
+ if self.base.conf.assumeno:
|
||||
+ rc = False
|
||||
+ elif self.base.conf.assumeyes:
|
||||
+ # DNS Extension: We assume, that the key is trusted in case it is valid,
|
||||
+ # its existence is explicitly denied or in case the domain is not signed
|
||||
+ # and therefore there is no way to know for sure (this is mainly for
|
||||
+ # backward compatibility)
|
||||
+ # FAQ:
|
||||
+ # * What is PROVEN_NONEXISTENCE?
|
||||
+ # In DNSSEC, your domain does not need to be signed, but this state
|
||||
+ # (not signed) has to be proven by the upper domain. e.g. when example.com.
|
||||
+ # is not signed, com. servers have to sign the message, that example.com.
|
||||
+ # does not have any signing key (KSK to be more precise).
|
||||
+ if self.base.conf.gpgkey_dns_verification:
|
||||
+ if dns_result in (dnf.dnssec.Validity.VALID,
|
||||
+ dnf.dnssec.Validity.PROVEN_NONEXISTENCE):
|
||||
+ rc = True
|
||||
+ logger.info(dnf.dnssec.any_msg(_("The key has been approved.")))
|
||||
+ else:
|
||||
+ rc = False
|
||||
+ logger.info(dnf.dnssec.any_msg(_("The key has been rejected.")))
|
||||
+ else:
|
||||
+ rc = True
|
||||
+
|
||||
+ # grab the .sig/.asc for the keyurl, if it exists if it
|
||||
+ # does check the signature on the key if it is signed by
|
||||
+ # one of our ca-keys for this repo or the global one then
|
||||
+ # rc = True else ask as normal.
|
||||
+
|
||||
+ elif fullaskcb:
|
||||
+ rc = fullaskcb({"po": po, "userid": info.userid,
|
||||
+ "hexkeyid": info.short_id,
|
||||
+ "keyurl": keyurl,
|
||||
+ "fingerprint": info.fingerprint,
|
||||
+ "timestamp": info.timestamp})
|
||||
+ elif askcb:
|
||||
+ rc = askcb(po, info.userid, info.short_id)
|
||||
+
|
||||
+ if not rc:
|
||||
+ user_cb_fail = True
|
||||
+ continue
|
||||
+
|
||||
+ # Import the key
|
||||
+ # XXX: raw_key of second info erroneously contains first and
|
||||
+ # second key. Probably a bug in key parser.
|
||||
+ #logger.debug(_("Multisig: Importing a key: {}").format(info.raw_key))
|
||||
+ result = self.importKey(info)
|
||||
+ if result == False:
|
||||
+ msg = _('Key import failed')
|
||||
+ raise dnf.exceptions.Error(_prov_key_data(msg))
|
||||
+ logger.info(_('Key imported successfully'))
|
||||
+ key_installed = True
|
||||
+
|
||||
+ if not key_installed and user_cb_fail:
|
||||
+ raise dnf.exceptions.Error(_("Didn't install any keys"))
|
||||
+
|
||||
+ if not key_installed:
|
||||
+ msg = _('The GPG keys listed for the "%s" repository are '
|
||||
+ 'already installed but they are not correct for this '
|
||||
+ 'package.\n'
|
||||
+ 'Check that the correct key URLs are configured for '
|
||||
+ 'this repository.') % repo.name
|
||||
+ raise dnf.exceptions.Error(_prov_key_data(msg))
|
||||
+
|
||||
+ # Check if the newly installed keys helped
|
||||
+ result, errmsg = self._sig_check_pkg(po)
|
||||
+ if result != 0:
|
||||
+ if keyurls:
|
||||
+ msg = _("Import of key(s) didn't help, wrong key(s)?")
|
||||
+ logger.info(msg)
|
||||
+ errmsg = ucd(errmsg)
|
||||
+ raise dnf.exceptions.Error(_prov_key_data(errmsg))
|
||||
+
|
||||
+ def gpgsigcheck(self, pkgs):
|
||||
+ """Perform GPG signature verification on the given packages,
|
||||
+ installing keys if possible.
|
||||
+
|
||||
+ :param pkgs: a list of package objects to verify the GPG
|
||||
+ signatures of
|
||||
+ :raises: Will raise :class:`Error` if there's a problem
|
||||
+ """
|
||||
+ error_messages = []
|
||||
+ for po in pkgs:
|
||||
+ result, errmsg = self._sig_check_pkg(po)
|
||||
+
|
||||
+ if result == 0:
|
||||
+ # Verified ok, or verify not req'd
|
||||
+ continue
|
||||
+
|
||||
+ elif result == 1:
|
||||
+ ay = self.base.conf.assumeyes and not self.base.conf.assumeno
|
||||
+ if (not sys.stdin or not sys.stdin.isatty()) and not ay:
|
||||
+ raise dnf.exceptions.Error(_('Refusing to automatically import keys when running ' \
|
||||
+ 'unattended.\nUse "-y" to override.'))
|
||||
+
|
||||
+ # the callback here expects to be able to take options which
|
||||
+ # userconfirm really doesn't... so fake it
|
||||
+ fn = lambda x, y, z: self.base.output.userconfirm()
|
||||
+ try:
|
||||
+ self._get_key_for_package(po, fn)
|
||||
+ except (dnf.exceptions.Error, ValueError) as e:
|
||||
+ error_messages.append(str(e))
|
||||
+
|
||||
+ else:
|
||||
+ # Fatal error
|
||||
+ error_messages.append(errmsg)
|
||||
+
|
||||
+ if error_messages:
|
||||
+ for msg in error_messages:
|
||||
+ logger.critical(msg)
|
||||
+ raise dnf.exceptions.Error(_("GPG check FAILED"))
|
||||
+
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -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
|
||||
|
||||
242
SOURCES/0024-multisig-Do-not-parse-OpenPGP-keys.patch
Normal file
242
SOURCES/0024-multisig-Do-not-parse-OpenPGP-keys.patch
Normal file
@ -0,0 +1,242 @@
|
||||
From 3fd00a0bf41ac2c9342e0ba1d8550ee1ac5f2604 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||
Date: Fri, 12 Sep 2025 18:12:38 +0200
|
||||
Subject: [PATCH] multisig: Do not parse OpenPGP keys
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If a key in OpenPGP version 6 format format was defined for
|
||||
a repository, the key was always omitted and never imported to pqrpm
|
||||
key store. As a result, packages signed with that key could not be
|
||||
verified:
|
||||
|
||||
[...]
|
||||
Importing GPG key 0xC9D3B13C:
|
||||
Userid : "rsa4k_user"
|
||||
Fingerprint: CE77 8FBE 1E8D 4DD2 7691 FB33 CA58 1189 C9D3 B13C
|
||||
From : /root/repo/rsa4k.cert
|
||||
Key imported successfully
|
||||
foo 16 MB/s | 16 kB 00:00
|
||||
Import of key(s) didn't help, wrong key(s)?
|
||||
Public key for foo-1.0-1.noarch.rpm is not installed. Failing package is: foo-1.0-1.noarch
|
||||
GPG Keys are configured as: file:///root/repo/rsa4k.cert, file:///root/repo/mldsa87.cert
|
||||
Error: GPG check FAILED
|
||||
|
||||
The cause was that multisig plugin called dnf.crypto.retrieve() to
|
||||
obtain a list of OpenPGP objects from the gpgkey URLs. That DNF
|
||||
function uses dnf.crypto.rawkey2infos() to parse the OpenPGP packets
|
||||
with a gpgme library. But library does not support OpenPGPv6. As
|
||||
a result, multisig got an empty list of OpenPGP objects and dis not
|
||||
import any key in OpenPGPv6 format into pqrm key store.
|
||||
|
||||
Considering that the only available OpenPGPv6 parser is rpm-sequoia
|
||||
library wrapped by pqrpm's librpmio library, and this plugin cannot
|
||||
load them into its name space not to clash with the system librpmio
|
||||
library, an ideal fix would have to develop standalone executable on
|
||||
top of them and parse it output by this plugin. And considering that
|
||||
best code is no code,
|
||||
|
||||
I removed printing any details about the imported keys from this
|
||||
plugin. The only details about the key this plugin now prints is URL
|
||||
or local path to the key file:
|
||||
|
||||
Importing GPG keys from: /root/repos/opgp6/mldsa65.cert
|
||||
Is this ok [y/N]: y
|
||||
Key imported successfully
|
||||
|
||||
Because the user ID and key ID were also required for DNSSEC
|
||||
validation, I had to remove that code. This patch also removes all
|
||||
code that became unreachable because of this fix.
|
||||
|
||||
Another downside is that now the plugin cannot does not check whether
|
||||
a key has already been imported, resulting always asking a using for
|
||||
importing the keys associated with a repository the unverifiable
|
||||
package comes from.
|
||||
|
||||
Resolve: https://issues.redhat.com/browse/RHEL-114424
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
plugins/multisig.py | 115 +++++++++++++++-----------------------------
|
||||
1 file changed, 40 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/plugins/multisig.py b/plugins/multisig.py
|
||||
index 8735a26..f29e41f 100644
|
||||
--- a/plugins/multisig.py
|
||||
+++ b/plugins/multisig.py
|
||||
@@ -1,16 +1,26 @@
|
||||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
import dnf
|
||||
-import dnf.crypto
|
||||
-import dnf.dnssec
|
||||
import dnf.exceptions
|
||||
from dnf.i18n import ucd
|
||||
import dnf.rpm.transaction
|
||||
import dnf.transaction
|
||||
+import dnf.util
|
||||
from dnfpluginscore import _, logger
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
+class MultiSigKey(object):
|
||||
+ def __init__(self, data, url):
|
||||
+ self.id_ = None
|
||||
+ self.fingerprint = None
|
||||
+ self.timestamp = None
|
||||
+ self.raw_key = data
|
||||
+ self.url = url
|
||||
+ self.userid = None
|
||||
+ self.short_id = None
|
||||
+ self.rpm_id = None
|
||||
+
|
||||
class MultiSig(dnf.Plugin):
|
||||
"""
|
||||
This plugin verifies signatures of RPM packages by executing an
|
||||
@@ -168,33 +178,6 @@ class MultiSig(dnf.Plugin):
|
||||
logger.debug(_("Multisig: verification result: {} (code={})").format(msg, result))
|
||||
return result, msg
|
||||
|
||||
- def keyInstalled(self, fingerprint):
|
||||
- '''
|
||||
- Return if the GPG key described by the given fingerprint is installed
|
||||
- in the multisig keyring.
|
||||
-
|
||||
- Return values:
|
||||
- - True key is installed
|
||||
- - False otherwise
|
||||
- Trows: If rpmkeys program could not been executed.
|
||||
-
|
||||
- No effort is made to handle duplicates.
|
||||
- '''
|
||||
- # XXX: rpmkeys expects lowercase
|
||||
- # <https://github.com/rpm-software-management/rpm/issues/3721>
|
||||
- logger.debug(_("Multisig: Checking a presence of key={}").format(fingerprint))
|
||||
- args = (self.rpmkeys_executable,
|
||||
- '--root', self.base.conf.installroot,
|
||||
- '--list', fingerprint.lower())
|
||||
- p = subprocess.run(
|
||||
- args=args,
|
||||
- executable=self.rpmkeys_executable,
|
||||
- cwd='/',
|
||||
- stdin=subprocess.DEVNULL,
|
||||
- stdout=subprocess.DEVNULL,
|
||||
- stderr=subprocess.DEVNULL)
|
||||
- return p.returncode == 0
|
||||
-
|
||||
def importKey(self, key):
|
||||
'''
|
||||
Import given Key object into the multisig keyring.
|
||||
@@ -232,6 +215,28 @@ class MultiSig(dnf.Plugin):
|
||||
returncode, stdout, stderr))
|
||||
return returncode == 0
|
||||
|
||||
+ def retrieve(self, keyurl, repo=None):
|
||||
+ """Retrieve a content of a key file specified by the URL using
|
||||
+ repository's proxy configuration.
|
||||
+
|
||||
+ :param keyurl URL of the key file
|
||||
+ :param repo repository object
|
||||
+ :returns: list of MultiSigKey objects populated from the key file
|
||||
+ """
|
||||
+ if keyurl.startswith('http:'):
|
||||
+ logger.warning(_("retrieving repo key for %s unencrypted from %s"), repo.id, keyurl)
|
||||
+ with dnf.util._urlopen(keyurl, repo=repo) as handle:
|
||||
+ # This is a place for parsing the key file and populating key ID etc.
|
||||
+ keyinfos = [MultiSigKey(handle.read(), keyurl)]
|
||||
+ return keyinfos
|
||||
+
|
||||
+ def log_key_import(self, keyinfo):
|
||||
+ """Print and log details about keys to be imported.
|
||||
+ """
|
||||
+ msg = (_('Importing GPG keys from: %s') %
|
||||
+ (keyinfo.url.replace("file://", "")))
|
||||
+ logger.critical("%s", msg)
|
||||
+
|
||||
def _get_key_for_package(self, po, askcb=None, fullaskcb=None):
|
||||
"""Retrieve a key for a package. If needed, use the given
|
||||
callback to prompt whether the key should be imported.
|
||||
@@ -264,53 +269,17 @@ class MultiSig(dnf.Plugin):
|
||||
user_cb_fail = False
|
||||
self._repo_set_imported_gpg_keys.append(repo.id)
|
||||
for keyurl in keyurls:
|
||||
- keys = dnf.crypto.retrieve(keyurl, repo)
|
||||
+ keys = self.retrieve(keyurl, repo)
|
||||
|
||||
for info in keys:
|
||||
- # Check if key is already installed
|
||||
- if self.keyInstalled(info.fingerprint):
|
||||
- msg = _('GPG key at %s (0x%s) is already installed')
|
||||
- logger.info(msg, keyurl, info.short_id)
|
||||
- continue
|
||||
-
|
||||
- # DNS Extension: create a key object, pass it to the verification class
|
||||
- # and print its result as an advice to the user.
|
||||
- if self.base.conf.gpgkey_dns_verification:
|
||||
- dns_input_key = dnf.dnssec.KeyInfo.from_rpm_key_object(info.userid,
|
||||
- info.raw_key)
|
||||
- dns_result = dnf.dnssec.DNSSECKeyVerification.verify(dns_input_key)
|
||||
- logger.info(dnf.dnssec.nice_user_msg(dns_input_key, dns_result))
|
||||
-
|
||||
# Try installing/updating GPG key
|
||||
info.url = keyurl
|
||||
- if self.base.conf.gpgkey_dns_verification:
|
||||
- dnf.crypto.log_dns_key_import(info, dns_result)
|
||||
- else:
|
||||
- dnf.crypto.log_key_import(info)
|
||||
+ self.log_key_import(info)
|
||||
rc = False
|
||||
if self.base.conf.assumeno:
|
||||
rc = False
|
||||
elif self.base.conf.assumeyes:
|
||||
- # DNS Extension: We assume, that the key is trusted in case it is valid,
|
||||
- # its existence is explicitly denied or in case the domain is not signed
|
||||
- # and therefore there is no way to know for sure (this is mainly for
|
||||
- # backward compatibility)
|
||||
- # FAQ:
|
||||
- # * What is PROVEN_NONEXISTENCE?
|
||||
- # In DNSSEC, your domain does not need to be signed, but this state
|
||||
- # (not signed) has to be proven by the upper domain. e.g. when example.com.
|
||||
- # is not signed, com. servers have to sign the message, that example.com.
|
||||
- # does not have any signing key (KSK to be more precise).
|
||||
- if self.base.conf.gpgkey_dns_verification:
|
||||
- if dns_result in (dnf.dnssec.Validity.VALID,
|
||||
- dnf.dnssec.Validity.PROVEN_NONEXISTENCE):
|
||||
- rc = True
|
||||
- logger.info(dnf.dnssec.any_msg(_("The key has been approved.")))
|
||||
- else:
|
||||
- rc = False
|
||||
- logger.info(dnf.dnssec.any_msg(_("The key has been rejected.")))
|
||||
- else:
|
||||
- rc = True
|
||||
+ rc = True
|
||||
|
||||
# grab the .sig/.asc for the keyurl, if it exists if it
|
||||
# does check the signature on the key if it is signed by
|
||||
@@ -318,11 +287,8 @@ class MultiSig(dnf.Plugin):
|
||||
# rc = True else ask as normal.
|
||||
|
||||
elif fullaskcb:
|
||||
- rc = fullaskcb({"po": po, "userid": info.userid,
|
||||
- "hexkeyid": info.short_id,
|
||||
- "keyurl": keyurl,
|
||||
- "fingerprint": info.fingerprint,
|
||||
- "timestamp": info.timestamp})
|
||||
+ rc = fullaskcb({"po": po,
|
||||
+ "keyurl": keyurl})
|
||||
elif askcb:
|
||||
rc = askcb(po, info.userid, info.short_id)
|
||||
|
||||
@@ -331,8 +297,7 @@ class MultiSig(dnf.Plugin):
|
||||
continue
|
||||
|
||||
# Import the key
|
||||
- # XXX: raw_key of second info erroneously contains first and
|
||||
- # second key. Probably a bug in key parser.
|
||||
+ # XXX: raw_key contains all keys found in the key file.
|
||||
#logger.debug(_("Multisig: Importing a key: {}").format(info.raw_key))
|
||||
result = self.importKey(info)
|
||||
if result == False:
|
||||
--
|
||||
2.51.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
%{?!dnf_lowest_compatible: %global dnf_lowest_compatible 4.7.0-6}
|
||||
%{?!dnf_lowest_compatible: %global dnf_lowest_compatible 4.11.0}
|
||||
%global dnf_plugins_extra 2.0.0
|
||||
%global hawkey_version 0.63.0-6
|
||||
%global hawkey_version 0.64.0
|
||||
%global yum_utils_subpackage_name dnf-utils
|
||||
%if 0%{?rhel} > 7
|
||||
%global yum_utils_subpackage_name yum-utils
|
||||
@ -33,49 +33,33 @@
|
||||
%endif
|
||||
|
||||
Name: dnf-plugins-core
|
||||
Version: 4.0.21
|
||||
Release: 25%{?dist}
|
||||
Version: 4.3.0
|
||||
Release: 23%{?dist}
|
||||
Summary: Core Plugins for DNF
|
||||
License: GPLv2+
|
||||
URL: https://github.com/rpm-software-management/dnf-plugins-core
|
||||
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
|
||||
Patch1: 0001-versionlock-Do-not-exclude-locked-obsoleters-RhBug1957280.patch
|
||||
Patch2: 0002-repomanage-Allow-running-only-with-metadata.patch
|
||||
Patch3: 0003-repomanage-Enhance-repomanage-documentation-RhBug1898293.patch
|
||||
Patch4: 0004-copr-dont-traceback-on-empty-lines-in-etcos-release.patch
|
||||
Patch5: 0005-reposync-Use-fail_fastFalse-when-downloading-packages-RhBug2009894.patch
|
||||
Patch6: 0006-copr-migrate-all-calls-to-APIv3.patch
|
||||
Patch7: 0007-groups-manager-More-benevolent-resolving-of-packages-RhBug2013633.patch
|
||||
Patch8: 0008-versionlock-fix-multi-pkg-lock-RhBug2013324.patch
|
||||
Patch9: 0009-Update-documentation-for-adding-specific-version-RhBug2013332.patch
|
||||
Patch10: 0010-needs-restarting-Fix-wrong-boot-time-RhBug1960437.patch
|
||||
Patch11: 0011-Add-new-command-modulesync-RhBug1868047.patch
|
||||
Patch12: 0012-Update-translations-RhBug-2017271.patch
|
||||
Patch13: 0013-repomanage-Use-modules-only-from-repo-they-are-handl.patch
|
||||
Patch14: 0014-feat-repomanage-Add-new-option-oldonly.patch
|
||||
Patch15: 0015-Skip-all-non-rpm-tsi-for-transaction_action-plugins-.patch
|
||||
Patch16: 0016-Fix-dnf-copr-enable-on-Fedora-35.patch
|
||||
Patch17: 0017-Disable-dnf-playground-command.patch
|
||||
Patch18: 0018-Fix-baseurl-for-centos-stream-chroot.patch
|
||||
Patch19: 0019-Silence-a-deprecation-warning-in-plugins-copr.py.patch
|
||||
Patch20: 0020-Shorter-verification-that-the-project-exists.patch
|
||||
Patch21: 0021-Better-error-message-for-dnf-copr-enable.patch
|
||||
Patch22: 0022-copr-allow-specifying-protocol-as-part-of-hub.patch
|
||||
Patch23: 0023-copr-Guess-EPEL-chroots-for-CentOS-Stream-RhBug-2058.patch
|
||||
Patch24: 0024-builddep-Warning-when-using-macros-with-source-rpms-.patch
|
||||
Patch25: 0025-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch
|
||||
Patch26: 0026-Add-a-warning-when-using-system-upgrade-on-RHEL.patch
|
||||
Patch27: 0027-offline-upgrade-Add-security-filters.patch
|
||||
Patch28: 0028-system-upgrade-Show-warning-always-for-a-downstream.patch
|
||||
Patch29: 0029-Update-translations.patch
|
||||
Patch30: 0030-versionlock-Use-only-most-specif-NEVRA-RhBug-1961217.patch
|
||||
Patch31: 0031-Fix-boot-time-derivation-for-systems-with-no-rtc.patch
|
||||
Patch32: 0032-Doc-update-for-reposync-RhBug-2132383-2182004.patch
|
||||
Patch33: 0033-Add-fix-and-test-assertion-for-no-systemd-unit-exist.patch
|
||||
Patch34: 0034-Fix-zlib-reboot-requirement-RhBug-2092033.patch
|
||||
Patch35: 0035-Fix-for-issue-with-binary-garbage-in-smaps-files.patch
|
||||
Patch36: 0036-needs-restarting-Add-microcode_ctl-to-a-reboot-list.patch
|
||||
|
||||
Patch1: 0001-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch
|
||||
Patch2: 0002-Add-a-warning-when-using-system-upgrade-on-RHEL.patch
|
||||
Patch3: 0003-offline-upgrade-Add-security-filters.patch
|
||||
Patch4: 0004-system-upgrade-Show-warning-always-for-a-downstream.patch
|
||||
Patch5: 0005-Update-translations.patch
|
||||
Patch6: 0006-Fix-boot-time-derivation-for-systems-with-no-rtc.patch
|
||||
Patch7: 0007-system-upgrade-Add-poweroff-option-to-reboot-subcomm.patch
|
||||
Patch8: 0008-Doc-update-for-reposync-RhBug-2132383-2182004.patch
|
||||
Patch9: 0009-Add-fix-and-test-assertion-for-no-systemd-unit-exist.patch
|
||||
Patch10: 0010-sys-upgrade_Wait_until_upgrade_done_before_poweoff.patch
|
||||
Patch11: 0011-Update-translations-RHEL-9.3.patch
|
||||
Patch12: 0012-RHEL-6394-Fix-incorrect-spanish-translation-file.patch
|
||||
Patch13: 0013-Fix-for-issue-with-binary-garbage-in-smaps-files.patch
|
||||
Patch14: 0014-needs-restarting-Add-microcode_ctl-to-a-reboot-list.patch
|
||||
Patch18: 0018-system-upgrade-change-http-to-https-in-unit-file.patch
|
||||
Patch19: 0019-reposync-Respect-norepopath-with-metadata-path.patch
|
||||
Patch20: 0020-needs-restarting-Get-boot-time-from-systemd-UnitsLoa.patch
|
||||
Patch21: 0021-dnf-copr-enable-on-Asahi-Fedora-Linux-Remix-guesses.patch
|
||||
Patch22: 0022-reposync-Avoid-multiple-downloads-of-duplicate-packa.patch
|
||||
Patch23: 0023-multisig-A-new-plugin-for-verifying-extraordinary-RP.patch
|
||||
Patch24: 0024-multisig-Do-not-parse-OpenPGP-keys.patch
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: cmake
|
||||
@ -250,7 +234,7 @@ repoquery, reposync, repotrack, repodiff, builddep, config-manager, debug,
|
||||
download and yum-groups-manager that use new implementations using DNF.
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} == 0 && %{with python2}
|
||||
%if %{with python2}
|
||||
%package -n python2-dnf-plugin-leaves
|
||||
Summary: Leaves Plugin for DNF
|
||||
Requires: python2-%{name} = %{version}-%{release}
|
||||
@ -269,7 +253,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}
|
||||
@ -339,6 +323,18 @@ Obsoletes: python-dnf-plugins-extras-migrate < %{dnf_plugins_extra}
|
||||
Migrate Plugin for DNF, Python 2 version. Migrates history, group and yumdb data from yum to dnf.
|
||||
%endif
|
||||
|
||||
%if %{with python3}
|
||||
%package -n python3-dnf-plugin-multisig
|
||||
Summary: Multisig Plugin for DNF
|
||||
Requires: pqrpm
|
||||
Requires: python3-%{name} = %{version}-%{release}
|
||||
Provides: dnf-plugin-multisig = %{version}-%{release}
|
||||
|
||||
%description -n python3-dnf-plugin-multisig
|
||||
Multisig Plugin for DNF, Python 3 version. The plugin verifies multiple RPMv6
|
||||
signatures on RPMv4 packages by using an external rpmkeys program.
|
||||
%endif
|
||||
|
||||
%if %{with python2}
|
||||
%package -n python2-dnf-plugin-post-transaction-actions
|
||||
Summary: Post transaction actions Plugin for DNF
|
||||
@ -367,7 +363,7 @@ Post 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}
|
||||
@ -388,7 +384,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}
|
||||
@ -718,8 +714,6 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%exclude %{_mandir}/man1/yum-utils.*
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} == 0
|
||||
|
||||
%if %{with python2}
|
||||
%files -n python2-dnf-plugin-leaves
|
||||
%{python2_sitelib}/dnf-plugins/leaves.*
|
||||
@ -733,18 +727,6 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%{_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
|
||||
@ -768,6 +750,13 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%exclude %{_mandir}/man8/dnf-migrate.*
|
||||
%endif
|
||||
|
||||
%if %{with python3}
|
||||
%files -n python3-dnf-plugin-multisig
|
||||
%{python3_sitelib}/dnf-plugins/multisig.*
|
||||
%{python3_sitelib}/dnf-plugins/__pycache__/multisig.*
|
||||
%{_mandir}/man8/dnf*-multisig.*
|
||||
%endif
|
||||
|
||||
%if %{with python2}
|
||||
%files -n python2-dnf-plugin-post-transaction-actions
|
||||
%config(noreplace) %{_sysconfdir}/dnf/plugins/post-transaction-actions.conf
|
||||
@ -785,8 +774,6 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%{_mandir}/man8/dnf-post-transaction-actions.*
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} == 0
|
||||
|
||||
%if %{with python2}
|
||||
%files -n python2-dnf-plugin-show-leaves
|
||||
%{python2_sitelib}/dnf-plugins/show_leaves.*
|
||||
@ -800,18 +787,6 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%{_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
|
||||
@ -851,108 +826,150 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Jan 15 2024 Petr Pisar <ppisar@redhat.com> - 4.0.21-25
|
||||
- Add microcode_ctl to a reboot list (RHEL-17356)
|
||||
* Mon Sep 15 2025 Petr Pisar <ppisar@redhat.com> - 4.3.0-23
|
||||
- Fix importing OpenPGPv6 keys (RHEL-114424)
|
||||
|
||||
* Mon Oct 16 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.0.21-24
|
||||
- Fix for strange issue with binary garbage in smaps files (RHEL-6392, RhBug:2212953)
|
||||
* Wed Jun 25 2025 Petr Pisar <ppisar@redhat.com> - 4.3.0-22
|
||||
- Add multisig plugin (RHEL-100157)
|
||||
|
||||
* Tue Jun 27 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.0.21-23
|
||||
- Add patch: Fix zlib reboot requirement (RhBug:2092033)
|
||||
* Tue Mar 11 2025 Marek Blaha <mblaha@redhat.com> - 4.3.0-21
|
||||
- reposync: Avoid multiple downloads of duplicate packages (RHEL-64320)
|
||||
- Fix bogus changelog entry date
|
||||
|
||||
* Wed May 31 2023 Nicola Sella <nsella@redhat.com> - 4.0.21-22
|
||||
* Mon Dec 16 2024 Jan Kolarik <jkolarik@redhat.com> - 4.3.0-20
|
||||
- Add forgotten changelog
|
||||
|
||||
* Mon Dec 16 2024 Jan Kolarik <jkolarik@redhat.com> - 4.3.0-19
|
||||
- Backport patch: "dnf copr enable" on "Asahi Fedora Linux Remix" guesses (RHEL-56143)
|
||||
|
||||
* Thu Nov 21 2024 Evan Goode <egoode@redhat.com> - 4.3.0-18
|
||||
- needs-restarting: Get boot time from systemd UnitsLoadStartTimestamp (RHEL-14900)
|
||||
|
||||
* Thu Oct 10 2024 Pavla Kratochvilova <pkratoch@redhat.com> - 4.3.0-17
|
||||
- reposync: Respect --norepopath with --metadata-path (RHEL-40914)
|
||||
|
||||
* Thu Jun 06 2024 Petr Pisar <ppisar@redhat.com> - 4.3.0-16
|
||||
- Revert needs-restarting prefers to obtain a boot time from systemd to deal
|
||||
with RTCs running in local time (RHEL-39775)
|
||||
|
||||
* Mon May 20 2024 Petr Pisar <ppisar@redhat.com> - 4.3.0-15
|
||||
- Fix a link to dnf-system-upgrade service documentation (RHEL-13053)
|
||||
|
||||
* Mon May 06 2024 Petr Pisar <ppisar@redhat.com> - 4.3.0-14
|
||||
- needs-restarting prefers to obtain a boot time from systemd to deal with
|
||||
RTCs running in local time (RHEL-14900)
|
||||
|
||||
* Mon Jan 15 2024 Petr Pisar <ppisar@redhat.com> - 4.3.0-13
|
||||
- Add microcode_ctl to a reboot list (RHEL-4600)
|
||||
|
||||
* Wed Oct 25 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.3.0-12
|
||||
- Fix incorrect spanish translation file (RHEL-6394)
|
||||
- Fix for strange issue with binary garbage in smaps files (RHEL-6420, RhBug:2231923)
|
||||
|
||||
* Fri Sep 08 2023 Marek Blaha <mblaha@redhat.com> - 4.3.0-11
|
||||
- Rebuild in correct target
|
||||
|
||||
* Thu Sep 07 2023 Marek Blaha <mblaha@redhat.com> - 4.3.0-10
|
||||
- Update translations RHEL 9.3
|
||||
|
||||
* Mon Jun 26 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.3.0-9
|
||||
- system-upgrade: Wait until the upgrade is done before poweroff (RhBug:2214510)
|
||||
|
||||
* Wed May 31 2023 Nicola Sella <nsella@redhat.com> - 4.3.0-8
|
||||
- Add fix and test assertion for "no systemd unit exists for pid"
|
||||
|
||||
* Fri May 19 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.0.21-21
|
||||
- Remove patch: "reposync: Implement --safe-write-path option (RhBug:1898089,2203766)" (RhBug:2208444)
|
||||
* Wed May 17 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.3.0-7
|
||||
- Remove patch: "reposync: Implement --safe-write-path option (RhBug:1898089,2203766)" (RhBug:2207946)
|
||||
|
||||
* Wed May 17 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.0.21-20
|
||||
- versionlock: Use only the most specific NEVRA (RhBug:1961217)
|
||||
* Mon May 15 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.3.0-6
|
||||
- Fix boot time derivation for systems with no rtc (RhBug:2166444,2182157)
|
||||
- system-upgrade: Add --poweroff option to reboot subcommand (RhBug:2157844)
|
||||
- Doc update for reposync (RhBug:2132383,2182004)
|
||||
- reposync: Implement --safe-write-path option (RhBug:1898089,2203766)
|
||||
- Enable the leaves and show-leaves DNF plugins (RhBug:2134638)
|
||||
|
||||
* Wed Mar 08 2023 Marek Blaha <mblaha@redhat.com> - 4.0.21-19
|
||||
* Wed Mar 15 2023 Marek Blaha <mblaha@redhat.com> - 4.3.0-5
|
||||
- Update translations
|
||||
|
||||
* Thu Jan 05 2023 Nicola Sella <nsella@redhat.com> - 4.0.21-18
|
||||
- Show downstream warning during system-upgrade
|
||||
* Fri Jan 06 2023 Nicola Sella <nsella@redhat.com> - 4.3.0-4
|
||||
- Remove requirement of python3-distro (fix specfile)
|
||||
|
||||
* Wed Nov 30 2022 Nicola Sella <nsella@redhat.com> - 4.0.21-17
|
||||
- offline-upgrade: add support for security filters (RhBug:1939975,2139324)
|
||||
* Thu Jan 05 2023 Nicola Sella <nsella@redhat.com> - 4.3.0-3
|
||||
- Remove requirement of python3-distro
|
||||
|
||||
* Sat Dec 03 2022 Nicola Sella <nsella@redhat.com> - 4.3.0-2
|
||||
- Move system-upgrade plugin to core (RhBug:2054235)
|
||||
- offline-upgrade: add support for security filters (RhBug:1939975)
|
||||
|
||||
* Wed Oct 26 2022 Nicola Sella <nsella@redhat.com> - 4.0.21-16
|
||||
- Move system-upgrade plugin to core (RhBug:2054235)
|
||||
* Thu Sep 22 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.3.0-1
|
||||
- Update to 4.3.0
|
||||
- [config-manager] Update documentation (RhBug:2075366)
|
||||
- [builddep] Warning when using macros with source rpms (RhBug:2077820)
|
||||
- [repomanage] Use modules only from repo they are handling (RhBug:2072441)
|
||||
- Skip all non rpm transaction items for transaction_action plugins (rhbug:2023652)
|
||||
- feat(repomanage): Add new option --oldonly
|
||||
|
||||
* Tue Sep 13 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.0.21-15
|
||||
- builddep: Warning when using macros with source rpms (RhBug:2077820)
|
||||
* Wed Sep 14 2022 Marek Blaha <mblaha@redhat.com> - 4.1.0-3
|
||||
- Update translations
|
||||
|
||||
* Tue Jul 19 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.0.21-14
|
||||
* Tue Jul 19 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.1.0-2
|
||||
- [copr] Guess EPEL chroots for CentOS Stream
|
||||
|
||||
* Tue Jun 14 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.0.21-13
|
||||
- [copr] Fix 'dnf copr enable' on Fedora 35
|
||||
- [copr] Disable dnf playground command
|
||||
- [copr] Fix baseurl for centos stream chroot
|
||||
- [copr] Silence a deprecation warning in plugins/copr.py
|
||||
- [copr] Shorter verification that the project exists
|
||||
- [copr] Better error message for dnf copr enable
|
||||
- [copr] allow specifying protocol as part of --hub
|
||||
* Thu Apr 28 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.1.0-1
|
||||
- Add a new subpackage with modulesync command. The command downloads packages from modules and/or creates a repository with modular data. (RhBug:1868047)
|
||||
- [repoclosure] Print counts of missing dependencies
|
||||
- [reposync] Do not stop downloading packages on the first error (RhBug:2009894)
|
||||
|
||||
* Tue Jun 14 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.0.21-12
|
||||
- [repomanage] Use modules only from repo they are handling
|
||||
- [repomanage] Add new option --oldonly
|
||||
- Skip all non rpm tsi for transaction_action plugins
|
||||
- Update translations
|
||||
* Mon Feb 07 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.24-3
|
||||
- Backport patch with new way to determine rpmdb version
|
||||
|
||||
* Fri Jan 14 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-10
|
||||
- Rebuild with new release number
|
||||
|
||||
* Tue Jan 11 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-9
|
||||
- Add new command modulesync (RhBug:1868047)
|
||||
|
||||
* Thu Jan 06 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-8
|
||||
- [needs-restarting] Fix wrong boot time (RhBug:1960437,2022389)
|
||||
|
||||
* Wed Dec 1 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-7
|
||||
- [groups-manager] Use full NEVRA for matching packages instead of only name (RhBug:2013633)
|
||||
- [versionlock] Fix: Multiple package-name-spec arguments don't lock (RhBug:2013324)
|
||||
* Thu Dec 09 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.24-2
|
||||
- [groups-manager] Use full NEVRA for matching packages instead of only name (RhBug:2029864)
|
||||
- [versionlock] Fix: Multiple package-name-spec arguments don't lock (RhBug:2029871)
|
||||
- [versionlock] Update documentation for adding specifi version (RhBug:2013332)
|
||||
|
||||
* Tue Nov 23 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-6
|
||||
- Increase dependency on dnf as it's required by reposync (RhBug:2023739)
|
||||
* Mon Oct 25 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.24-1
|
||||
- Update to 4.0.24
|
||||
- [repomanage] Allow running only with metadata
|
||||
- [repomanage] Enhance documentation (RhBug:1898293)
|
||||
- [versionlock] Locking obsoleted package does not make the obsoleter unavailable (RhBug:1957280)
|
||||
- [versionlock] Work correctly with packages with minorbump part of release (RhBug:1961217)
|
||||
- [leaves] Show strongly connected components
|
||||
- [needs-restarting] Fix wrong boot time (RhBug:1960437)
|
||||
- [playground] Disable playground command, since it doesn't work
|
||||
- [copr] on CentOS Stream, enable centos stream chroot instead of not epel 8 (RhBug:1994154)
|
||||
- [copr] Avoid using deprecated function distro.linux_distribution() (RhBug:2011550)
|
||||
- [copr] don't traceback on empty lines in /etc/os-release
|
||||
|
||||
* Fri Nov 12 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-5
|
||||
- [copr] Migrate all calls to APIv3 (RhBug:2021821)
|
||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 4.0.21-2
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
|
||||
* Tue Nov 09 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-4
|
||||
- [reposync] Don't stop downloading packages on the first error (RhBug:2009894)
|
||||
- [copr] Fix traceback of copr search (RhBug:2019868)
|
||||
|
||||
* Tue Jul 27 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-2
|
||||
- [versionlock] Locking obsoleted package does not make the obsoleter unavailable (RhBug:1957280)
|
||||
- [repomanage] Allow running with metadata only
|
||||
- [repomanage] Enhance repomanage documentation (RhBug:1898293)
|
||||
|
||||
* Wed May 19 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-1
|
||||
* Wed Jun 02 2021 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.21-1
|
||||
- Update to 4.0.21
|
||||
- [repomanage] Don't use cached metadata (RhBug:1899852)
|
||||
- [needs-restarting] fix -r in nspawn containers (RhBug:1913962,1914251)
|
||||
- Removed dependency on dnf.yum.misc.Checksum class (RhBug:1935465)
|
||||
- Add missing command line option to documentation
|
||||
- doc: add packages to needs-restarting conf
|
||||
- Set blacklist subcommand as deprecated
|
||||
- Removed dependency on dnf.yum.misc.Checksum class (RhBug:1935465)
|
||||
- Bugs fixed (RhBug:1914827,1916782)
|
||||
|
||||
* Fri Jan 15 2021 Nicola Sella <nsella@redhat.com> - 4.0.18-3
|
||||
- [reposync] Check GPG signatures of downloaded packages (RhBug:1856818)
|
||||
|
||||
* Tue Dec 8 2020 Marek Blaha <mblaha@redhat.com> - 4.0.18-2
|
||||
- Introduce groups-manager plugin (RhBug:1826016)
|
||||
- [needs-restarting] add -s to list services (RhBug:1772939)
|
||||
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 4.0.19-2
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
|
||||
* Tue Nov 10 2020 Nicola Sella <nsella@redhat.com> - 4.0.18-1
|
||||
- Update to 4.0.18
|
||||
* Thu Jan 28 2021 Nicola Sella <nsella@redhat.com> - 4.0.19-1
|
||||
- Update to 4.0.19
|
||||
- copr: allow only 2 arguments with copr enable command
|
||||
- [needs-restarting] fix -r in nspawn containers (RhBug:1913962,1914251)
|
||||
- Add --gpgcheck option to reposync (RhBug:1856818) (RhBug:1856818)
|
||||
- Re-introduce yum-groups-manager functionality (RhBug:1826016)
|
||||
- [repomanage] Don't use cached metadata (RhBug:1899852)
|
||||
- [needs-restarting] add -s to list services (RhBug:1772939) (RhBug:1772939)
|
||||
|
||||
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.18-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Thu Oct 08 2020 Nicola Sella <nsella@redhat.com> - 4.0.18-1
|
||||
- [needs-restarting] Fix plugin fail if needs-restarting.d does not exist
|
||||
- [needs-restarting] add kernel-rt to reboot list
|
||||
- Fix debug-restore command
|
||||
@ -964,53 +981,50 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
- [reposync] Add latest NEVRAs per stream to download (RhBug: 1833074)
|
||||
- copr: don't try to list runtime dependencies
|
||||
|
||||
* Wed Aug 05 2020 Nicola Sella <nsella@redhat.com> - 4.0.17-5
|
||||
- [reposync] Add latest NEVRAs per stream to download (RhBug: 1833074)
|
||||
* Mon Aug 10 2020 Nicola Sella <nsella@redhat.com> - 4.0.16-4
|
||||
- spec: Fix building with new cmake macros
|
||||
|
||||
* Tue Jul 28 2020 Marek Blaha <mblaha@redhat.com> - 4.0.17-4
|
||||
- Debug-restore command do not remove installonly packages (RhBug:1844533)
|
||||
- Update translations (RhBug:1820546)
|
||||
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.16-3
|
||||
- Second attempt - Rebuilt for
|
||||
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Fri Jul 17 2020 Nicola Sella <nsella@redhat.com> - 4.0.17-3
|
||||
- Fix debug-restore command (RhBug:1844533)
|
||||
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.16-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Thu Jun 11 2020 Nicola Sella <nsella@redhat.com> - 4.0.17-2
|
||||
- [needs-restarting] Fix plugin fail if needs-restarting.d does not exist
|
||||
|
||||
* Wed Jun 10 2020 Nicola Sella <nsella@redhat.com> - 4.0.17-1
|
||||
- [repomanage] Add modular support (RhBug:1804720)
|
||||
- [needs-restarting] add options using .conf file (RhBug:1810123)
|
||||
|
||||
* Wed Jun 03 2020 Nicola Sella <nsella@redhat.com> - 4.0.16-1
|
||||
* Wed Jun 03 06:48:41 CEST 2020 Igor Raits <ignatenkobrain@fedoraproject.org> - 4.0.16-1
|
||||
- Update to 4.0.16
|
||||
- [versionlock] Take obsoletes into account (RhBug:1627124)
|
||||
- Move args "--set-enabled", "--set-disabled" from DNF (RhBug:1727882)
|
||||
- Add missing arguments --set-enabled/--set-diabled into error message
|
||||
- Warn when --enablerepo/--disablerepo args were passed (RhBug:1727882)
|
||||
- [copr] add support for enabling/disabling runtime dependencies
|
||||
- [copr] no-liability text to be always printed
|
||||
+ [versionlock] Take obsoletes into account (RhBug:1627124)
|
||||
+ Move args "--set-enabled", "--set-disabled" from DNF (RhBug:1727882)
|
||||
+ Add missing arguments --set-enabled/--set-diabled into error message
|
||||
+ Warn when --enablerepo/--disablerepo args were passed (RhBug:1727882)
|
||||
+ [copr] add support for enabling/disabling runtime dependencies
|
||||
+ [copr] no-liability text to be always printed
|
||||
|
||||
* Mon Apr 06 2020 Ales Matej <amatej@redhat.com> - 4.0.15-1
|
||||
- Update to 4.0.15
|
||||
- Fix: config_manager respect config file location during save
|
||||
* Sun May 24 2020 Miro Hrončok <mhroncok@redhat.com> - 4.0.15-2
|
||||
- Rebuilt for Python 3.9
|
||||
|
||||
* Wed Apr 01 2020 Aleš Matěj <amatej@redhat.com> - 4.0.15-1
|
||||
- Support remote files in dnf builddep
|
||||
- [download] Respect repo priority (RhBug:1800342)
|
||||
|
||||
* Mon Feb 24 2020 Aleš Matěj <amatej@redhat.com> - 4.0.14-1
|
||||
- Fix conflict for dnf download --resolve (RhBug:1787908)
|
||||
- Fix: don't open stdin if versionlock is missing (RhBug:1785563)
|
||||
- config-manager calls parser error when without options (RhBug:1782822)
|
||||
- Update reposync.py with --norepopath option
|
||||
- Support remote files in dnf builddep
|
||||
- [versionlock] Prevent conflicting/duplicate entries (RhBug:1782052)
|
||||
- [download] Respect repo priority (RhBug:1800342)
|
||||
- [doc] Skip creating and installing migrate documentation for Python 3+
|
||||
- Fix: don't open stdin if versionlock is missing (RhBug:1785563)
|
||||
|
||||
* Fri Jan 31 2020 Marek Blaha <mblaha@redhat.com> - 4.0.12-3
|
||||
- [translations] Update translations from zanata (RhBug:1754960)
|
||||
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.13-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||
|
||||
* Mon Jan 13 2020 Ales Matej <amatej@redhat.com> - 4.0.12-2
|
||||
- [config-manager] Allow use of --set-enabled without arguments (RhBug:1679213)
|
||||
- [reposync] Fix --delete with multiple repos (RhBug:1774103)
|
||||
* Wed Jan 15 2020 Aleš Matěj <amatej@redhat.com> - 4.0.13-1
|
||||
- Fix: config_manager respect config file location during save
|
||||
- Redesign reposync --latest for modular system (RhBug:1775434)
|
||||
- [reposync] Fix --delete with multiple repos (RhBug:1774103)
|
||||
- [doc] Skip creating and installing migrate documentation for Python 3+
|
||||
- [config-manager] Allow use of --set-enabled without arguments (RhBug:1679213)
|
||||
- [versionlock] Prevent conflicting/duplicate entries (RhBug:1782052)
|
||||
|
||||
* Mon Nov 25 2019 Ales Matej <amatej@redhat.com> - 4.0.12-1
|
||||
* Fri Nov 29 2019 Aleš Matěj <amatej@redhat.com> - 4.0.12-1
|
||||
- Update to 4.0.12
|
||||
- [reposync] Add --urls option (RhBug:1686602)
|
||||
- [versionlock] Add --raw option (RhBug:1645564)
|
||||
@ -1020,70 +1034,77 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
- [versionlock] Don't apply excludes on @System (RhBug:1726712)
|
||||
- [reposync] Ignore only modular excludes (RhBug:1750273)
|
||||
|
||||
* Thu Nov 14 2019 Ales Matej <amatej@redhat.com> - 4.0.11-1
|
||||
* Wed Nov 06 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.11-1
|
||||
- Update to 4.0.11
|
||||
- [spec] Specify attributes for ghost file (RhBug:1754463)
|
||||
- [spec] Specify attributes for ghost file (RhBug: 1754463)
|
||||
- download: add the --debugsource option (RhBug:1637008)
|
||||
- Fix incorrect handling richdeps in buildep (RhBug:1756902)
|
||||
|
||||
* Tue Oct 22 2019 Ales Matej <amatej@redhat.com> - 4.0.10-1
|
||||
* Tue Oct 01 2019 Ales Matej <amatej@redhat.com> - 4.0.10-1
|
||||
- Update to 4.0.10
|
||||
- debuginfo-install: Update both debuginfo and debugsource for updated package (RhBug:1586084)
|
||||
- copr: Support multilib repofiles (RhBug:1393664)
|
||||
- copr: Fix disable if copr instance has non-default port
|
||||
- copr: Fix repoid when using subdirectories in copr project
|
||||
|
||||
* Wed Aug 14 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.8-3
|
||||
- Generate yum-utils(1) instead of symlinking (RhBug:1676418)
|
||||
* Sun Aug 18 2019 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 4.0.9-2
|
||||
- Rebuilt for Python 3.8
|
||||
|
||||
* Tue Aug 06 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.8-2
|
||||
- Update localizations from zanata (RhBug:1689984)
|
||||
- Rename dnf-utils to yum-utils (RhBug:1722093)
|
||||
- [builddep] Report all rpm errors (RhBug:1724668)
|
||||
- [config-manager] Behaviour of --setopt (RhBug:1702678)
|
||||
|
||||
* Tue Jun 11 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.8-1
|
||||
- Update to 4.0.8
|
||||
* Tue Aug 13 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.9-1
|
||||
- Update to 4.0.9
|
||||
- [reposync] Enable timestamp preserving for downloaded data (RhBug:1688537)
|
||||
- [reposync] Download packages from all streams (RhBug:1714788)
|
||||
- Make yum-copr manpage available (RhBug:1673902)
|
||||
- [needs-restarting] Add --reboothint option (RhBug:1192946) (RhBug:1639468)
|
||||
- Set the cost of ``_dnf_local`` repo to 500, to make it preferred to normal
|
||||
repos
|
||||
- [needs-restarting] Add ``--reboothint`` option (RhBug:1192946) (RhBug:1639468)
|
||||
- Set the cost of ``_dnf_local`` repo to 500, to make it preferred to normal repos
|
||||
- [builddep] Report all rpm errors (RhBug:1663619,1658292,1724668)
|
||||
- [config-manager] --setopt: Fix crash with "--save --dump"
|
||||
- [config-manager] --setopt: Add globs support to repoid
|
||||
- [config-manager] --setopt=key=value is applied only to the main config
|
||||
- [config-manager] --setopt and empty list of repositories (RhBug:1702678)
|
||||
- [config-manager] --setopt: Add check for existence of input repositories
|
||||
|
||||
* Mon May 13 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.7-1
|
||||
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.7-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Tue May 21 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.7-1
|
||||
- Update to 4.0.7
|
||||
- Use improved config parser that preserves order of data
|
||||
- Fix: copr disable command traceback (RhBug:1693551)
|
||||
- [doc] state repoid as repo identifier of config-manager (RhBug:1686779)
|
||||
- Fix download of src when not the latest requested (RhBug:1649627)
|
||||
|
||||
* Mon Mar 11 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.6-1
|
||||
- Update to 4.0.6
|
||||
- Use improved config parser that preserves order of data
|
||||
- [leaves] Show multiply satisfied dependencies as leaves
|
||||
- [download] Fix downloading an rpm from a URL (RhBug:1678582)
|
||||
- [download] Do not download src without ``--source`` (RhBug:1666648)
|
||||
- [download] Fix problem with downloading src pkgs (RhBug:1649627)
|
||||
- [download] Fix download of src when not the latest requested (RhBug:1649627)
|
||||
|
||||
* Tue Jan 08 2019 Daniel Mach <dmach@redhat.com> - 4.0.2.2-3
|
||||
- reposync: fix-up path traversal prevention (RhBug: 1600722)
|
||||
* Sat Feb 23 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 4.0.4-2
|
||||
- Raise yum-utils conflict version
|
||||
|
||||
* Fri Jan 04 2019 Jaroslav Mracek <jmracek@redhat.com> - 4.0.2.2-1
|
||||
- Add option for reposync
|
||||
- Add changelog plugin
|
||||
* Wed Feb 13 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 4.0.4-1
|
||||
- Update to 4.0.4
|
||||
- [download] Do not download src without ``--source`` (RhBug:1666648)
|
||||
|
||||
* Mon Dec 17 2018 Daniel Mach <dmach@redhat.com> - 4.0.2.1-1
|
||||
- zanata update
|
||||
- Attribute repo.metadata._comps_fn does not exist anymore
|
||||
- [download] Fix traceback when local rpm / url is passed
|
||||
- Run transaction hook only if transaction
|
||||
- [versionlock] Accept more NEVRA forms in the deletion code (RhBug:1654529)
|
||||
- [spec] Obsolete yum-utils < 1.1.31-513 (RhBug: 1579322)
|
||||
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Fri Nov 23 2018 Jaroslav Mracek <jmracek@redhat.com> - 4.0.2-1
|
||||
* Wed Dec 12 2018 Jaroslav Mracek <jmracek@redhat.com> - 4.0.3-1
|
||||
- Update to 4.0.3
|
||||
- Add ``changelog`` plugin that is used for viewing package changelogs
|
||||
- New option ``--metadata-path`` option for reposync plugin
|
||||
|
||||
* Thu Nov 22 2018 Jaroslav Mracek <jmracek@redhat.com> - 4.0.2-1
|
||||
- Added repodif command
|
||||
- copr: fix enabling Rawhide repository
|
||||
- Add needs-restarting CLI shim
|
||||
- [reposync] Fix traceback with --quiet option
|
||||
- [versionlock] Accept more pkgspec forms
|
||||
|
||||
* Wed Oct 17 2018 Jaroslav Mracek <jmracek@redhat.com> - 4.0.0-2
|
||||
- Allow build of dnf-utils in F29
|
||||
|
||||
* Mon Oct 15 2018 Jaroslav Mracek <jmracek@redhat.com> - 4.0.0-1
|
||||
- Update to 4.0.0
|
||||
- Enhance documentation
|
||||
@ -1099,10 +1120,18 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/
|
||||
- Add characters into repo URL sanitization (RhBug:1615416)
|
||||
- copr: add support for multiple copr instances (RhBug:1478208)
|
||||
- Redirect repo progress to std error (RhBug:1626011)
|
||||
- Resolves: rhbz#1578787 - repodiff command not available in dnf-utils
|
||||
|
||||
* Wed Aug 01 2018 Charalampos Stratakis <cstratak@redhat.com> - 3.0.1-3
|
||||
- Rebuild for platform-python
|
||||
* Fri Sep 07 2018 Jaroslav Mracek <jmracek@redhat.com> - 3.0.3-1
|
||||
- Resolves: rhbz#1582152
|
||||
- Resolves: rhbz#1581117
|
||||
- Resolves: rhbz#1579737
|
||||
|
||||
* Mon Jul 23 2018 Marek Blaha <mblaha@redhat.com> 3.0.2-1
|
||||
- Resolves: rhbz#1603805
|
||||
- Resolves: rhbz#1571251
|
||||
|
||||
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.0.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
|
||||
* Fri Jun 29 2018 Jaroslav Mracek <jmracek@redhat.com> 3.0.1-2
|
||||
- Rebuilt for Python 3.7
|
||||
|
||||
Loading…
Reference in New Issue
Block a user