mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 18:24:07 +00:00
PodStatus
This commit is contained in:
parent
93ed9173e3
commit
deafd90280
@ -294,8 +294,12 @@ func getPodStatus(pod *api.Pod, nodes client.NodeInterface) (api.PodPhase, error
|
|||||||
if pod.Status.Info == nil {
|
if pod.Status.Info == nil {
|
||||||
return api.PodPending, nil
|
return api.PodPending, nil
|
||||||
}
|
}
|
||||||
|
// TODO(dchen1107): move the entire logic to kubelet?
|
||||||
running := 0
|
running := 0
|
||||||
|
waiting := 0
|
||||||
stopped := 0
|
stopped := 0
|
||||||
|
failed := 0
|
||||||
|
succeeded := 0
|
||||||
unknown := 0
|
unknown := 0
|
||||||
for _, container := range pod.Spec.Containers {
|
for _, container := range pod.Spec.Containers {
|
||||||
if containerStatus, ok := pod.Status.Info[container.Name]; ok {
|
if containerStatus, ok := pod.Status.Info[container.Name]; ok {
|
||||||
@ -303,6 +307,13 @@ func getPodStatus(pod *api.Pod, nodes client.NodeInterface) (api.PodPhase, error
|
|||||||
running++
|
running++
|
||||||
} else if containerStatus.State.Termination != nil {
|
} else if containerStatus.State.Termination != nil {
|
||||||
stopped++
|
stopped++
|
||||||
|
if containerStatus.State.Termination.ExitCode == 0 {
|
||||||
|
succeeded++
|
||||||
|
} else {
|
||||||
|
failed++
|
||||||
|
}
|
||||||
|
} else if containerStatus.State.Waiting != nil {
|
||||||
|
waiting++
|
||||||
} else {
|
} else {
|
||||||
unknown++
|
unknown++
|
||||||
}
|
}
|
||||||
@ -311,12 +322,32 @@ func getPodStatus(pod *api.Pod, nodes client.NodeInterface) (api.PodPhase, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
case waiting > 0:
|
||||||
|
// One or more containers has not been started
|
||||||
|
return api.PodPending, nil
|
||||||
case running > 0 && unknown == 0:
|
case running > 0 && unknown == 0:
|
||||||
|
// All containers have been started, and at least
|
||||||
|
// one container is running
|
||||||
return api.PodRunning, nil
|
return api.PodRunning, nil
|
||||||
case running == 0 && stopped > 0 && unknown == 0:
|
case running == 0 && stopped > 0 && unknown == 0:
|
||||||
return api.PodFailed, nil
|
// All containers are terminated
|
||||||
case running == 0 && stopped == 0 && unknown > 0:
|
if pod.Spec.RestartPolicy.Always != nil {
|
||||||
return api.PodPending, nil
|
// All containers are in the process of restarting
|
||||||
|
return api.PodRunning, nil
|
||||||
|
}
|
||||||
|
if stopped == succeeded {
|
||||||
|
// RestartPolicy is not Always, and all
|
||||||
|
// containers are terminated in success
|
||||||
|
return api.PodSucceeded, nil
|
||||||
|
}
|
||||||
|
if pod.Spec.RestartPolicy.Never != nil {
|
||||||
|
// RestartPolicy is Never, and all containers are
|
||||||
|
// terminated with at least one in failure
|
||||||
|
return api.PodFailed, nil
|
||||||
|
}
|
||||||
|
// RestartPolicy is OnFailure, and at least one in failure
|
||||||
|
// and in the process of restarting
|
||||||
|
return api.PodRunning, nil
|
||||||
default:
|
default:
|
||||||
return api.PodPending, nil
|
return api.PodPending, nil
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ func TestGetPodCloud(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMakePodStatus(t *testing.T) {
|
func TestPodStatusWithBadNode(t *testing.T) {
|
||||||
fakeClient := client.Fake{
|
fakeClient := client.Fake{
|
||||||
MinionsList: api.NodeList{
|
MinionsList: api.NodeList{
|
||||||
Items: []api.Node{
|
Items: []api.Node{
|
||||||
@ -383,6 +383,89 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
{Name: "containerA"},
|
{Name: "containerA"},
|
||||||
{Name: "containerB"},
|
{Name: "containerB"},
|
||||||
},
|
},
|
||||||
|
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
|
||||||
|
}
|
||||||
|
runningState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Running: &api.ContainerStateRunning{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
stoppedState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Termination: &api.ContainerStateTerminated{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
pod *api.Pod
|
||||||
|
status api.PodPhase
|
||||||
|
test string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Host: "machine-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodFailed,
|
||||||
|
"no info, but bad machine",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
"containerB": runningState,
|
||||||
|
},
|
||||||
|
Host: "machine-two",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodFailed,
|
||||||
|
"all running but minion is missing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": stoppedState,
|
||||||
|
"containerB": stoppedState,
|
||||||
|
},
|
||||||
|
Host: "machine-two",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodFailed,
|
||||||
|
"all stopped but minion missing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if status, err := getPodStatus(test.pod, fakeClient.Nodes()); status != test.status {
|
||||||
|
t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("In test %s, unexpected error: %v", test.test, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodStatusWithRestartAlways(t *testing.T) {
|
||||||
|
fakeClient := client.Fake{
|
||||||
|
MinionsList: api.NodeList{
|
||||||
|
Items: []api.Node{
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "machine"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
desiredState := api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "containerA"},
|
||||||
|
{Name: "containerB"},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
|
||||||
}
|
}
|
||||||
currentState := api.PodStatus{
|
currentState := api.PodStatus{
|
||||||
Host: "machine",
|
Host: "machine",
|
||||||
@ -404,16 +487,6 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
test string
|
test string
|
||||||
}{
|
}{
|
||||||
{&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"},
|
{&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"},
|
||||||
{
|
|
||||||
&api.Pod{
|
|
||||||
Spec: desiredState,
|
|
||||||
Status: api.PodStatus{
|
|
||||||
Host: "machine-2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
api.PodFailed,
|
|
||||||
"no info, but bad machine",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
&api.Pod{
|
&api.Pod{
|
||||||
Spec: desiredState,
|
Spec: desiredState,
|
||||||
@ -428,20 +501,6 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
api.PodRunning,
|
api.PodRunning,
|
||||||
"all running",
|
"all running",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
&api.Pod{
|
|
||||||
Spec: desiredState,
|
|
||||||
Status: api.PodStatus{
|
|
||||||
Info: map[string]api.ContainerStatus{
|
|
||||||
"containerA": runningState,
|
|
||||||
"containerB": runningState,
|
|
||||||
},
|
|
||||||
Host: "machine-two",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
api.PodFailed,
|
|
||||||
"all running but minion is missing",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
&api.Pod{
|
&api.Pod{
|
||||||
Spec: desiredState,
|
Spec: desiredState,
|
||||||
@ -453,22 +512,8 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
Host: "machine",
|
Host: "machine",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
api.PodFailed,
|
api.PodRunning,
|
||||||
"all stopped",
|
"all stopped with restart always",
|
||||||
},
|
|
||||||
{
|
|
||||||
&api.Pod{
|
|
||||||
Spec: desiredState,
|
|
||||||
Status: api.PodStatus{
|
|
||||||
Info: map[string]api.ContainerStatus{
|
|
||||||
"containerA": stoppedState,
|
|
||||||
"containerB": stoppedState,
|
|
||||||
},
|
|
||||||
Host: "machine-two",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
api.PodFailed,
|
|
||||||
"all stopped but minion missing",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&api.Pod{
|
&api.Pod{
|
||||||
@ -482,7 +527,7 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
api.PodRunning,
|
api.PodRunning,
|
||||||
"mixed state #1",
|
"mixed state #1 with restart always",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&api.Pod{
|
&api.Pod{
|
||||||
@ -495,7 +540,259 @@ func TestMakePodStatus(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
api.PodPending,
|
api.PodPending,
|
||||||
"mixed state #2",
|
"mixed state #2 with restart always",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if status, err := getPodStatus(test.pod, fakeClient.Nodes()); status != test.status {
|
||||||
|
t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("In test %s, unexpected error: %v", test.test, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodStatusWithRestartNever(t *testing.T) {
|
||||||
|
fakeClient := client.Fake{
|
||||||
|
MinionsList: api.NodeList{
|
||||||
|
Items: []api.Node{
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "machine"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
desiredState := api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "containerA"},
|
||||||
|
{Name: "containerB"},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicy{Never: &api.RestartPolicyNever{}},
|
||||||
|
}
|
||||||
|
currentState := api.PodStatus{
|
||||||
|
Host: "machine",
|
||||||
|
}
|
||||||
|
runningState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Running: &api.ContainerStateRunning{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
succeededState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Termination: &api.ContainerStateTerminated{
|
||||||
|
ExitCode: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
failedState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Termination: &api.ContainerStateTerminated{
|
||||||
|
ExitCode: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
pod *api.Pod
|
||||||
|
status api.PodPhase
|
||||||
|
test string
|
||||||
|
}{
|
||||||
|
{&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
"containerB": runningState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodRunning,
|
||||||
|
"all running with restart never",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": succeededState,
|
||||||
|
"containerB": succeededState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodSucceeded,
|
||||||
|
"all succeeded with restart never",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": failedState,
|
||||||
|
"containerB": failedState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodFailed,
|
||||||
|
"all failed with restart never",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
"containerB": succeededState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodRunning,
|
||||||
|
"mixed state #1 with restart never",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodPending,
|
||||||
|
"mixed state #2 with restart never",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if status, err := getPodStatus(test.pod, fakeClient.Nodes()); status != test.status {
|
||||||
|
t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("In test %s, unexpected error: %v", test.test, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodStatusWithRestartOnFailure(t *testing.T) {
|
||||||
|
fakeClient := client.Fake{
|
||||||
|
MinionsList: api.NodeList{
|
||||||
|
Items: []api.Node{
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "machine"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
desiredState := api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "containerA"},
|
||||||
|
{Name: "containerB"},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicy{OnFailure: &api.RestartPolicyOnFailure{}},
|
||||||
|
}
|
||||||
|
currentState := api.PodStatus{
|
||||||
|
Host: "machine",
|
||||||
|
}
|
||||||
|
runningState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Running: &api.ContainerStateRunning{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
succeededState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Termination: &api.ContainerStateTerminated{
|
||||||
|
ExitCode: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
failedState := api.ContainerStatus{
|
||||||
|
State: api.ContainerState{
|
||||||
|
Termination: &api.ContainerStateTerminated{
|
||||||
|
ExitCode: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
pod *api.Pod
|
||||||
|
status api.PodPhase
|
||||||
|
test string
|
||||||
|
}{
|
||||||
|
{&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
"containerB": runningState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodRunning,
|
||||||
|
"all running with restart onfailure",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": succeededState,
|
||||||
|
"containerB": succeededState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodSucceeded,
|
||||||
|
"all succeeded with restart onfailure",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": failedState,
|
||||||
|
"containerB": failedState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodRunning,
|
||||||
|
"all failed with restart never",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
"containerB": succeededState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodRunning,
|
||||||
|
"mixed state #1 with restart onfailure",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&api.Pod{
|
||||||
|
Spec: desiredState,
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Info: map[string]api.ContainerStatus{
|
||||||
|
"containerA": runningState,
|
||||||
|
},
|
||||||
|
Host: "machine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
api.PodPending,
|
||||||
|
"mixed state #2 with restart onfailure",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user