Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ RUN if [ "${TAGS}" = "fcos" ]; then \
# comment out rhel-coreos-10 for scos
sed -i '/- name: rhel-coreos-10/,+3 s/^/#/' /manifests/* && \
# rewrite image names for scos
sed -i 's/rhel-coreos/stream-coreos/g' /manifests/*; fi && \
sed -i 's/rhel-coreos/stream-coreos/g' /manifests/*; \
else \
# rewrite image names for rhel-coreos-10
sed -i 's/rhel-coreos/rhel-coreos-10/g' /manifests/0000_80_machine-config_05_osimageurl.yaml; fi && \
dnf -y install 'nmstate >= 2.2.10' && \
if ! rpm -q util-linux; then dnf install -y util-linux; fi && \
# We also need to install fuse-overlayfs and cpp for Buildah to work correctly.
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile.rhel7
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ RUN if [ "${TAGS}" = "fcos" ]; then \
# comment out rhel-coreos-10 for scos
sed -i '/- name: rhel-coreos-10/,+3 s/^/#/' /manifests/* && \
# rewrite image names for scos
sed -i 's/rhel-coreos/stream-coreos/g' /manifests/*; fi && \
sed -i 's/rhel-coreos/stream-coreos/g' /manifests/*; \
else \
# rewrite image names for rhel-coreos-10
sed -i 's/rhel-coreos/rhel-coreos-10/g' /manifests/0000_80_machine-config_05_osimageurl.yaml; fi && \
dnf -y install 'nmstate >= 2.2.10' && \
if ! rpm -q util-linux; then dnf install -y util-linux; fi && \
# We also need to install fuse-overlayfs and cpp for Buildah to work correctly.
Expand Down
2 changes: 1 addition & 1 deletion cmd/machine-config-operator/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func runBootstrapCmd(_ *cobra.Command, _ []string) {
// To help debugging, immediately log version
klog.Infof("Version: %+v (%s)", version.Raw, version.Hash)

baseOSContainerImageTag := "rhel-coreos"
baseOSContainerImageTag := "rhel-coreos-10"
if version.IsFCOS() {
baseOSContainerImageTag = "fedora-coreos"
} else if version.IsSCOS() {
Expand Down
4 changes: 2 additions & 2 deletions install/image-references
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ spec:
- name: rhel-coreos-10
from:
kind: DockerImage
name: placeholder.url.oc.will.replace.this.org/placeholdernamespace:rhel10-coreos
name: placeholder.url.oc.will.replace.this.org/placeholdernamespace:rhel-coreos-10
- name: rhel-coreos-10-extensions
from:
kind: DockerImage
name: placeholder.url.oc.will.replace.this.org/placeholdernamespace:rhel10-coreos-extensions
name: placeholder.url.oc.will.replace.this.org/placeholdernamespace:rhel-coreos-10-extensions
- name: keepalived-ipfailover
from:
kind: DockerImage
Expand Down
55 changes: 36 additions & 19 deletions test/e2e-1of2/mcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestRunShared(t *testing.T) {
func TestKernelArguments(t *testing.T) {
cs := framework.NewClientSet("")

delete := helpers.CreateMCP(t, cs, "infra")
deleteMCP := helpers.CreateMCP(t, cs, "infra")
workerOldMc := helpers.GetMcName(t, cs, "worker")

unlabelFunc := helpers.LabelRandomNodeFromPool(t, cs, "worker", "node-role.kubernetes.io/infra")
Expand All @@ -124,7 +124,7 @@ func TestKernelArguments(t *testing.T) {
if err := helpers.WaitForPoolComplete(t, cs, "worker", workerOldMc); err != nil {
t.Fatal(err)
}
delete()
deleteMCP()
require.Nil(t, cs.MachineConfigs().Delete(context.TODO(), oldInfraConfig.Name, metav1.DeleteOptions{}))
})
// create old mc to have something to verify we successfully rolled back
Expand Down Expand Up @@ -204,7 +204,7 @@ func TestKernelType(t *testing.T) {
t.Skip("skipping test on OKD")
}

delete := helpers.CreateMCP(t, cs, "infra")
deleteMCP := helpers.CreateMCP(t, cs, "infra")
workerOldMc := helpers.GetMcName(t, cs, "worker")

unlabelFunc := helpers.LabelRandomNodeFromPool(t, cs, "worker", "node-role.kubernetes.io/infra")
Expand All @@ -216,9 +216,8 @@ func TestKernelType(t *testing.T) {
if err := helpers.WaitForPoolComplete(t, cs, "worker", workerOldMc); err != nil {
t.Fatal(err)
}
delete()
deleteMCP()
require.Nil(t, cs.MachineConfigs().Delete(context.TODO(), oldInfraConfig.Name, metav1.DeleteOptions{}))

})

_, err = cs.MachineConfigs().Create(context.TODO(), oldInfraConfig, metav1.CreateOptions{})
Expand Down Expand Up @@ -296,12 +295,11 @@ func TestKernelType(t *testing.T) {
}
err = helpers.WaitForPoolComplete(t, cs, "infra", oldInfraRenderedConfig)
require.Nil(t, err)

}

func TestNoReboot(t *testing.T) {
cs := framework.NewClientSet("")
delete := helpers.CreateMCP(t, cs, "infra")
deleteMCP := helpers.CreateMCP(t, cs, "infra")
workerOldMc := helpers.GetMcName(t, cs, "worker")

unlabelFunc := helpers.LabelRandomNodeFromPool(t, cs, "worker", "node-role.kubernetes.io/infra")
Expand All @@ -313,13 +311,14 @@ func TestNoReboot(t *testing.T) {
if err := helpers.WaitForPoolComplete(t, cs, "worker", workerOldMc); err != nil {
t.Fatal(err)
}
delete()
deleteMCP()
require.Nil(t, cs.MachineConfigs().Delete(context.TODO(), oldInfraConfig.Name, metav1.DeleteOptions{}))

})
_, err := cs.MachineConfigs().Create(context.TODO(), oldInfraConfig, metav1.CreateOptions{})
require.Nil(t, err)
oldInfraRenderedConfig, err := helpers.WaitForRenderedConfig(t, cs, "infra", oldInfraConfig.Name)
require.NoError(t, err)

infraNode := helpers.GetSingleNodeByRole(t, cs, "infra")

sshKeyContent := "test adding authorized key without node reboot"
Expand Down Expand Up @@ -408,8 +407,11 @@ func TestNoReboot(t *testing.T) {

currentEtcShadowContents := helpers.ExecCmdOnNode(t, cs, infraNode, "grep", "^core:", "/rootfs/etc/shadow")

if currentEtcShadowContents == initialEtcShadowContents {
t.Fatalf("updated password hash not found in etc/shadow, got %s", currentEtcShadowContents)
initialPasswordHash := extractPasswordHashFromShadowLine(initialEtcShadowContents)
currentPasswordHash := extractPasswordHashFromShadowLine(currentEtcShadowContents)

if currentPasswordHash == initialPasswordHash {
t.Fatalf("updated password hash not found in etc/shadow")
}

t.Logf("Node %s has Password Hash", infraNode.Name)
Expand Down Expand Up @@ -489,7 +491,9 @@ func TestNoReboot(t *testing.T) {
require.Nil(t, err)

rollbackEtcShadowContents := helpers.ExecCmdOnNode(t, cs, infraNode, "grep", "^core:", "/rootfs/etc/shadow")
assert.Equal(t, initialEtcShadowContents, rollbackEtcShadowContents)

assert.Equal(t, extractPasswordHashFromShadowLine(initialEtcShadowContents), extractPasswordHashFromShadowLine(rollbackEtcShadowContents),
"password hash should match after rollback")
}

func TestPoolDegradedOnFailToRender(t *testing.T) {
Expand Down Expand Up @@ -545,7 +549,7 @@ func TestPoolDegradedOnFailToRender(t *testing.T) {
func TestDontDeleteRPMFiles(t *testing.T) {
cs := framework.NewClientSet("")

delete := helpers.CreateMCP(t, cs, "infra")
deleteMCP := helpers.CreateMCP(t, cs, "infra")
workerOldMc := helpers.GetMcName(t, cs, "worker")

unlabelFunc := helpers.LabelRandomNodeFromPool(t, cs, "worker", "node-role.kubernetes.io/infra")
Expand All @@ -557,9 +561,8 @@ func TestDontDeleteRPMFiles(t *testing.T) {
if err := helpers.WaitForPoolComplete(t, cs, "worker", workerOldMc); err != nil {
t.Fatal(err)
}
delete()
deleteMCP()
require.Nil(t, cs.MachineConfigs().Delete(context.TODO(), oldInfraConfig.Name, metav1.DeleteOptions{}))

})

_, err := cs.MachineConfigs().Create(context.TODO(), oldInfraConfig, metav1.CreateOptions{})
Expand Down Expand Up @@ -944,6 +947,17 @@ func assertExpectedPerms(t *testing.T, cs *framework.ClientSet, node corev1.Node
assert.Equal(t, expectedPerms, actualPerms, "expected %s to have perms %v, got: %v", path, expectedPerms, actualPerms)
}

// extractPasswordHashFromShadowLine extracts the password hash field from an /etc/shadow line.
// The shadow file format is: username:password:lastchg:min:max:warn:inactive:expire:reserved
// This function returns the password hash (field index 1).
func extractPasswordHashFromShadowLine(shadowLine string) string {
fields := strings.Split(strings.TrimSpace(shadowLine), ":")
if len(fields) < 2 {
return ""
}
return fields[1]
}

// Tests that changes to the internal image registry pull secret has the
// desired effect on both the ControllerConfig and the individual nodes
// filesystems.
Expand Down Expand Up @@ -1160,12 +1174,15 @@ func TestInstallRPMAndCheckMCDMetrics(t *testing.T) {

// Download the RPM package on the node
t.Logf("Downloading the RPM package on node %s", node.Name)
pkg := "epel-release-latest-10.noarch.rpm"
pkgSrc := "https://dl.fedoraproject.org/pub/epel/" + pkg
pkgDest := filepath.Join("/tmp", pkg)
downloadCmd := []string{
"chroot", "/rootfs", "curl", "-KL", "https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm", "-o", "/tmp/epel-release-latest-9.noarch.rpm",
"chroot", "/rootfs", "curl", "-L", pkgSrc, "-o", pkgDest,
}

_, err := helpers.ExecCmdOnNodeWithError(cs, node, downloadCmd...)
require.NoError(t, err, "Failed to download RPM package on node %s: %v", node.Name, err)
output, err := helpers.ExecCmdOnNodeWithError(cs, node, downloadCmd...)
require.NoError(t, err, "Failed to download RPM package on node %s: %v: error: %v", node.Name, output, err)
t.Logf("RPM package downloaded successfully")

// Reboot the node to apply changes
Expand All @@ -1177,7 +1194,7 @@ func TestInstallRPMAndCheckMCDMetrics(t *testing.T) {
t.Logf("Executing rpm-ostree install command on node %s", node.Name)
// Install the RPM package
installCmd := []string{
"chroot", "/rootfs", "rpm-ostree", "install", "/tmp/epel-release-latest-9.noarch.rpm",
"chroot", "/rootfs", "rpm-ostree", "install", pkgDest,
}

out, err := helpers.ExecCmdOnNodeWithError(cs, node, installCmd...)
Expand Down
12 changes: 7 additions & 5 deletions test/e2e-ocl-shared/Containerfile.cowsay
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
FROM quay.io/centos/centos:stream9 AS centos
RUN dnf install -y epel-release
FROM quay.io/centos/centos:stream10 AS centos
RUN dnf install -y epel-release && \
sed -i 's/\$stream/10-stream/g' /etc/yum.repos.d/centos*.repo && \
sed -i 's/EPEL\-\$releasever_major/EPEL-10/g' /etc/yum.repos.d/epel*.repo && \
sed -i -E 's/\$\{releasever_minor\:\+\-z\}//g' /etc/yum.repos.d/epel*.repo

FROM configs AS final
COPY --from=centos /etc/yum.repos.d /etc/yum.repos.d
COPY --from=centos /etc/pki/rpm-gpg/RPM-GPG-KEY-* /etc/pki/rpm-gpg/
RUN sed -i 's/\$stream/9-stream/g' /etc/yum.repos.d/centos*.repo && \
rpm-ostree install cowsay && \
ostree container commit
RUN dnf install -y cowsay && \
ostree container commit
4 changes: 2 additions & 2 deletions test/e2e-ocl-shared/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ func SkipIfEntitlementNotPresent(t *testing.T, cs *framework.ClientSet) {
require.NoError(t, err)
}

// Uses the centos stream 9 container and extracts the contents of both the
// Uses the centos stream 10 container and extracts the contents of both the
// /etc/yum.repos.d and /etc/pki/rpm-gpg directories and injects those into a
// ConfigMap and Secret, respectively. This is so that the build process will
// consume those objects as part of the build process, injecting them into the
Expand All @@ -872,7 +872,7 @@ func InjectYumRepos(t *testing.T, cs *framework.ClientSet, skipCleanupAlways, sk
yumReposPath := filepath.Join(tempDir, "yum-repos-d")
require.NoError(t, os.MkdirAll(yumReposPath, 0o755))

centosPullspec := "quay.io/centos/centos:stream9"
centosPullspec := "quay.io/centos/centos:stream10"
yumReposContents := ConvertFilesFromContainerImageToBytesMap(t, centosPullspec, "/etc/yum.repos.d/")
rpmGpgContents := ConvertFilesFromContainerImageToBytesMap(t, centosPullspec, "/etc/pki/rpm-gpg/")
Comment on lines +875 to 877
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stream10 pullspec now conflicts with hardcoded 9-stream rewrite logic

After switching to quay.io/centos/centos:stream10 (Line 875), the extracted repo content is still rewritten to 9-stream in ConvertFilesFromContainerImageToBytesMap. That mismatch can point builds at the wrong repos and break package resolution.

Suggested fix
 func ConvertFilesFromContainerImageToBytesMap(t *testing.T, pullspec, containerFilepath string) map[string][]byte {
@@
-	isCentosImage := strings.Contains(pullspec, "centos")
+	isCentosImage := strings.Contains(pullspec, "centos")
+	streamValue := "10-stream"
+	if strings.Contains(pullspec, "stream9") {
+		streamValue = "9-stream"
+	}
@@
-		if isCentosImage {
-			contents = bytes.ReplaceAll(contents, []byte("$stream"), []byte("9-stream"))
-		}
-
-		// Replace $stream with 9-stream in any of the Centos repo content we pulled.
+		if isCentosImage {
+			contents = bytes.ReplaceAll(contents, []byte("$stream"), []byte(streamValue))
+		}
+
+		// Replace $stream with the matching stream value in any of the CentOS repo content.
 		out[filepath.Base(path)] = contents
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e-ocl-shared/helpers.go` around lines 875 - 877, The test now pulls
quay.io/centos/centos:stream10 but ConvertFilesFromContainerImageToBytesMap
contains hardcoded repo rewrite logic that forces repo names to "9-stream";
update the rewrite logic in ConvertFilesFromContainerImageToBytesMap to derive
the stream version from the centosPullspec (or from the repo file contents)
instead of always substituting "9-stream" — specifically detect tags like
"stream10" and rewrite to "10-stream" (or preserve the original stream token) so
repo entries produced for centosPullspec match the pulled image; ensure the
change touches the rewrite branch that references "9-stream" and keeps tests
using centosPullspec unchanged.


Expand Down
10 changes: 6 additions & 4 deletions test/extended-priv/mco_ocb.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,11 @@ var _ = g.Describe("[sig-mco][Suite:openshift/machine-config-operator/disruptive

containerFileContent = `
# Pull the centos base image and enable the EPEL repository.
FROM quay.io/centos/centos:stream9 AS centos
RUN dnf install -y epel-release
FROM quay.io/centos/centos:stream10 AS centos
RUN dnf install -y epel-release && \
sed -i 's/\$stream/10-stream/g' /etc/yum.repos.d/centos*.repo && \
sed -i 's/EPEL\-\$releasever_major/EPEL-10/g' /etc/yum.repos.d/epel*.repo && \
sed -i -E 's/\$\{releasever_minor\:\+\-z\}//g' /etc/yum.repos.d/epel*.repo

# Pull an image containing the yq utility.
FROM quay.io/multi-arch/yq:4.25.3 AS yq
Expand All @@ -130,8 +133,7 @@ var _ = g.Describe("[sig-mco][Suite:openshift/machine-config-operator/disruptive

# Install cowsay and ripgrep from the EPEL repository into the final image,
# along with a custom cow file.
RUN sed -i 's/\$stream/9-stream/g' /etc/yum.repos.d/centos*.repo && \
rpm-ostree install cowsay ripgrep
RUN dnf install -y cowsay ripgrep
`

checkers = []Checker{
Expand Down
2 changes: 1 addition & 1 deletion test/helpers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ type SSHPaths struct {

// Determines where to expect SSH keys for the core user on a given node based upon the node's OS.
func GetSSHPaths(os osrelease.OperatingSystem) SSHPaths {
if os.IsEL9() || os.IsSCOS() || os.IsFCOS() {
if os.IsEL9() || os.IsEL10() || os.IsSCOS() || os.IsFCOS() {
return SSHPaths{
Expected: constants.RHCOS9SSHKeyPath,
NotExpected: constants.RHCOS8SSHKeyPath,
Expand Down