Skip to content

Commit 435bbef

Browse files
reboot work
1 parent b7b1294 commit 435bbef

File tree

10 files changed

+312
-83
lines changed

10 files changed

+312
-83
lines changed

pkg/controller/build/buildrequest/assets/Containerfile.on-cluster-build-template

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ RUN mkdir -p /etc/machine-config-daemon && \
1313
FROM {{.BaseOSImage}} AS configs
1414
# Copy the extracted MachineConfig into the expected place in the image.
1515
COPY --from=extract /etc/machine-config-daemon/currentconfig /etc/machine-config-daemon/currentconfig
16+
# Do the ignition live-apply, extracting the Ignition config from the MachineConfig.
17+
# Not sure why Ignition explicitly requires the container env var to be set
18+
# since it should be set by the container runtime / builder.
19+
RUN container="oci" exec -a ignition-apply /usr/lib/dracut/modules.d/30ignition/ignition --ignore-unsupported <(cat /etc/machine-config-daemon/currentconfig | jq '.spec.config') && \
20+
ostree container commit
1621
# Install any extensions specified
1722
{{if and .ExtensionsImage .ExtensionsPackages}}
1823
# Mount the extensions image to use the content from it

pkg/controller/build/clients.go

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
type informers struct {
2424
controllerConfigInformer mcfginformersv1.ControllerConfigInformer
2525
machineConfigPoolInformer mcfginformersv1.MachineConfigPoolInformer
26+
machineConfigInformer mcfginformersv1.MachineConfigInformer
2627
jobInformer batchinformersv1.JobInformer
2728
machineOSBuildInformer mcfginformersv1.MachineOSBuildInformer
2829
machineOSConfigInformer mcfginformersv1.MachineOSConfigInformer
@@ -43,6 +44,7 @@ func (i *informers) listers() *listers {
4344
machineOSBuildLister: i.machineOSBuildInformer.Lister(),
4445
machineOSConfigLister: i.machineOSConfigInformer.Lister(),
4546
machineConfigPoolLister: i.machineConfigPoolInformer.Lister(),
47+
machineConfigLister: i.machineConfigInformer.Lister(),
4648
jobLister: i.jobInformer.Lister(),
4749
controllerConfigLister: i.controllerConfigInformer.Lister(),
4850
}
@@ -53,6 +55,7 @@ type listers struct {
5355
machineOSBuildLister mcfglistersv1.MachineOSBuildLister
5456
machineOSConfigLister mcfglistersv1.MachineOSConfigLister
5557
machineConfigPoolLister mcfglistersv1.MachineConfigPoolLister
58+
machineConfigLister mcfglistersv1.MachineConfigLister
5659
jobLister batchlisterv1.JobLister
5760
controllerConfigLister mcfglistersv1.ControllerConfigLister
5861
}
@@ -84,6 +87,7 @@ func newInformers(mcfgclient mcfgclientset.Interface, kubeclient clientset.Inter
8487
controllerConfigInformer := mcoInformerFactory.Machineconfiguration().V1().ControllerConfigs()
8588
machineConfigPoolInformer := mcoInformerFactory.Machineconfiguration().V1().MachineConfigPools()
8689
machineOSBuildInformer := mcoInformerFactory.Machineconfiguration().V1().MachineOSBuilds()
90+
machineConfigInformer := mcoInformerFactory.Machineconfiguration().V1().MachineConfigs()
8791
machineOSConfigInformer := mcoInformerFactory.Machineconfiguration().V1().MachineOSConfigs()
8892
jobInformer := coreInformerFactory.Batch().V1().Jobs()
8993

@@ -92,6 +96,7 @@ func newInformers(mcfgclient mcfgclientset.Interface, kubeclient clientset.Inter
9296
machineConfigPoolInformer: machineConfigPoolInformer,
9397
machineOSBuildInformer: machineOSBuildInformer,
9498
machineOSConfigInformer: machineOSConfigInformer,
99+
machineConfigInformer: machineConfigInformer,
95100
jobInformer: jobInformer,
96101
toStart: []interface{ Start(<-chan struct{}) }{
97102
mcoInformerFactory,
@@ -103,6 +108,7 @@ func newInformers(mcfgclient mcfgclientset.Interface, kubeclient clientset.Inter
103108
jobInformer.Informer().HasSynced,
104109
machineOSBuildInformer.Informer().HasSynced,
105110
machineOSConfigInformer.Informer().HasSynced,
111+
machineConfigInformer.Informer().HasSynced,
106112
},
107113
}
108114
}

pkg/controller/build/constants/constants.go

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ const (
2929
CurrentMachineOSBuildAnnotationKey string = "machineconfiguration.openshift.io/current-machine-os-build"
3030
)
3131

32+
// RenderedMCWithImageLabel is the label that signifies an MC change requires an OCL image change and node reboot
33+
const (
34+
RenderedMCWithImageLabel = "machineconfiguration.openshift.io/rendered-mc-with-image"
35+
)
36+
3237
// When this annotation is added to a MachineOSConfig, the current
3338
// MachineOSBuild will be deleted, which will cause a rebuild to occur.
3439
const (

pkg/controller/build/reconciler.go

+171-17
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func (b *buildReconciler) updateMachineOSConfig(ctx context.Context, old, cur *m
102102

103103
// Whenever the MachineOSConfig spec has changed, create a new MachineOSBuild.
104104
if !equality.Semantic.DeepEqual(old.Spec, cur.Spec) {
105-
klog.Infof("Detected MachineOSConfig change for %s", cur.Name)
105+
klog.Infof("[updateMachineOSConfig] Detected MachineOSConfig change and kicking off createNewMachineOSBuildOrReuseExisting for %s", cur.Name)
106106
return b.createNewMachineOSBuildOrReuseExisting(ctx, cur, false)
107107
}
108108

@@ -316,7 +316,7 @@ func (b *buildReconciler) updateMachineOSConfigStatus(ctx context.Context, mosc
316316

317317
// skip the status update if the current image pullspec equals the digest image pushspec.
318318
if mosc.Status.CurrentImagePullSpec == mosb.Status.DigestedImagePushSpec {
319-
klog.Infof("MachineOSConfig %q already has final image pushspec for MachineOSBuild %q", mosc.Name, mosb.Name)
319+
klog.Infof("[updateMachineOSConfig] MachineOSConfig %q already has final image pushspec for MachineOSBuild %q", mosc.Name, mosb.Name)
320320
return nil
321321
}
322322

@@ -356,16 +356,56 @@ func (b *buildReconciler) UpdateMachineConfigPool(ctx context.Context, oldMCP, c
356356
// Sepcifically, whenever a new rendered MachineConfig is applied, it will
357357
// create a new MachineOSBuild in response.
358358
func (b *buildReconciler) updateMachineConfigPool(ctx context.Context, oldMCP, curMCP *mcfgv1.MachineConfigPool) error {
359-
if oldMCP.Spec.Configuration.Name != curMCP.Spec.Configuration.Name {
360-
klog.Infof("Rendered config for pool %s changed from %s to %s", curMCP.Name, oldMCP.Spec.Configuration.Name, curMCP.Spec.Configuration.Name)
361-
if err := b.createNewMachineOSBuildOrReuseExistingForPoolChange(ctx, curMCP); err != nil {
362-
return fmt.Errorf("could not create or reuse existing MachineOSBuild for MachineConfigPool %q change: %w", curMCP.Name, err)
359+
360+
// Did the rendered-MC actually change?
361+
needsImageRebuild, err := b.reconcilePoolChange(oldMCP, curMCP)
362+
if err != nil {
363+
return err
364+
}
365+
366+
/////////// REMOVE JUST FOR LOGS ///////////
367+
// Get current and desired MachineConfigs
368+
curMC, err := b.machineConfigLister.Get(oldMCP.Spec.Configuration.Name)
369+
if err != nil {
370+
return fmt.Errorf("error getting current MachineConfig %s: %w", oldMCP.Spec.Configuration.Name, err)
371+
}
372+
373+
desMC, err := b.machineConfigLister.Get(curMCP.Spec.Configuration.Name)
374+
if err != nil {
375+
return fmt.Errorf("error getting desired MachineConfig %s: %w", curMCP.Spec.Configuration.Name, err)
376+
}
377+
378+
klog.Infof("desMC is %s", desMC.Name)
379+
klog.Infof("currMC is %s", curMC.Name)
380+
/////////// REMOVE JUST FOR LOGS ///////////
381+
382+
mosc, err := utils.GetMachineOSConfigForMachineConfigPool(curMCP, b.utilListers())
383+
if err != nil {
384+
return fmt.Errorf("could not find MachineOSConfig for pool %q: %w", curMCP.Name, err)
385+
}
386+
existingName := mosc.Annotations[constants.CurrentMachineOSBuildAnnotationKey]
387+
if existingName == "" {
388+
return fmt.Errorf("no current build annotation on MachineOSConfig %q", mosc.Name)
389+
}
390+
existingMosb, err := b.machineOSBuildLister.Get(existingName)
391+
if err != nil {
392+
return fmt.Errorf("could not fetch existing MachineOSBuild %q: %w", existingName, err)
393+
}
394+
if !needsImageRebuild && existingMosb != nil {
395+
if err := b.deleteMachineOSBuild(ctx, existingMosb); err != nil {
396+
return err
363397
}
398+
return b.createNewMachineOSBuildOrReuseExisting(ctx, mosc, true)
399+
} else {
400+
return b.createNewMachineOSBuildOrReuseExistingForPoolChange(ctx, curMCP)
364401
}
402+
}
365403

366-
// Not sure if we need to do this here yet or not.
367-
// TODO: Determine if we should call b.syncMachineConfigPools() here or not.
368-
return b.syncAll(ctx)
404+
func (b *buildReconciler) patchMOSBLabels(ctx context.Context, mosb *mcfgv1.MachineOSBuild, newMCName string) error {
405+
mosbCopy := mosb.DeepCopy()
406+
mosbCopy.Labels[constants.RenderedMachineConfigLabelKey] = newMCName
407+
_, err := b.mcfgclient.MachineconfigurationV1().MachineOSBuilds().Update(ctx, mosbCopy, metav1.UpdateOptions{})
408+
return err
369409
}
370410

371411
// Adds a MachineOSBuild.
@@ -525,7 +565,7 @@ func (b *buildReconciler) createNewMachineOSBuildOrReuseExisting(ctx context.Con
525565
// previously built image pullspec and adjust the MachineOSConfig to use that
526566
// image instead.
527567
if err == nil && existingMosb != nil {
528-
if err := b.reuseExistingMachineOSBuildIfPossible(ctx, mosc, existingMosb); err != nil {
568+
if err := b.reuseExistingMachineOSBuildIfPossible(ctx, mosc, existingMosb, mcp); err != nil {
529569
return fmt.Errorf("could not reuse existing MachineOSBuild %q for MachineOSConfig %q: %w", existingMosb.Name, mosc.Name, err)
530570
}
531571
return nil
@@ -534,7 +574,7 @@ func (b *buildReconciler) createNewMachineOSBuildOrReuseExisting(ctx context.Con
534574
// In this situation, we've determined that the MachineOSBuild does not
535575
// exist, so we need to create it.
536576
if k8serrors.IsNotFound(err) {
537-
_, err := b.mcfgclient.MachineconfigurationV1().MachineOSBuilds().Create(ctx, mosb, metav1.CreateOptions{})
577+
mosb, err := b.mcfgclient.MachineconfigurationV1().MachineOSBuilds().Create(ctx, mosb, metav1.CreateOptions{})
538578
if err != nil {
539579
return fmt.Errorf("could not create new MachineOSBuild %q: %w", mosb.Name, err)
540580
}
@@ -545,7 +585,7 @@ func (b *buildReconciler) createNewMachineOSBuildOrReuseExisting(ctx context.Con
545585
}
546586

547587
// Determines if a preexising MachineOSBuild can be reused and if possible, does it.
548-
func (b *buildReconciler) reuseExistingMachineOSBuildIfPossible(ctx context.Context, mosc *mcfgv1.MachineOSConfig, existingMosb *mcfgv1.MachineOSBuild) error {
588+
func (b *buildReconciler) reuseExistingMachineOSBuildIfPossible(ctx context.Context, mosc *mcfgv1.MachineOSConfig, existingMosb *mcfgv1.MachineOSBuild, mcp *mcfgv1.MachineConfigPool) error {
549589
existingMosbState := ctrlcommon.NewMachineOSBuildState(existingMosb)
550590

551591
canBeReused := false
@@ -572,6 +612,10 @@ func (b *buildReconciler) reuseExistingMachineOSBuildIfPossible(ctx context.Cont
572612
if err := b.updateMachineOSConfigStatus(ctx, mosc, existingMosb); err != nil {
573613
return fmt.Errorf("could not update MachineOSConfig %q status to reuse preexisting MachineOSBuild %q: %w", mosc.Name, existingMosb.Name, err)
574614
}
615+
616+
if err := b.patchMOSBLabels(ctx, existingMosb, mcp.Spec.Configuration.Name); err != nil {
617+
return fmt.Errorf("could not patch MOSB labels")
618+
}
575619
}
576620

577621
return nil
@@ -927,12 +971,62 @@ func (b *buildReconciler) syncMachineOSBuild(ctx context.Context, mosb *mcfgv1.M
927971
return fmt.Errorf("could not get MachineConfigPool from MachineOSBuild %q: %w", mosb.Name, err)
928972
}
929973

930-
// An mosb which had previously been forgotten by the queue and is no longer desired by the mcp should not build
931974
if mosb.ObjectMeta.Labels[constants.RenderedMachineConfigLabelKey] != mcp.Spec.Configuration.Name {
932975
klog.Infof("The MachineOSBuild %q which builds the rendered Machine Config %q is no longer desired by the MCP %q", mosb.Name, mosb.ObjectMeta.Labels[constants.RenderedMachineConfigLabelKey], mosb.ObjectMeta.Labels[constants.TargetMachineConfigPoolLabelKey])
933976
return nil
934977
}
935978

979+
// desiredMC, err := b.machineConfigLister.Get(mcp.Spec.Configuration.Name)
980+
// if err != nil {
981+
// return fmt.Errorf("error getting desired MC: %w", err)
982+
// }
983+
984+
// // existing MC labels
985+
// currentWithImage := mosb.Labels[constants.RenderedMCWithImageLabel]
986+
// currMC := mosb.Labels[constants.RenderedMachineConfigLabelKey]
987+
988+
// oldMC, err := b.machineConfigLister.Get(currMC)
989+
// if err != nil {
990+
// return fmt.Errorf("could not fetch old MachineConfig %q: %w", currMC, err)
991+
// }
992+
993+
// // new MC labels
994+
// desMC := desiredMC.Name
995+
// newWithImage := currentWithImage
996+
997+
// mosbCopy := mosb.DeepCopy()
998+
// updateLabels := false
999+
1000+
// if currMC != desMC {
1001+
// klog.Info("Current MC does not equal the new MC, we need to update our labels to reflect that")
1002+
// mosbCopy.Labels[constants.RenderedMachineConfigLabelKey] = desMC
1003+
// updateLabels = true
1004+
// }
1005+
1006+
// if ctrlcommon.RequiresRebuild(oldMC, desiredMC) && currentWithImage != newWithImage {
1007+
// mosbCopy.Labels[constants.RenderedMCWithImageLabel] = newWithImage
1008+
// updateLabels = true
1009+
// }
1010+
1011+
// if updateLabels {
1012+
// klog.Infof("syncMachineOSBuild: Updating labels for MOSB %q (currentNoImage=%s, desiredMCName=%s, desiredWithImage=%s, currentWithImage=%s)",
1013+
// mosb.Name, currMC, desMC, newWithImage, currentWithImage)
1014+
1015+
// mosbCopy.Labels[constants.RenderedMachineConfigLabelKey] = desMC
1016+
// mosbCopy.Labels[constants.RenderedMCWithImageLabel] = newWithImage
1017+
1018+
// // Update the MOSB object
1019+
// _, err := b.mcfgclient.MachineconfigurationV1().MachineOSBuilds().Update(ctx, mosbCopy, metav1.UpdateOptions{})
1020+
// if err != nil {
1021+
// klog.Errorf("syncMachineOSBuild: Failed to update MOSB %q labels: %v", mosb.Name, err)
1022+
1023+
// return fmt.Errorf("failed to sync labels: %v", err)
1024+
// }
1025+
// klog.Infof("syncMachineOSBuild: Updated MOSB %q labels to RenderedMCNoImageLabel=%s, RenderedMCWithImageLabel=%s",
1026+
// mosb.Name, desiredMC.Name, newWithImage)
1027+
// return nil
1028+
// }
1029+
9361030
mosbState := ctrlcommon.NewMachineOSBuildState(mosb)
9371031

9381032
if mosbState.IsInTerminalState() {
@@ -1029,7 +1123,7 @@ func (b *buildReconciler) syncMachineOSConfig(ctx context.Context, mosc *mcfgv1.
10291123
}
10301124
}
10311125

1032-
klog.Infof("No matching MachineOSBuild found for MachineOSConfig %q, will create one", mosc.Name)
1126+
klog.Infof("syncMachineOSConfig: No matching MachineOSBuild found for MachineOSConfig %q, will create one by kicking off createNewMachineOSBuildOrReuseExisting", mosc.Name)
10331127
if err := b.createNewMachineOSBuildOrReuseExisting(ctx, mosc, false); err != nil {
10341128
return fmt.Errorf("could not create new or reuse existing MachineOSBuild for MachineOSConfig %q: %w", mosc.Name, err)
10351129
}
@@ -1066,7 +1160,67 @@ func (b *buildReconciler) syncMachineConfigPools(ctx context.Context) error {
10661160
// MachineOSConfigs and MachineOSBuilds, which will create a new MachineOSBuild,
10671161
// if needed.
10681162
func (b *buildReconciler) syncMachineConfigPool(ctx context.Context, mcp *mcfgv1.MachineConfigPool) error {
1069-
return b.timeObjectOperation(mcp, syncingVerb, func() error {
1070-
return b.createNewMachineOSBuildOrReuseExistingForPoolChange(ctx, mcp)
1071-
})
1163+
mosc, err := utils.GetMachineOSConfigForMachineConfigPool(mcp, b.utilListers())
1164+
if err != nil {
1165+
// Not opted in yet, so nothing for us to do.
1166+
klog.V(4).Infof("buildReconciler: no MachineOSConfig for pool %q, skipping", mcp.Name)
1167+
return nil
1168+
}
1169+
// old pool
1170+
old := mcp.DeepCopy()
1171+
old.Spec.Configuration.Name = mcp.Status.Configuration.Name
1172+
1173+
// decide if we annotate or reuse
1174+
needsImageRebuild, err := b.reconcilePoolChange(old, mcp)
1175+
if err != nil {
1176+
return err
1177+
}
1178+
1179+
existingName := mosc.Annotations[constants.CurrentMachineOSBuildAnnotationKey]
1180+
if existingName == "" {
1181+
return fmt.Errorf("no current build annotation on MachineOSConfig %q", mosc.Name)
1182+
}
1183+
1184+
existingMosb, err := b.machineOSBuildLister.Get(existingName)
1185+
if err != nil {
1186+
return fmt.Errorf("could not fetch existing MachineOSBuild %q: %w", existingName, err)
1187+
}
1188+
klog.Infof("existing MOSB is %s", existingMosb.Name)
1189+
1190+
if !needsImageRebuild && existingMosb != nil {
1191+
if err := b.deleteMachineOSBuild(ctx, existingMosb); err != nil {
1192+
return err
1193+
}
1194+
return b.createNewMachineOSBuildOrReuseExisting(ctx, mosc, true)
1195+
}
1196+
return b.createNewMachineOSBuildOrReuseExistingForPoolChange(ctx, mcp)
1197+
1198+
}
1199+
1200+
// reconcilePoolChange returns (annotateRebuild bool, reuseOnly bool, err error)
1201+
func (b *buildReconciler) reconcilePoolChange(oldMCP, curMCP *mcfgv1.MachineConfigPool) (bool, error) {
1202+
1203+
// // if the old mc is the same as the new mc, no updates needed
1204+
// if oldMCP.Spec.Configuration.Name == curMCP.Spec.Configuration.Name {
1205+
// klog.Info("old mc is the same as the new mc")
1206+
// return false, true, nil
1207+
// }
1208+
1209+
curr, err := b.machineConfigLister.Get(oldMCP.Spec.Configuration.Name)
1210+
if err != nil {
1211+
return false, err
1212+
}
1213+
des, err := b.machineConfigLister.Get(curMCP.Spec.Configuration.Name)
1214+
if err != nil {
1215+
return false, err
1216+
}
1217+
1218+
needsImageRebuild := ctrlcommon.RequiresRebuild(curr, des)
1219+
if needsImageRebuild {
1220+
klog.Info("needsimage rebuild is true, signalling a rebuild")
1221+
return true, nil
1222+
}
1223+
1224+
klog.Info("reconciled pool change, no rebuild needed")
1225+
return false, nil
10721226
}

pkg/controller/build/utils/selectors.go

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func GetMachineOSBuildLabels(mosc *mcfgv1.MachineOSConfig, mcp *mcfgv1.MachineCo
1717
return map[string]string{
1818
constants.TargetMachineConfigPoolLabelKey: mcp.Name,
1919
constants.RenderedMachineConfigLabelKey: mcp.Spec.Configuration.Name,
20+
constants.RenderedMCWithImageLabel: mcp.Spec.Configuration.Name,
2021
constants.MachineOSConfigNameLabelKey: mosc.Name,
2122
}
2223
}

pkg/controller/common/helpers.go

+8
Original file line numberDiff line numberDiff line change
@@ -1462,3 +1462,11 @@ func GetCAsFromConfigMap(cm *corev1.ConfigMap, key string) ([]byte, error) {
14621462
}
14631463
return nil, fmt.Errorf("%s not found in %s/%s", key, cm.Namespace, cm.Name)
14641464
}
1465+
1466+
// Determines if an on-cluster layering image rollout and rebuild is required for the changes applied on the new MC
1467+
func RequiresRebuild(oldMC, newMC *mcfgv1.MachineConfig) bool {
1468+
return oldMC.Spec.OSImageURL != newMC.Spec.OSImageURL ||
1469+
oldMC.Spec.KernelType != newMC.Spec.KernelType ||
1470+
!reflect.DeepEqual(oldMC.Spec.Extensions, newMC.Spec.Extensions) ||
1471+
!reflect.DeepEqual(oldMC.Spec.KernelArguments, newMC.Spec.KernelArguments)
1472+
}

0 commit comments

Comments
 (0)