PodInfo should indicate when a pod is not found

Client should react.  Also, dial down the chattiness of errors for
pods which do not exist and stop processing NotFound earlier in
the podinfo chain
pull/6/head
Clayton Coleman 2014-07-18 10:54:43 -04:00
parent 2f593c92fa
commit a17f0d04d4
6 changed files with 62 additions and 7 deletions

View File

@ -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

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)
}
}
}