Skip to content

Commit 75e3ff0

Browse files
evan-goodekontura
authored andcommitted
Override releasever_{major,minor} with provides
The releasever_major and releasever_minor substitution variables are usually derived by splitting releasever on the first `.`. However, to support EPEL 10 [1], we would like a way for distributions to override these values. Specifically, we would like RHEL 10 to have a releasever of `10` with a releasever_major of `10` and a releasever_minor of `0` (later incrementing to `1`, `2`, to correspond with the RHEL minor version). This commit adds a new API function, `detect_releasevers`, which derives releasever, releasever_major, and releasever_minor from virtual provides on the system-release package (any of `DISTROVERPKG`). The detection of releasever is unchanged. releasever_major and releasever_minor are specified by the versions of the `system-release-major` and `system-release-minor` provides, respectively. If the user specifies a `--releasever=X.Y` on the command line, the distribution settings for releasever, releasever_major, and releasever_minor will all be overridden: releasever will be set to X.Y, releasever_major will be set to X, and releasever_minor will be set to Y, same as before. If a user wants to specify a custom releasever_major and releasever_minor, they have to set all three with `--setopt=releasever=X --setopt=releasever_major=Y --setopt=releasever_minor=z`, taking care to put `releasever_major` and `releasever_minor` after `releasever` so they are not overridden. [1] https://issues.redhat.com/browse/RHEL-68034
1 parent 0e283fb commit 75e3ff0

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

dnf/base.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,14 @@ def _setup_default_conf():
157157
conf = dnf.conf.Conf()
158158
subst = conf.substitutions
159159
if 'releasever' not in subst:
160-
subst['releasever'] = \
161-
dnf.rpm.detect_releasever(conf.installroot)
160+
releasever, major, minor = \
161+
dnf.rpm.detect_releasevers(conf.installroot)
162+
subst['releasever'] = releasever
163+
if major is not None:
164+
subst['releasever_major'] = major
165+
if minor is not None:
166+
subst['releasever_minor'] = minor
167+
162168
return conf
163169

164170
def _setup_modular_excludes(self):

dnf/cli/cli.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -979,13 +979,20 @@ def _read_conf_file(self, releasever=None):
979979
from_root = "/"
980980
subst = conf.substitutions
981981
subst.update_from_etc(from_root, varsdir=conf._get_value('varsdir'))
982+
982983
# cachedir, logs, releasever, and gpgkey are taken from or stored in installroot
984+
major = None
985+
minor = None
983986
if releasever is None and conf.releasever is None:
984-
releasever = dnf.rpm.detect_releasever(conf.installroot)
987+
releasever, major, minor = dnf.rpm.detect_releasevers(conf.installroot)
985988
elif releasever == '/':
986-
releasever = dnf.rpm.detect_releasever(releasever)
989+
releasever, major, minor = dnf.rpm.detect_releasevers(releasever)
987990
if releasever is not None:
988991
conf.releasever = releasever
992+
if major is not None:
993+
conf.releasever_major = major
994+
if minor is not None:
995+
conf.releasever_minor = minor
989996
if conf.releasever is None:
990997
logger.warning(_("Unable to detect release version (use '--releasever' to specify "
991998
"release version)"))

dnf/const.py.in

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ CONF_AUTOMATIC_FILENAME='/etc/dnf/automatic.conf'
2525
DISTROVERPKG=('system-release(releasever)', 'system-release',
2626
'distribution-release(releasever)', 'distribution-release',
2727
'redhat-release', 'suse-release')
28+
DISTROVER_MAJOR_PKG='system-release(releasever_major)'
29+
DISTROVER_MINOR_PKG='system-release(releasever_minor)'
2830
GROUP_PACKAGE_TYPES = ('mandatory', 'default', 'conditional') # :api
2931
INSTALLONLYPKGS=['kernel', 'kernel-PAE',
3032
'installonlypkg(kernel)',

dnf/rpm/__init__.py

+39-4
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,21 @@
2626
import rpm # used by ansible (dnf.rpm.rpm.labelCompare in lib/ansible/modules/packaging/os/dnf.py)
2727

2828

29-
def detect_releasever(installroot):
29+
def detect_releasevers(installroot):
3030
# :api
31-
"""Calculate the release version for the system."""
31+
"""Calculate the release version for the system, including releasever_major
32+
and releasever_minor if they are overriden by the system-release-major or
33+
system-release-minor provides."""
3234

3335
ts = transaction.initReadOnlyTransaction(root=installroot)
3436
ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES | rpm._RPMVSF_NODIGESTS))
37+
38+
distrover_major_pkg = dnf.const.DISTROVER_MAJOR_PKG
39+
distrover_minor_pkg = dnf.const.DISTROVER_MINOR_PKG
40+
if dnf.pycomp.PY3:
41+
distrover_major_pkg = bytes(distrover_major_pkg, 'utf-8')
42+
distrover_minor_pkg = bytes(distrover_minor_pkg, 'utf-8')
43+
3544
for distroverpkg in dnf.const.DISTROVERPKG:
3645
if dnf.pycomp.PY3:
3746
distroverpkg = bytes(distroverpkg, 'utf-8')
@@ -47,6 +56,8 @@ def detect_releasever(installroot):
4756
msg = 'Error: rpmdb failed to list provides. Try: rpm --rebuilddb'
4857
raise dnf.exceptions.Error(msg)
4958
releasever = hdr['version']
59+
releasever_major = None
60+
releasever_minor = None
5061
try:
5162
try:
5263
# header returns bytes -> look for bytes
@@ -61,13 +72,37 @@ def detect_releasever(installroot):
6172
if hdr['name'] not in (distroverpkg, distroverpkg.decode("utf8")):
6273
# override the package version
6374
releasever = ver
75+
76+
for provide, flag, ver in zip(
77+
hdr[rpm.RPMTAG_PROVIDENAME],
78+
hdr[rpm.RPMTAG_PROVIDEFLAGS],
79+
hdr[rpm.RPMTAG_PROVIDEVERSION]):
80+
if isinstance(provide, str):
81+
provide = bytes(provide, "utf-8")
82+
if provide == distrover_major_pkg and flag == rpm.RPMSENSE_EQUAL and ver:
83+
releasever_major = ver
84+
if provide == distrover_minor_pkg and flag == rpm.RPMSENSE_EQUAL and ver:
85+
releasever_minor = ver
86+
6487
except (ValueError, KeyError, IndexError):
6588
pass
6689

6790
if is_py3bytes(releasever):
6891
releasever = str(releasever, "utf-8")
69-
return releasever
70-
return None
92+
if is_py3bytes(releasever_major):
93+
releasever_major = str(releasever_major, "utf-8")
94+
if is_py3bytes(releasever_minor):
95+
releasever_minor = str(releasever_minor, "utf-8")
96+
return releasever, releasever_major, releasever_minor
97+
return (None, None, None)
98+
99+
100+
def detect_releasever(installroot):
101+
# :api
102+
"""Calculate the release version for the system."""
103+
104+
releasever, _, _ = detect_releasevers(installroot)
105+
return releasever
71106

72107

73108
def _header(path):

0 commit comments

Comments
 (0)