mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
Populate last terminated container information
This commit is contained in:
parent
72fed9a2f3
commit
563f2965ba
@ -138,10 +138,11 @@ func (self *DockerManager) inspectContainer(dockerID, containerName, tPath strin
|
||||
reason = inspectResult.State.Error
|
||||
}
|
||||
result.status.State.Termination = &api.ContainerStateTerminated{
|
||||
ExitCode: inspectResult.State.ExitCode,
|
||||
Reason: reason,
|
||||
StartedAt: util.NewTime(inspectResult.State.StartedAt),
|
||||
FinishedAt: util.NewTime(inspectResult.State.FinishedAt),
|
||||
ExitCode: inspectResult.State.ExitCode,
|
||||
Reason: reason,
|
||||
StartedAt: util.NewTime(inspectResult.State.StartedAt),
|
||||
FinishedAt: util.NewTime(inspectResult.State.FinishedAt),
|
||||
ContainerID: DockerPrefix + dockerID,
|
||||
}
|
||||
if tPath != "" {
|
||||
path, found := inspectResult.Volumes[tPath]
|
||||
@ -215,6 +216,13 @@ func (self *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
|
||||
}
|
||||
// We assume docker return us a list of containers in time order
|
||||
if containerStatus, found := statuses[dockerContainerName]; found {
|
||||
// Populate last termination state
|
||||
if containerStatus.LastTerminationState.Termination == nil {
|
||||
result := self.inspectContainer(value.ID, dockerContainerName, terminationMessagePath)
|
||||
if result.err == nil && result.status.State.Termination != nil {
|
||||
containerStatus.LastTerminationState = result.status.State
|
||||
}
|
||||
}
|
||||
containerStatus.RestartCount += 1
|
||||
statuses[dockerContainerName] = containerStatus
|
||||
continue
|
||||
|
@ -1987,6 +1987,7 @@ func (kl *Kubelet) generatePodStatus(pod *api.Pod) (api.PodStatus, error) {
|
||||
}
|
||||
}
|
||||
podStatus.Conditions = append(podStatus.Conditions, getPodReadyCondition(spec, podStatus.ContainerStatuses)...)
|
||||
|
||||
hostIP, err := kl.GetHostIP()
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot get host IP: %v", err)
|
||||
|
@ -3602,13 +3602,13 @@ func TestSyncPodsWithRestartPolicy(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
api.RestartPolicyAlways,
|
||||
[]string{"list", "list", "list", "inspect_container", "inspect_container", "inspect_container", "create", "start", "create", "start", "list", "inspect_container", "inspect_container", "inspect_container"},
|
||||
[]string{"list", "list", "list", "inspect_container", "inspect_container", "inspect_container", "create", "start", "create", "start", "list", "inspect_container", "inspect_container", "inspect_container", "inspect_container", "inspect_container"},
|
||||
[]string{"succeeded", "failed"},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
api.RestartPolicyOnFailure,
|
||||
[]string{"list", "list", "list", "inspect_container", "inspect_container", "inspect_container", "create", "start", "list", "inspect_container", "inspect_container", "inspect_container"},
|
||||
[]string{"list", "list", "list", "inspect_container", "inspect_container", "inspect_container", "create", "start", "list", "inspect_container", "inspect_container", "inspect_container", "inspect_container"},
|
||||
[]string{"failed"},
|
||||
[]string{},
|
||||
},
|
||||
@ -3657,3 +3657,138 @@ func TestSyncPodsWithRestartPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPodStatusWithLastTermination(t *testing.T) {
|
||||
testKubelet := newTestKubelet(t)
|
||||
testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil)
|
||||
kubelet := testKubelet.kubelet
|
||||
fakeDocker := testKubelet.fakeDocker
|
||||
waitGroup := testKubelet.waitGroup
|
||||
|
||||
containers := []api.Container{
|
||||
{Name: "succeeded"},
|
||||
{Name: "failed"},
|
||||
}
|
||||
|
||||
runningAPIContainers := []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
exitedAPIContainers := []docker.APIContainers{
|
||||
{
|
||||
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>
|
||||
Names: []string{"/k8s_succeeded." + strconv.FormatUint(dockertools.HashContainer(&containers[0]), 16) + "_foo_new_12345678_0"},
|
||||
ID: "1234",
|
||||
},
|
||||
{
|
||||
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>
|
||||
Names: []string{"/k8s_failed." + strconv.FormatUint(dockertools.HashContainer(&containers[1]), 16) + "_foo_new_12345678_0"},
|
||||
ID: "5678",
|
||||
},
|
||||
}
|
||||
|
||||
containerMap := map[string]*docker.Container{
|
||||
"1234": {
|
||||
ID: "1234",
|
||||
Name: "succeeded",
|
||||
Config: &docker.Config{},
|
||||
State: docker.State{
|
||||
ExitCode: 0,
|
||||
StartedAt: time.Now(),
|
||||
FinishedAt: time.Now(),
|
||||
},
|
||||
},
|
||||
"5678": {
|
||||
ID: "5678",
|
||||
Name: "failed",
|
||||
Config: &docker.Config{},
|
||||
State: docker.State{
|
||||
ExitCode: 42,
|
||||
StartedAt: time.Now(),
|
||||
FinishedAt: time.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
policy api.RestartPolicy
|
||||
created []string
|
||||
stopped []string
|
||||
lastTerminations []string
|
||||
}{
|
||||
{
|
||||
api.RestartPolicyAlways,
|
||||
[]string{"succeeded", "failed"},
|
||||
[]string{},
|
||||
[]string{"docker://1234", "docker://5678"},
|
||||
},
|
||||
{
|
||||
api.RestartPolicyOnFailure,
|
||||
[]string{"failed"},
|
||||
[]string{},
|
||||
[]string{"docker://5678"},
|
||||
},
|
||||
{
|
||||
api.RestartPolicyNever,
|
||||
[]string{},
|
||||
[]string{"9876"},
|
||||
[]string{},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
fakeDocker.ContainerList = runningAPIContainers
|
||||
fakeDocker.ExitedContainerList = exitedAPIContainers
|
||||
fakeDocker.ContainerMap = containerMap
|
||||
fakeDocker.ClearCalls()
|
||||
pods := []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: containers,
|
||||
RestartPolicy: tt.policy,
|
||||
},
|
||||
},
|
||||
}
|
||||
kubelet.podManager.SetPods(pods)
|
||||
waitGroup.Add(1)
|
||||
err := kubelet.SyncPods(pods, emptyPodUIDs, map[string]api.Pod{}, time.Now())
|
||||
if err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
}
|
||||
waitGroup.Wait()
|
||||
|
||||
// Check if we can retrieve the pod status from GetPodStatus().
|
||||
podName := kubecontainer.GetPodFullName(&pods[0])
|
||||
status, err := kubelet.GetPodStatus(podName)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to retrieve pod status for pod %q: %#v.", podName, err)
|
||||
} else {
|
||||
terminatedContainers := []string{}
|
||||
for _, cs := range status.ContainerStatuses {
|
||||
if cs.LastTerminationState.Termination != nil {
|
||||
terminatedContainers = append(terminatedContainers, cs.LastTerminationState.Termination.ContainerID)
|
||||
}
|
||||
}
|
||||
sort.StringSlice(terminatedContainers).Sort()
|
||||
sort.StringSlice(tt.lastTerminations).Sort()
|
||||
if !reflect.DeepEqual(terminatedContainers, tt.lastTerminations) {
|
||||
t.Errorf("Expected(sorted): %#v, Actual(sorted): %#v", tt.lastTerminations, terminatedContainers)
|
||||
}
|
||||
}
|
||||
|
||||
if err := fakeDocker.AssertCreated(tt.created); err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
}
|
||||
if err := fakeDocker.AssertStopped(tt.stopped); err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user