diff --git a/pkg/kubelet/kubelet_node_status.go b/pkg/kubelet/kubelet_node_status.go index 97d2d03cf3..bc86e4d006 100644 --- a/pkg/kubelet/kubelet_node_status.go +++ b/pkg/kubelet/kubelet_node_status.go @@ -528,6 +528,7 @@ func (kl *Kubelet) defaultNodeStatusFuncs() []func(*v1.Node) error { nodestatus.PIDPressureCondition(kl.clock.Now, kl.evictionManager.IsUnderPIDPressure, kl.recordNodeStatusEvent), nodestatus.ReadyCondition(kl.clock.Now, kl.runtimeState.runtimeErrors, kl.runtimeState.networkErrors, validateHostFunc, kl.containerManager.Status, kl.recordNodeStatusEvent), nodestatus.VolumesInUse(kl.volumeManager.ReconcilerStatesHasBeenSynced, kl.volumeManager.GetVolumesInUse), + nodestatus.RemoveOutOfDiskCondition(), // TODO(mtaufen): I decided not to move this setter for now, since all it does is send an event // and record state back to the Kubelet runtime object. In the future, I'd like to isolate // these side-effects by decoupling the decisions to send events and partial status recording diff --git a/pkg/kubelet/nodestatus/setters.go b/pkg/kubelet/nodestatus/setters.go index 85d1e1748f..71bd5e4a58 100644 --- a/pkg/kubelet/nodestatus/setters.go +++ b/pkg/kubelet/nodestatus/setters.go @@ -746,3 +746,18 @@ func VolumeLimits(volumePluginListFunc func() []volume.VolumePluginWithAttachLim return nil } } + +// RemoveOutOfDiskCondition removes stale OutOfDisk condition +// OutOfDisk condition has been removed from kubelet in 1.12 +func RemoveOutOfDiskCondition() Setter { + return func(node *v1.Node) error { + var conditions []v1.NodeCondition + for i := range node.Status.Conditions { + if node.Status.Conditions[i].Type != v1.NodeOutOfDisk { + conditions = append(conditions, node.Status.Conditions[i]) + } + } + node.Status.Conditions = conditions + return nil + } +} diff --git a/pkg/kubelet/nodestatus/setters_test.go b/pkg/kubelet/nodestatus/setters_test.go index 321c9f1800..c0267a686f 100644 --- a/pkg/kubelet/nodestatus/setters_test.go +++ b/pkg/kubelet/nodestatus/setters_test.go @@ -1508,6 +1508,54 @@ func TestVolumeLimits(t *testing.T) { } } +func TestRemoveOutOfDiskCondition(t *testing.T) { + now := time.Now() + + var cases = []struct { + desc string + inputNode *v1.Node + expectNode *v1.Node + }{ + { + desc: "should remove stale OutOfDiskCondition from node status", + inputNode: &v1.Node{ + Status: v1.NodeStatus{ + Conditions: []v1.NodeCondition{ + *makeMemoryPressureCondition(false, now, now), + { + Type: v1.NodeOutOfDisk, + Status: v1.ConditionFalse, + }, + *makeDiskPressureCondition(false, now, now), + }, + }, + }, + expectNode: &v1.Node{ + Status: v1.NodeStatus{ + Conditions: []v1.NodeCondition{ + *makeMemoryPressureCondition(false, now, now), + *makeDiskPressureCondition(false, now, now), + }, + }, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + // construct setter + setter := RemoveOutOfDiskCondition() + // call setter on node + if err := setter(tc.inputNode); err != nil { + t.Fatalf("unexpected error: %v", err) + } + // check expected node + assert.True(t, apiequality.Semantic.DeepEqual(tc.expectNode, tc.inputNode), + "Diff: %s", diff.ObjectDiff(tc.expectNode, tc.inputNode)) + }) + } +} + // Test Helpers: // sortableNodeAddress is a type for sorting []v1.NodeAddress