Generate ContainersReady condition

pull/8/head
Minhan Xia 2018-06-01 18:32:07 -07:00
parent 6b08ef575f
commit 176f34ea07
2 changed files with 120 additions and 8 deletions

View File

@ -32,14 +32,13 @@ const (
ReadinessGatesNotReady = "ReadinessGatesNotReady"
)
// GeneratePodReadyCondition returns "Ready" condition of a pod.
// The status of "Ready" condition is "True", if all containers in a pod are ready
// AND all matching conditions specified in the ReadinessGates have status equal to "True".
func GeneratePodReadyCondition(spec *v1.PodSpec, conditions []v1.PodCondition, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition {
// GenerateContainersReadyCondition returns the status of "ContainersReady" condition.
// The status of "ContainersReady" condition is true when all containers are ready.
func GenerateContainersReadyCondition(spec *v1.PodSpec, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition {
// Find if all containers are ready or not.
if containerStatuses == nil {
return v1.PodCondition{
Type: v1.PodReady,
Type: v1.ContainersReady,
Status: v1.ConditionFalse,
Reason: UnknownContainerStatuses,
}
@ -59,7 +58,7 @@ func GeneratePodReadyCondition(spec *v1.PodSpec, conditions []v1.PodCondition, c
// If all containers are known and succeeded, just return PodCompleted.
if podPhase == v1.PodSucceeded && len(unknownContainers) == 0 {
return v1.PodCondition{
Type: v1.PodReady,
Type: v1.ContainersReady,
Status: v1.ConditionFalse,
Reason: PodCompleted,
}
@ -76,16 +75,37 @@ func GeneratePodReadyCondition(spec *v1.PodSpec, conditions []v1.PodCondition, c
unreadyMessage := strings.Join(unreadyMessages, ", ")
if unreadyMessage != "" {
return v1.PodCondition{
Type: v1.PodReady,
Type: v1.ContainersReady,
Status: v1.ConditionFalse,
Reason: ContainersNotReady,
Message: unreadyMessage,
}
}
return v1.PodCondition{
Type: v1.ContainersReady,
Status: v1.ConditionTrue,
}
}
// GeneratePodReadyCondition returns "Ready" condition of a pod.
// The status of "Ready" condition is "True", if all containers in a pod are ready
// AND all matching conditions specified in the ReadinessGates have status equal to "True".
func GeneratePodReadyCondition(spec *v1.PodSpec, conditions []v1.PodCondition, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition {
containersReady := GenerateContainersReadyCondition(spec, containerStatuses, podPhase)
// If the status of ContainersReady is not True, return the same status, reason and message as ContainersReady.
if containersReady.Status != v1.ConditionTrue {
return v1.PodCondition{
Type: v1.PodReady,
Status: containersReady.Status,
Reason: containersReady.Reason,
Message: containersReady.Message,
}
}
// Evaluate corresponding conditions specified in readiness gate
// Generate message if any readiness gate is not satisfied.
unreadyMessages = []string{}
unreadyMessages := []string{}
for _, rg := range spec.ReadinessGates {
_, c := podutil.GetPodConditionFromList(conditions, rg.ConditionType)
if c == nil {

View File

@ -24,6 +24,98 @@ import (
"k8s.io/api/core/v1"
)
func TestGenerateContainersReadyCondition(t *testing.T) {
tests := []struct {
spec *v1.PodSpec
containerStatuses []v1.ContainerStatus
podPhase v1.PodPhase
expectReady v1.PodCondition
}{
{
spec: nil,
containerStatuses: nil,
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, UnknownContainerStatuses, ""),
},
{
spec: &v1.PodSpec{},
containerStatuses: []v1.ContainerStatus{},
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""),
},
{
spec: &v1.PodSpec{
Containers: []v1.Container{
{Name: "1234"},
},
},
containerStatuses: []v1.ContainerStatus{},
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [1234]"),
},
{
spec: &v1.PodSpec{
Containers: []v1.Container{
{Name: "1234"},
{Name: "5678"},
},
},
containerStatuses: []v1.ContainerStatus{
getReadyStatus("1234"),
getReadyStatus("5678"),
},
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""),
},
{
spec: &v1.PodSpec{
Containers: []v1.Container{
{Name: "1234"},
{Name: "5678"},
},
},
containerStatuses: []v1.ContainerStatus{
getReadyStatus("1234"),
},
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [5678]"),
},
{
spec: &v1.PodSpec{
Containers: []v1.Container{
{Name: "1234"},
{Name: "5678"},
},
},
containerStatuses: []v1.ContainerStatus{
getReadyStatus("1234"),
getNotReadyStatus("5678"),
},
podPhase: v1.PodRunning,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [5678]"),
},
{
spec: &v1.PodSpec{
Containers: []v1.Container{
{Name: "1234"},
},
},
containerStatuses: []v1.ContainerStatus{
getNotReadyStatus("1234"),
},
podPhase: v1.PodSucceeded,
expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, PodCompleted, ""),
},
}
for i, test := range tests {
ready := GenerateContainersReadyCondition(test.spec, test.containerStatuses, test.podPhase)
if !reflect.DeepEqual(ready, test.expectReady) {
t.Errorf("On test case %v, expectReady:\n%+v\ngot\n%+v\n", i, test.expectReady, ready)
}
}
}
func TestGeneratePodReadyCondition(t *testing.T) {
tests := []struct {
spec *v1.PodSpec