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
This commit is contained in:
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 {
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 {
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)
}
}
}