diff --git a/hack/e2e-suite/basic.sh b/hack/e2e-suite/basic.sh index 2bf882d5f3..1f38ceb4b7 100755 --- a/hack/e2e-suite/basic.sh +++ b/hack/e2e-suite/basic.sh @@ -50,7 +50,7 @@ while [ $ALL_RUNNING -ne 1 ]; do ALL_RUNNING=1 for id in $POD_ID_LIST; do CURRENT_STATUS=$($KUBECFG -template '{{and .CurrentState.Info.mynginx.State.Running .CurrentState.Info.net.State.Running}}' get pods/$id) - if [ "$CURRENT_STATUS" != "true" ]; then + if [ "$CURRENT_STATUS" != "{}" ]; then ALL_RUNNING=0 fi done diff --git a/hack/e2e-suite/update.sh b/hack/e2e-suite/update.sh index 8fa0cf1255..f6d02db48b 100755 --- a/hack/e2e-suite/update.sh +++ b/hack/e2e-suite/update.sh @@ -40,10 +40,10 @@ function validate() { for id in $POD_ID_LIST; do TEMPLATE_STRING="{{and ((index .CurrentState.Info \"${CONTROLLER_NAME}\").State.Running) .CurrentState.Info.net.State.Running}}" CURRENT_STATUS=$($KUBECFG -template "${TEMPLATE_STRING}" get pods/$id) - if [ "$CURRENT_STATUS" != "true" ]; then + if [ "$CURRENT_STATUS" != "{}" ]; then ALL_RUNNING=0 else - CURRENT_IMAGE=$($KUBECFG -template "{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").Config.Image}}" get pods/$id) + CURRENT_IMAGE=$($KUBECFG -template "{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").DetailInfo.Config.Image}}" get pods/$id) if [ "$CURRENT_IMAGE" != "${DOCKER_HUB_USER}/update-demo:${CONTAINER_IMAGE_VERSION}" ]; then ALL_RUNNING=0 fi diff --git a/pkg/api/types.go b/pkg/api/types.go index ec1419b6e7..4e77444d59 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -288,8 +288,7 @@ type ContainerStatus struct { } // PodInfo contains one entry for every container with available info. -// TODO(dchen1107): Replace docker.Container below with ContainerStatus defined above. -type PodInfo map[string]docker.Container +type PodInfo map[string]ContainerStatus type RestartPolicyAlways struct{} diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index b85fec9670..2d73b33198 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -301,7 +301,7 @@ type ContainerStatus struct { } // PodInfo contains one entry for every container with available info. -type PodInfo map[string]docker.Container +type PodInfo map[string]ContainerStatus type RestartPolicyAlways struct{} diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 4816d5f590..77feef0dfc 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -298,7 +298,7 @@ type ContainerStatus struct { // PodInfo contains one entry for every container with available info. // TODO(dchen1107): Replace docker.Container below with ContainerStatus defined above. -type PodInfo map[string]docker.Container +type PodInfo map[string]ContainerStatus type RestartPolicyAlways struct{} diff --git a/pkg/client/podinfo_test.go b/pkg/client/podinfo_test.go index 6d20cddcfd..6282f55170 100644 --- a/pkg/client/podinfo_test.go +++ b/pkg/client/podinfo_test.go @@ -32,7 +32,9 @@ import ( func TestHTTPPodInfoGetter(t *testing.T) { expectObj := api.PodInfo{ - "myID": docker.Container{ID: "myID"}, + "myID": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "myID"}, + }, } body, err := json.Marshal(expectObj) if err != nil { @@ -67,14 +69,17 @@ func TestHTTPPodInfoGetter(t *testing.T) { } // reflect.DeepEqual(expectObj, gotObj) doesn't handle blank times well - if len(gotObj) != len(expectObj) || expectObj["myID"].ID != gotObj["myID"].ID { + if len(gotObj) != len(expectObj) || + expectObj["myID"].DetailInfo.ID != gotObj["myID"].DetailInfo.ID { t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj) } } func TestHTTPPodInfoGetterNotFound(t *testing.T) { expectObj := api.PodInfo{ - "myID": docker.Container{ID: "myID"}, + "myID": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "myID"}, + }, } _, err := json.Marshal(expectObj) if err != nil { diff --git a/pkg/kubelet/dockertools/docker.go b/pkg/kubelet/dockertools/docker.go index 306a6245e3..35cb2a6b87 100644 --- a/pkg/kubelet/dockertools/docker.go +++ b/pkg/kubelet/dockertools/docker.go @@ -228,6 +228,25 @@ func GetKubeletDockerContainerLogs(client DockerInterface, containerID, tail str return } +func generateContainerStatus(inspectResult *docker.Container) api.ContainerStatus { + if inspectResult == nil { + // Why did we not get an error? + return api.ContainerStatus{} + } + + var containerStatus api.ContainerStatus + + if inspectResult.State.Running { + containerStatus.State.Running = &api.ContainerStateRunning{} + } else { + containerStatus.State.Termination = &api.ContainerStateTerminated{ + ExitCode: inspectResult.State.ExitCode, + } + } + containerStatus.DetailInfo = *inspectResult + return containerStatus +} + // ErrNoContainersInPod is returned when there are no containers for a given pod var ErrNoContainersInPod = errors.New("no containers exist for this pod") @@ -249,7 +268,9 @@ func GetDockerPodInfo(client DockerInterface, podFullName, uuid string) (api.Pod continue } // We assume docker return us a list of containers in time order - if _, ok := info[dockerContainerName]; ok { + if containerStatus, found := info[dockerContainerName]; found { + containerStatus.RestartCount += 1 + info[dockerContainerName] = containerStatus continue } @@ -257,12 +278,7 @@ func GetDockerPodInfo(client DockerInterface, podFullName, uuid string) (api.Pod if err != nil { return nil, err } - if inspectResult == nil { - // Why did we not get an error? - info[dockerContainerName] = docker.Container{} - } else { - info[dockerContainerName] = *inspectResult - } + info[dockerContainerName] = generateContainerStatus(inspectResult) } if len(info) == 0 { return nil, ErrNoContainersInPod diff --git a/pkg/kubelet/handlers.go b/pkg/kubelet/handlers.go index f3583fc71b..bae598f5ed 100644 --- a/pkg/kubelet/handlers.go +++ b/pkg/kubelet/handlers.go @@ -77,8 +77,8 @@ func (h *httpActionHandler) Run(podFullName, uuid string, container *api.Contain return err } netInfo, found := info[networkContainerName] - if found && netInfo.NetworkSettings != nil { - host = netInfo.NetworkSettings.IPAddress + if found && netInfo.DetailInfo.NetworkSettings != nil { + host = netInfo.DetailInfo.NetworkSettings.IPAddress } else { return fmt.Errorf("failed to find networking container: %v", info) } diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 012531fd18..8e097a95b3 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -488,8 +488,8 @@ func (kl *Kubelet) syncPod(pod *Pod, dockerContainers dockertools.DockerContaine podFullName, uuid) } netInfo, found := info[networkContainerName] - if found && netInfo.NetworkSettings != nil { - podState.PodIP = netInfo.NetworkSettings.IPAddress + if found && netInfo.DetailInfo.NetworkSettings != nil { + podState.PodIP = netInfo.DetailInfo.NetworkSettings.IPAddress } for _, container := range pod.Manifest.Containers { diff --git a/pkg/kubelet/server_test.go b/pkg/kubelet/server_test.go index 3b7f8417a7..70bd644f5b 100644 --- a/pkg/kubelet/server_test.go +++ b/pkg/kubelet/server_test.go @@ -146,7 +146,11 @@ func TestContainers(t *testing.T) { func TestPodInfo(t *testing.T) { fw := newServerTest() - expected := api.PodInfo{"goodpod": docker.Container{ID: "myContainerID"}} + expected := api.PodInfo{ + "goodpod": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "myContainerID"}, + }, + } fw.fakeKubelet.infoFunc = func(name string) (api.PodInfo, error) { if name == "goodpod.etcd" { return expected, nil diff --git a/pkg/master/pod_cache_test.go b/pkg/master/pod_cache_test.go index ed45e58a6a..654b0bef74 100644 --- a/pkg/master/pod_cache_test.go +++ b/pkg/master/pod_cache_test.go @@ -41,7 +41,11 @@ func (f *FakePodInfoGetter) GetPodInfo(host, id string) (api.PodInfo, error) { func TestPodCacheGet(t *testing.T) { cache := NewPodCache(nil, nil) - expected := api.PodInfo{"foo": docker.Container{ID: "foo"}} + expected := api.PodInfo{ + "foo": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "foo"}, + }, + } cache.podInfo["foo"] = expected info, err := cache.GetPodInfo("host", "foo") @@ -66,7 +70,11 @@ func TestPodCacheGetMissing(t *testing.T) { } func TestPodGetPodInfoGetter(t *testing.T) { - expected := api.PodInfo{"foo": docker.Container{ID: "foo"}} + expected := api.PodInfo{ + "foo": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "foo"}, + }, + } fake := FakePodInfoGetter{ data: expected, } @@ -98,7 +106,11 @@ func TestPodUpdateAllContainers(t *testing.T) { pods := []api.Pod{pod} mockRegistry := registrytest.NewPodRegistry(&api.PodList{Items: pods}) - expected := api.PodInfo{"foo": docker.Container{ID: "foo"}} + expected := api.PodInfo{ + "foo": api.ContainerStatus{ + DetailInfo: docker.Container{ID: "foo"}, + }, + } fake := FakePodInfoGetter{ data: expected, } diff --git a/pkg/registry/pod/rest.go b/pkg/registry/pod/rest.go index efd85ec47d..5bd46414f1 100644 --- a/pkg/registry/pod/rest.go +++ b/pkg/registry/pod/rest.go @@ -196,8 +196,8 @@ func (rs *REST) fillPodInfo(pod *api.Pod) { pod.CurrentState.Info = info netContainerInfo, ok := info["net"] if ok { - if netContainerInfo.NetworkSettings != nil { - pod.CurrentState.PodIP = netContainerInfo.NetworkSettings.IPAddress + if netContainerInfo.DetailInfo.NetworkSettings != nil { + pod.CurrentState.PodIP = netContainerInfo.DetailInfo.NetworkSettings.IPAddress } else { glog.Warningf("No network settings: %#v", netContainerInfo) } @@ -253,11 +253,13 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodStatus, stopped := 0 unknown := 0 for _, container := range pod.DesiredState.Manifest.Containers { - if info, ok := pod.CurrentState.Info[container.Name]; ok { - if info.State.Running { + if containerStatus, ok := pod.CurrentState.Info[container.Name]; ok { + if containerStatus.State.Running != nil { running++ - } else { + } else if containerStatus.State.Termination != nil { stopped++ + } else { + unknown++ } } else { unknown++ diff --git a/pkg/registry/pod/rest_test.go b/pkg/registry/pod/rest_test.go index b256b97dec..553ddcd333 100644 --- a/pkg/registry/pod/rest_test.go +++ b/pkg/registry/pod/rest_test.go @@ -360,14 +360,14 @@ func TestMakePodStatus(t *testing.T) { currentState := api.PodState{ Host: "machine", } - runningState := docker.Container{ - State: docker.State{ - Running: true, + runningState := api.ContainerStatus{ + State: api.ContainerState{ + Running: &api.ContainerStateRunning{}, }, } - stoppedState := docker.Container{ - State: docker.State{ - Running: false, + stoppedState := api.ContainerStatus{ + State: api.ContainerState{ + Termination: &api.ContainerStateTerminated{}, }, } @@ -376,14 +376,7 @@ func TestMakePodStatus(t *testing.T) { status api.PodStatus test string }{ - { - &api.Pod{ - DesiredState: desiredState, - CurrentState: currentState, - }, - api.PodWaiting, - "waiting", - }, + {&api.Pod{DesiredState: desiredState, CurrentState: currentState}, api.PodWaiting, "waiting"}, { &api.Pod{ DesiredState: desiredState, @@ -398,7 +391,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": runningState, }, @@ -412,7 +405,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": runningState, }, @@ -426,7 +419,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": stoppedState, "containerB": stoppedState, }, @@ -440,7 +433,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": stoppedState, "containerB": stoppedState, }, @@ -454,7 +447,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": stoppedState, }, @@ -468,7 +461,7 @@ func TestMakePodStatus(t *testing.T) { &api.Pod{ DesiredState: desiredState, CurrentState: api.PodState{ - Info: map[string]docker.Container{ + Info: map[string]api.ContainerStatus{ "containerA": runningState, }, Host: "machine", @@ -566,12 +559,14 @@ func (f *FakePodInfoGetter) GetPodInfo(host, podID string) (api.PodInfo, error) func TestFillPodInfo(t *testing.T) { expectedIP := "1.2.3.4" fakeGetter := FakePodInfoGetter{ - info: map[string]docker.Container{ + info: map[string]api.ContainerStatus{ "net": { - ID: "foobar", - Path: "bin/run.sh", - NetworkSettings: &docker.NetworkSettings{ - IPAddress: expectedIP, + DetailInfo: docker.Container{ + ID: "foobar", + Path: "bin/run.sh", + NetworkSettings: &docker.NetworkSettings{ + IPAddress: expectedIP, + }, }, }, }, @@ -592,10 +587,12 @@ func TestFillPodInfo(t *testing.T) { func TestFillPodInfoNoData(t *testing.T) { expectedIP := "" fakeGetter := FakePodInfoGetter{ - info: map[string]docker.Container{ + info: map[string]api.ContainerStatus{ "net": { - ID: "foobar", - Path: "bin/run.sh", + DetailInfo: docker.Container{ + ID: "foobar", + Path: "bin/run.sh", + }, }, }, }