Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revert the revert along with fixes to make it pass e2e tests. #2942

Merged
merged 2 commits into from
Dec 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ var (

type fakeKubeletClient struct{}

func (fakeKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error) {
func (fakeKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) {
// This is a horrible hack to get around the fact that we can't provide
// different port numbers per kubelet...
var c client.PodInfoGetter
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var Scheme = runtime.NewScheme()

func init() {
Scheme.AddKnownTypes("",
&PodContainerInfo{},
&PodList{},
&Pod{},
&ReplicationControllerList{},
Expand Down Expand Up @@ -52,6 +53,7 @@ func init() {
Scheme.AddKnownTypeWithName("", "MinionList", &NodeList{})
}

func (*PodContainerInfo) IsAnAPIObject() {}
func (*Pod) IsAnAPIObject() {}
func (*PodList) IsAnAPIObject() {}
func (*ReplicationController) IsAnAPIObject() {}
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,13 @@ 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"`
}

type RestartPolicyAlways struct{}

// TODO(dchen1107): Define what kinds of failures should restart.
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func init() {

api.Scheme.AddKnownTypes("v1beta1",
&Pod{},
&PodContainerInfo{},
&PodList{},
&ReplicationController{},
&ReplicationControllerList{},
Expand Down Expand Up @@ -58,6 +59,7 @@ func init() {
}

func (*Pod) IsAnAPIObject() {}
func (*PodContainerInfo) IsAnAPIObject() {}
func (*PodList) IsAnAPIObject() {}
func (*ReplicationController) IsAnAPIObject() {}
func (*ReplicationControllerList) IsAnAPIObject() {}
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ 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"`
ContainerInfo PodInfo `json:"containerInfo" description:"information about each container in this pod"`
}

type RestartPolicyAlways struct{}

// TODO(dchen1107): Define what kinds of failures should restart
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func init() {

api.Scheme.AddKnownTypes("v1beta2",
&Pod{},
&PodContainerInfo{},
&PodList{},
&ReplicationController{},
&ReplicationControllerList{},
Expand Down Expand Up @@ -58,6 +59,7 @@ func init() {
}

func (*Pod) IsAnAPIObject() {}
func (*PodContainerInfo) IsAnAPIObject() {}
func (*PodList) IsAnAPIObject() {}
func (*ReplicationController) IsAnAPIObject() {}
func (*ReplicationControllerList) IsAnAPIObject() {}
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,12 @@ 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"`
ContainerInfo PodInfo `json:"containerInfo" description:"information about each container in this pod"`
}

type RestartPolicyAlways struct{}

// TODO(dchen1107): Define what kinds of failures should restart.
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta3/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta3")

func init() {
api.Scheme.AddKnownTypes("v1beta3",
&PodContainerInfo{},
&Pod{},
&PodList{},
&PodTemplate{},
Expand Down Expand Up @@ -53,6 +54,7 @@ func init() {
api.Scheme.AddKnownTypeWithName("v1beta3", "MinionList", &NodeList{})
}

func (*PodContainerInfo) IsAnAPIObject() {}
func (*Pod) IsAnAPIObject() {}
func (*PodList) IsAnAPIObject() {}
func (*PodTemplate) IsAnAPIObject() {}
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/v1beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ 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.
Expand Down
26 changes: 13 additions & 13 deletions pkg/client/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package client

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
Expand All @@ -26,6 +25,7 @@ import (
"strconv"

"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/health"
)

Expand All @@ -48,7 +48,7 @@ type KubeletHealthChecker interface {
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.PodInfo, error)
GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error)
}

// HTTPKubeletClient is the default implementation of PodInfoGetter and KubeletHealthchecker, accesses the kubelet over HTTP.
Expand Down Expand Up @@ -89,35 +89,35 @@ func (c *HTTPKubeletClient) url(host string) string {
}

// GetPodInfo gets information about the specified pod.
func (c *HTTPKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error) {
func (c *HTTPKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) {
request, err := http.NewRequest(
"GET",
fmt.Sprintf(
"%s/podInfo?podID=%s&podNamespace=%s",
"%s/api/v1beta1/podInfo?podID=%s&podNamespace=%s",
c.url(host),
podID,
podNamespace),
nil)
info := api.PodContainerInfo{}
if err != nil {
return nil, err
return info, err
}
response, err := c.Client.Do(request)
if err != nil {
return nil, err
return info, err
}
defer response.Body.Close()
if response.StatusCode == http.StatusNotFound {
return nil, ErrPodInfoNotAvailable
return info, ErrPodInfoNotAvailable
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
return info, err
}
// Check that this data can be unmarshalled
info := api.PodInfo{}
err = json.Unmarshal(body, &info)
err = latest.Codec.DecodeInto(body, &info)
if err != nil {
return nil, err
return info, err
}
return info, nil
}
Expand All @@ -132,8 +132,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.PodInfo, error) {
return api.PodInfo{}, errors.New("Not Implemented")
func (c FakeKubeletClient) GetPodInfo(host, podNamespace string, podID string) (api.PodContainerInfo, error) {
return api.PodContainerInfo{}, errors.New("Not Implemented")
}

func (c FakeKubeletClient) HealthCheck(host string) (health.Status, error) {
Expand Down
14 changes: 9 additions & 5 deletions pkg/client/kubelet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ import (
)

func TestHTTPKubeletClient(t *testing.T) {
expectObj := api.PodInfo{
"myID": api.ContainerStatus{},
expectObj := api.PodContainerInfo{
ContainerInfo: map[string]api.ContainerStatus{
"myID": {},
},
}
body, err := json.Marshal(expectObj)
if err != nil {
Expand Down Expand Up @@ -68,14 +70,16 @@ func TestHTTPKubeletClient(t *testing.T) {
}

// reflect.DeepEqual(expectObj, gotObj) doesn't handle blank times well
if len(gotObj) != len(expectObj) {
if len(gotObj.ContainerInfo) != len(expectObj.ContainerInfo) {
t.Errorf("Unexpected response. Expected: %#v, received %#v", expectObj, gotObj)
}
}

func TestHTTPKubeletClientNotFound(t *testing.T) {
expectObj := api.PodInfo{
"myID": api.ContainerStatus{},
expectObj := api.PodContainerInfo{
ContainerInfo: map[string]api.ContainerStatus{
"myID": {},
},
}
_, err := json.Marshal(expectObj)
if err != nil {
Expand Down
36 changes: 33 additions & 3 deletions pkg/kubelet/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/ghodss/yaml"
"github.com/golang/glog"
"github.com/google/cadvisor/info"
Expand Down Expand Up @@ -91,7 +92,8 @@ func NewServer(host HostInterface, updates chan<- interface{}, enableDebuggingHa
// InstallDefaultHandlers registers the default set of supported HTTP request patterns with the mux.
func (s *Server) InstallDefaultHandlers() {
healthz.InstallHandler(s.mux)
s.mux.HandleFunc("/podInfo", s.handlePodInfo)
s.mux.HandleFunc("/podInfo", s.handlePodInfoOld)
s.mux.HandleFunc("/api/v1beta1/podInfo", s.handlePodInfoVersioned)
s.mux.HandleFunc("/boundPods", s.handleBoundPods)
s.mux.HandleFunc("/stats/", s.handleStats)
s.mux.HandleFunc("/spec/", s.handleSpec)
Expand Down Expand Up @@ -249,8 +251,16 @@ func (s *Server) handleBoundPods(w http.ResponseWriter, req *http.Request) {
w.Write(data)
}

func (s *Server) handlePodInfoOld(w http.ResponseWriter, req *http.Request) {
s.handlePodInfo(w, req, false)
}

func (s *Server) handlePodInfoVersioned(w http.ResponseWriter, req *http.Request) {
s.handlePodInfo(w, req, true)
}

// handlePodInfo handles podInfo requests against the Kubelet
func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request) {
func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request, versioned bool) {
u, err := url.ParseRequestURI(req.RequestURI)
if err != nil {
s.error(w, err)
Expand Down Expand Up @@ -286,7 +296,7 @@ func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request) {
s.error(w, err)
return
}
data, err := json.Marshal(info)
data, err := exportPodInfo(info, versioned)
if err != nil {
s.error(w, err)
return
Expand Down Expand Up @@ -437,3 +447,23 @@ func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) {
w.Write(data)
return
}

func exportPodInfo(info api.PodInfo, 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 json.Marshal(info)
}

func findCodec(version string) (runtime.Codec, error) {
versions, err := latest.InterfacesFor(version)
if err != nil {
return nil, err
}
return versions.Codec, nil
}
8 changes: 4 additions & 4 deletions pkg/master/pod_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type PodCache struct {
containerInfo client.PodInfoGetter
pods pod.Registry
// This is a map of pod id to a map of container name to the
podInfo map[string]api.PodInfo
podInfo map[string]api.PodContainerInfo
podLock sync.Mutex
}

Expand All @@ -42,7 +42,7 @@ func NewPodCache(info client.PodInfoGetter, pods pod.Registry) *PodCache {
return &PodCache{
containerInfo: info,
pods: pods,
podInfo: map[string]api.PodInfo{},
podInfo: map[string]api.PodContainerInfo{},
}
}

Expand All @@ -54,12 +54,12 @@ func makePodCacheKey(podNamespace, podID string) string {
// GetPodInfo implements the PodInfoGetter.GetPodInfo.
// The returned value should be treated as read-only.
// TODO: Remove the host from this call, it's totally unnecessary.
func (p *PodCache) GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error) {
func (p *PodCache) GetPodInfo(host, podNamespace, podID string) (api.PodContainerInfo, error) {
p.podLock.Lock()
defer p.podLock.Unlock()
value, ok := p.podInfo[makePodCacheKey(podNamespace, podID)]
if !ok {
return nil, client.ErrPodInfoNotAvailable
return api.PodContainerInfo{}, client.ErrPodInfoNotAvailable
}
return value, nil
}
Expand Down