From b9b699356893a7bc57e69307ac7bb45e150227f6 Mon Sep 17 00:00:00 2001 From: Isabella Janssen Date: Wed, 3 Sep 2025 10:57:52 -0400 Subject: [PATCH] controller: update is node done check to handle image mode disabling case & add unit test cases for scenario --- pkg/controller/common/layered_node_state.go | 10 ++++++---- pkg/controller/node/status_test.go | 22 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/controller/common/layered_node_state.go b/pkg/controller/common/layered_node_state.go index 6bbb1f9e3d..ea4309df85 100644 --- a/pkg/controller/common/layered_node_state.go +++ b/pkg/controller/common/layered_node_state.go @@ -26,14 +26,16 @@ func NewLayeredNodeState(n *corev1.Node) *LayeredNodeState { return &LayeredNodeState{node: n} } -// Checks if the node is done "working" and that the node is targeting is MachineConfig -// determined by the pool. If in layered mode, the image annotations are also checked -// checked against the OCL objects. +// Checks if the node is done "working." For a node in both layered and non-layered MCPs, the +// node's state annotation must be "Done" and it must be targeting the correct MachineConfig. For +// `layered` MCPs, the node's desired image annotation must match the image defined in the +// MachineOsConfig and the desired MachineConfig must match the config version defined in the +// MachineOSBuild. For non-layered MCPs, the node must not have a desired image annotation value. func (l *LayeredNodeState) IsDone(mcp *mcfgv1.MachineConfigPool, layered bool, mosc *mcfgv1.MachineOSConfig, mosb *mcfgv1.MachineOSBuild) bool { if layered { return l.IsNodeDone() && l.IsDesiredMachineConfigEqualToPool(mcp) && l.IsDesiredEqualToBuild(mosc, mosb) } - return l.IsNodeDone() && l.IsDesiredMachineConfigEqualToPool(mcp) + return l.IsNodeDone() && l.IsDesiredMachineConfigEqualToPool(mcp) && !l.IsDesiredImageAnnotationPresentOnNode() } // The original behavior of getUnavailableMachines is: getUnavailableMachines diff --git a/pkg/controller/node/status_test.go b/pkg/controller/node/status_test.go index 66a6b1b9cc..c7edecbdba 100644 --- a/pkg/controller/node/status_test.go +++ b/pkg/controller/node/status_test.go @@ -287,6 +287,28 @@ func TestGetUpdatedMachines(t *testing.T) { newNode("node-1", machineConfigV1, machineConfigV1), newNodeWithReady("node-2", machineConfigV1, machineConfigV1, corev1.ConditionTrue), }, + }, { + name: "Pool with image mode disabling, one node updating, 2 nodes not not acted upon", + nodes: []*corev1.Node{ + newLayeredNode("node-0", machineConfigV0, machineConfigV0, imageV1, ""), + newLayeredNode("node-1", machineConfigV0, machineConfigV0, imageV1, imageV1), + newLayeredNode("node-2", machineConfigV0, machineConfigV0, imageV1, imageV1), + }, + currentConfig: machineConfigV0, + updated: nil, + layered: false, + }, { + name: "Pool with image mode disabling, one node updated, 1 node updating, 1 node not acted upon", + nodes: []*corev1.Node{ + newNode("node-0", machineConfigV0, machineConfigV0), + newLayeredNode("node-1", machineConfigV0, machineConfigV0, imageV1, ""), + newLayeredNode("node-2", machineConfigV0, machineConfigV0, imageV1, imageV1), + }, + currentConfig: machineConfigV0, + updated: []*corev1.Node{ + newNode("node-0", machineConfigV0, machineConfigV0), + }, + layered: false, }, }