From 8e9db7c53f173a117e263381389c3b01f27caff6 Mon Sep 17 00:00:00 2001 From: Zack Zlotnik Date: Fri, 26 Sep 2025 16:59:52 -0400 Subject: [PATCH 1/2] extract oc binary from base OS image after build --- Dockerfile | 4 +++- Dockerfile.rhel7 | 5 ++++- .../build/buildrequest/assets/buildah-build.sh | 12 ++++++++++++ .../buildrequest/assets/create-digest-cm.sh | 15 ++++++++++++++- .../build/buildrequest/buildrequest.go | 17 ++++++++--------- .../build/buildrequest/buildrequest_test.go | 9 +++------ 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 05c97f722f..df7fb1952c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN --mount=type=cache,target=/go/rhel8/.cache,z \ --mount=type=cache,target=/go/rhel8/pkg/mod,z \ make install DESTDIR=./instroot-rhel8 && tar -C instroot-rhel8 -cf instroot-rhel8.tar . -FROM registry.ci.openshift.org/ocp/builder:rhel-9-enterprise-base-multi-openshift-4.19 +FROM registry.ci.openshift.org/ocp/4.20:base-rhel9 ARG TAGS="" COPY install /manifests RUN --mount=type=cache,target=/var/cache/dnf,z \ @@ -41,6 +41,8 @@ RUN --mount=type=cache,target=/var/cache/dnf,z \ if ! rpm -q util-linux; then dnf install --setopt=keepcache=true -y util-linux; fi && \ # We also need to install fuse-overlayfs and cpp for Buildah to work correctly. if ! rpm -q buildah; then dnf install --setopt=keepcache=true -y buildah fuse-overlayfs cpp --exclude container-selinux; fi && \ + # Install the oc binary. + if ! rpm -q openshift-clients; then dnf install --setopt=keepcache=true -y openshift-clients; fi && \ # Create the build user which will be used for doing OS image builds. We # use the username "build" and the uid 1000 since this matches what is in # the official Buildah image. diff --git a/Dockerfile.rhel7 b/Dockerfile.rhel7 index 09509d1a80..497f315935 100644 --- a/Dockerfile.rhel7 +++ b/Dockerfile.rhel7 @@ -42,10 +42,13 @@ RUN --mount=type=cache,target=/var/cache/dnf,z \ if ! rpm -q util-linux; then dnf install --setopt=keepcache=true -y util-linux; fi && \ # We also need to install fuse-overlayfs and cpp for Buildah to work correctly. if ! rpm -q buildah; then dnf install --setopt=keepcache=true -y buildah fuse-overlayfs cpp --exclude container-selinux; fi && \ + # Install the oc binary. + if ! rpm -q openshift-clients; then dnf install --setopt=keepcache=true -y openshift-clients; fi && \ # Create the build user which will be used for doing OS image builds. We # use the username "build" and the uid 1000 since this matches what is in # the official Buildah image. - useradd --uid 1000 build + # Conditional checks if "build" user does not exist before adding user. + if ! id -u "build" >/dev/null 2>&1; then useradd --uid 1000 build; fi # Copy the binaries *after* we install nmstate so we don't invalidate our cache for local builds. COPY --from=rhel9-builder /go/src/github.com/openshift/machine-config-operator/instroot-rhel9.tar /tmp/instroot-rhel9.tar RUN cd / && tar xf /tmp/instroot-rhel9.tar && rm -f /tmp/instroot-rhel9.tar diff --git a/pkg/controller/build/buildrequest/assets/buildah-build.sh b/pkg/controller/build/buildrequest/assets/buildah-build.sh index fdaba3120a..7080709ce9 100644 --- a/pkg/controller/build/buildrequest/assets/buildah-build.sh +++ b/pkg/controller/build/buildrequest/assets/buildah-build.sh @@ -98,4 +98,16 @@ buildah push \ --authfile="$FINAL_IMAGE_PUSH_CREDS" \ --digestfile="/tmp/done/digestfile" \ --cert-dir /var/run/secrets/kubernetes.io/serviceaccount "$TAG" + +# If the oc command is not present, then we must extract it from the base OS +# image which we've already pulled to do the build. +if ! command -v "oc" &> /dev/null; then + # Extract the oc binary from the base OS image and place it into the + # /tmp/done path. + container="$(buildah from --authfile="$BASE_IMAGE_PULL_CREDS" "$BASE_OS_IMAGE_PULLSPEC")" + buildah unshare /bin/bash -c 'cp "$(buildah mount "$container")/usr/bin/oc" "/tmp/done/oc"; buildah umount "$container"' + buildah rm "$container" + echo "Extracted oc command from $BASE_OS_IMAGE_PULLSPEC" +fi + EOF diff --git a/pkg/controller/build/buildrequest/assets/create-digest-cm.sh b/pkg/controller/build/buildrequest/assets/create-digest-cm.sh index db013c2040..39a783258e 100644 --- a/pkg/controller/build/buildrequest/assets/create-digest-cm.sh +++ b/pkg/controller/build/buildrequest/assets/create-digest-cm.sh @@ -6,7 +6,20 @@ set -xeuo -# Inject the contents of the digestfile into a ConfigMap. +# Check if the oc command is available. +if command -v "oc" &> /dev/null; then + echo "Using built-in oc command" +else + # If the oc command is not available, check under /tmp/done/oc. + if [[ -x /tmp/done/oc ]]; then + # Add this to our PATH if found. + export PATH="$PATH:/tmp/done" + else + # If it cannot be found, return a non-zero exit code. + echo "oc command not found" + exit 1 + fi +fi # Create and label the digestfile ConfigMap if ! oc create configmap \ diff --git a/pkg/controller/build/buildrequest/buildrequest.go b/pkg/controller/build/buildrequest/buildrequest.go index 5bd5b300e3..32f3867a33 100644 --- a/pkg/controller/build/buildrequest/buildrequest.go +++ b/pkg/controller/build/buildrequest/buildrequest.go @@ -451,6 +451,10 @@ func (br buildRequestImpl) toBuildahPod() *corev1.Pod { Name: "NO_PROXY", Value: noProxy, }, + { + Name: "BASE_OS_IMAGE_PULLSPEC", + Value: br.opts.OSImageURLConfig.BaseOSContainerImage, + }, } securityContext := &corev1.SecurityContext{} @@ -560,7 +564,6 @@ func (br buildRequestImpl) toBuildahPod() *corev1.Pod { VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: br.getBasePullSecretName(), - // SecretName: br.opts.MachineOSConfig.Spec.BuildInputs.BaseImagePullSecret.Name, Items: []corev1.KeyToPath{ { Key: corev1.DockerConfigJsonKey, @@ -575,7 +578,6 @@ func (br buildRequestImpl) toBuildahPod() *corev1.Pod { Name: "final-image-push-creds", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - // SecretName: br.opts.MachineOSConfig.Spec.BuildInputs.RenderedImagePushSecret.Name, SecretName: br.getFinalPushSecretName(), Items: []corev1.KeyToPath{ { @@ -587,14 +589,11 @@ func (br buildRequestImpl) toBuildahPod() *corev1.Pod { }, }, { - // Provides a way for the "image-build" container to signal that it - // finished so that the "wait-for-done" container can retrieve the - // iamge SHA. + // Provides a way for the "image-build" container to pass the digested + // pullspec and oc binary to the "create-digest-configmap" container. Name: "done", VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: corev1.StorageMediumMemory, - }, + EmptyDir: &corev1.EmptyDirVolumeSource{}, }, }, { @@ -671,7 +670,7 @@ func (br buildRequestImpl) toBuildahPod() *corev1.Pod { // us to avoid parsing log files. Name: "create-digest-configmap", Command: append(command, digestCMScript), - Image: br.opts.OSImageURLConfig.BaseOSContainerImage, + Image: br.opts.Images.MachineConfigOperator, Env: env, ImagePullPolicy: corev1.PullAlways, SecurityContext: securityContext, diff --git a/pkg/controller/build/buildrequest/buildrequest_test.go b/pkg/controller/build/buildrequest/buildrequest_test.go index 7939084747..f0131cf61d 100644 --- a/pkg/controller/build/buildrequest/buildrequest_test.go +++ b/pkg/controller/build/buildrequest/buildrequest_test.go @@ -211,6 +211,8 @@ func assertSecretInCorrectFormat(t *testing.T, secret *corev1.Secret) { } func assertBuildJobIsCorrect(t *testing.T, buildJob *batchv1.Job, opts BuildRequestOpts) { + t.Helper() + etcRpmGpgKeysOpts := optsForEtcRpmGpgKeys() assertBuildJobMatchesExpectations(t, opts.HasEtcPkiRpmGpgKeys, buildJob, etcRpmGpgKeysOpts.envVar(), @@ -233,12 +235,7 @@ func assertBuildJobIsCorrect(t *testing.T, buildJob *batchv1.Job, opts BuildRequ ) assert.Equal(t, buildJob.Spec.Template.Spec.InitContainers[0].Image, mcoImagePullspec) - expectedPullspecs := []string{ - "base-os-image-from-machineosconfig", - fixtures.OSImageURLConfig().BaseOSContainerImage, - } - - assert.Contains(t, expectedPullspecs, buildJob.Spec.Template.Spec.Containers[0].Image) + assert.Equal(t, buildJob.Spec.Template.Spec.Containers[0].Image, mcoImagePullspec) assertPodHasVolume(t, buildJob.Spec.Template.Spec, corev1.Volume{ Name: "final-image-push-creds", From 70f394ef8dca60d34c0850d7a163363be8708682 Mon Sep 17 00:00:00 2001 From: Zack Zlotnik Date: Wed, 15 Oct 2025 12:03:55 -0400 Subject: [PATCH 2/2] [REVERT LATER] - removed -failfast flag --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 619ad298ae..1ed8bae2b7 100644 --- a/Makefile +++ b/Makefile @@ -204,7 +204,7 @@ test-e2e-single-node: install-go-junit-report set -o pipefail; go test -tags=$(GOTAGS) -failfast -timeout 120m -v$${WHAT:+ -run="$$WHAT"} ./test/e2e-single-node/ | ./hack/test-with-junit.sh $(@) test-e2e-ocl: install-go-junit-report - set -o pipefail; go test -tags=$(GOTAGS) -failfast -timeout 120m -v$${WHAT:+ -run="$$WHAT"} ./test/e2e-ocl/ | ./hack/test-with-junit.sh $(@) + set -o pipefail; go test -tags=$(GOTAGS) -timeout 120m -v$${WHAT:+ -run="$$WHAT"} ./test/e2e-ocl/ | ./hack/test-with-junit.sh $(@) bootstrap-e2e: install-go-junit-report install-setup-envtest @echo "Setting up KUBEBUILDER_ASSETS"