add pod util to verify pod is terminal

pods on phase succeeded or failed are guaranteed to have all containers
stopped and to not ever regress
This commit is contained in:
Antonio Ojea 2022-05-18 16:42:04 +02:00
parent 7397e60477
commit d16d23e0c7
3 changed files with 53 additions and 6 deletions

View File

@ -301,6 +301,16 @@ func IsPodReady(pod *v1.Pod) bool {
return IsPodReadyConditionTrue(pod.Status)
}
// IsPodTerminal returns true if a pod is terminal, all containers are stopped and cannot ever regress.
func IsPodTerminal(pod *v1.Pod) bool {
return IsPodPhaseTerminal(pod.Status.Phase)
}
// IsPhaseTerminal returns true if the pod's phase is terminal.
func IsPodPhaseTerminal(phase v1.PodPhase) bool {
return phase == v1.PodFailed || phase == v1.PodSucceeded
}
// IsPodReadyConditionTrue returns true if a pod is ready; false otherwise.
func IsPodReadyConditionTrue(status v1.PodStatus) bool {
condition := GetPodReadyCondition(status)

View File

@ -749,6 +749,48 @@ func TestIsPodAvailable(t *testing.T) {
}
}
func TestIsPodTerminal(t *testing.T) {
now := metav1.Now()
tests := []struct {
podPhase v1.PodPhase
expected bool
}{
{
podPhase: v1.PodFailed,
expected: true,
},
{
podPhase: v1.PodSucceeded,
expected: true,
},
{
podPhase: v1.PodUnknown,
expected: false,
},
{
podPhase: v1.PodPending,
expected: false,
},
{
podPhase: v1.PodRunning,
expected: false,
},
{
expected: false,
},
}
for i, test := range tests {
pod := newPod(now, true, 0)
pod.Status.Phase = test.podPhase
isTerminal := IsPodTerminal(pod)
if isTerminal != test.expected {
t.Errorf("[tc #%d] expected terminal pod: %t, got: %t", i, test.expected, isTerminal)
}
}
}
func TestGetContainerStatus(t *testing.T) {
type ExpectedStruct struct {
status v1.ContainerStatus

View File

@ -859,7 +859,7 @@ func mergePodStatus(oldPodStatus, newPodStatus v1.PodStatus, couldHaveRunningCon
// the Kubelet exclusively owns must be released prior to a pod being reported terminal,
// while resources that have participanting components above the API use the pod's
// transition to a terminal phase (or full deletion) to release those resources.
if !isPhaseTerminal(oldPodStatus.Phase) && isPhaseTerminal(newPodStatus.Phase) {
if !podutil.IsPodPhaseTerminal(oldPodStatus.Phase) && podutil.IsPodPhaseTerminal(newPodStatus.Phase) {
if couldHaveRunningContainers {
newPodStatus.Phase = oldPodStatus.Phase
newPodStatus.Reason = oldPodStatus.Reason
@ -870,11 +870,6 @@ func mergePodStatus(oldPodStatus, newPodStatus v1.PodStatus, couldHaveRunningCon
return newPodStatus
}
// isPhaseTerminal returns true if the pod's phase is terminal.
func isPhaseTerminal(phase v1.PodPhase) bool {
return phase == v1.PodFailed || phase == v1.PodSucceeded
}
// NeedToReconcilePodReadiness returns if the pod "Ready" condition need to be reconcile
func NeedToReconcilePodReadiness(pod *v1.Pod) bool {
if len(pod.Spec.ReadinessGates) == 0 {