Merge pull request #512 from smarterclayton/communicate_missing_pod_info

PodInfo should indicate when a pod is not found
This commit is contained in:
Daniel Smith 2014-07-18 13:03:16 -07:00
commit d8faca9e81
6 changed files with 62 additions and 7 deletions

View File

@ -18,6 +18,7 @@ package client
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
@ -27,6 +28,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "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. // PodInfoGetter is an interface for things that can get information about a pod's containers.
// Injectable for easy testing. // Injectable for easy testing.
type PodInfoGetter interface { type PodInfoGetter interface {
@ -58,6 +62,9 @@ func (c *HTTPPodInfoGetter) GetPodInfo(host, podID string) (api.PodInfo, error)
return nil, err return nil, err
} }
defer response.Body.Close() defer response.Body.Close()
if response.StatusCode == http.StatusNotFound {
return nil, ErrPodInfoNotAvailable
}
body, err := ioutil.ReadAll(response.Body) body, err := ioutil.ReadAll(response.Body)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -67,3 +67,31 @@ func TestHTTPPodInfoGetter(t *testing.T) {
t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj) 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 package kubelet
import ( import (
"errors"
"fmt" "fmt"
"math/rand" "math/rand"
"strings" "strings"
@ -115,6 +116,9 @@ func getKubeletDockerContainers(client DockerInterface) (DockerContainers, error
return result, nil 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. // GetDockerPodInfo returns docker info for all containers in the pod/manifest.
func getDockerPodInfo(client DockerInterface, manifestID string) (api.PodInfo, error) { func getDockerPodInfo(client DockerInterface, manifestID string) (api.PodInfo, error) {
info := api.PodInfo{} info := api.PodInfo{}
@ -140,6 +144,10 @@ func getDockerPodInfo(client DockerInterface, manifestID string) (api.PodInfo, e
info[dockerContainerName] = *inspectResult info[dockerContainerName] = *inspectResult
} }
} }
if len(info) == 0 {
return nil, ErrNoContainersInPod
}
return info, nil 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) { 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) u, err := url.ParseRequestURI(req.RequestURI)
if err != nil { if err != nil {
@ -95,6 +100,10 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return return
} }
info, err := s.Kubelet.GetPodInfo(podID) info, err := s.Kubelet.GetPodInfo(podID)
if err == ErrNoContainersInPod {
http.Error(w, "Pod does not exist", http.StatusNotFound)
return
}
if err != nil { if err != nil {
s.error(w, err) s.error(w, err)
return return

View File

@ -17,7 +17,6 @@ limitations under the License.
package master package master
import ( import (
"errors"
"sync" "sync"
"time" "time"
@ -57,7 +56,7 @@ func (p *PodCache) GetPodInfo(host, podID string) (api.PodInfo, error) {
defer p.podLock.Unlock() defer p.podLock.Unlock()
value, ok := p.podInfo[podID] value, ok := p.podInfo[podID]
if !ok { if !ok {
return nil, errors.New("no cached pod info") return nil, client.ErrPodInfoNotAvailable
} }
return value, nil return value, nil
} }
@ -82,7 +81,7 @@ func (p *PodCache) UpdateAllContainers() {
} }
for _, pod := range pods { for _, pod := range pods {
err := p.updatePodInfo(pod.CurrentState.Host, pod.ID) err := p.updatePodInfo(pod.CurrentState.Host, pod.ID)
if err != nil { if err != nil && err != client.ErrPodInfoNotAvailable {
glog.Errorf("Error synchronizing container: %#v", err) glog.Errorf("Error synchronizing container: %#v", err)
} }
} }

View File

@ -86,12 +86,16 @@ func (storage *PodRegistryStorage) fillPodInfo(pod *api.Pod) {
if storage.podCache != nil { if storage.podCache != nil {
info, err := storage.podCache.GetPodInfo(pod.CurrentState.Host, pod.ID) info, err := storage.podCache.GetPodInfo(pod.CurrentState.Host, pod.ID)
if err != nil { 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 { if storage.podInfoGetter != nil {
info, err = storage.podInfoGetter.GetPodInfo(pod.CurrentState.Host, pod.ID) info, err = storage.podInfoGetter.GetPodInfo(pod.CurrentState.Host, pod.ID)
} }
if err != nil { 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 return
} }
} }
@ -104,7 +108,7 @@ func (storage *PodRegistryStorage) fillPodInfo(pod *api.Pod) {
glog.Warningf("No network settings: %#v", netContainerInfo) glog.Warningf("No network settings: %#v", netContainerInfo)
} }
} else { } 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)
} }
} }
} }