osbuild-composer
osbuild-composer copied to clipboard
The "new" way of getting RHSM secrets does not work with the default RHEL repos shipped by composer
Describe the bug
The new code for getting RHSM secrets does not work with the currently shipped repo definitions for RHEL. The reason is that these use release with minor version (e.g. 8.5
) as the releasever
in the baseurl
https://github.com/osbuild/osbuild-composer/blob/c37b688dd2c0dbc325533c0919b9c56dfe789c25/repositories/rhel-85.json#L53, however the RHSM code is replacing the $releasever
in the baseurl
found in redhat.repo
with value returned by Distro.Releasever()
, which is always only the major version, e.g. 8
for all RHEL-8.Y distros.
Relevant code is: https://github.com/osbuild/osbuild-composer/blob/c37b688dd2c0dbc325533c0919b9c56dfe789c25/internal/rhsm/secrets.go#L144 https://github.com/osbuild/osbuild-composer/blob/c37b688dd2c0dbc325533c0919b9c56dfe789c25/internal/distro/rhel85/distro.go#L59-L61 https://github.com/osbuild/osbuild-composer/blob/c37b688dd2c0dbc325533c0919b9c56dfe789c25/internal/distro/rhel85/distro.go#L21
So as a result, the condition https://github.com/osbuild/osbuild-composer/blob/e4d535ea5fdc730d0a8eed310e64efbd4baa4a5c/internal/rhsm/secrets.go#L146 will always evaluate on RHEL as false
and the code falls back to the old way - using the first cert found on the disk.
I implemented extension to the RHSM unit test which test this situation and fails on current main
:
https://github.com/thozza/osbuild-composer/commit/1cc9f35bf472b7587318123108558dcc9750a95e
diff --git a/internal/rhsm/secrets_test.go b/internal/rhsm/secrets_test.go
index 55d3740d..906c49c3 100644
--- a/internal/rhsm/secrets_test.go
+++ b/internal/rhsm/secrets_test.go
@@ -32,6 +32,32 @@ sslclientkey = /etc/pki/entitlement/789-key.pem
sslclientcert = /etc/pki/entitlement/101112.pem
metadata_expire = 86400
enabled_metadata = 0
+
+[rhel-8-for-x86_64-appstream-rpms]
+name = Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)
+baseurl = https://cdn.redhat.com/content/dist/rhel8/$releasever/x86_64/appstream/os
+enabled = 1
+gpgcheck = 1
+gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
+sslverify = 1
+sslcacert = /etc/rhsm/ca/redhat-uep.pem
+sslclientkey = /etc/pki/entitlement/121-key.pem
+sslclientcert = /etc/pki/entitlement/121.pem
+metadata_expire = 86400
+enabled_metadata = 1
+
+[rhel-8-for-x86_64-baseos-rpms]
+name = Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)
+baseurl = https://cdn.redhat.com/content/dist/rhel8/$releasever/x86_64/baseos/os
+enabled = 1
+gpgcheck = 1
+gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
+sslverify = 1
+sslcacert = /etc/rhsm/ca/redhat-uep.pem
+sslclientkey = /etc/pki/entitlement/121-key.pem
+sslclientcert = /etc/pki/entitlement/121.pem
+metadata_expire = 86400
+enabled_metadata = 1
`
func TestParseRepoFile(t *testing.T) {
@@ -46,4 +72,16 @@ func TestParseRepoFile(t *testing.T) {
assert.Equal(t, secrets.SSLCACert, "/etc/rhsm/ca/redhat-uep.pem", "Unexpected path to the CA certificate")
assert.Equal(t, secrets.SSLClientCert, "/etc/pki/entitlement/456.pem", "Unexpected path to the client cert")
assert.Equal(t, secrets.SSLClientKey, "/etc/pki/entitlement/123-key.pem", "Unexpected path to the client key")
+
+ // BaseURL from `repositories/rhel-85.json`
+ x86ComposerRepoBaseURL := "https://cdn.redhat.com/content/dist/rhel8/8.5/x86_64/baseos/os"
+ x86ArchName := "x86_64"
+ // value returned by rhel_85 Distro.Releasever()
+ rhel85distroReleasever := "8"
+
+ secrets, err = subscriptions.GetSecretsForBaseurl(x86ComposerRepoBaseURL, x86ArchName, rhel85distroReleasever)
+ require.NoError(t, err, "Failed to get secrets for a baseurl")
+ assert.Equal(t, secrets.SSLCACert, "/etc/rhsm/ca/redhat-uep.pem", "Unexpected path to the CA certificate")
+ assert.Equal(t, secrets.SSLClientCert, "/etc/pki/entitlement/121.pem", "Unexpected path to the client cert")
+ assert.Equal(t, secrets.SSLClientKey, "/etc/pki/entitlement/121-key.pem", "Unexpected path to the client key")
}
Environment
- OS version (
/etc/os-release
and/etc/redhat-release
): RHEL - osbuild-composer version (
rpm -qi osbuild-composer)
: latestmain
To Reproduce Steps to reproduce the behavior: Hard to reproduce, because of the fallback code which makes all work in the most usual simple case.
Expected behavior
Either the RHSM code should be extended to cope with the minor version in releasever
or composer should not ship RHEL repo definitions with minor version specified in it.
This is a problem because there are multiple sources of this information:
- There is the redhat-release package (see
rpm -q --provides redhat-release
) - There are overrides in
/etc/dnf/vars/releasever
I tried to run fresh RHEL 8.5 QCOW2 and subscribe it. It defaults to the URL without minor version (8
instead of 8.5
). It might be confusing for some users if the images are built using a different distro than the host system is subscribed to.
And what is even worse is the combination with cross-distro (in this case cross-minor-version) image building. Imagine you have the same URL for two minor versions. The only difference is in the $releasever
variable. I don't know if that is possible, but if there were two subscriptions, one for each minor version, how is the osbuild-composer going to decide which one to use?
I'm afraid we are doomed to fail if we try to cover all use cases in composer for example by allowing the user to set the releasever by hand.
It might be better to rethink the source management, e.g.:
- Using system repos if the user wish to do so (by configuring composer). This seems to be the most common use case in our internal bug reports.
- Specifying exact repos and their CA/cert/key. Tedious but at least it would provide a space for a workaround.