Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pkg/monitor/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,18 @@ func startPodMonitoring(ctx context.Context, m Recorder, client kubernetes.Inter
}
return conditions
},
// inform when a pod gets reassigned to a new node
func(pod, oldPod *corev1.Pod) []monitorapi.Condition {
var conditions []monitorapi.Condition
if len(oldPod.Spec.NodeName) > 0 && pod.Spec.NodeName != oldPod.Spec.NodeName {
conditions = append(conditions, monitorapi.Condition{
Level: monitorapi.Error,
Locator: locatePod(pod),
Message: fmt.Sprintf("invariant violation, pod once assigned to a node must stay on it. The pod previously scheduled to %s, has just been assigned to a new node %s", oldPod.Spec.NodeName, pod.Spec.NodeName),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if this gets cleared, you will constantly wonder what that nodename is. I suggest

  1. include the resourceversion for old and new.
  2. use %q for your node names
  3. inspect the field owners in metadata for old and new to determine who overwrite the value.

})
}
return conditions
},
}
podDeleteFns := []func(pod *corev1.Pod) []monitorapi.Condition{
// check for transitions to being deleted
Expand Down
22 changes: 22 additions & 0 deletions pkg/synthetictests/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,25 @@ func testAllIngressAvailability(events monitorapi.Intervals, jobRunDuration time

return ret
}

func testPodNodeNameIsImmutable(events monitorapi.Intervals) []*junitapi.JUnitTestCase {
const testName = "[sig-api-machinery] the pod.spec.nodeName field is immutable, once set cannot be changed"

failures := []string{}
for _, event := range events {
if strings.Contains(event.Message, "pod once assigned to a node must stay on it") {
failures = append(failures, fmt.Sprintf("%v %v", event.Locator, event.Message))
}
}
if len(failures) == 0 {
return []*junitapi.JUnitTestCase{{Name: testName}}
}

return []*junitapi.JUnitTestCase{{
Name: testName,
SystemOut: strings.Join(failures, "\n"),
FailureOutput: &junitapi.FailureOutput{
Output: fmt.Sprintf("Please report in https://bugzilla.redhat.com/show_bug.cgi?id=2042657\n\n%d pods had their immutable field (spec.nodeName) changed\n\n%v", len(failures), strings.Join(failures, "\n")),
},
}}
}
3 changes: 3 additions & 0 deletions pkg/synthetictests/event_junits.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func StableSystemEventInvariants(events monitorapi.Intervals, duration time.Dura
tests = append(tests, testErrImagePullGeneric(events)...)
tests = append(tests, testAlerts(events, kubeClientConfig)...)
tests = append(tests, testOperatorOSUpdateStaged(events)...)
tests = append(tests, testPodNodeNameIsImmutable(events)...)

return tests
}
Expand All @@ -56,6 +57,8 @@ func SystemUpgradeEventInvariants(events monitorapi.Intervals, duration time.Dur
tests = append(tests, testErrImagePullGeneric(events)...)
tests = append(tests, testAlerts(events, kubeClientConfig)...)
tests = append(tests, testOperatorOSUpdateStaged(events)...)
tests = append(tests, testPodNodeNameIsImmutable(events)...)

return tests
}

Expand Down