diff --git a/pkg/controller/drain/drain_controller.go b/pkg/controller/drain/drain_controller.go index 09e87047cd..2553375fec 100644 --- a/pkg/controller/drain/drain_controller.go +++ b/pkg/controller/drain/drain_controller.go @@ -316,7 +316,7 @@ func (ctrl *Controller) syncNode(key string) error { } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(ctrl.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(ctrl.mcpLister, node) if err != nil { return err } @@ -334,7 +334,8 @@ func (ctrl *Controller) syncNode(key string) error { node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if nErr != nil { klog.Errorf("Error making MCN for Uncordon failure: %v", err) @@ -350,7 +351,8 @@ func (ctrl *Controller) syncNode(key string) error { node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for UnCordon success: %v", err) @@ -406,7 +408,7 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(ctrl.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(ctrl.mcpLister, node) if err != nil { return err } @@ -422,7 +424,8 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if Nerr != nil { klog.Errorf("Error making MCN for Cordon Failure: %v", Nerr) @@ -437,7 +440,8 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Cordon Success: %v", err) @@ -454,7 +458,8 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Drain beginning: %v", err) @@ -484,7 +489,8 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if nErr != nil { klog.Errorf("Error making MCN for Drain failure: %v", nErr) @@ -501,7 +507,8 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro node, ctrl.client, ctrl.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Drain success: %v", err) diff --git a/pkg/controller/node/node_controller_test.go b/pkg/controller/node/node_controller_test.go index 3b26af09fc..195c0ec3e1 100644 --- a/pkg/controller/node/node_controller_test.go +++ b/pkg/controller/node/node_controller_test.go @@ -91,7 +91,7 @@ func newFixtureWithFeatureGates(t *testing.T, enabled, disabled []configv1.Featu } func newFixture(t *testing.T) *fixture { - return newFixtureWithFeatureGates(t, []configv1.FeatureGateName{features.FeatureGatePinnedImages, features.FeatureGateOnClusterBuild}, []configv1.FeatureGateName{}) + return newFixtureWithFeatureGates(t, []configv1.FeatureGateName{features.FeatureGateMachineConfigNodes, features.FeatureGatePinnedImages, features.FeatureGateOnClusterBuild}, []configv1.FeatureGateName{}) } func (f *fixture) newControllerWithStopChan(stopCh <-chan struct{}) *Controller { @@ -140,18 +140,10 @@ func (f *fixture) newController() *Controller { return f.newControllerWithStopChan(stopCh) } -func (f *fixture) newControllerWithContext(ctx context.Context) *Controller { - return f.newControllerWithStopChan(ctx.Done()) -} - func (f *fixture) run(pool string) { f.runController(pool, false) } -func (f *fixture) runExpectError(pool string) { - f.runController(pool, true) -} - func (f *fixture) runController(pool string, expectError bool) { c := f.newController() @@ -260,7 +252,9 @@ func filterInformerActions(actions []core.Action) []core.Action { action.Matches("list", "machineosbuilds") || action.Matches("watch", "machineosbuilds") || action.Matches("list", "machineosconfigs") || - action.Matches("watch", "machineosconfigs")) { + action.Matches("watch", "machineosconfigs") || + action.Matches("get", "machineconfignodes") || + action.Matches("create", "machineconfignodes")) { continue } ret = append(ret, action) @@ -1146,7 +1140,7 @@ func TestShouldMakeProgress(t *testing.T) { expectTaintsAddPatch: false, }, { - description: "node not at desired config, patch on annotation and taints", // failing + description: "node not at desired config, patch on annotation and taints", node: newNodeWithLabel("nodeNeedingUpdates", machineConfigV0, machineConfigV0, map[string]string{"node-role/worker": "", "node-role/infra": ""}), expectAnnotationPatch: true, expectTaintsAddPatch: true, diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 44309a92f5..f2cbd91501 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -713,7 +713,7 @@ func (dn *Daemon) syncNode(key string) error { } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, node) if err != nil { return err } @@ -728,7 +728,8 @@ func (dn *Daemon) syncNode(key string) error { node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Rebooted: %v", err) @@ -804,7 +805,8 @@ func (dn *Daemon) syncNode(key string) error { node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Resumed true: %v", err) @@ -843,7 +845,8 @@ func (dn *Daemon) syncNode(key string) error { dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Updated false: %v", err) @@ -868,7 +871,8 @@ func (dn *Daemon) syncNode(key string) error { dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Updated: %v", err) @@ -2319,7 +2323,7 @@ func (dn *Daemon) updateConfigAndState(state *stateAndConfigs) (bool, bool, erro // let's mark it done! // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return missingODC, inDesiredConfig, err } @@ -2332,7 +2336,8 @@ func (dn *Daemon) updateConfigAndState(state *stateAndConfigs) (bool, bool, erro dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Resumed true: %v", err) diff --git a/pkg/daemon/drain.go b/pkg/daemon/drain.go index cfc4ffaed1..1ecec21394 100644 --- a/pkg/daemon/drain.go +++ b/pkg/daemon/drain.go @@ -43,7 +43,7 @@ func (dn *Daemon) performDrain() error { logSystem("Drain not required, skipping") // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } @@ -56,7 +56,8 @@ func (dn *Daemon) performDrain() error { dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Drain not required: %v", err) diff --git a/pkg/daemon/pinned_image_set.go b/pkg/daemon/pinned_image_set.go index b514441bf7..5414618c56 100644 --- a/pkg/daemon/pinned_image_set.go +++ b/pkg/daemon/pinned_image_set.go @@ -547,7 +547,7 @@ func (p *PinnedImageSetManager) updateStatusProgressing(pools []*mcfgv1.MachineC } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(p.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(p.mcpLister, node) if err != nil { return err } @@ -565,7 +565,8 @@ func (p *PinnedImageSetManager) updateStatusProgressing(pools []*mcfgv1.MachineC p.mcfgClient, applyCfg, p.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) } @@ -582,7 +583,7 @@ func (p *PinnedImageSetManager) updateStatusProgressingComplete(pools []*mcfgv1. } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(p.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(p.mcpLister, node) if err != nil { return err } @@ -600,7 +601,8 @@ func (p *PinnedImageSetManager) updateStatusProgressingComplete(pools []*mcfgv1. p.mcfgClient, applyCfg, p.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Failed to update machine config node: %v", err) @@ -620,7 +622,8 @@ func (p *PinnedImageSetManager) updateStatusProgressingComplete(pools []*mcfgv1. p.mcfgClient, nil, p.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) } @@ -637,7 +640,7 @@ func (p *PinnedImageSetManager) updateStatusError(pools []*mcfgv1.MachineConfigP } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(p.mcpLister, node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(p.mcpLister, node) if err != nil { return err } @@ -655,7 +658,8 @@ func (p *PinnedImageSetManager) updateStatusError(pools []*mcfgv1.MachineConfigP p.mcfgClient, applyCfg, p.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) } diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go index 637f1f8977..16fed4b6db 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -124,7 +124,7 @@ func (dn *Daemon) executeReloadServiceNodeDisruptionAction(serviceName string, r } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } @@ -137,7 +137,8 @@ func (dn *Daemon) executeReloadServiceNodeDisruptionAction(serviceName string, r dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Reloading success: %v", err) @@ -165,7 +166,7 @@ func (dn *Daemon) performPostConfigChangeNodeDisruptionAction(postConfigChangeAc logSystem("Performing post config change action: %v for config %s", action.Type, configName) // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } @@ -180,7 +181,8 @@ func (dn *Daemon) performPostConfigChangeNodeDisruptionAction(postConfigChangeAc dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for rebooting: %v", err) @@ -200,7 +202,8 @@ func (dn *Daemon) performPostConfigChangeNodeDisruptionAction(postConfigChangeAc dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for no post config change action: %v", err) @@ -269,7 +272,7 @@ func (dn *Daemon) performPostConfigChangeNodeDisruptionAction(postConfigChangeAc // If at any point an error occurs, we reboot the node so that node has correct configuration. func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string, configName string) error { // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } @@ -283,7 +286,8 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for rebooting: %v", err) @@ -304,7 +308,8 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for no post config change action: %v", err) @@ -330,7 +335,8 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Reloading success: %v", err) @@ -869,22 +875,16 @@ func (dn *Daemon) updateOnClusterLayering(oldConfig, newConfig *mcfgv1.MachineCo // Add the desired config version to the MCN // get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } // Update the MCN's NodeNodeDegraded condition with the update result defer func() { - dn.reportMachineNodeDegradeStatus(retErr, pool) + dn.reportMachineNodeDegradeStatus(retErr, mcpName, desiredConfigVersion) }() - // update the MCN spec - err = upgrademonitor.GenerateAndApplyMachineConfigNodeSpec(dn.featureGatesAccessor, pool, dn.node, dn.mcfgClient) - if err != nil { - return fmt.Errorf("error updating MCN spec for node %s: %w", dn.node.Name, err) - } - oldIgnConfig, err := ctrlcommon.ParseAndConvertConfig(oldConfig.Spec.Config.Raw) if err != nil { return fmt.Errorf("parsing old Ignition config failed: %w", err) @@ -1110,14 +1110,14 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi }() // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(dn.mcpLister, dn.node) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(dn.mcpLister, dn.node) if err != nil { return err } // Update the MCN's NodeNodeDegraded condition with the update result defer func() { - dn.reportMachineNodeDegradeStatus(retErr, pool) + dn.reportMachineNodeDegradeStatus(retErr, mcpName, desiredConfigVersion) }() oldConfigName := oldConfig.GetName() @@ -1146,7 +1146,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if Nerr != nil { klog.Errorf("Error making MCN for Preparing update failed: %v", err) @@ -1193,7 +1194,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if Nerr != nil { klog.Errorf("Error making MCN for Preparing update failed: %v", err) @@ -1228,16 +1230,13 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Update Compatible: %v", err) } - err = upgrademonitor.GenerateAndApplyMachineConfigNodeSpec(dn.featureGatesAccessor, pool, dn.node, dn.mcfgClient) - if err != nil { - klog.Errorf("Error making MCN spec for Update Compatible: %v", err) - } if drain { if err := dn.performDrain(); err != nil { return err @@ -1252,7 +1251,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Drain not required: %v", err) @@ -1280,7 +1280,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Updating Files and OS: %v", err) @@ -1393,7 +1394,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ) if err != nil { klog.Errorf("Error making MCN for Updated Files and OS: %v", err) @@ -3083,7 +3085,7 @@ func canonicalizeMachineConfigImage(img string, mc *mcfgv1.MachineConfig) *mcfgv // If the error is not nil the condition status is set to [metav1.ConditionTrue] and the condition // message is formatted accordingly to include the error message. The condition is otherwise set to // [metav1.ConditionFalse]. -func (dn *Daemon) reportMachineNodeDegradeStatus(err error, pool string) { +func (dn *Daemon) reportMachineNodeDegradeStatus(err error, mcpName, desiredConfigVersion string) { if dn.node == nil { return } @@ -3107,7 +3109,8 @@ func (dn *Daemon) reportMachineNodeDegradeStatus(err error, pool string) { dn.node, dn.mcfgClient, dn.featureGatesAccessor, - pool, + mcpName, + desiredConfigVersion, ); applyErr != nil { klog.Errorf("Error updating MCN degraded status condition %v", applyErr) } diff --git a/pkg/daemon/upgrade_monitor_test.go b/pkg/daemon/upgrade_monitor_test.go index 9f8f290a55..6dde7ee0c5 100644 --- a/pkg/daemon/upgrade_monitor_test.go +++ b/pkg/daemon/upgrade_monitor_test.go @@ -154,12 +154,12 @@ func (tc upgradeMonitorTestCase) run(t *testing.T) { for _, n := range f.nodeLister { // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(d.mcpLister, n) + mcpName, desiredConfigVersion, err := helpers.GetPrimaryPoolDetailsForMCN(d.mcpLister, n) if err != nil { f.t.Fatalf("Error getting primary pool for node: %v", n.Name) } - err = upgrademonitor.GenerateAndApplyMachineConfigNodes(tc.parentCondition, tc.childCondition, tc.parentStatus, tc.childStatus, n, d.mcfgClient, d.featureGatesAccessor, pool) + err = upgrademonitor.GenerateAndApplyMachineConfigNodes(tc.parentCondition, tc.childCondition, tc.parentStatus, tc.childStatus, n, d.mcfgClient, d.featureGatesAccessor, mcpName, desiredConfigVersion) if err != nil { f.t.Fatalf("Could not generate and apply MCN %v", err) } diff --git a/pkg/helpers/helpers.go b/pkg/helpers/helpers.go index 0b0ad484d8..23054e6a20 100644 --- a/pkg/helpers/helpers.go +++ b/pkg/helpers/helpers.go @@ -51,30 +51,32 @@ func GetNodesForPool(mcpLister v1.MachineConfigPoolLister, nodeLister corev1list return nodes, nil } -// GetPrimaryPoolNameForMCN gets the MCP pool name value that is used in a node's MachineConfigNode object. -// When the node does not yet exist (is nil) or the node does not yet have annotations, the pool name will -// temporarily be set to `not-yet-set` (the default not yet set placeholder value for upgrade monitor -// functions). Once the node exists (is not nil) and the annotations are properly set, the node will update -// again and the pool name will be updated. -func GetPrimaryPoolNameForMCN(mcpLister v1.MachineConfigPoolLister, node *corev1.Node) (string, error) { +// GetPrimaryPoolDetailsForMCN gets the MCP details needed to populate a node's MachineConfigNode object, +// which are the MCP name and desired config version. +// - When the node does not yet exist (is nil) or the node does not yet have annotations, the MCP name +// and desried config version will temporarily be set to `not-yet-set` (the default not yet set +// placeholder value for upgrade monitor functions). +// - Once the node exists (is not nil) and the node annotations are properly set, the node will update +// again and the MCP name and desired config version will be updated accordingly. +func GetPrimaryPoolDetailsForMCN(mcpLister v1.MachineConfigPoolLister, node *corev1.Node) (mcpName, desiredConfig string, err error) { // Handle case of nil node if node == nil { - klog.Error("node object is nil, setting associated MCP to unknown") - return upgrademonitor.NotYetSet, nil + klog.Error("node object is nil, setting associated MCP values to 'not-yet-set'") + return upgrademonitor.NotYetSet, upgrademonitor.NotYetSet, nil } // Use `GetPrimaryPoolForNode` to get primary MCP associated with node primaryPool, err := GetPrimaryPoolForNode(mcpLister, node) if err != nil { - klog.Errorf("error getting primary pool for node: %v", node.Name) - return "", err + klog.Errorf("error getting primary MCP for node: %v", node.Name) + return "", "", err } else if primaryPool == nil { // On first provisioning, the node may not have annoatations and, thus, will not be associated with a pool. // In this case, the pool value will be set to a temporary dummy value. - klog.Infof("No primary pool is associated with node: %v", node.Name) - return upgrademonitor.NotYetSet, nil + klog.Infof("No primary MCP is associated with node: %v", node.Name) + return upgrademonitor.NotYetSet, upgrademonitor.NotYetSet, nil } - return primaryPool.Name, nil + return primaryPool.Name, primaryPool.Spec.Configuration.Name, nil } func GetPrimaryPoolForNode(mcpLister v1.MachineConfigPoolLister, node *corev1.Node) (*mcfgv1.MachineConfigPool, error) { diff --git a/pkg/operator/sync.go b/pkg/operator/sync.go index fc0b709c85..faf8a4a15f 100644 --- a/pkg/operator/sync.go +++ b/pkg/operator/sync.go @@ -773,7 +773,7 @@ func (optr *Operator) syncMachineConfigNodes(_ *renderConfig, _ *configv1.Cluste } // Get MCP associated with node - pool, err := helpers.GetPrimaryPoolNameForMCN(optr.mcpLister, node) + mcpName, mcpDesiredConfig, err := helpers.GetPrimaryPoolDetailsForMCN(optr.mcpLister, node) if err != nil { return err } @@ -784,7 +784,7 @@ func (optr *Operator) syncMachineConfigNodes(_ *renderConfig, _ *configv1.Cluste Name: node.Name, }, Pool: mcfgv1.MCOObjectReference{ - Name: pool, + Name: mcpName, }, ConfigVersion: mcfgv1.MachineConfigNodeSpecMachineConfigVersion{ Desired: upgrademonitor.NotYetSet, @@ -818,7 +818,7 @@ func (optr *Operator) syncMachineConfigNodes(_ *renderConfig, _ *configv1.Cluste } // if this is the first time we are applying the MCN and the node is ready, set the config version probably if mcn.Spec.ConfigVersion.Desired == upgrademonitor.NotYetSet { - err = upgrademonitor.GenerateAndApplyMachineConfigNodeSpec(optr.fgAccessor, pool, node, optr.client) + err = upgrademonitor.GenerateAndApplyMachineConfigNodeSpec(optr.fgAccessor, mcpName, mcpDesiredConfig, node, optr.client) if err != nil { klog.Errorf("Error making MCN spec for Update Compatible: %v", err) } diff --git a/pkg/upgrademonitor/upgrade_monitor.go b/pkg/upgrademonitor/upgrade_monitor.go index 299439b300..130be1598a 100644 --- a/pkg/upgrademonitor/upgrade_monitor.go +++ b/pkg/upgrademonitor/upgrade_monitor.go @@ -41,9 +41,10 @@ func GenerateAndApplyMachineConfigNodes( node *corev1.Node, mcfgClient mcfgclientset.Interface, fgAccessor featuregates.FeatureGateAccess, - pool string, + mcpName string, + desiredConfigVersion string, ) error { - return generateAndApplyMachineConfigNodes(parentCondition, childCondition, parentStatus, childStatus, node, mcfgClient, nil, fgAccessor, pool) + return generateAndApplyMachineConfigNodes(parentCondition, childCondition, parentStatus, childStatus, node, mcfgClient, nil, fgAccessor, mcpName, desiredConfigVersion) } func UpdateMachineConfigNodeStatus( @@ -55,9 +56,10 @@ func UpdateMachineConfigNodeStatus( mcfgClient mcfgclientset.Interface, imageSetApplyConfig []*machineconfigurationv1.MachineConfigNodeStatusPinnedImageSetApplyConfiguration, fgAccessor featuregates.FeatureGateAccess, - pool string, + mcpName string, + desiredConfigVersion string, ) error { - return generateAndApplyMachineConfigNodes(parentCondition, childCondition, parentStatus, childStatus, node, mcfgClient, imageSetApplyConfig, fgAccessor, pool) + return generateAndApplyMachineConfigNodes(parentCondition, childCondition, parentStatus, childStatus, node, mcfgClient, imageSetApplyConfig, fgAccessor, mcpName, desiredConfigVersion) } // Helper function to convert metav1.Condition to ConditionApplyConfiguration @@ -90,7 +92,8 @@ func generateAndApplyMachineConfigNodes( mcfgClient mcfgclientset.Interface, imageSetApplyConfig []*machineconfigurationv1.MachineConfigNodeStatusPinnedImageSetApplyConfiguration, fgAccessor featuregates.FeatureGateAccess, - pool string, + mcpName string, + desiredConfigVersion string, ) error { if fgAccessor == nil || node == nil || parentCondition == nil || mcfgClient == nil { return nil @@ -305,7 +308,7 @@ func generateAndApplyMachineConfigNodes( newMCNode.Spec.ConfigVersion.Desired = NotYetSet } newMCNode.Name = node.Name - newMCNode.Spec.Pool = mcfgv1.MCOObjectReference{Name: pool} + newMCNode.Spec.Pool = mcfgv1.MCOObjectReference{Name: mcpName} newMCNode.Spec.Node = mcfgv1.MCOObjectReference{Name: node.Name} _, err := mcfgClient.MachineconfigurationV1().MachineConfigNodes().Create(context.TODO(), newMCNode, metav1.CreateOptions{}) @@ -316,7 +319,7 @@ func generateAndApplyMachineConfigNodes( } // if this is the first time we are applying the MCN and the node is ready, set the config version probably if node.Status.Phase != corev1.NodePending && node.Status.Phase != corev1.NodePhase("Provisioning") && newMCNode.Spec.ConfigVersion.Desired == "NotYetSet" { - err = GenerateAndApplyMachineConfigNodeSpec(fgAccessor, pool, node, mcfgClient) + err = GenerateAndApplyMachineConfigNodeSpec(fgAccessor, mcpName, desiredConfigVersion, node, mcfgClient) if err != nil { klog.Errorf("Error making MCN spec for Update Compatible: %v", err) } @@ -338,8 +341,8 @@ func isSingletonCondition(singletonConditionTypes []mcfgv1.StateProgress, condit return false } -// GenerateAndApplyMachineConfigNodeSpec generates and applies a new MCN spec based off the node state -func GenerateAndApplyMachineConfigNodeSpec(fgAccessor featuregates.FeatureGateAccess, pool string, node *corev1.Node, mcfgClient mcfgclientset.Interface) error { +// GenerateAndApplyMachineConfigNodeSpec generates and applies a new MCN spec based off node and MCP properties +func GenerateAndApplyMachineConfigNodeSpec(fgAccessor featuregates.FeatureGateAccess, mcpName, desiredConfigVersion string, node *corev1.Node, mcfgClient mcfgclientset.Interface) error { if fgAccessor == nil || node == nil { return nil } @@ -349,14 +352,16 @@ func GenerateAndApplyMachineConfigNodeSpec(fgAccessor featuregates.FeatureGateAc return err } if fg == nil || !fg.Enabled(features.FeatureGateMachineConfigNodes) { - klog.Infof("MCN Featuregate is not enabled. Please enable the TechPreviewNoUpgrade featureset to use MachineConfigNodes") + klog.V(4).Infof("MachineConfigNode feature gate is not enabled. Please enable the featureset to use the MCN resource.") return nil } - // get the existing MCN, or if it DNE create one below - mcNode, needNewMCNode := createOrGetMachineConfigNode(mcfgClient, node) - newMCNode := mcNode.DeepCopy() - // set the spec config version - newMCNode.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ + + // Get the existing MCN for the node or, if one does not exist, create one later in the flow + mcn, needNewMCN := createOrGetMachineConfigNode(mcfgClient, node) + newMCN := mcn.DeepCopy() + + // Set the MCN metadata + newMCN.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ { APIVersion: "v1", Name: node.ObjectMeta.Name, @@ -365,38 +370,37 @@ func GenerateAndApplyMachineConfigNodeSpec(fgAccessor featuregates.FeatureGateAc }, } - newMCNode.Spec.ConfigVersion = mcfgv1.MachineConfigNodeSpecMachineConfigVersion{ - Desired: node.Annotations[daemonconsts.DesiredMachineConfigAnnotationKey], - } - // Set desired config to NotYetSet if the annotation is empty to satisfy API validation - if newMCNode.Spec.ConfigVersion.Desired == "" { - newMCNode.Spec.ConfigVersion.Desired = NotYetSet + // Set MCN.Spec values + newMCN.Spec.ConfigVersion = mcfgv1.MachineConfigNodeSpecMachineConfigVersion{ + Desired: desiredConfigVersion, } - - newMCNode.Spec.Pool = mcfgv1.MCOObjectReference{ - Name: pool, + newMCN.Spec.Pool = mcfgv1.MCOObjectReference{ + Name: mcpName, } - newMCNode.Spec.Node = mcfgv1.MCOObjectReference{ + newMCN.Spec.Node = mcfgv1.MCOObjectReference{ Name: node.Name, } - if !needNewMCNode { - nodeRefApplyConfig := machineconfigurationv1.MCOObjectReference().WithName(newMCNode.Spec.Node.Name) - poolRefApplyConfig := machineconfigurationv1.MCOObjectReference().WithName(newMCNode.Spec.Pool.Name) - specconfigVersionApplyConfig := machineconfigurationv1.MachineConfigNodeSpecMachineConfigVersion().WithDesired(newMCNode.Spec.ConfigVersion.Desired) - specApplyConfig := machineconfigurationv1.MachineConfigNodeSpec().WithNode(nodeRefApplyConfig).WithPool(poolRefApplyConfig).WithConfigVersion(specconfigVersionApplyConfig) - mcnodeApplyConfig := machineconfigurationv1.MachineConfigNode(newMCNode.Name).WithSpec(specApplyConfig) - _, err := mcfgClient.MachineconfigurationV1().MachineConfigNodes().Apply(context.TODO(), mcnodeApplyConfig, metav1.ApplyOptions{FieldManager: "machine-config-operator", Force: true}) + + // Update the existing MCN if one exists + if !needNewMCN { + nodeRefApplyConfig := machineconfigurationv1.MCOObjectReference().WithName(newMCN.Spec.Node.Name) + poolRefApplyConfig := machineconfigurationv1.MCOObjectReference().WithName(newMCN.Spec.Pool.Name) + specConfigVersionApplyConfig := machineconfigurationv1.MachineConfigNodeSpecMachineConfigVersion().WithDesired(newMCN.Spec.ConfigVersion.Desired) + specApplyConfig := machineconfigurationv1.MachineConfigNodeSpec().WithNode(nodeRefApplyConfig).WithPool(poolRefApplyConfig).WithConfigVersion(specConfigVersionApplyConfig) + mcnApplyConfig := machineconfigurationv1.MachineConfigNode(newMCN.Name).WithSpec(specApplyConfig) + _, err := mcfgClient.MachineconfigurationV1().MachineConfigNodes().Apply(context.TODO(), mcnApplyConfig, metav1.ApplyOptions{FieldManager: "machine-config-operator", Force: true}) if err != nil { klog.Errorf("Error applying MCN Spec: %v", err) return err } - } else { - _, err := mcfgClient.MachineconfigurationV1().MachineConfigNodes().Create(context.TODO(), newMCNode, metav1.CreateOptions{}) + } else { // Create a new MCN if one does not yet exist + _, err := mcfgClient.MachineconfigurationV1().MachineConfigNodes().Create(context.TODO(), newMCN, metav1.CreateOptions{}) if err != nil { klog.Errorf("Error creating MCN: %v", err) return err } } + return nil }