diff --git a/hack/e2e-suite/basic.sh b/hack/e2e-suite/basic.sh index 1f38ceb4b7b..793aac0dba3 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" != "{}" ]; then + if [ "$CURRENT_STATUS" != "{0001-01-01 00:00:00 +0000 UTC}" ]; then ALL_RUNNING=0 fi done diff --git a/hack/e2e-suite/update.sh b/hack/e2e-suite/update.sh index 471646497e1..d5a3ebe15e9 100755 --- a/hack/e2e-suite/update.sh +++ b/hack/e2e-suite/update.sh @@ -47,12 +47,12 @@ function validate() { local template_string current_status current_image host_ip 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" != "{}" ]]; then + if [ "$current_status" != "{0001-01-01 00:00:00 +0000 UTC}" ]; then echo " $id is created but not running" continue fi - template_string="{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").DetailInfo.Config.Image}}" + template_string="{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").Image}}" current_image=$($KUBECFG -template="${template_string}" get "pods/$id") if [[ "$current_image" != "${DOCKER_HUB_USER}/update-demo:${container_image_version}" ]]; then echo " ${id} is created but running wrong image" diff --git a/pkg/api/types.go b/pkg/api/types.go index f1b53633101..d504e51adc6 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -18,9 +18,9 @@ package api import ( "strings" + "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" ) // Common string formats @@ -302,12 +302,15 @@ type ContainerStateWaiting struct { } type ContainerStateRunning struct { + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` } type ContainerStateTerminated struct { - ExitCode int `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` - Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + ExitCode int `json:"exitCode" yaml:"exitCode"` + Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` + FinishedAt time.Time `json:"finishedAt,omitempty" yaml:"finishedAt,omitempty"` } type ContainerState struct { @@ -323,12 +326,13 @@ type ContainerStatus struct { // defined for container? State ContainerState `json:"state,omitempty" yaml:"state,omitempty"` RestartCount int `json:"restartCount" yaml:"restartCount"` - // TODO(dchen1107): Introduce our own NetworkSettings struct here? + // TODO(dchen1107): Deprecated this soon once we pull entire PodStatus from node, + // not just PodInfo. Now we need this to remove docker.Container from API + PodIP string `json:"podIP,omitempty" yaml:"podIP,omitempty"` + // TODO(dchen1107): Need to decide how to represent this in v1beta3 + Image string `yaml:"image" json:"image"` // TODO(dchen1107): Once we have done with integration with cadvisor, resource // usage should be included. - // TODO(dchen1107): In long run, I think we should replace this with our own struct to remove - // the dependency on docker. - DetailInfo docker.Container `json:"detailInfo,omitempty" yaml:"detailInfo,omitempty"` } // PodInfo contains one entry for every container with available info. diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 8fb4e553700..dc88f1cd4c2 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -17,8 +17,9 @@ limitations under the License. package v1beta1 import ( + "time" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" ) // Common string formats @@ -286,12 +287,15 @@ type ContainerStateWaiting struct { } type ContainerStateRunning struct { + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` } type ContainerStateTerminated struct { - ExitCode int `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` - Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + ExitCode int `json:"exitCode" yaml:"exitCode"` + Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` + FinishedAt time.Time `json:"finishedAt,omitempty" yaml:"finishedAt,omitempty"` } type ContainerState struct { @@ -307,12 +311,13 @@ type ContainerStatus struct { // defined for container? State ContainerState `json:"state,omitempty" yaml:"state,omitempty"` RestartCount int `json:"restartCount" yaml:"restartCount"` - // TODO(dchen1107): Introduce our own NetworkSettings struct here? + // TODO(dchen1107): Deprecated this soon once we pull entire PodStatus from node, + // not just PodInfo. Now we need this to remove docker.Container from API + PodIP string `json:"podIP,omitempty" yaml:"podIP,omitempty"` + // TODO(dchen1107): Need to decide how to reprensent this in v1beta3 + Image string `yaml:"image" json:"image"` // TODO(dchen1107): Once we have done with integration with cadvisor, resource // usage should be included. - // TODO(dchen1107): In long run, I think we should replace this with our own struct to remove - // the dependency on docker. - DetailInfo docker.Container `json:"detailInfo,omitempty" yaml:"detailInfo,omitempty"` } // PodInfo contains one entry for every container with available info. diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 8b96c8b98db..770a1cb8ca3 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -17,8 +17,9 @@ limitations under the License. package v1beta2 import ( + "time" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" ) // Common string formats @@ -282,12 +283,15 @@ type ContainerStateWaiting struct { } type ContainerStateRunning struct { + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` } type ContainerStateTerminated struct { - ExitCode int `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` - Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + ExitCode int `json:"exitCode" yaml:"exitCode"` + Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` + FinishedAt time.Time `json:"finishedAt,omitempty" yaml:"finishedAt,omitempty"` } type ContainerState struct { @@ -303,16 +307,16 @@ type ContainerStatus struct { // defined for container? State ContainerState `json:"state,omitempty" yaml:"state,omitempty"` RestartCount int `json:"restartCount" yaml:"restartCount"` - // TODO(dchen1107): Introduce our own NetworkSettings struct here? + // TODO(dchen1107): Deprecated this soon once we pull entire PodStatus from node, + // not just PodInfo. Now we need this to remove docker.Container from API + PodIP string `json:"podIP,omitempty" yaml:"podIP,omitempty"` + // TODO(dchen1107): Need to decide how to reprensent this in v1beta3 + Image string `yaml:"image" json:"image"` // TODO(dchen1107): Once we have done with integration with cadvisor, resource // usage should be included. - // TODO(dchen1107): In long run, I think we should replace this with our own struct to remove - // the dependency on docker. - DetailInfo docker.Container `json:"detailInfo,omitempty" yaml:"detailInfo,omitempty"` } // PodInfo contains one entry for every container with available info. -// TODO(dchen1107): Replace docker.Container below with ContainerStatus defined above. type PodInfo map[string]ContainerStatus type RestartPolicyAlways struct{} diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index b02b5a41561..84f2f0869ea 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -17,8 +17,9 @@ limitations under the License. package v1beta3 import ( + "time" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" ) // Common string formats @@ -312,12 +313,15 @@ type ContainerStateWaiting struct { } type ContainerStateRunning struct { + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` } type ContainerStateTerminated struct { - ExitCode int `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` - Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + ExitCode int `json:"exitCode" yaml:"exitCode"` + Signal int `json:"signal,omitempty" yaml:"signal,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + StartedAt time.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` + FinishedAt time.Time `json:"finishedAt,omitempty" yaml:"finishedAt,omitempty"` } type ContainerState struct { @@ -334,16 +338,14 @@ type ContainerStatus struct { State ContainerState `json:"state,omitempty" yaml:"state,omitempty"` RestartCount int `json:"restartCount" yaml:"restartCount"` // TODO(dchen1107): Introduce our own NetworkSettings struct here? + // TODO(dchen1107): Which image the container is running with? // TODO(dchen1107): Once we have done with integration with cadvisor, resource // usage should be included. - // TODO(dchen1107): In long run, I think we should replace this with our own struct to remove - // the dependency on docker. - DetailInfo docker.Container `json:"detailInfo,omitempty" yaml:"detailInfo,omitempty"` } // 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 6282f55170e..b14231d9334 100644 --- a/pkg/client/podinfo_test.go +++ b/pkg/client/podinfo_test.go @@ -27,14 +27,11 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" ) func TestHTTPPodInfoGetter(t *testing.T) { expectObj := api.PodInfo{ - "myID": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "myID"}, - }, + "myID": api.ContainerStatus{}, } body, err := json.Marshal(expectObj) if err != nil { @@ -69,17 +66,14 @@ func TestHTTPPodInfoGetter(t *testing.T) { } // reflect.DeepEqual(expectObj, gotObj) doesn't handle blank times well - if len(gotObj) != len(expectObj) || - expectObj["myID"].DetailInfo.ID != gotObj["myID"].DetailInfo.ID { + if len(gotObj) != len(expectObj) { t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj) } } func TestHTTPPodInfoGetterNotFound(t *testing.T) { expectObj := api.PodInfo{ - "myID": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "myID"}, - }, + "myID": api.ContainerStatus{}, } _, err := json.Marshal(expectObj) if err != nil { diff --git a/pkg/kubelet/dockertools/docker.go b/pkg/kubelet/dockertools/docker.go index 13c4f3d12eb..c46f96123b9 100644 --- a/pkg/kubelet/dockertools/docker.go +++ b/pkg/kubelet/dockertools/docker.go @@ -270,30 +270,66 @@ func GetKubeletDockerContainerLogs(client DockerInterface, containerID, tail str return } -func generateContainerStatus(inspectResult *docker.Container) api.ContainerStatus { +var ( + // ErrNoContainersInPod is returned when there are no containers for a given pod + ErrNoContainersInPod = errors.New("no containers exist for this pod") + + // ErrNoNetworkContainerInPod is returned when there is no network container for a given pod + ErrNoNetworkContainerInPod = errors.New("No network container exists for this pod") + + // ErrContainerCannotRun is returned when a container is created, but cannot run properly + ErrContainerCannotRun = errors.New("Container cannot run") +) + +func inspectContainer(client DockerInterface, dockerID, containerName string) (*api.ContainerStatus, error) { + inspectResult, err := client.InspectContainer(dockerID) + if err != nil { + return nil, err + } if inspectResult == nil { // Why did we not get an error? - return api.ContainerStatus{} + return &api.ContainerStatus{}, nil } - var containerStatus api.ContainerStatus + glog.V(3).Infof("Container: %s [%s] inspect result %+v", *inspectResult) + containerStatus := api.ContainerStatus{ + Image: inspectResult.Config.Image, + } + waiting := true if inspectResult.State.Running { - containerStatus.State.Running = &api.ContainerStateRunning{} - } else { + containerStatus.State.Running = &api.ContainerStateRunning{ + StartedAt: inspectResult.State.StartedAt, + } + if containerName == "net" && inspectResult.NetworkSettings != nil { + containerStatus.PodIP = inspectResult.NetworkSettings.IPAddress + } + waiting = false + } else if !inspectResult.State.FinishedAt.IsZero() { + // TODO(dchen1107): Integrate with event to provide a better reason containerStatus.State.Termination = &api.ContainerStateTerminated{ - ExitCode: inspectResult.State.ExitCode, + ExitCode: inspectResult.State.ExitCode, + Reason: "", + StartedAt: inspectResult.State.StartedAt, + FinishedAt: inspectResult.State.FinishedAt, + } + waiting = false + } + + if waiting { + // TODO(dchen1107): Separate issue docker/docker#8294 was filed + // TODO(dchen1107): Need to figure out why we are still waiting + // Check any issue to run container + containerStatus.State.Waiting = &api.ContainerStateWaiting{ + Reason: ErrContainerCannotRun.Error(), } } - containerStatus.DetailInfo = *inspectResult - return containerStatus + + return &containerStatus, nil } -// ErrNoContainersInPod is returned when there are no containers for a given pod -var ErrNoContainersInPod = errors.New("no containers exist for this pod") - // GetDockerPodInfo returns docker info for all containers in the pod/manifest. -func GetDockerPodInfo(client DockerInterface, podFullName, uuid string) (api.PodInfo, error) { +func GetDockerPodInfo(client DockerInterface, manifest api.ContainerManifest, podFullName, uuid string) (api.PodInfo, error) { info := api.PodInfo{} containers, err := client.ListContainers(docker.ListContainersOptions{All: true}) @@ -316,16 +352,53 @@ func GetDockerPodInfo(client DockerInterface, podFullName, uuid string) (api.Pod continue } - inspectResult, err := client.InspectContainer(value.ID) + containerStatus, err := inspectContainer(client, value.ID, dockerContainerName) if err != nil { return nil, err } - info[dockerContainerName] = generateContainerStatus(inspectResult) + info[dockerContainerName] = *containerStatus } + if len(info) == 0 { return nil, ErrNoContainersInPod } + // First make sure we are not missing network container + if _, found := info["net"]; !found { + return nil, ErrNoNetworkContainerInPod + } + + if len(info) < (len(manifest.Containers) + 1) { + var containerStatus api.ContainerStatus + // Not all containers expected are created, verify if there are + // image related issues + for _, container := range manifest.Containers { + if _, found := info[container.Name]; found { + continue + } + + image := container.Image + // Check image is ready on the node or not + // TODO(dchen1107): docker/docker/issues/8365 to figure out if the image exists + _, err := client.InspectImage(image) + if err == nil { + containerStatus.State.Waiting = &api.ContainerStateWaiting{ + Reason: fmt.Sprintf("Image: %s is ready, container is creating", image), + } + } else if err == docker.ErrNoSuchImage { + containerStatus.State.Waiting = &api.ContainerStateWaiting{ + Reason: fmt.Sprintf("Image: %s is not ready on the node", image), + } + } else { + containerStatus.State.Waiting = &api.ContainerStateWaiting{ + Reason: err.Error(), + } + } + + info[container.Name] = containerStatus + } + } + return info, nil } diff --git a/pkg/kubelet/dockertools/fake_docker_client.go b/pkg/kubelet/dockertools/fake_docker_client.go index 13d0a47cb34..10c80335a66 100644 --- a/pkg/kubelet/dockertools/fake_docker_client.go +++ b/pkg/kubelet/dockertools/fake_docker_client.go @@ -29,6 +29,7 @@ type FakeDockerClient struct { sync.Mutex ContainerList []docker.APIContainers Container *docker.Container + Image *docker.Image Err error called []string Stopped []string @@ -67,10 +68,19 @@ func (f *FakeDockerClient) ListContainers(options docker.ListContainersOptions) func (f *FakeDockerClient) InspectContainer(id string) (*docker.Container, error) { f.Lock() defer f.Unlock() - f.called = append(f.called, "inspect") + f.called = append(f.called, "inspect_container") return f.Container, f.Err } +// InspectImage is a test-spy implementation of DockerInterface.InspectImage. +// It adds an entry "inspect" to the internal method call record. +func (f *FakeDockerClient) InspectImage(name string) (*docker.Image, error) { + f.Lock() + defer f.Unlock() + f.called = append(f.called, "inspect_image") + return f.Image, f.Err +} + // CreateContainer is a test-spy implementation of DockerInterface.CreateContainer. // It adds an entry "create" to the internal method call record. func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*docker.Container, error) { @@ -130,10 +140,6 @@ func (f *FakeDockerClient) PullImage(opts docker.PullImageOptions, auth docker.A return f.Err } -func (f *FakeDockerClient) InspectImage(name string) (*docker.Image, error) { - return nil, f.Err -} - // FakeDockerPuller is a stub implementation of DockerPuller. type FakeDockerPuller struct { sync.Mutex diff --git a/pkg/kubelet/handlers.go b/pkg/kubelet/handlers.go index bae598f5ed4..c420d687f2d 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.DetailInfo.NetworkSettings != nil { - host = netInfo.DetailInfo.NetworkSettings.IPAddress + if found { + host = netInfo.PodIP } else { return fmt.Errorf("failed to find networking container: %v", info) } diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 039be7b890d..2c1820abbaa 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -113,6 +113,7 @@ type Kubelet struct { networkContainerImage string podWorkers podWorkers resyncInterval time.Duration + pods []Pod // Optional, no events will be sent without it etcdClient tools.EtcdClient @@ -482,8 +483,8 @@ func (kl *Kubelet) syncPod(pod *Pod, dockerContainers dockertools.DockerContaine podFullName, uuid) } netInfo, found := info[networkContainerName] - if found && netInfo.DetailInfo.NetworkSettings != nil { - podState.PodIP = netInfo.DetailInfo.NetworkSettings.IPAddress + if found { + podState.PodIP = netInfo.PodIP } for _, container := range pod.Manifest.Containers { @@ -699,15 +700,14 @@ func filterHostPortConflicts(pods []Pod) []Pod { // no changes are seen to the configuration, will synchronize the last known desired // state every sync_frequency seconds. Never returns. func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { - var pods []Pod for { select { case u := <-updates: switch u.Op { case SET: glog.V(3).Infof("Containers changed [%s]", kl.hostname) - pods = u.Pods - pods = filterHostPortConflicts(pods) + kl.pods = u.Pods + kl.pods = filterHostPortConflicts(kl.pods) case UPDATE: //TODO: implement updates of containers @@ -718,12 +718,12 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { panic("syncLoop does not support incremental changes") } case <-time.After(kl.resyncInterval): - if pods == nil { + if kl.pods == nil { continue } } - err := handler.SyncPods(pods) + err := handler.SyncPods(kl.pods) if err != nil { glog.Errorf("Couldn't sync containers : %v", err) } @@ -769,7 +769,14 @@ func (kl *Kubelet) GetKubeletContainerLogs(podFullName, containerName, tail stri // GetPodInfo returns information from Docker about the containers in a pod func (kl *Kubelet) GetPodInfo(podFullName, uuid string) (api.PodInfo, error) { - return dockertools.GetDockerPodInfo(kl.dockerClient, podFullName, uuid) + var manifest api.ContainerManifest + for _, pod := range kl.pods { + if GetPodFullName(&pod) == podFullName { + manifest = pod.Manifest + break + } + } + return dockertools.GetDockerPodInfo(kl.dockerClient, manifest, podFullName, uuid) } // GetContainerInfo returns stats (from Cadvisor) for a container. diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 0334f57d008..dfeb7fabdf1 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -227,7 +227,7 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) { kubelet.drainWorkers() verifyCalls(t, fakeDocker, []string{ - "list", "list", "create", "start", "list", "inspect", "list", "create", "start"}) + "list", "list", "create", "start", "list", "inspect_container", "list", "create", "start"}) fakeDocker.Lock() @@ -273,7 +273,7 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) { kubelet.drainWorkers() verifyCalls(t, fakeDocker, []string{ - "list", "list", "create", "start", "list", "inspect", "list", "create", "start"}) + "list", "list", "create", "start", "list", "inspect_container", "list", "create", "start"}) fakeDocker.Lock() @@ -316,7 +316,7 @@ func TestSyncPodsWithNetCreatesContainer(t *testing.T) { kubelet.drainWorkers() verifyCalls(t, fakeDocker, []string{ - "list", "list", "list", "inspect", "list", "create", "start"}) + "list", "list", "list", "inspect_container", "list", "create", "start"}) fakeDocker.Lock() if len(fakeDocker.Created) != 1 || @@ -366,7 +366,7 @@ func TestSyncPodsWithNetCreatesContainerCallsHandler(t *testing.T) { kubelet.drainWorkers() verifyCalls(t, fakeDocker, []string{ - "list", "list", "list", "inspect", "list", "create", "start"}) + "list", "list", "list", "inspect_container", "list", "create", "start"}) fakeDocker.Lock() if len(fakeDocker.Created) != 1 || @@ -406,7 +406,7 @@ func TestSyncPodsDeletesWithNoNetContainer(t *testing.T) { kubelet.drainWorkers() verifyCalls(t, fakeDocker, []string{ - "list", "list", "stop", "create", "start", "list", "list", "inspect", "list", "create", "start"}) + "list", "list", "stop", "create", "start", "list", "list", "inspect_container", "list", "create", "start"}) // A map iteration is used to delete containers, so must not depend on // order here. diff --git a/pkg/kubelet/runonce_test.go b/pkg/kubelet/runonce_test.go index 4949a99594c..5766dcd98e5 100644 --- a/pkg/kubelet/runonce_test.go +++ b/pkg/kubelet/runonce_test.go @@ -85,8 +85,20 @@ func TestRunOnce(t *testing.T) { }}, }, inspectContainersResults: []inspectContainersResult{ - {label: "syncPod", container: docker.Container{State: docker.State{Running: true}}}, - {label: "syncPod", container: docker.Container{State: docker.State{Running: true}}}, + { + label: "syncPod", + container: docker.Container{ + Config: &docker.Config{Image: "someimage"}, + State: docker.State{Running: true}, + }, + }, + { + label: "syncPod", + container: docker.Container{ + Config: &docker.Config{Image: "someimage"}, + State: docker.State{Running: true}, + }, + }, }, t: t, } diff --git a/pkg/kubelet/server_test.go b/pkg/kubelet/server_test.go index 6c137c98cc8..4a6aa2fd24d 100644 --- a/pkg/kubelet/server_test.go +++ b/pkg/kubelet/server_test.go @@ -31,7 +31,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/fsouza/go-dockerclient" "github.com/google/cadvisor/info" ) @@ -147,9 +146,7 @@ func TestContainers(t *testing.T) { func TestPodInfo(t *testing.T) { fw := newServerTest() expected := api.PodInfo{ - "goodpod": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "myContainerID"}, - }, + "goodpod": api.ContainerStatus{}, } fw.fakeKubelet.infoFunc = func(name string) (api.PodInfo, error) { if name == "goodpod.etcd" { diff --git a/pkg/master/pod_cache_test.go b/pkg/master/pod_cache_test.go index 654b0bef741..0febfb4ce20 100644 --- a/pkg/master/pod_cache_test.go +++ b/pkg/master/pod_cache_test.go @@ -22,7 +22,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" - "github.com/fsouza/go-dockerclient" ) type FakePodInfoGetter struct { @@ -42,9 +41,7 @@ func TestPodCacheGet(t *testing.T) { cache := NewPodCache(nil, nil) expected := api.PodInfo{ - "foo": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "foo"}, - }, + "foo": api.ContainerStatus{}, } cache.podInfo["foo"] = expected @@ -71,9 +68,7 @@ func TestPodCacheGetMissing(t *testing.T) { func TestPodGetPodInfoGetter(t *testing.T) { expected := api.PodInfo{ - "foo": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "foo"}, - }, + "foo": api.ContainerStatus{}, } fake := FakePodInfoGetter{ data: expected, @@ -107,9 +102,7 @@ func TestPodUpdateAllContainers(t *testing.T) { mockRegistry := registrytest.NewPodRegistry(&api.PodList{Items: pods}) expected := api.PodInfo{ - "foo": api.ContainerStatus{ - DetailInfo: docker.Container{ID: "foo"}, - }, + "foo": api.ContainerStatus{}, } fake := FakePodInfoGetter{ data: expected, diff --git a/pkg/registry/pod/rest.go b/pkg/registry/pod/rest.go index 835221635e1..e55929a8a72 100644 --- a/pkg/registry/pod/rest.go +++ b/pkg/registry/pod/rest.go @@ -226,8 +226,8 @@ func (rs *REST) fillPodInfo(pod *api.Pod) { pod.CurrentState.Info = info netContainerInfo, ok := info["net"] if ok { - if netContainerInfo.DetailInfo.NetworkSettings != nil { - pod.CurrentState.PodIP = netContainerInfo.DetailInfo.NetworkSettings.IPAddress + if netContainerInfo.PodIP != "" { + pod.CurrentState.PodIP = netContainerInfo.PodIP } else { glog.Warningf("No network settings: %#v", netContainerInfo) } diff --git a/pkg/registry/pod/rest_test.go b/pkg/registry/pod/rest_test.go index b7af44aa5f6..c255208c79e 100644 --- a/pkg/registry/pod/rest_test.go +++ b/pkg/registry/pod/rest_test.go @@ -31,8 +31,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - - "github.com/fsouza/go-dockerclient" ) func expectApiStatusError(t *testing.T, ch <-chan runtime.Object, msg string) { @@ -605,16 +603,17 @@ func (f *FakePodInfoGetter) GetPodInfo(host, podID string) (api.PodInfo, error) func TestFillPodInfo(t *testing.T) { expectedIP := "1.2.3.4" + expectedTime, _ := time.Parse("2013-Feb-03", "2013-Feb-03") fakeGetter := FakePodInfoGetter{ info: map[string]api.ContainerStatus{ "net": { - DetailInfo: docker.Container{ - ID: "foobar", - Path: "bin/run.sh", - NetworkSettings: &docker.NetworkSettings{ - IPAddress: expectedIP, + State: api.ContainerState{ + Running: &api.ContainerStateRunning{ + StartedAt: expectedTime, }, }, + RestartCount: 1, + PodIP: expectedIP, }, }, } @@ -636,10 +635,7 @@ func TestFillPodInfoNoData(t *testing.T) { fakeGetter := FakePodInfoGetter{ info: map[string]api.ContainerStatus{ "net": { - DetailInfo: docker.Container{ - ID: "foobar", - Path: "bin/run.sh", - }, + State: api.ContainerState{}, }, }, }