From 8a9d126f83dc32aa531beb7a68e8c4a7a4198171 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 5 Jun 2026 14:44:41 -0400 Subject: [PATCH 1/3] Added check for missingAnnotation --- pkg/controller/build/reconciler.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/controller/build/reconciler.go b/pkg/controller/build/reconciler.go index 6bb112dcea..08d5f26234 100644 --- a/pkg/controller/build/reconciler.go +++ b/pkg/controller/build/reconciler.go @@ -1371,6 +1371,12 @@ func (b *buildReconciler) reconcilePoolChange(ctx context.Context, mcp *mcfgv1.M return err } + // No action needed if the rendered config has not changed. + if oldRendered == newRendered && firstOptIn != "" { + klog.V(4).Infof("pool %q: Configuration unchanged (%s), no action needed", mcp.Name, oldRendered) + return nil + } + // This is our trigger point if (oldRendered != newRendered && needsImageRebuild) || firstOptIn == "" { klog.Infof("pool %q: rendered config changed and requires an image rebuild. Verifying if a valid build already exists...", mcp.Name) From a52bfa99c0a038cb5cf174f4b23f697168e8a7f5 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 22 Jun 2026 10:11:26 -0400 Subject: [PATCH 2/3] Allow empty firstOptIn annotation in reconciler --- pkg/controller/build/reconciler.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/controller/build/reconciler.go b/pkg/controller/build/reconciler.go index 08d5f26234..8c21038073 100644 --- a/pkg/controller/build/reconciler.go +++ b/pkg/controller/build/reconciler.go @@ -1362,16 +1362,13 @@ func (b *buildReconciler) reconcilePoolChange(ctx context.Context, mcp *mcfgv1.M // old pool old := mcp.DeepCopy() old.Spec.Configuration.Name = mcp.Status.Configuration.Name - if firstOptIn == "" { - return fmt.Errorf("no current build annotation on MachineOSConfig %q", mosc.Name) - } needsImageRebuild, err := b.reconcileImageRebuild(old, mcp) if err != nil { return err } - // No action needed if the rendered config has not changed. + // No action needed if the rendered config has not changed and we have an annotation if oldRendered == newRendered && firstOptIn != "" { klog.V(4).Infof("pool %q: Configuration unchanged (%s), no action needed", mcp.Name, oldRendered) return nil From 1f723981b88713b0aff5f71d7607a4f90e481b27 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 2 Jul 2026 11:03:31 -0400 Subject: [PATCH 3/3] Annotate MOSB with job UID when reusing an existing build job --- .../build/imagebuilder/jobimagebuilder.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pkg/controller/build/imagebuilder/jobimagebuilder.go b/pkg/controller/build/imagebuilder/jobimagebuilder.go index ad65e9670c..84276d6c60 100644 --- a/pkg/controller/build/imagebuilder/jobimagebuilder.go +++ b/pkg/controller/build/imagebuilder/jobimagebuilder.go @@ -147,7 +147,21 @@ func (j *jobImageBuilder) start(ctx context.Context) (*batchv1.Job, error) { } if k8serrors.IsAlreadyExists(err) { - return j.getBuildJobStrict(ctx) + existingJob, getErr := j.getBuildJobStrict(ctx) + if getErr != nil { + return nil, getErr + } + + klog.Infof("Build job %q already exists for MachineOSBuild %q, reusing", existingJob.Name, mosbName) + + if j.mosb != nil { + metav1.SetMetaDataAnnotation(&j.mosb.ObjectMeta, constants.JobUIDAnnotationKey, string(existingJob.UID)) + if _, updateErr := j.mcfgclient.MachineconfigurationV1().MachineOSBuilds().Update(ctx, j.mosb, metav1.UpdateOptions{}); updateErr != nil && !k8serrors.IsNotFound(updateErr) { + return nil, fmt.Errorf("could not update MachineOSBuild %s with job UID annotation: %w", mosbName, updateErr) + } + } + + return existingJob, nil } return nil, fmt.Errorf("could not create build job: %w", err)