diff --git a/pkg/client/podinfo.go b/pkg/client/podinfo.go index b55c8aed276..5009961dd9a 100644 --- a/pkg/client/podinfo.go +++ b/pkg/client/podinfo.go @@ -18,6 +18,7 @@ package client import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net" @@ -27,6 +28,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" ) +// ErrPodInfoNotAvailable may be returned when the requested pod info is not available +var ErrPodInfoNotAvailable = errors.New("no pod info available") + // PodInfoGetter is an interface for things that can get information about a pod's containers. // Injectable for easy testing. type PodInfoGetter interface { @@ -58,6 +62,9 @@ func (c *HTTPPodInfoGetter) GetPodInfo(host, podID string) (api.PodInfo, error) return nil, err } defer response.Body.Close() + if response.StatusCode == http.StatusNotFound { + return nil, ErrPodInfoNotAvailable + } body, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err diff --git a/pkg/client/podinfo_test.go b/pkg/client/podinfo_test.go index 88c0a4c565d..620aced9cde 100644 --- a/pkg/client/podinfo_test.go +++ b/pkg/client/podinfo_test.go @@ -67,3 +67,31 @@ func TestHTTPPodInfoGetter(t *testing.T) { t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj) } } + +func TestHTTPPodInfoGetterNotFound(t *testing.T) { + expectObj := api.PodInfo{ + "myID": docker.Container{ID: "myID"}, + } + _, err := json.Marshal(expectObj) + expectNoError(t, err) + fakeHandler := util.FakeHandler{ + StatusCode: 404, + ResponseBody: "Pod not found", + } + testServer := httptest.NewServer(&fakeHandler) + + hostURL, err := url.Parse(testServer.URL) + expectNoError(t, err) + parts := strings.Split(hostURL.Host, ":") + + port, err := strconv.Atoi(parts[1]) + expectNoError(t, err) + podInfoGetter := &HTTPPodInfoGetter{ + Client: http.DefaultClient, + Port: uint(port), + } + _, err = podInfoGetter.GetPodInfo(parts[0], "foo") + if err != ErrPodInfoNotAvailable { + t.Errorf("Expected %#v, Got %#v", ErrPodInfoNotAvailable, err) + } +} diff --git a/pkg/kubelet/docker.go b/pkg/kubelet/docker.go index c16e982e68d..3123aacf7d8 100644 --- a/pkg/kubelet/docker.go +++ b/pkg/kubelet/docker.go @@ -17,6 +17,7 @@ limitations under the License. package kubelet import ( + "errors" "fmt" "math/rand" "strings" @@ -115,6 +116,9 @@ func getKubeletDockerContainers(client DockerInterface) (DockerContainers, error return result, nil } +// ErrNoContainersInPod is returned when there are no running 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, manifestID string) (api.PodInfo, error) { info := api.PodInfo{} @@ -140,6 +144,10 @@ func getDockerPodInfo(client DockerInterface, manifestID string) (api.PodInfo, e info[dockerContainerName] = *inspectResult } } + if len(info) == 0 { + return nil, ErrNoContainersInPod + } + return info, nil } diff --git a/pkg/kubelet/server.go b/pkg/kubelet/server.go index 9eda58a4066..1cbf3dcebd2 100644 --- a/pkg/kubelet/server.go +++ b/pkg/kubelet/server.go @@ -54,7 +54,12 @@ func (s *Server) error(w http.ResponseWriter, err error) { } func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { - defer httplog.MakeLogged(req, &w).Log() + defer httplog.MakeLogged(req, &w).StacktraceWhen( + httplog.StatusIsNot( + http.StatusOK, + http.StatusNotFound, + ), + ).Log() u, err := url.ParseRequestURI(req.RequestURI) if err != nil { @@ -95,6 +100,10 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } info, err := s.Kubelet.GetPodInfo(podID) + if err == ErrNoContainersInPod { + http.Error(w, "Pod does not exist", http.StatusNotFound) + return + } if err != nil { s.error(w, err) return diff --git a/pkg/master/pod_cache.go b/pkg/master/pod_cache.go index c6be9a9f9dd..b652ab221fc 100644 --- a/pkg/master/pod_cache.go +++ b/pkg/master/pod_cache.go @@ -17,7 +17,6 @@ limitations under the License. package master import ( - "errors" "sync" "time" @@ -57,7 +56,7 @@ func (p *PodCache) GetPodInfo(host, podID string) (api.PodInfo, error) { defer p.podLock.Unlock() value, ok := p.podInfo[podID] if !ok { - return nil, errors.New("no cached pod info") + return nil, client.ErrPodInfoNotAvailable } return value, nil } @@ -82,7 +81,7 @@ func (p *PodCache) UpdateAllContainers() { } for _, pod := range pods { err := p.updatePodInfo(pod.CurrentState.Host, pod.ID) - if err != nil { + if err != nil && err != client.ErrPodInfoNotAvailable { glog.Errorf("Error synchronizing container: %#v", err) } } diff --git a/pkg/registry/pod_registry.go b/pkg/registry/pod_registry.go index 1a5541b5bf9..e358ea71853 100644 --- a/pkg/registry/pod_registry.go +++ b/pkg/registry/pod_registry.go @@ -86,12 +86,16 @@ func (storage *PodRegistryStorage) fillPodInfo(pod *api.Pod) { if storage.podCache != nil { info, err := storage.podCache.GetPodInfo(pod.CurrentState.Host, pod.ID) if err != nil { - glog.Errorf("Error getting container info from cache: %#v", err) + if err != client.ErrPodInfoNotAvailable { + glog.Errorf("Error getting container info from cache: %#v", err) + } if storage.podInfoGetter != nil { info, err = storage.podInfoGetter.GetPodInfo(pod.CurrentState.Host, pod.ID) } if err != nil { - glog.Errorf("Error getting fresh container info: %#v", err) + if err != client.ErrPodInfoNotAvailable { + glog.Errorf("Error getting fresh container info: %#v", err) + } return } } @@ -104,7 +108,7 @@ func (storage *PodRegistryStorage) fillPodInfo(pod *api.Pod) { glog.Warningf("No network settings: %#v", netContainerInfo) } } else { - glog.Warningf("Couldn't find network container in %v", info) + glog.Warningf("Couldn't find network container for %s in %v", pod.ID, info) } } }