mirror of https://github.com/k3s-io/k3s
Revert "Revert "Add an api object for the kubelet, and a versioned endpoint.""
This reverts commit dcfcf315e5
.
pull/6/head
parent
1abc3e423c
commit
a6f967b6e7
|
@ -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
|
||||
|
|
|
@ -25,6 +25,7 @@ var Scheme = runtime.NewScheme()
|
|||
|
||||
func init() {
|
||||
Scheme.AddKnownTypes("",
|
||||
&PodContainerInfo{},
|
||||
&PodList{},
|
||||
&Pod{},
|
||||
&ReplicationControllerList{},
|
||||
|
@ -52,6 +53,7 @@ func init() {
|
|||
Scheme.AddKnownTypeWithName("", "MinionList", &NodeList{})
|
||||
}
|
||||
|
||||
func (*PodContainerInfo) IsAnAPIObject() {}
|
||||
func (*Pod) IsAnAPIObject() {}
|
||||
func (*PodList) IsAnAPIObject() {}
|
||||
func (*ReplicationController) IsAnAPIObject() {}
|
||||
|
|
|
@ -203,7 +203,7 @@ func TestList(t *testing.T) {
|
|||
api.Scheme.Log(nil)
|
||||
}
|
||||
|
||||
var nonRoundTrippableTypes = util.NewStringSet("ContainerManifest")
|
||||
var nonRoundTrippableTypes = util.NewStringSet("ContainerManifest", "PodContainerInfo")
|
||||
var nonInternalRoundTrippableTypes = util.NewStringSet("List")
|
||||
|
||||
func TestRoundTripTypes(t *testing.T) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -31,6 +31,7 @@ func init() {
|
|||
|
||||
api.Scheme.AddKnownTypes("v1beta2",
|
||||
&Pod{},
|
||||
&PodContainerInfo{},
|
||||
&PodList{},
|
||||
&ReplicationController{},
|
||||
&ReplicationControllerList{},
|
||||
|
@ -58,6 +59,7 @@ func init() {
|
|||
}
|
||||
|
||||
func (*Pod) IsAnAPIObject() {}
|
||||
func (*PodContainerInfo) IsAnAPIObject() {}
|
||||
func (*PodList) IsAnAPIObject() {}
|
||||
func (*ReplicationController) IsAnAPIObject() {}
|
||||
func (*ReplicationControllerList) IsAnAPIObject() {}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -26,6 +26,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta3")
|
|||
|
||||
func init() {
|
||||
api.Scheme.AddKnownTypes("v1beta3",
|
||||
&PodContainerInfo{},
|
||||
&Pod{},
|
||||
&PodList{},
|
||||
&PodTemplate{},
|
||||
|
@ -53,6 +54,7 @@ func init() {
|
|||
api.Scheme.AddKnownTypeWithName("v1beta3", "MinionList", &NodeList{})
|
||||
}
|
||||
|
||||
func (*PodContainerInfo) IsAnAPIObject() {}
|
||||
func (*Pod) IsAnAPIObject() {}
|
||||
func (*PodList) IsAnAPIObject() {}
|
||||
func (*PodTemplate) IsAnAPIObject() {}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -17,15 +17,16 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/health"
|
||||
)
|
||||
|
||||
|
@ -48,7 +49,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.
|
||||
|
@ -89,35 +90,36 @@ 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)
|
||||
log.Printf("FOOO: %s", string(body))
|
||||
err = latest.Codec.DecodeInto(body, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return info, err
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
@ -132,8 +134,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) {
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -28,11 +28,11 @@ type FakePodInfoGetter struct {
|
|||
host string
|
||||
id string
|
||||
namespace string
|
||||
data api.PodInfo
|
||||
data api.PodContainerInfo
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *FakePodInfoGetter) GetPodInfo(host, namespace, id string) (api.PodInfo, error) {
|
||||
func (f *FakePodInfoGetter) GetPodInfo(host, namespace, id string) (api.PodContainerInfo, error) {
|
||||
f.host = host
|
||||
f.id = id
|
||||
f.namespace = namespace
|
||||
|
@ -42,11 +42,15 @@ func (f *FakePodInfoGetter) GetPodInfo(host, namespace, id string) (api.PodInfo,
|
|||
func TestPodCacheGetDifferentNamespace(t *testing.T) {
|
||||
cache := NewPodCache(nil, nil)
|
||||
|
||||
expectedDefault := api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
expectedDefault := api.PodContainerInfo{
|
||||
ContainerInfo: api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
},
|
||||
}
|
||||
expectedOther := api.PodInfo{
|
||||
"bar": api.ContainerStatus{},
|
||||
expectedOther := api.PodContainerInfo{
|
||||
ContainerInfo: api.PodInfo{
|
||||
"bar": api.ContainerStatus{},
|
||||
},
|
||||
}
|
||||
|
||||
cache.podInfo[makePodCacheKey(api.NamespaceDefault, "foo")] = expectedDefault
|
||||
|
@ -72,8 +76,10 @@ func TestPodCacheGetDifferentNamespace(t *testing.T) {
|
|||
func TestPodCacheGet(t *testing.T) {
|
||||
cache := NewPodCache(nil, nil)
|
||||
|
||||
expected := api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
expected := api.PodContainerInfo{
|
||||
ContainerInfo: api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
},
|
||||
}
|
||||
cache.podInfo[makePodCacheKey(api.NamespaceDefault, "foo")] = expected
|
||||
|
||||
|
@ -93,14 +99,16 @@ func TestPodCacheGetMissing(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Errorf("Unexpected non-error: %#v", err)
|
||||
}
|
||||
if info != nil {
|
||||
if !reflect.DeepEqual(info, api.PodContainerInfo{}) {
|
||||
t.Errorf("Unexpected info: %#v", info)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPodGetPodInfoGetter(t *testing.T) {
|
||||
expected := api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
expected := api.PodContainerInfo{
|
||||
ContainerInfo: api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
},
|
||||
}
|
||||
fake := FakePodInfoGetter{
|
||||
data: expected,
|
||||
|
@ -133,8 +141,10 @@ func TestPodUpdateAllContainers(t *testing.T) {
|
|||
pods := []api.Pod{pod}
|
||||
mockRegistry := registrytest.NewPodRegistry(&api.PodList{Items: pods})
|
||||
|
||||
expected := api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
expected := api.PodContainerInfo{
|
||||
ContainerInfo: api.PodInfo{
|
||||
"foo": api.ContainerStatus{},
|
||||
},
|
||||
}
|
||||
fake := FakePodInfoGetter{
|
||||
data: expected,
|
||||
|
|
|
@ -230,8 +230,8 @@ func (rs *REST) fillPodInfo(pod *api.Pod) {
|
|||
return
|
||||
}
|
||||
}
|
||||
pod.Status.Info = info
|
||||
netContainerInfo, ok := info["net"]
|
||||
pod.Status.Info = info.ContainerInfo
|
||||
netContainerInfo, ok := pod.Status.Info["net"]
|
||||
if ok {
|
||||
if netContainerInfo.PodIP != "" {
|
||||
pod.Status.PodIP = netContainerInfo.PodIP
|
||||
|
|
|
@ -566,8 +566,8 @@ type FakePodInfoGetter struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (f *FakePodInfoGetter) GetPodInfo(host, podNamespace string, podID string) (api.PodInfo, error) {
|
||||
return f.info, f.err
|
||||
func (f *FakePodInfoGetter) GetPodInfo(host, podNamespace string, podID string) (api.PodContainerInfo, error) {
|
||||
return api.PodContainerInfo{ContainerInfo: f.info}, f.err
|
||||
}
|
||||
|
||||
func TestFillPodInfo(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue