From 15e9fa8a9df5b522a354d292cab9254f00ae2748 Mon Sep 17 00:00:00 2001 From: Dawn Chen Date: Tue, 13 Jan 2015 18:11:24 -0800 Subject: [PATCH] Introduce PodStatusResult, and deprecate PodContainerInfo. --- cmd/integration/integration.go | 6 ++-- pkg/api/register.go | 6 ++-- pkg/api/types.go | 10 ++++++ pkg/api/v1beta1/conversion.go | 24 +++++++++++++ pkg/api/v1beta1/register.go | 4 +-- pkg/api/v1beta1/types.go | 5 +++ pkg/api/v1beta2/conversion.go | 25 ++++++++++++++ pkg/api/v1beta2/register.go | 4 +-- pkg/api/v1beta2/types.go | 5 +++ pkg/api/v1beta3/register.go | 4 +-- pkg/api/v1beta3/types.go | 16 +++++---- pkg/client/kubelet.go | 28 +++++++-------- pkg/client/kubelet_test.go | 15 ++++---- pkg/kubelet/handlers.go | 8 ++--- pkg/kubelet/kubelet.go | 22 +++++++----- pkg/kubelet/server.go | 20 +++++------ pkg/kubelet/server_test.go | 18 +++++----- pkg/master/pod_cache.go | 4 +-- pkg/master/pod_cache_test.go | 63 +++++++++++++++++++--------------- 19 files changed, 189 insertions(+), 98 deletions(-) diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index d3377d07fc0..e8744e045db 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -62,7 +62,7 @@ var ( type fakeKubeletClient struct{} -func (fakeKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) { +func (fakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) { glog.V(3).Infof("Trying to get container info for %v/%v/%v", host, podNamespace, podID) // This is a horrible hack to get around the fact that we can't provide // different port numbers per kubelet... @@ -81,7 +81,7 @@ func (fakeKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodCo default: glog.Fatalf("Can't get info for: '%v', '%v - %v'", host, podNamespace, podID) } - return c.GetPodInfo("localhost", podNamespace, podID) + return c.GetPodStatus("localhost", podNamespace, podID) } func (fakeKubeletClient) HealthCheck(host string) (health.Status, error) { @@ -223,7 +223,7 @@ func podsOnMinions(c *client.Client, pods api.PodList) wait.ConditionFunc { if len(host) == 0 { return false, nil } - if _, err := podInfo.GetPodInfo(host, namespace, id); err != nil { + if _, err := podInfo.GetPodStatus(host, namespace, id); err != nil { return false, nil } } diff --git a/pkg/api/register.go b/pkg/api/register.go index 298c62cea18..5c138425b18 100644 --- a/pkg/api/register.go +++ b/pkg/api/register.go @@ -25,9 +25,9 @@ var Scheme = runtime.NewScheme() func init() { Scheme.AddKnownTypes("", - &PodContainerInfo{}, - &PodList{}, &Pod{}, + &PodList{}, + &PodStatusResult{}, &ReplicationControllerList{}, &ReplicationController{}, &ServiceList{}, @@ -55,9 +55,9 @@ func init() { Scheme.AddKnownTypeWithName("", "ServerOpList", &OperationList{}) } -func (*PodContainerInfo) IsAnAPIObject() {} func (*Pod) IsAnAPIObject() {} func (*PodList) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} func (*ReplicationController) IsAnAPIObject() {} func (*ReplicationControllerList) IsAnAPIObject() {} func (*Service) IsAnAPIObject() {} diff --git a/pkg/api/types.go b/pkg/api/types.go index 730c9646063..fb383a9282b 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -418,6 +418,7 @@ type ContainerStatus struct { type PodInfo map[string]ContainerStatus // PodContainerInfo is a wrapper for PodInfo that can be encode/decoded +// DEPRECATED: Replaced with PodStatusResult type PodContainerInfo struct { TypeMeta `json:",inline"` ObjectMeta `json:"metadata,omitempty"` @@ -503,6 +504,15 @@ type PodStatus struct { Info PodInfo `json:"info,omitempty"` } +// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded +type PodStatusResult struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + // Status represents the current information about a pod. This data may not be up + // to date. + Status PodStatus `json:"status,omitempty"` +} + // Pod is a collection of containers, used as either input (create, update) or as output (list, get). type Pod struct { TypeMeta `json:",inline"` diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 45674058ea0..3b80296b9c9 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -314,6 +314,30 @@ func init() { } return nil }, + func(in *newer.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.State, 0); err != nil { + return err + } + return nil + }, + func(in *PodStatusResult, out *newer.PodStatusResult, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.State, &out.Status, 0); err != nil { + return err + } + return nil + }, func(in *newer.ReplicationController, out *ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { diff --git a/pkg/api/v1beta1/register.go b/pkg/api/v1beta1/register.go index 6f936305d2c..9d5e19bc8e8 100644 --- a/pkg/api/v1beta1/register.go +++ b/pkg/api/v1beta1/register.go @@ -27,7 +27,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta1") func init() { api.Scheme.AddKnownTypes("v1beta1", &Pod{}, - &PodContainerInfo{}, + &PodStatusResult{}, &PodList{}, &ReplicationController{}, &ReplicationControllerList{}, @@ -57,7 +57,7 @@ func init() { } func (*Pod) IsAnAPIObject() {} -func (*PodContainerInfo) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} func (*PodList) IsAnAPIObject() {} func (*ReplicationController) IsAnAPIObject() {} func (*ReplicationControllerList) IsAnAPIObject() {} diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 0a8c4875a5c..777c11cf47c 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -412,6 +412,11 @@ type PodState struct { Info PodInfo `json:"info,omitempty" description:"map of container name to container status"` } +type PodStatusResult struct { + TypeMeta `json:",inline"` + State PodState `json:"state,omitempty" description:"current state of the pod"` +} + // PodList is a list of Pods. type PodList struct { TypeMeta `json:",inline"` diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index 64bf790f200..16e3e974a74 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -345,6 +345,31 @@ func init() { return nil }, + func(in *newer.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.State, 0); err != nil { + return err + } + return nil + }, + func(in *PodStatusResult, out *newer.PodStatusResult, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.State, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *newer.PodSpec, out *PodState, s conversion.Scope) error { if err := s.Convert(&in, &out.Manifest, 0); err != nil { return err diff --git a/pkg/api/v1beta2/register.go b/pkg/api/v1beta2/register.go index 121f3d20a8e..7682d9ad246 100644 --- a/pkg/api/v1beta2/register.go +++ b/pkg/api/v1beta2/register.go @@ -27,7 +27,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta2") func init() { api.Scheme.AddKnownTypes("v1beta2", &Pod{}, - &PodContainerInfo{}, + &PodStatusResult{}, &PodList{}, &ReplicationController{}, &ReplicationControllerList{}, @@ -57,7 +57,7 @@ func init() { } func (*Pod) IsAnAPIObject() {} -func (*PodContainerInfo) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} func (*PodList) IsAnAPIObject() {} func (*ReplicationController) IsAnAPIObject() {} func (*ReplicationControllerList) IsAnAPIObject() {} diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 463a78d6f72..77a85fff054 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -375,6 +375,11 @@ type PodState struct { Info PodInfo `json:"info,omitempty" description:"map of container name to container status"` } +type PodStatusResult struct { + TypeMeta `json:",inline"` + State PodState `json:"state,omitempty" description:"current state of the pod"` +} + // PodList is a list of Pods. type PodList struct { TypeMeta `json:",inline"` diff --git a/pkg/api/v1beta3/register.go b/pkg/api/v1beta3/register.go index 3bb97847189..6594cb67e89 100644 --- a/pkg/api/v1beta3/register.go +++ b/pkg/api/v1beta3/register.go @@ -26,9 +26,9 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta3") func init() { api.Scheme.AddKnownTypes("v1beta3", - &PodContainerInfo{}, &Pod{}, &PodList{}, + &PodStatusResult{}, &PodTemplate{}, &PodTemplateList{}, &BoundPod{}, @@ -56,9 +56,9 @@ func init() { api.Scheme.AddKnownTypeWithName("v1beta3", "ServerOpList", &OperationList{}) } -func (*PodContainerInfo) IsAnAPIObject() {} func (*Pod) IsAnAPIObject() {} func (*PodList) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} func (*PodTemplate) IsAnAPIObject() {} func (*PodTemplateList) IsAnAPIObject() {} func (*BoundPod) IsAnAPIObject() {} diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index fbb147455d4..a4b87ef7050 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -435,13 +435,6 @@ type ContainerStatus struct { // PodInfo contains one entry for every container with available info. type PodInfo map[string]ContainerStatus -// PodContainerInfo is a wrapper for PodInfo that can be encode/decoded -type PodContainerInfo struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - ContainerInfo PodInfo `json:"containerInfo" description:"information about each container in this pod"` -} - type RestartPolicyAlways struct{} // TODO(dchen1107): Define what kinds of failures should restart. @@ -511,6 +504,15 @@ type PodStatus struct { Info PodInfo `json:"info,omitempty"` } +// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded +type PodStatusResult struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + // Status represents the current information about a pod. This data may not be up + // to date. + Status PodStatus `json:"status,omitempty"` +} + // Pod is a collection of containers that can run on a host. This resource is created // by clients and scheduled onto hosts. BoundPod represents the state of this resource // to hosts. diff --git a/pkg/client/kubelet.go b/pkg/client/kubelet.go index bfb3688a3cf..ef76bd4cc77 100644 --- a/pkg/client/kubelet.go +++ b/pkg/client/kubelet.go @@ -46,9 +46,9 @@ type KubeletHealthChecker interface { // PodInfoGetter is an interface for things that can get information about a pod's containers. // Injectable for easy testing. type PodInfoGetter interface { - // GetPodInfo returns information about all containers which are part - // Returns an api.PodInfo, or an error if one occurs. - GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) + // GetPodStatus returns information about all containers which are part + // Returns an api.PodStatus, or an error if one occurs. + GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) } // HTTPKubeletClient is the default implementation of PodInfoGetter and KubeletHealthchecker, accesses the kubelet over HTTP. @@ -95,7 +95,7 @@ func (c *HTTPKubeletClient) url(host string) string { } // GetPodInfo gets information about the specified pod. -func (c *HTTPKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) { +func (c *HTTPKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) { request, err := http.NewRequest( "GET", fmt.Sprintf( @@ -104,28 +104,28 @@ func (c *HTTPKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.Po podID, podNamespace), nil) - info := api.PodContainerInfo{} + status := api.PodStatusResult{} if err != nil { - return info, err + return status, err } response, err := c.Client.Do(request) if err != nil { - return info, err + return status, err } defer response.Body.Close() if response.StatusCode == http.StatusNotFound { - return info, ErrPodInfoNotAvailable + return status, ErrPodInfoNotAvailable } body, err := ioutil.ReadAll(response.Body) if err != nil { - return info, err + return status, err } // Check that this data can be unmarshalled - err = latest.Codec.DecodeInto(body, &info) + err = latest.Codec.DecodeInto(body, &status) if err != nil { - return info, err + return status, err } - return info, nil + return status, nil } func (c *HTTPKubeletClient) HealthCheck(host string) (health.Status, error) { @@ -138,8 +138,8 @@ func (c *HTTPKubeletClient) HealthCheck(host string) (health.Status, error) { type FakeKubeletClient struct{} // GetPodInfo is a fake implementation of PodInfoGetter.GetPodInfo. -func (c FakeKubeletClient) GetPodInfo(host, podNamespace string, podID string) (api.PodContainerInfo, error) { - return api.PodContainerInfo{}, errors.New("Not Implemented") +func (c FakeKubeletClient) GetPodStatus(host, podNamespace string, podID string) (api.PodStatusResult, error) { + return api.PodStatusResult{}, errors.New("Not Implemented") } func (c FakeKubeletClient) HealthCheck(host string) (health.Status, error) { diff --git a/pkg/client/kubelet_test.go b/pkg/client/kubelet_test.go index dcdb9185d84..a36b2986ec2 100644 --- a/pkg/client/kubelet_test.go +++ b/pkg/client/kubelet_test.go @@ -31,9 +31,12 @@ import ( ) func TestHTTPKubeletClient(t *testing.T) { - expectObj := api.PodContainerInfo{ - ContainerInfo: map[string]api.ContainerStatus{ - "myID": {}, + expectObj := api.PodStatusResult{ + Status: api.PodStatus{ + Info: map[string]api.ContainerStatus{ + "myID1": {}, + "myID2": {}, + }, }, } body, err := json.Marshal(expectObj) @@ -64,13 +67,13 @@ func TestHTTPKubeletClient(t *testing.T) { Client: http.DefaultClient, Port: uint(port), } - gotObj, err := podInfoGetter.GetPodInfo(parts[0], api.NamespaceDefault, "foo") + gotObj, err := podInfoGetter.GetPodStatus(parts[0], api.NamespaceDefault, "foo") if err != nil { t.Errorf("unexpected error: %v", err) } // reflect.DeepEqual(expectObj, gotObj) doesn't handle blank times well - if len(gotObj.ContainerInfo) != len(expectObj.ContainerInfo) { + if len(gotObj.Status.Info) != len(expectObj.Status.Info) { t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj) } } @@ -109,7 +112,7 @@ func TestHTTPKubeletClientNotFound(t *testing.T) { Client: http.DefaultClient, Port: uint(port), } - _, err = podInfoGetter.GetPodInfo(parts[0], api.NamespaceDefault, "foo") + _, err = podInfoGetter.GetPodStatus(parts[0], api.NamespaceDefault, "foo") if err != ErrPodInfoNotAvailable { t.Errorf("Expected %#v, Got %#v", ErrPodInfoNotAvailable, err) } diff --git a/pkg/kubelet/handlers.go b/pkg/kubelet/handlers.go index 4a20dcfb62f..0e285660564 100644 --- a/pkg/kubelet/handlers.go +++ b/pkg/kubelet/handlers.go @@ -71,17 +71,17 @@ func ResolvePort(portReference util.IntOrString, container *api.Container) (int, func (h *httpActionHandler) Run(podFullName string, uid types.UID, container *api.Container, handler *api.Handler) error { host := handler.HTTPGet.Host if len(host) == 0 { - var info api.PodInfo - info, err := h.kubelet.GetPodInfo(podFullName, uid) + var status api.PodStatus + status, err := h.kubelet.GetPodStatus(podFullName, uid) if err != nil { glog.Errorf("unable to get pod info, event handlers may be invalid.") return err } - netInfo, found := info[networkContainerName] + netInfo, found := status.Info[networkContainerName] if found { host = netInfo.PodIP } else { - return fmt.Errorf("failed to find networking container: %v", info) + return fmt.Errorf("failed to find networking container: %v", status) } } var port int diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index ccdafda93fa..a917af1ae60 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1010,12 +1010,11 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke return err } - podStatus := api.PodStatus{} - info, err := kl.GetPodInfo(podFullName, uid) + podStatus, err := kl.GetPodStatus(podFullName, uid) if err != nil { glog.Errorf("Unable to get pod with name %q and uid %q info, health checks may be invalid", podFullName, uid) } - netInfo, found := info[networkContainerName] + netInfo, found := podStatus.Info[networkContainerName] if found { podStatus.PodIP = netInfo.PodIP } @@ -1340,11 +1339,11 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { } // GetKubeletContainerLogs returns logs from the container -// The second parameter of GetPodInfo and FindPodContainer methods represents pod UUID, which is allowed to be blank +// The second parameter of GetPodStatus and FindPodContainer methods represents pod UUID, which is allowed to be blank // TODO: this method is returning logs of random container attempts, when it should be returning the most recent attempt // or all of them. func (kl *Kubelet) GetKubeletContainerLogs(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error { - _, err := kl.GetPodInfo(podFullName, "") + _, err := kl.GetPodStatus(podFullName, "") if err == dockertools.ErrNoContainersInPod { return fmt.Errorf("pod not found (%q)\n", podFullName) } @@ -1376,8 +1375,8 @@ func (kl *Kubelet) GetPodByName(namespace, name string) (*api.BoundPod, bool) { return nil, false } -// GetPodInfo returns information from Docker about the containers in a pod -func (kl *Kubelet) GetPodInfo(podFullName string, uid types.UID) (api.PodInfo, error) { +// GetPodStatus returns information from Docker about the containers in a pod +func (kl *Kubelet) GetPodStatus(podFullName string, uid types.UID) (api.PodStatus, error) { var manifest api.PodSpec for _, pod := range kl.pods { if GetPodFullName(&pod) == podFullName { @@ -1385,7 +1384,14 @@ func (kl *Kubelet) GetPodInfo(podFullName string, uid types.UID) (api.PodInfo, e break } } - return dockertools.GetDockerPodInfo(kl.dockerClient, manifest, podFullName, uid) + + info, err := dockertools.GetDockerPodInfo(kl.dockerClient, manifest, podFullName, uid) + + // TODO(dchen1107): Determine PodPhase here + var podStatus api.PodStatus + podStatus.Info = info + + return podStatus, err } func (kl *Kubelet) healthy(podFullName string, podUID types.UID, status api.PodStatus, container api.Container, dockerContainer *docker.APIContainers) (health.Status, error) { diff --git a/pkg/kubelet/server.go b/pkg/kubelet/server.go index 53b540cba69..222cedb52e2 100644 --- a/pkg/kubelet/server.go +++ b/pkg/kubelet/server.go @@ -67,7 +67,7 @@ type HostInterface interface { GetMachineInfo() (*info.MachineInfo, error) GetBoundPods() ([]api.BoundPod, error) GetPodByName(namespace, name string) (*api.BoundPod, bool) - GetPodInfo(name string, uid types.UID) (api.PodInfo, error) + GetPodStatus(name string, uid types.UID) (api.PodStatus, error) RunInContainer(name string, uid types.UID, container string, cmd []string) ([]byte, error) GetKubeletContainerLogs(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error ServeLogs(w http.ResponseWriter, req *http.Request) @@ -189,15 +189,15 @@ func (s *Server) handleBoundPods(w http.ResponseWriter, req *http.Request) { } func (s *Server) handlePodInfoOld(w http.ResponseWriter, req *http.Request) { - s.handlePodInfo(w, req, false) + s.handlePodStatus(w, req, false) } func (s *Server) handlePodInfoVersioned(w http.ResponseWriter, req *http.Request) { - s.handlePodInfo(w, req, true) + s.handlePodStatus(w, req, true) } -// handlePodInfo handles podInfo requests against the Kubelet -func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request, versioned bool) { +// handlePodStatus handles podInfo requests against the Kubelet +func (s *Server) handlePodStatus(w http.ResponseWriter, req *http.Request, versioned bool) { u, err := url.ParseRequestURI(req.RequestURI) if err != nil { s.error(w, err) @@ -221,12 +221,12 @@ func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request, version http.Error(w, "Pod does not exist", http.StatusNotFound) return } - info, err := s.host.GetPodInfo(GetPodFullName(pod), podUID) + status, err := s.host.GetPodStatus(GetPodFullName(pod), podUID) if err != nil { s.error(w, err) return } - data, err := exportPodInfo(info, versioned) + data, err := exportPodStatus(status, versioned) if err != nil { s.error(w, err) return @@ -373,16 +373,16 @@ func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) { return } -func exportPodInfo(info api.PodInfo, versioned bool) ([]byte, error) { +func exportPodStatus(status api.PodStatus, versioned bool) ([]byte, error) { if versioned { // TODO: support arbitrary versions here codec, err := findCodec("v1beta1") if err != nil { return nil, err } - return codec.Encode(&api.PodContainerInfo{ContainerInfo: info}) + return codec.Encode(&api.PodStatusResult{Status: status}) } - return json.Marshal(info) + return json.Marshal(status) } func findCodec(version string) (runtime.Codec, error) { diff --git a/pkg/kubelet/server_test.go b/pkg/kubelet/server_test.go index 1af31c1f9a2..69dd77eeb12 100644 --- a/pkg/kubelet/server_test.go +++ b/pkg/kubelet/server_test.go @@ -35,7 +35,7 @@ import ( type fakeKubelet struct { podByNameFunc func(namespace, name string) (*api.BoundPod, bool) - infoFunc func(name string) (api.PodInfo, error) + statusFunc func(name string) (api.PodStatus, error) containerInfoFunc func(podFullName string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) rootInfoFunc func(query *info.ContainerInfoRequest) (*info.ContainerInfo, error) machineInfoFunc func() (*info.MachineInfo, error) @@ -49,8 +49,8 @@ func (fk *fakeKubelet) GetPodByName(namespace, name string) (*api.BoundPod, bool return fk.podByNameFunc(namespace, name) } -func (fk *fakeKubelet) GetPodInfo(name string, uid types.UID) (api.PodInfo, error) { - return fk.infoFunc(name) +func (fk *fakeKubelet) GetPodStatus(name string, uid types.UID) (api.PodStatus, error) { + return fk.statusFunc(name) } func (fk *fakeKubelet) GetContainerInfo(podFullName string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) { @@ -128,16 +128,18 @@ func readResp(resp *http.Response) (string, error) { return string(body), err } -func TestPodInfo(t *testing.T) { +func TestPodStatus(t *testing.T) { fw := newServerTest() - expected := api.PodInfo{ - "goodpod": api.ContainerStatus{}, + expected := api.PodStatus{ + Info: map[string]api.ContainerStatus{ + "goodpod": {}, + }, } - fw.fakeKubelet.infoFunc = func(name string) (api.PodInfo, error) { + fw.fakeKubelet.statusFunc = func(name string) (api.PodStatus, error) { if name == "goodpod.default.etcd" { return expected, nil } - return nil, fmt.Errorf("bad pod %s", name) + return api.PodStatus{}, fmt.Errorf("bad pod %s", name) } resp, err := http.Get(fw.testHTTPServer.URL + "/podInfo?podID=goodpod&podNamespace=default") if err != nil { diff --git a/pkg/master/pod_cache.go b/pkg/master/pod_cache.go index 4da89469813..7b2ba52a0ba 100644 --- a/pkg/master/pod_cache.go +++ b/pkg/master/pod_cache.go @@ -144,13 +144,13 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) { return newStatus, nil } - info, err := p.containerInfo.GetPodInfo(pod.Status.Host, pod.Namespace, pod.Name) + result, err := p.containerInfo.GetPodStatus(pod.Status.Host, pod.Namespace, pod.Name) newStatus.HostIP = p.ipCache.GetInstanceIP(pod.Status.Host) if err != nil { newStatus.Phase = api.PodUnknown } else { - newStatus.Info = info.ContainerInfo + newStatus.Info = result.Status.Info newStatus.Phase = getPhase(&pod.Spec, newStatus.Info) if netContainerInfo, ok := newStatus.Info["net"]; ok { if netContainerInfo.PodIP != "" { diff --git a/pkg/master/pod_cache_test.go b/pkg/master/pod_cache_test.go index 09c09a9e397..37f7257ad9f 100644 --- a/pkg/master/pod_cache_test.go +++ b/pkg/master/pod_cache_test.go @@ -36,7 +36,7 @@ type podInfoCall struct { type podInfoResponse struct { useCount int - data api.PodContainerInfo + data api.PodStatusResult err error } @@ -48,11 +48,11 @@ type FakePodInfoGetter struct { // default data/error to return, or you can add // responses to specific calls-- that will take precedence. - data api.PodContainerInfo + data api.PodStatusResult err error } -func (f *FakePodInfoGetter) GetPodInfo(host, namespace, name string) (api.PodContainerInfo, error) { +func (f *FakePodInfoGetter) GetPodStatus(host, namespace, name string) (api.PodStatusResult, error) { f.lock.Lock() defer f.lock.Unlock() @@ -147,7 +147,7 @@ type podCacheTestConfig struct { ipFunc func(string) string // Construct will set a default if nil nodes []api.Node pods []api.Pod - kubeletContainerInfo api.PodInfo + kubeletContainerInfo api.PodStatus // Construct will fill in these fields fakePodInfo *FakePodInfoGetter @@ -162,8 +162,8 @@ func (c *podCacheTestConfig) Construct() *PodCache { } } c.fakePodInfo = &FakePodInfoGetter{ - data: api.PodContainerInfo{ - ContainerInfo: c.kubeletContainerInfo, + data: api.PodStatusResult{ + Status: c.kubeletContainerInfo, }, } c.fakeNodes = &client.Fake{ @@ -209,9 +209,10 @@ func TestPodUpdateAllContainers(t *testing.T) { } return "" }, - kubeletContainerInfo: api.PodInfo{"bar": api.ContainerStatus{}}, - nodes: []api.Node{*makeNode("machine")}, - pods: []api.Pod{*pod, *pod2}, + kubeletContainerInfo: api.PodStatus{ + Info: api.PodInfo{"bar": api.ContainerStatus{}}}, + nodes: []api.Node{*makeNode("machine")}, + pods: []api.Pod{*pod, *pod2}, } cache := config.Construct() @@ -233,7 +234,7 @@ func TestPodUpdateAllContainers(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %+v", err) } - if e, a := config.kubeletContainerInfo, status.Info; !reflect.DeepEqual(e, a) { + if e, a := config.kubeletContainerInfo.Info, status.Info; !reflect.DeepEqual(e, a) { t.Errorf("Unexpected mismatch. Expected: %+v, Got: %+v", e, a) } if e, a := "1.2.3.5", status.HostIP; e != a { @@ -252,7 +253,7 @@ func TestPodUpdateAllContainers(t *testing.T) { func TestFillPodStatusNoHost(t *testing.T) { pod := makePod(api.NamespaceDefault, "foo", "", "bar") config := podCacheTestConfig{ - kubeletContainerInfo: api.PodInfo{}, + kubeletContainerInfo: api.PodStatus{}, nodes: []api.Node{*makeNode("machine")}, pods: []api.Pod{*pod}, } @@ -271,7 +272,7 @@ func TestFillPodStatusNoHost(t *testing.T) { func TestFillPodStatusMissingMachine(t *testing.T) { pod := makePod(api.NamespaceDefault, "foo", "machine", "bar") config := podCacheTestConfig{ - kubeletContainerInfo: api.PodInfo{}, + kubeletContainerInfo: api.PodStatus{}, nodes: []api.Node{}, pods: []api.Pod{*pod}, } @@ -292,15 +293,21 @@ func TestFillPodStatus(t *testing.T) { expectedIP := "1.2.3.4" expectedTime, _ := time.Parse("2013-Feb-03", "2013-Feb-03") config := podCacheTestConfig{ - kubeletContainerInfo: api.PodInfo{ - "net": { - State: api.ContainerState{ - Running: &api.ContainerStateRunning{ - StartedAt: util.NewTime(expectedTime), + kubeletContainerInfo: api.PodStatus{ + Phase: api.PodPending, + Host: "machine", + HostIP: "ip of machine", + PodIP: expectedIP, + Info: api.PodInfo{ + "net": { + State: api.ContainerState{ + Running: &api.ContainerStateRunning{ + StartedAt: util.NewTime(expectedTime), + }, }, + RestartCount: 1, + PodIP: expectedIP, }, - RestartCount: 1, - PodIP: expectedIP, }, }, nodes: []api.Node{*makeNode("machine")}, @@ -313,20 +320,22 @@ func TestFillPodStatus(t *testing.T) { } status, err := cache.GetPodStatus(pod.Namespace, pod.Name) - if e, a := config.kubeletContainerInfo, status.Info; !reflect.DeepEqual(e, a) { + if e, a := &config.kubeletContainerInfo, status; !reflect.DeepEqual(e, a) { t.Errorf("Expected: %+v, Got %+v", e, a) } - if status.PodIP != expectedIP { - t.Errorf("Expected %s, Got %s\n%+v", expectedIP, status.PodIP, status) - } } func TestFillPodInfoNoData(t *testing.T) { pod := makePod(api.NamespaceDefault, "foo", "machine", "bar") expectedIP := "" config := podCacheTestConfig{ - kubeletContainerInfo: api.PodInfo{ - "net": {}, + kubeletContainerInfo: api.PodStatus{ + Phase: api.PodPending, + Host: "machine", + HostIP: "ip of machine", + Info: api.PodInfo{ + "net": {}, + }, }, nodes: []api.Node{*makeNode("machine")}, pods: []api.Pod{*pod}, @@ -338,7 +347,7 @@ func TestFillPodInfoNoData(t *testing.T) { } status, err := cache.GetPodStatus(pod.Namespace, pod.Name) - if e, a := config.kubeletContainerInfo, status.Info; !reflect.DeepEqual(e, a) { + if e, a := &config.kubeletContainerInfo, status; !reflect.DeepEqual(e, a) { t.Errorf("Expected: %+v, Got %+v", e, a) } if status.PodIP != expectedIP { @@ -411,7 +420,7 @@ func TestPodPhaseWithBadNode(t *testing.T) { } for _, test := range tests { config := podCacheTestConfig{ - kubeletContainerInfo: test.pod.Status.Info, + kubeletContainerInfo: test.pod.Status, nodes: []api.Node{}, pods: []api.Pod{*test.pod}, }