Merge pull request #2788 from smarterclayton/roundtrip_node_nodelist

Rename Minions -> Nodes internally
This commit is contained in:
Daniel Smith
2014-12-10 11:12:15 -08:00
52 changed files with 577 additions and 332 deletions

View File

@@ -79,7 +79,8 @@ var parser = kubecfg.NewParser(map[string]runtime.Object{
"pods": &api.Pod{},
"services": &api.Service{},
"replicationControllers": &api.ReplicationController{},
"minions": &api.Minion{},
"minions": &api.Node{},
"nodes": &api.Node{},
"events": &api.Event{},
})

View File

@@ -126,6 +126,10 @@ kube::log::status "Testing kubectl(minions)"
"${kube_cmd[@]}" get minions "${kube_flags[@]}"
"${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}"
kube::log::status "Testing kubectl(nodes)"
"${kube_cmd[@]}" get nodes "${kube_flags[@]}"
"${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}"
kube::log::status "TEST PASSED"
# Start proxy

View File

@@ -31,8 +31,8 @@ func init() {
&ReplicationController{},
&ServiceList{},
&Service{},
&MinionList{},
&Minion{},
&NodeList{},
&Node{},
&Status{},
&ServerOpList{},
&ServerOp{},
@@ -46,6 +46,9 @@ func init() {
&BoundPod{},
&BoundPods{},
)
// Legacy names are supported
Scheme.AddKnownTypeWithName("", "Minion", &Node{})
Scheme.AddKnownTypeWithName("", "MinionList", &NodeList{})
}
func (*Pod) IsAnAPIObject() {}
@@ -56,8 +59,8 @@ func (*Service) IsAnAPIObject() {}
func (*ServiceList) IsAnAPIObject() {}
func (*Endpoints) IsAnAPIObject() {}
func (*EndpointsList) IsAnAPIObject() {}
func (*Minion) IsAnAPIObject() {}
func (*MinionList) IsAnAPIObject() {}
func (*Node) IsAnAPIObject() {}
func (*NodeList) IsAnAPIObject() {}
func (*Binding) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
func (*ServerOp) IsAnAPIObject() {}

View File

@@ -672,10 +672,9 @@ type ResourceName string
type ResourceList map[ResourceName]util.IntOrString
// Minion is a worker node in Kubernetenes
// The name of the minion according to etcd is in ObjectMeta.Name.
// TODO: Rename to Node
type Minion struct {
// Node is a worker node in Kubernetenes
// The name of the node according to etcd is in ObjectMeta.Name.
type Node struct {
TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty"`
@@ -686,12 +685,12 @@ type Minion struct {
Status NodeStatus `json:"status,omitempty"`
}
// MinionList is a list of minions.
type MinionList struct {
// NodeList is a list of minions.
type NodeList struct {
TypeMeta `json:",inline"`
ListMeta `json:"metadata,omitempty"`
Items []Minion `json:"items"`
Items []Node `json:"items"`
}
// Binding is written by a scheduler to cause a pod to be bound to a host.

View File

@@ -137,7 +137,7 @@ func init() {
},
// MinionList.Items had a wrong name in v1beta1
func(in *newer.MinionList, out *MinionList, s conversion.Scope) error {
func(in *newer.NodeList, out *MinionList, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
@@ -150,7 +150,7 @@ func init() {
out.Minions = out.Items
return nil
},
func(in *MinionList, out *newer.MinionList, s conversion.Scope) error {
func(in *MinionList, out *newer.NodeList, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
@@ -444,7 +444,7 @@ func init() {
return nil
},
func(in *newer.Minion, out *Minion, s conversion.Scope) error {
func(in *newer.Node, out *Minion, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
@@ -458,7 +458,7 @@ func init() {
out.HostIP = in.Status.HostIP
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
},
func(in *Minion, out *newer.Minion, s conversion.Scope) error {
func(in *Minion, out *newer.Node, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}

View File

@@ -21,13 +21,36 @@ import (
"testing"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
current "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
)
var Convert = newer.Scheme.Convert
func TestNodeConversion(t *testing.T) {
obj, err := current.Codec.Decode([]byte(`{"kind":"Node","apiVersion":"v1beta1"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.Node); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj, err = current.Codec.Decode([]byte(`{"kind":"NodeList","apiVersion":"v1beta1"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.NodeList); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj = &newer.Node{}
if err := current.Codec.DecodeInto([]byte(`{"kind":"Node","apiVersion":"v1beta1"}`), obj); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestEnvConversion(t *testing.T) {
nonCanonical := []v1beta1.EnvVar{
nonCanonical := []current.EnvVar{
{Key: "EV"},
{Key: "EV", Name: "EX"},
}
@@ -48,7 +71,7 @@ func TestEnvConversion(t *testing.T) {
// Test conversion the other way, too.
for i := range canonical {
var got v1beta1.EnvVar
var got current.EnvVar
err := Convert(&canonical[i], &got)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -65,15 +88,15 @@ func TestEnvConversion(t *testing.T) {
func TestVolumeMountConversionToOld(t *testing.T) {
table := []struct {
in newer.VolumeMount
out v1beta1.VolumeMount
out current.VolumeMount
}{
{
in: newer.VolumeMount{Name: "foo", MountPath: "/dev/foo", ReadOnly: true},
out: v1beta1.VolumeMount{Name: "foo", MountPath: "/dev/foo", Path: "/dev/foo", ReadOnly: true},
out: current.VolumeMount{Name: "foo", MountPath: "/dev/foo", Path: "/dev/foo", ReadOnly: true},
},
}
for _, item := range table {
got := v1beta1.VolumeMount{}
got := current.VolumeMount{}
err := Convert(&item.in, &got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
@@ -87,17 +110,17 @@ func TestVolumeMountConversionToOld(t *testing.T) {
func TestVolumeMountConversionToNew(t *testing.T) {
table := []struct {
in v1beta1.VolumeMount
in current.VolumeMount
out newer.VolumeMount
}{
{
in: v1beta1.VolumeMount{Name: "foo", MountPath: "/dev/foo", ReadOnly: true},
in: current.VolumeMount{Name: "foo", MountPath: "/dev/foo", ReadOnly: true},
out: newer.VolumeMount{Name: "foo", MountPath: "/dev/foo", ReadOnly: true},
}, {
in: v1beta1.VolumeMount{Name: "foo", MountPath: "/dev/foo", Path: "/dev/bar", ReadOnly: true},
in: current.VolumeMount{Name: "foo", MountPath: "/dev/foo", Path: "/dev/bar", ReadOnly: true},
out: newer.VolumeMount{Name: "foo", MountPath: "/dev/foo", ReadOnly: true},
}, {
in: v1beta1.VolumeMount{Name: "foo", Path: "/dev/bar", ReadOnly: true},
in: current.VolumeMount{Name: "foo", Path: "/dev/bar", ReadOnly: true},
out: newer.VolumeMount{Name: "foo", MountPath: "/dev/bar", ReadOnly: true},
},
}
@@ -115,42 +138,42 @@ func TestVolumeMountConversionToNew(t *testing.T) {
}
func TestMinionListConversionToNew(t *testing.T) {
oldMinion := func(id string) v1beta1.Minion {
return v1beta1.Minion{TypeMeta: v1beta1.TypeMeta{ID: id}}
oldMinion := func(id string) current.Minion {
return current.Minion{TypeMeta: current.TypeMeta{ID: id}}
}
newMinion := func(id string) newer.Minion {
return newer.Minion{ObjectMeta: newer.ObjectMeta{Name: id}}
newNode := func(id string) newer.Node {
return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}}
}
oldMinions := []v1beta1.Minion{
oldMinions := []current.Minion{
oldMinion("foo"),
oldMinion("bar"),
}
newMinions := []newer.Minion{
newMinion("foo"),
newMinion("bar"),
newMinions := []newer.Node{
newNode("foo"),
newNode("bar"),
}
table := []struct {
oldML *v1beta1.MinionList
newML *newer.MinionList
oldML *current.MinionList
newML *newer.NodeList
}{
{
oldML: &v1beta1.MinionList{Items: oldMinions},
newML: &newer.MinionList{Items: newMinions},
oldML: &current.MinionList{Items: oldMinions},
newML: &newer.NodeList{Items: newMinions},
}, {
oldML: &v1beta1.MinionList{Minions: oldMinions},
newML: &newer.MinionList{Items: newMinions},
oldML: &current.MinionList{Minions: oldMinions},
newML: &newer.NodeList{Items: newMinions},
}, {
oldML: &v1beta1.MinionList{
oldML: &current.MinionList{
Items: oldMinions,
Minions: []v1beta1.Minion{oldMinion("baz")},
Minions: []current.Minion{oldMinion("baz")},
},
newML: &newer.MinionList{Items: newMinions},
newML: &newer.NodeList{Items: newMinions},
},
}
for _, item := range table {
got := &newer.MinionList{}
got := &newer.NodeList{}
err := Convert(item.oldML, got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
@@ -162,28 +185,28 @@ func TestMinionListConversionToNew(t *testing.T) {
}
func TestMinionListConversionToOld(t *testing.T) {
oldMinion := func(id string) v1beta1.Minion {
return v1beta1.Minion{TypeMeta: v1beta1.TypeMeta{ID: id}}
oldMinion := func(id string) current.Minion {
return current.Minion{TypeMeta: current.TypeMeta{ID: id}}
}
newMinion := func(id string) newer.Minion {
return newer.Minion{ObjectMeta: newer.ObjectMeta{Name: id}}
newNode := func(id string) newer.Node {
return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}}
}
oldMinions := []v1beta1.Minion{
oldMinions := []current.Minion{
oldMinion("foo"),
oldMinion("bar"),
}
newMinions := []newer.Minion{
newMinion("foo"),
newMinion("bar"),
newMinions := []newer.Node{
newNode("foo"),
newNode("bar"),
}
newML := &newer.MinionList{Items: newMinions}
oldML := &v1beta1.MinionList{
newML := &newer.NodeList{Items: newMinions}
oldML := &current.MinionList{
Items: oldMinions,
Minions: oldMinions,
}
got := &v1beta1.MinionList{}
got := &current.MinionList{}
err := Convert(newML, got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
@@ -195,7 +218,7 @@ func TestMinionListConversionToOld(t *testing.T) {
func TestServiceEmptySelector(t *testing.T) {
// Nil map should be preserved
svc := &v1beta1.Service{Selector: nil}
svc := &current.Service{Selector: nil}
data, err := newer.Scheme.EncodeToVersion(svc, "v1beta1")
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -210,7 +233,7 @@ func TestServiceEmptySelector(t *testing.T) {
}
// Empty map should be preserved
svc2 := &v1beta1.Service{Selector: map[string]string{}}
svc2 := &current.Service{Selector: map[string]string{}}
data, err = newer.Scheme.EncodeToVersion(svc2, "v1beta1")
if err != nil {
t.Fatalf("unexpected error: %v", err)

View File

@@ -25,6 +25,10 @@ import (
var Codec = runtime.CodecFor(api.Scheme, "v1beta1")
func init() {
// Future names are supported, and declared first so they take precedence
api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
api.Scheme.AddKnownTypeWithName("v1beta1", "NodeList", &MinionList{})
api.Scheme.AddKnownTypes("v1beta1",
&Pod{},
&PodList{},
@@ -47,6 +51,9 @@ func init() {
&BoundPod{},
&BoundPods{},
)
// Future names are supported
api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
api.Scheme.AddKnownTypeWithName("v1beta1", "NodeList", &MinionList{})
}
func (*Pod) IsAnAPIObject() {}

View File

@@ -374,7 +374,7 @@ func init() {
return nil
},
func(in *newer.Minion, out *Minion, s conversion.Scope) error {
func(in *newer.Node, out *Minion, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
@@ -388,7 +388,7 @@ func init() {
out.HostIP = in.Status.HostIP
return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0)
},
func(in *Minion, out *newer.Minion, s conversion.Scope) error {
func(in *Minion, out *newer.Node, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}

View File

@@ -20,12 +20,12 @@ import (
"testing"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
current "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
)
func TestServiceEmptySelector(t *testing.T) {
// Nil map should be preserved
svc := &v1beta2.Service{Selector: nil}
svc := &current.Service{Selector: nil}
data, err := newer.Scheme.EncodeToVersion(svc, "v1beta2")
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -40,7 +40,7 @@ func TestServiceEmptySelector(t *testing.T) {
}
// Empty map should be preserved
svc2 := &v1beta2.Service{Selector: map[string]string{}}
svc2 := &current.Service{Selector: map[string]string{}}
data, err = newer.Scheme.EncodeToVersion(svc2, "v1beta2")
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -54,3 +54,26 @@ func TestServiceEmptySelector(t *testing.T) {
t.Errorf("unexpected selector: %#v", obj)
}
}
func TestNodeConversion(t *testing.T) {
obj, err := current.Codec.Decode([]byte(`{"kind":"Node","apiVersion":"v1beta2"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.Node); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj, err = current.Codec.Decode([]byte(`{"kind":"NodeList","apiVersion":"v1beta2"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.NodeList); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj = &newer.Node{}
if err := current.Codec.DecodeInto([]byte(`{"kind":"Node","apiVersion":"v1beta2"}`), obj); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}

View File

@@ -25,6 +25,10 @@ import (
var Codec = runtime.CodecFor(api.Scheme, "v1beta2")
func init() {
// Future names are supported, and declared first so they take precedence
api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
api.Scheme.AddKnownTypeWithName("v1beta2", "NodeList", &MinionList{})
api.Scheme.AddKnownTypes("v1beta2",
&Pod{},
&PodList{},
@@ -47,6 +51,9 @@ func init() {
&BoundPod{},
&BoundPods{},
)
// Future names are supported
api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
api.Scheme.AddKnownTypeWithName("v1beta2", "NodeList", &MinionList{})
}
func (*Pod) IsAnAPIObject() {}

View File

@@ -0,0 +1,47 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta3_test
import (
"testing"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
current "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
)
func TestNodeConversion(t *testing.T) {
obj, err := current.Codec.Decode([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.Node); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj, err = current.Codec.Decode([]byte(`{"kind":"MinionList","apiVersion":"v1beta3"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, ok := obj.(*newer.NodeList); !ok {
t.Errorf("unexpected type: %#v", obj)
}
obj = &newer.Node{}
if err := current.Codec.DecodeInto([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`), obj); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}

View File

@@ -47,6 +47,9 @@ func init() {
&Event{},
&EventList{},
)
// Legacy names are supported
api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{})
api.Scheme.AddKnownTypeWithName("v1beta3", "MinionList", &NodeList{})
}
func (*Pod) IsAnAPIObject() {}

View File

@@ -550,7 +550,7 @@ func ValidateBoundPod(pod *api.BoundPod) (errors []error) {
}
// ValidateMinion tests if required fields in the minion are set.
func ValidateMinion(minion *api.Minion) errs.ValidationErrorList {
func ValidateMinion(minion *api.Node) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(minion.Namespace) != 0 {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", minion.Namespace, ""))
@@ -563,7 +563,7 @@ func ValidateMinion(minion *api.Minion) errs.ValidationErrorList {
}
// ValidateMinionUpdate tests to make sure a minion update can be applied. Modifies oldMinion.
func ValidateMinionUpdate(oldMinion *api.Minion, minion *api.Minion) errs.ValidationErrorList {
func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
oldMinion.Labels = minion.Labels
if !reflect.DeepEqual(oldMinion, minion) {

View File

@@ -1077,7 +1077,7 @@ func TestValidateBoundPodNoName(t *testing.T) {
func TestValidateMinion(t *testing.T) {
validSelector := map[string]string{"a": "b"}
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
successCases := []api.Minion{
successCases := []api.Node{
{
ObjectMeta: api.ObjectMeta{
Name: "abc",
@@ -1100,7 +1100,7 @@ func TestValidateMinion(t *testing.T) {
}
}
errorCases := map[string]api.Minion{
errorCases := map[string]api.Node{
"zero-length Name": {
ObjectMeta: api.ObjectMeta{
Name: "",
@@ -1134,45 +1134,45 @@ func TestValidateMinion(t *testing.T) {
func TestValidateMinionUpdate(t *testing.T) {
tests := []struct {
oldMinion api.Minion
minion api.Minion
oldMinion api.Node
minion api.Node
valid bool
}{
{api.Minion{}, api.Minion{}, true},
{api.Minion{
{api.Node{}, api.Node{}, true},
{api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo"}},
api.Minion{
api.Node{
ObjectMeta: api.ObjectMeta{
Name: "bar"},
}, false},
{api.Minion{
{api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "bar"},
},
}, api.Minion{
}, api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "baz"},
},
}, true},
{api.Minion{
{api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
},
}, api.Minion{
}, api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "baz"},
},
}, true},
{api.Minion{
{api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"bar": "foo"},
},
}, api.Minion{
}, api.Node{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "baz"},

View File

@@ -32,7 +32,7 @@ type Interface interface {
ServicesNamespacer
EndpointsNamespacer
VersionInterface
MinionsInterface
NodesInterface
EventNamespacer
}
@@ -40,8 +40,8 @@ func (c *Client) ReplicationControllers(namespace string) ReplicationControllerI
return newReplicationControllers(c, namespace)
}
func (c *Client) Minions() MinionInterface {
return newMinions(c)
func (c *Client) Nodes() NodeInterface {
return newNodes(c, c.preV1Beta3)
}
func (c *Client) Events(namespace string) EventInterface {
@@ -75,6 +75,9 @@ type APIStatus interface {
// Client is the implementation of a Kubernetes client.
type Client struct {
*RESTClient
// preV1Beta3 is true for v1beta1 and v1beta2
preV1Beta3 bool
}
// ServerVersion retrieves and parses the server's version.

View File

@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@@ -59,6 +60,7 @@ type testClient struct {
Response Response
Error bool
Created bool
Version string
server *httptest.Server
handler *util.FakeHandler
// For query args, an optional function to validate the contents
@@ -77,9 +79,13 @@ func (c *testClient) Setup() *testClient {
}
c.server = httptest.NewServer(c.handler)
if c.Client == nil {
version := c.Version
if len(version) == 0 {
version = testapi.Version()
}
c.Client = NewOrDie(&Config{
Host: c.server.URL,
Version: "v1beta1",
Version: version,
})
}
c.QueryValidator = map[string]func(string, string) bool{}
@@ -604,23 +610,23 @@ func TestGetServerAPIVersions(t *testing.T) {
func TestListMinions(t *testing.T) {
c := &testClient{
Request: testRequest{Method: "GET", Path: "/minions"},
Response: Response{StatusCode: 200, Body: &api.MinionList{ListMeta: api.ListMeta{ResourceVersion: "1"}}},
Response: Response{StatusCode: 200, Body: &api.NodeList{ListMeta: api.ListMeta{ResourceVersion: "1"}}},
}
response, err := c.Setup().Minions().List()
response, err := c.Setup().Nodes().List()
c.Validate(t, response, err)
}
func TestGetMinion(t *testing.T) {
c := &testClient{
Request: testRequest{Method: "GET", Path: "/minions/1"},
Response: Response{StatusCode: 200, Body: &api.Minion{ObjectMeta: api.ObjectMeta{Name: "minion-1"}}},
Response: Response{StatusCode: 200, Body: &api.Node{ObjectMeta: api.ObjectMeta{Name: "minion-1"}}},
}
response, err := c.Setup().Minions().Get("1")
response, err := c.Setup().Nodes().Get("1")
c.Validate(t, response, err)
}
func TestCreateMinion(t *testing.T) {
requestMinion := &api.Minion{
requestMinion := &api.Node{
ObjectMeta: api.ObjectMeta{
Name: "minion-1",
},
@@ -641,7 +647,7 @@ func TestCreateMinion(t *testing.T) {
Body: requestMinion,
},
}
receivedMinion, err := c.Setup().Minions().Create(requestMinion)
receivedMinion, err := c.Setup().Nodes().Create(requestMinion)
c.Validate(t, receivedMinion, err)
}
@@ -650,6 +656,17 @@ func TestDeleteMinion(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: "/minions/foo"},
Response: Response{StatusCode: 200},
}
err := c.Setup().Minions().Delete("foo")
err := c.Setup().Nodes().Delete("foo")
c.Validate(t, nil, err)
}
func TestNewMinionPath(t *testing.T) {
c := &testClient{
Request: testRequest{Method: "DELETE", Path: "/nodes/foo"},
Response: Response{StatusCode: 200},
}
cl := c.Setup()
cl.preV1Beta3 = false
err := cl.Nodes().Delete("foo")
c.Validate(t, nil, err)
}

View File

@@ -39,7 +39,7 @@ type Fake struct {
Ctrl api.ReplicationController
ServiceList api.ServiceList
EndpointsList api.EndpointsList
MinionsList api.MinionList
MinionsList api.NodeList
EventsList api.EventList
Err error
Watch watch.Interface
@@ -49,8 +49,8 @@ func (c *Fake) ReplicationControllers(namespace string) ReplicationControllerInt
return &FakeReplicationControllers{Fake: c, Namespace: namespace}
}
func (c *Fake) Minions() MinionInterface {
return &FakeMinions{Fake: c}
func (c *Fake) Nodes() NodeInterface {
return &FakeNodes{Fake: c}
}
func (c *Fake) Events(namespace string) EventInterface {

View File

@@ -18,30 +18,36 @@ package client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
)
// FakeMinions implements MinionInterface. Meant to be embedded into a struct to get a default
// FakeNodes implements MinionInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeMinions struct {
type FakeNodes struct {
Fake *Fake
}
func (c *FakeMinions) Get(name string) (*api.Minion, error) {
func (c *FakeNodes) Get(name string) (*api.Node, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-minion", Value: name})
return &api.Minion{}, nil
for i := range c.Fake.MinionsList.Items {
if c.Fake.MinionsList.Items[i].Name == name {
return &c.Fake.MinionsList.Items[i], nil
}
}
return nil, errors.NewNotFound("Minions", name)
}
func (c *FakeMinions) List() (*api.MinionList, error) {
func (c *FakeNodes) List() (*api.NodeList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-minions", Value: nil})
return &c.Fake.MinionsList, nil
}
func (c *FakeMinions) Create(minion *api.Minion) (*api.Minion, error) {
func (c *FakeNodes) Create(minion *api.Node) (*api.Node, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-minion", Value: minion})
return &api.Minion{}, nil
return &api.Node{}, nil
}
func (c *FakeMinions) Delete(id string) error {
func (c *FakeNodes) Delete(id string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-minion", Value: id})
return nil
}

View File

@@ -87,7 +87,9 @@ func New(c *Config) (*Client, error) {
if err != nil {
return nil, err
}
return &Client{client}, nil
version := defaultVersionFor(&config)
isPreV1Beta3 := (version == "v1beta1" || version == "v1beta2")
return &Client{client, isPreV1Beta3}, nil
}
// NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized.

View File

@@ -18,49 +18,58 @@ package client
import "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
type MinionsInterface interface {
Minions() MinionInterface
type NodesInterface interface {
Nodes() NodeInterface
}
type MinionInterface interface {
Get(id string) (result *api.Minion, err error)
Create(minion *api.Minion) (*api.Minion, error)
List() (*api.MinionList, error)
type NodeInterface interface {
Get(id string) (result *api.Node, err error)
Create(minion *api.Node) (*api.Node, error)
List() (*api.NodeList, error)
Delete(id string) error
}
// minions implements Minions interface
type minions struct {
r *Client
// nodes implements NodesInterface
type nodes struct {
r *Client
preV1Beta3 bool
}
// newMinions returns a minions
func newMinions(c *Client) *minions {
return &minions{c}
// newNodes returns a nodes object. Uses "minions" as the
// URL resource name for v1beta1 and v1beta2.
func newNodes(c *Client, isPreV1Beta3 bool) *nodes {
return &nodes{c, isPreV1Beta3}
}
func (c *nodes) resourceName() string {
if c.preV1Beta3 {
return "minions"
}
return "nodes"
}
// Create creates a new minion.
func (c *minions) Create(minion *api.Minion) (*api.Minion, error) {
result := &api.Minion{}
err := c.r.Post().Path("minions").Body(minion).Do().Into(result)
func (c *nodes) Create(minion *api.Node) (*api.Node, error) {
result := &api.Node{}
err := c.r.Post().Path(c.resourceName()).Body(minion).Do().Into(result)
return result, err
}
// List lists all the minions in the cluster.
func (c *minions) List() (*api.MinionList, error) {
result := &api.MinionList{}
err := c.r.Get().Path("minions").Do().Into(result)
// List lists all the nodes in the cluster.
func (c *nodes) List() (*api.NodeList, error) {
result := &api.NodeList{}
err := c.r.Get().Path(c.resourceName()).Do().Into(result)
return result, err
}
// Get gets an existing minion
func (c *minions) Get(id string) (*api.Minion, error) {
result := &api.Minion{}
err := c.r.Get().Path("minions").Path(id).Do().Into(result)
func (c *nodes) Get(id string) (*api.Node, error) {
result := &api.Node{}
err := c.r.Get().Path(c.resourceName()).Path(id).Do().Into(result)
return result, err
}
// Delete deletes an existing minion.
func (c *minions) Delete(id string) error {
return c.r.Delete().Path("minions").Path(id).Do().Error()
func (c *nodes) Delete(id string) error {
return c.r.Delete().Path(c.resourceName()).Path(id).Do().Error()
}

View File

@@ -73,7 +73,7 @@ func (s *MinionController) SyncStatic(period time.Duration) error {
if registered.Has(minionID) {
continue
}
_, err := s.kubeClient.Minions().Create(&api.Minion{
_, err := s.kubeClient.Nodes().Create(&api.Node{
ObjectMeta: api.ObjectMeta{Name: minionID},
Spec: api.NodeSpec{
Capacity: s.staticResources.Capacity,
@@ -97,11 +97,11 @@ func (s *MinionController) SyncCloud() error {
if err != nil {
return err
}
minions, err := s.kubeClient.Minions().List()
minions, err := s.kubeClient.Nodes().List()
if err != nil {
return err
}
minionMap := make(map[string]*api.Minion)
minionMap := make(map[string]*api.Node)
for _, minion := range minions.Items {
minionMap[minion.Name] = &minion
}
@@ -110,7 +110,7 @@ func (s *MinionController) SyncCloud() error {
for _, minion := range matches.Items {
if _, ok := minionMap[minion.Name]; !ok {
glog.Infof("Create minion in registry: %s", minion.Name)
_, err = s.kubeClient.Minions().Create(&minion)
_, err = s.kubeClient.Nodes().Create(&minion)
if err != nil {
glog.Errorf("Create minion error: %s", minion.Name)
}
@@ -120,7 +120,7 @@ func (s *MinionController) SyncCloud() error {
for minionID := range minionMap {
glog.Infof("Delete minion from registry: %s", minionID)
err = s.kubeClient.Minions().Delete(minionID)
err = s.kubeClient.Nodes().Delete(minionID)
if err != nil {
glog.Errorf("Delete minion error: %s", minionID)
}
@@ -128,8 +128,8 @@ func (s *MinionController) SyncCloud() error {
return nil
}
// cloudMinions constructs and returns api.MinionList from cloudprovider.
func (s *MinionController) cloudMinions() (*api.MinionList, error) {
// cloudMinions constructs and returns api.NodeList from cloudprovider.
func (s *MinionController) cloudMinions() (*api.NodeList, error) {
instances, ok := s.cloud.Instances()
if !ok {
return nil, fmt.Errorf("cloud doesn't support instances")
@@ -138,8 +138,8 @@ func (s *MinionController) cloudMinions() (*api.MinionList, error) {
if err != nil {
return nil, err
}
result := &api.MinionList{
Items: make([]api.Minion, len(matches)),
result := &api.NodeList{
Items: make([]api.Node, len(matches)),
}
for i := range matches {
result.Items[i].Name = matches[i]

View File

@@ -26,29 +26,29 @@ import (
fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
)
func newMinion(name string) *api.Minion {
return &api.Minion{ObjectMeta: api.ObjectMeta{Name: name}}
func newNode(name string) *api.Node {
return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}}
}
type FakeMinionHandler struct {
client.Fake
client.FakeMinions
client.FakeNodes
// Input: Hooks determine if request is valid or not
CreateHook func(*FakeMinionHandler, *api.Minion) bool
Existing []*api.Minion
CreateHook func(*FakeMinionHandler, *api.Node) bool
Existing []*api.Node
// Output
CreatedMinions []*api.Minion
DeletedMinions []*api.Minion
CreatedMinions []*api.Node
DeletedMinions []*api.Node
RequestCount int
}
func (c *FakeMinionHandler) Minions() client.MinionInterface {
func (c *FakeMinionHandler) Nodes() client.NodeInterface {
return c
}
func (m *FakeMinionHandler) Create(minion *api.Minion) (*api.Minion, error) {
func (m *FakeMinionHandler) Create(minion *api.Node) (*api.Node, error) {
defer func() { m.RequestCount++ }()
if m.CreateHook == nil || m.CreateHook(m, minion) {
m.CreatedMinions = append(m.CreatedMinions, minion)
@@ -58,9 +58,9 @@ func (m *FakeMinionHandler) Create(minion *api.Minion) (*api.Minion, error) {
}
}
func (m *FakeMinionHandler) List() (*api.MinionList, error) {
func (m *FakeMinionHandler) List() (*api.NodeList, error) {
defer func() { m.RequestCount++ }()
minions := []api.Minion{}
minions := []api.Node{}
for i := 0; i < len(m.Existing); i++ {
if !contains(m.Existing[i], m.DeletedMinions) {
minions = append(minions, *m.Existing[i])
@@ -71,18 +71,18 @@ func (m *FakeMinionHandler) List() (*api.MinionList, error) {
minions = append(minions, *m.CreatedMinions[i])
}
}
return &api.MinionList{Items: minions}, nil
return &api.NodeList{Items: minions}, nil
}
func (m *FakeMinionHandler) Delete(id string) error {
m.DeletedMinions = append(m.DeletedMinions, newMinion(id))
m.DeletedMinions = append(m.DeletedMinions, newNode(id))
m.RequestCount++
return nil
}
func TestSyncStaticCreateMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
CreateHook: func(fake *FakeMinionHandler, minion *api.Minion) bool {
CreateHook: func(fake *FakeMinionHandler, minion *api.Node) bool {
return true
},
}
@@ -104,7 +104,7 @@ func TestSyncStaticCreateMinion(t *testing.T) {
func TestSyncStaticCreateMinionWithError(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
CreateHook: func(fake *FakeMinionHandler, minion *api.Minion) bool {
CreateHook: func(fake *FakeMinionHandler, minion *api.Node) bool {
if fake.RequestCount == 0 {
return false
}
@@ -129,7 +129,7 @@ func TestSyncStaticCreateMinionWithError(t *testing.T) {
func TestSyncCloudCreateMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Minion{newMinion("minion0")},
Existing: []*api.Node{newNode("minion0")},
}
instances := []string{"minion0", "minion1"}
fakeCloud := fake_cloud.FakeCloud{
@@ -153,7 +153,7 @@ func TestSyncCloudCreateMinion(t *testing.T) {
func TestSyncCloudDeleteMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Minion{newMinion("minion0"), newMinion("minion1")},
Existing: []*api.Node{newNode("minion0"), newNode("minion1")},
}
instances := []string{"minion0"}
fakeCloud := fake_cloud.FakeCloud{
@@ -177,7 +177,7 @@ func TestSyncCloudDeleteMinion(t *testing.T) {
func TestSyncCloudRegexp(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Minion{newMinion("minion0")},
Existing: []*api.Node{newNode("minion0")},
}
instances := []string{"minion0", "minion1", "node0"}
fakeCloud := fake_cloud.FakeCloud{
@@ -199,7 +199,7 @@ func TestSyncCloudRegexp(t *testing.T) {
}
}
func contains(minion *api.Minion, minions []*api.Minion) bool {
func contains(minion *api.Node, minions []*api.Node) bool {
for i := 0; i < len(minions); i++ {
if minion.Name == minions[i].Name {
return true

View File

@@ -97,9 +97,6 @@ func (s *Scheme) DecodeInto(data []byte, obj interface{}) error {
// correct type.
dataKind = objKind
}
if dataKind != objKind {
return fmt.Errorf("data of kind '%v', obj of type '%v'", dataKind, objKind)
}
if dataVersion == "" {
// Assume objects with unset Version fields are being unmarshalled into the
// correct type.

View File

@@ -75,10 +75,12 @@ func (s *Scheme) Log(l DebugLogger) {
// nameFunc returns the name of the type that we wish to use for encoding. Defaults to
// the go name of the type if the type is not registered.
func (s *Scheme) nameFunc(t reflect.Type) string {
if kind, ok := s.typeToKind[t]; ok {
return kind[0]
// find the preferred names for this type
names, ok := s.typeToKind[t]
if !ok {
return t.Name()
}
return t.Name()
return names[0]
}
// AddKnownTypes registers all types passed in 'types' as being members of version 'version.

View File

@@ -228,6 +228,43 @@ func TestMultipleNames(t *testing.T) {
}
}
func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
s := NewScheme()
// create two names internally, with TestType1 being preferred
s.AddKnownTypeWithName("", "TestType1", &TestType1{})
s.AddKnownTypeWithName("", "OtherType1", &TestType1{})
// create two names externally, with TestType1 being preferred
s.AddKnownTypeWithName("v1", "TestType1", &ExternalTestType1{})
s.AddKnownTypeWithName("v1", "OtherType1", &ExternalTestType1{})
s.MetaFactory = testMetaFactory{}
ext := &ExternalTestType1{}
ext.APIVersion = "v1"
ext.ObjectKind = "OtherType1"
ext.A = "test"
data, err := json.Marshal(ext)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expect := &TestType1{A: "test"}
obj, err := s.Decode(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(expect, obj) {
t.Errorf("unexpected object: %#v", obj)
}
into := &TestType1{}
if err := s.DecodeInto(data, into); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(expect, obj) {
t.Errorf("unexpected object: %#v", obj)
}
}
func TestKnownTypes(t *testing.T) {
s := GetTestScheme()
if len(s.KnownTypes("v2")) != 0 {

View File

@@ -248,12 +248,12 @@ func printServiceList(list *api.ServiceList, w io.Writer) error {
return nil
}
func printMinion(minion *api.Minion, w io.Writer) error {
func printMinion(minion *api.Node, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\n", minion.Name, labels.Set(minion.Labels))
return err
}
func printMinionList(list *api.MinionList, w io.Writer) error {
func printMinionList(list *api.NodeList, w io.Writer) error {
for _, minion := range list.Items {
if err := printMinion(&minion, w); err != nil {
return err

View File

@@ -176,7 +176,7 @@ type MinionDescriber struct {
}
func (d *MinionDescriber) Describe(namespace, name string) (string, error) {
mc := d.Minions()
mc := d.Nodes()
minion, err := mc.Get(name)
if err != nil {
return "", err

View File

@@ -296,12 +296,12 @@ func printServiceList(list *api.ServiceList, w io.Writer) error {
return nil
}
func printMinion(minion *api.Minion, w io.Writer) error {
func printMinion(minion *api.Node, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\n", minion.Name, formatLabels(minion.Labels))
return err
}
func printMinionList(list *api.MinionList, w io.Writer) error {
func printMinionList(list *api.NodeList, w io.Writer) error {
for _, minion := range list.Items {
if err := printMinion(&minion, w); err != nil {
return err

View File

@@ -316,12 +316,13 @@ func (m *Master) init(c *Config) {
PodCache: podCache,
PodInfoGetter: c.KubeletClient,
Registry: m.podRegistry,
Minions: m.client.Minions(),
Nodes: m.client.Nodes(),
}),
"replicationControllers": controller.NewREST(m.controllerRegistry, m.podRegistry),
"services": service.NewREST(m.serviceRegistry, c.Cloud, m.minionRegistry, m.portalNet),
"endpoints": endpoint.NewREST(m.endpointRegistry),
"minions": minion.NewREST(m.minionRegistry),
"nodes": minion.NewREST(m.minionRegistry),
"events": event.NewREST(m.eventRegistry),
// TODO: should appear only in scheduler API group.

View File

@@ -574,26 +574,26 @@ func makeMinionKey(minionID string) string {
return "/registry/minions/" + minionID
}
func (r *Registry) ListMinions(ctx api.Context) (*api.MinionList, error) {
minions := &api.MinionList{}
func (r *Registry) ListMinions(ctx api.Context) (*api.NodeList, error) {
minions := &api.NodeList{}
err := r.ExtractToList("/registry/minions", minions)
return minions, err
}
func (r *Registry) CreateMinion(ctx api.Context, minion *api.Minion) error {
func (r *Registry) CreateMinion(ctx api.Context, minion *api.Node) error {
// TODO: Add some validations.
err := r.CreateObj(makeMinionKey(minion.Name), minion, 0)
return etcderr.InterpretCreateError(err, "minion", minion.Name)
}
func (r *Registry) UpdateMinion(ctx api.Context, minion *api.Minion) error {
func (r *Registry) UpdateMinion(ctx api.Context, minion *api.Node) error {
// TODO: Add some validations.
err := r.SetObj(makeMinionKey(minion.Name), minion)
return etcderr.InterpretUpdateError(err, "minion", minion.Name)
}
func (r *Registry) GetMinion(ctx api.Context, minionID string) (*api.Minion, error) {
var minion api.Minion
func (r *Registry) GetMinion(ctx api.Context, minionID string) (*api.Node, error) {
var minion api.Node
key := makeMinionKey(minionID)
err := r.ExtractObj(key, &minion, false)
if err != nil {

View File

@@ -1579,12 +1579,12 @@ func TestEtcdListMinions(t *testing.T) {
Node: &etcd.Node{
Nodes: []*etcd.Node{
{
Value: runtime.EncodeOrDie(latest.Codec, &api.Minion{
Value: runtime.EncodeOrDie(latest.Codec, &api.Node{
ObjectMeta: api.ObjectMeta{Name: "foo"},
}),
},
{
Value: runtime.EncodeOrDie(latest.Codec, &api.Minion{
Value: runtime.EncodeOrDie(latest.Codec, &api.Node{
ObjectMeta: api.ObjectMeta{Name: "bar"},
}),
},
@@ -1608,7 +1608,7 @@ func TestEtcdCreateMinion(t *testing.T) {
ctx := api.NewContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
err := registry.CreateMinion(ctx, &api.Minion{
err := registry.CreateMinion(ctx, &api.Node{
ObjectMeta: api.ObjectMeta{Name: "foo"},
})
if err != nil {
@@ -1620,7 +1620,7 @@ func TestEtcdCreateMinion(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
var minion api.Minion
var minion api.Node
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &minion)
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -1634,7 +1634,7 @@ func TestEtcdCreateMinion(t *testing.T) {
func TestEtcdGetMinion(t *testing.T) {
ctx := api.NewContext()
fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.Set("/registry/minions/foo", runtime.EncodeOrDie(latest.Codec, &api.Minion{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
fakeClient.Set("/registry/minions/foo", runtime.EncodeOrDie(latest.Codec, &api.Node{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
minion, err := registry.GetMinion(ctx, "foo")
if err != nil {

View File

@@ -36,7 +36,7 @@ func NewHealthyRegistry(delegate Registry, client client.KubeletHealthChecker) R
}
}
func (r *HealthyRegistry) GetMinion(ctx api.Context, minionID string) (*api.Minion, error) {
func (r *HealthyRegistry) GetMinion(ctx api.Context, minionID string) (*api.Node, error) {
minion, err := r.delegate.GetMinion(ctx, minionID)
if minion == nil {
return nil, ErrDoesNotExist
@@ -58,16 +58,16 @@ func (r *HealthyRegistry) DeleteMinion(ctx api.Context, minionID string) error {
return r.delegate.DeleteMinion(ctx, minionID)
}
func (r *HealthyRegistry) CreateMinion(ctx api.Context, minion *api.Minion) error {
func (r *HealthyRegistry) CreateMinion(ctx api.Context, minion *api.Node) error {
return r.delegate.CreateMinion(ctx, minion)
}
func (r *HealthyRegistry) UpdateMinion(ctx api.Context, minion *api.Minion) error {
func (r *HealthyRegistry) UpdateMinion(ctx api.Context, minion *api.Node) error {
return r.delegate.UpdateMinion(ctx, minion)
}
func (r *HealthyRegistry) ListMinions(ctx api.Context) (currentMinions *api.MinionList, err error) {
result := &api.MinionList{}
func (r *HealthyRegistry) ListMinions(ctx api.Context) (currentMinions *api.NodeList, err error) {
result := &api.NodeList{}
list, err := r.delegate.ListMinions(ctx)
if err != nil {
return result, err

View File

@@ -45,7 +45,7 @@ func TestBasicDelegation(t *testing.T) {
if !reflect.DeepEqual(list, &mockMinionRegistry.Minions) {
t.Errorf("Expected %v, Got %v", mockMinionRegistry.Minions, list)
}
err = healthy.CreateMinion(ctx, &api.Minion{
err = healthy.CreateMinion(ctx, &api.Node{
ObjectMeta: api.ObjectMeta{Name: "foo"},
})
if err != nil {

View File

@@ -20,9 +20,9 @@ import "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
// MinionRegistry is an interface for things that know how to store minions.
type Registry interface {
ListMinions(ctx api.Context) (*api.MinionList, error)
CreateMinion(ctx api.Context, minion *api.Minion) error
UpdateMinion(ctx api.Context, minion *api.Minion) error
GetMinion(ctx api.Context, minionID string) (*api.Minion, error)
ListMinions(ctx api.Context) (*api.NodeList, error)
CreateMinion(ctx api.Context, minion *api.Node) error
UpdateMinion(ctx api.Context, minion *api.Node) error
GetMinion(ctx api.Context, minionID string) (*api.Node, error)
DeleteMinion(ctx api.Context, minionID string) error
}

View File

@@ -47,7 +47,7 @@ var ErrDoesNotExist = errors.New("The requested resource does not exist.")
var ErrNotHealty = errors.New("The requested minion is not healthy.")
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
minion, ok := obj.(*api.Minion)
minion, ok := obj.(*api.Node)
if !ok {
return nil, fmt.Errorf("not a minion: %#v", obj)
}
@@ -93,11 +93,11 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj
}
func (rs *REST) New() runtime.Object {
return &api.Minion{}
return &api.Node{}
}
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
minion, ok := obj.(*api.Minion)
minion, ok := obj.(*api.Node)
if !ok {
return nil, fmt.Errorf("not a minion: %#v", obj)
}
@@ -121,8 +121,8 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
}), nil
}
func (rs *REST) toApiMinion(name string) *api.Minion {
return &api.Minion{ObjectMeta: api.ObjectMeta{Name: name}}
func (rs *REST) toApiMinion(name string) *api.Node {
return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}}
}
// ResourceLocation returns a URL to which one can send traffic for the specified minion.

View File

@@ -28,28 +28,28 @@ import (
func TestMinionREST(t *testing.T) {
ms := NewREST(registrytest.NewMinionRegistry([]string{"foo", "bar"}, api.NodeResources{}))
ctx := api.NewContext()
if obj, err := ms.Get(ctx, "foo"); err != nil || obj.(*api.Minion).Name != "foo" {
if obj, err := ms.Get(ctx, "foo"); err != nil || obj.(*api.Node).Name != "foo" {
t.Errorf("missing expected object")
}
if obj, err := ms.Get(ctx, "bar"); err != nil || obj.(*api.Minion).Name != "bar" {
if obj, err := ms.Get(ctx, "bar"); err != nil || obj.(*api.Node).Name != "bar" {
t.Errorf("missing expected object")
}
if _, err := ms.Get(ctx, "baz"); err != ErrDoesNotExist {
t.Errorf("has unexpected object")
}
c, err := ms.Create(ctx, &api.Minion{ObjectMeta: api.ObjectMeta{Name: "baz"}})
c, err := ms.Create(ctx, &api.Node{ObjectMeta: api.ObjectMeta{Name: "baz"}})
if err != nil {
t.Errorf("insert failed")
}
obj := <-c
if !api.HasObjectMetaSystemFieldValues(&obj.Object.(*api.Minion).ObjectMeta) {
if !api.HasObjectMetaSystemFieldValues(&obj.Object.(*api.Node).ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
if m, ok := obj.Object.(*api.Minion); !ok || m.Name != "baz" {
if m, ok := obj.Object.(*api.Node); !ok || m.Name != "baz" {
t.Errorf("insert return value was weird: %#v", obj)
}
if obj, err := ms.Get(ctx, "baz"); err != nil || obj.(*api.Minion).Name != "baz" {
if obj, err := ms.Get(ctx, "baz"); err != nil || obj.(*api.Node).Name != "baz" {
t.Errorf("insert didn't actually insert")
}
@@ -74,14 +74,14 @@ func TestMinionREST(t *testing.T) {
if err != nil {
t.Errorf("got error calling List")
}
expect := []api.Minion{
expect := []api.Node{
{
ObjectMeta: api.ObjectMeta{Name: "foo"},
}, {
ObjectMeta: api.ObjectMeta{Name: "baz"},
},
}
nodeList := list.(*api.MinionList)
nodeList := list.(*api.NodeList)
if len(expect) != len(nodeList.Items) || !contains(nodeList, "foo") || !contains(nodeList, "baz") {
t.Errorf("Unexpected list value: %#v", list)
}
@@ -97,12 +97,12 @@ func TestMinionStorageWithHealthCheck(t *testing.T) {
ms := NewREST(&minionHealthRegistry)
ctx := api.NewContext()
c, err := ms.Create(ctx, &api.Minion{ObjectMeta: api.ObjectMeta{Name: "m1"}})
c, err := ms.Create(ctx, &api.Node{ObjectMeta: api.ObjectMeta{Name: "m1"}})
if err != nil {
t.Errorf("insert failed")
}
result := <-c
if m, ok := result.Object.(*api.Minion); !ok || m.Name != "m1" {
if m, ok := result.Object.(*api.Node); !ok || m.Name != "m1" {
t.Errorf("insert return value was weird: %#v", result)
}
if _, err := ms.Get(ctx, "m1"); err == nil {
@@ -110,7 +110,7 @@ func TestMinionStorageWithHealthCheck(t *testing.T) {
}
}
func contains(nodes *api.MinionList, nodeID string) bool {
func contains(nodes *api.NodeList, nodeID string) bool {
for _, node := range nodes.Items {
if node.Name == nodeID {
return true
@@ -126,7 +126,7 @@ func TestMinionStorageInvalidUpdate(t *testing.T) {
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
minion, ok := obj.(*api.Minion)
minion, ok := obj.(*api.Node)
if !ok {
t.Fatalf("Object is not a minion: %#v", obj)
}
@@ -143,7 +143,7 @@ func TestMinionStorageValidUpdate(t *testing.T) {
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
minion, ok := obj.(*api.Minion)
minion, ok := obj.(*api.Node)
if !ok {
t.Fatalf("Object is not a minion: %#v", obj)
}
@@ -161,7 +161,7 @@ func TestMinionStorageValidatesCreate(t *testing.T) {
ctx := api.NewContext()
validSelector := map[string]string{"a": "b"}
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
failureCases := map[string]api.Minion{
failureCases := map[string]api.Node{
"zero-length Name": {
ObjectMeta: api.ObjectMeta{
Name: "",

View File

@@ -60,7 +60,7 @@ type REST struct {
podInfoGetter client.PodInfoGetter
podPollPeriod time.Duration
registry Registry
minions client.MinionInterface
nodes client.NodeInterface
ipCache ipCache
clock clock
}
@@ -70,7 +70,7 @@ type RESTConfig struct {
PodCache client.PodInfoGetter
PodInfoGetter client.PodInfoGetter
Registry Registry
Minions client.MinionInterface
Nodes client.NodeInterface
}
// NewREST returns a new REST.
@@ -81,7 +81,7 @@ func NewREST(config *RESTConfig) *REST {
podInfoGetter: config.PodInfoGetter,
podPollPeriod: time.Second * 10,
registry: config.Registry,
minions: config.Minions,
nodes: config.Nodes,
ipCache: ipCache{},
clock: realClock{},
}
@@ -125,7 +125,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
}
if rs.podCache != nil || rs.podInfoGetter != nil {
rs.fillPodInfo(pod)
status, err := getPodStatus(pod, rs.minions)
status, err := getPodStatus(pod, rs.nodes)
if err != nil {
return pod, err
}
@@ -169,7 +169,7 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj
for i := range pods.Items {
pod := &pods.Items[i]
rs.fillPodInfo(pod)
status, err := getPodStatus(pod, rs.minions)
status, err := getPodStatus(pod, rs.nodes)
if err != nil {
return pod, err
}
@@ -275,26 +275,19 @@ func getInstanceIPFromCloud(cloud cloudprovider.Interface, host string) string {
return addr.String()
}
func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodPhase, error) {
func getPodStatus(pod *api.Pod, nodes client.NodeInterface) (api.PodPhase, error) {
if pod.Status.Host == "" {
return api.PodPending, nil
}
if minions != nil {
res, err := minions.List()
if nodes != nil {
_, err := nodes.Get(pod.Status.Host)
if err != nil {
if errors.IsNotFound(err) {
return api.PodFailed, nil
}
glog.Errorf("Error listing minions: %v", err)
return "", err
}
found := false
for _, minion := range res.Items {
if minion.Name == pod.Status.Host {
found = true
break
}
}
if !found {
return api.PodFailed, nil
}
} else {
glog.Errorf("Unexpected missing minion interface, status may be in-accurate")
}

View File

@@ -370,8 +370,8 @@ func TestGetPodCloud(t *testing.T) {
func TestMakePodStatus(t *testing.T) {
fakeClient := client.Fake{
MinionsList: api.MinionList{
Items: []api.Minion{
MinionsList: api.NodeList{
Items: []api.Node{
{
ObjectMeta: api.ObjectMeta{Name: "machine"},
},
@@ -499,7 +499,7 @@ func TestMakePodStatus(t *testing.T) {
},
}
for _, test := range tests {
if status, err := getPodStatus(test.pod, fakeClient.Minions()); status != test.status {
if status, err := getPodStatus(test.pod, fakeClient.Nodes()); status != test.status {
t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status)
if err != nil {
t.Errorf("In test %s, unexpected error: %v", test.test, err)

View File

@@ -25,13 +25,13 @@ import (
type MinionRegistry struct {
Err error
Minion string
Minions api.MinionList
Minions api.NodeList
sync.Mutex
}
func MakeMinionList(minions []string, nodeResources api.NodeResources) *api.MinionList {
list := api.MinionList{
Items: make([]api.Minion, len(minions)),
func MakeMinionList(minions []string, nodeResources api.NodeResources) *api.NodeList {
list := api.NodeList{
Items: make([]api.Node, len(minions)),
}
for i := range minions {
list.Items[i].Name = minions[i]
@@ -46,13 +46,13 @@ func NewMinionRegistry(minions []string, nodeResources api.NodeResources) *Minio
}
}
func (r *MinionRegistry) ListMinions(ctx api.Context) (*api.MinionList, error) {
func (r *MinionRegistry) ListMinions(ctx api.Context) (*api.NodeList, error) {
r.Lock()
defer r.Unlock()
return &r.Minions, r.Err
}
func (r *MinionRegistry) CreateMinion(ctx api.Context, minion *api.Minion) error {
func (r *MinionRegistry) CreateMinion(ctx api.Context, minion *api.Node) error {
r.Lock()
defer r.Unlock()
r.Minion = minion.Name
@@ -60,7 +60,7 @@ func (r *MinionRegistry) CreateMinion(ctx api.Context, minion *api.Minion) error
return r.Err
}
func (r *MinionRegistry) UpdateMinion(ctx api.Context, minion *api.Minion) error {
func (r *MinionRegistry) UpdateMinion(ctx api.Context, minion *api.Node) error {
r.Lock()
defer r.Unlock()
for i, node := range r.Minions.Items {
@@ -72,7 +72,7 @@ func (r *MinionRegistry) UpdateMinion(ctx api.Context, minion *api.Minion) error
return r.Err
}
func (r *MinionRegistry) GetMinion(ctx api.Context, minionID string) (*api.Minion, error) {
func (r *MinionRegistry) GetMinion(ctx api.Context, minionID string) (*api.Node, error) {
r.Lock()
defer r.Unlock()
for _, node := range r.Minions.Items {
@@ -86,10 +86,10 @@ func (r *MinionRegistry) GetMinion(ctx api.Context, minionID string) (*api.Minio
func (r *MinionRegistry) DeleteMinion(ctx api.Context, minionID string) error {
r.Lock()
defer r.Unlock()
var newList []api.Minion
var newList []api.Node
for _, node := range r.Minions.Items {
if node.Name != minionID {
newList = append(newList, api.Minion{ObjectMeta: api.ObjectMeta{Name: node.Name}})
newList = append(newList, api.Node{ObjectMeta: api.ObjectMeta{Name: node.Name}})
}
}
r.Minions.Items = newList

View File

@@ -154,7 +154,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
}), nil
}
func hostsFromMinionList(list *api.MinionList) []string {
func hostsFromMinionList(list *api.NodeList) []string {
result := make([]string, len(list.Items))
for ix := range list.Items {
result[ix] = list.Items[ix].Name

View File

@@ -76,18 +76,18 @@ func (g *genericScheduler) selectHost(priorityList HostPriorityList) (string, er
// Filters the minions to find the ones that fit based on the given predicate functions
// Each minion is passed through the predicate functions to determine if it is a fit
func findNodesThatFit(pod api.Pod, podLister PodLister, predicates []FitPredicate, nodes api.MinionList) (api.MinionList, error) {
filtered := []api.Minion{}
func findNodesThatFit(pod api.Pod, podLister PodLister, predicates []FitPredicate, nodes api.NodeList) (api.NodeList, error) {
filtered := []api.Node{}
machineToPods, err := MapPodsToMachines(podLister)
if err != nil {
return api.MinionList{}, err
return api.NodeList{}, err
}
for _, node := range nodes.Items {
fits := true
for _, predicate := range predicates {
fit, err := predicate(pod, machineToPods[node.Name], node.Name)
if err != nil {
return api.MinionList{}, err
return api.NodeList{}, err
}
if !fit {
fits = false
@@ -98,7 +98,7 @@ func findNodesThatFit(pod api.Pod, podLister PodLister, predicates []FitPredicat
filtered = append(filtered, node)
}
}
return api.MinionList{Items: filtered}, nil
return api.NodeList{Items: filtered}, nil
}
// Prioritizes the minions by running the individual priority functions sequentially.

View File

@@ -83,9 +83,9 @@ func reverseNumericPriority(pod api.Pod, podLister PodLister, minionLister Minio
return reverseResult, nil
}
func makeMinionList(nodeNames []string) api.MinionList {
result := api.MinionList{
Items: make([]api.Minion, len(nodeNames)),
func makeMinionList(nodeNames []string) api.NodeList {
result := api.NodeList{
Items: make([]api.Node, len(nodeNames)),
}
for ix := range nodeNames {
result.Items[ix].Name = nodeNames[ix]

View File

@@ -23,15 +23,15 @@ import (
// MinionLister interface represents anything that can list minions for a scheduler.
type MinionLister interface {
List() (list api.MinionList, err error)
List() (list api.NodeList, err error)
}
// FakeMinionLister implements MinionLister on a []string for test purposes.
type FakeMinionLister api.MinionList
type FakeMinionLister api.NodeList
// List returns minions as a []string.
func (f FakeMinionLister) List() (api.MinionList, error) {
return api.MinionList(f), nil
func (f FakeMinionLister) List() (api.NodeList, error) {
return api.NodeList(f), nil
}
// PodLister interface represents anything that can list pods for a scheduler.

View File

@@ -27,14 +27,14 @@ import (
)
type NodeInfo interface {
GetNodeInfo(nodeID string) (*api.Minion, error)
GetNodeInfo(nodeID string) (*api.Node, error)
}
type StaticNodeInfo struct {
*api.MinionList
*api.NodeList
}
func (nodes StaticNodeInfo) GetNodeInfo(nodeID string) (*api.Minion, error) {
func (nodes StaticNodeInfo) GetNodeInfo(nodeID string) (*api.Node, error) {
for ix := range nodes.Items {
if nodes.Items[ix].Name == nodeID {
return &nodes.Items[ix], nil
@@ -47,8 +47,8 @@ type ClientNodeInfo struct {
*client.Client
}
func (nodes ClientNodeInfo) GetNodeInfo(nodeID string) (*api.Minion, error) {
return nodes.Minions().Get(nodeID)
func (nodes ClientNodeInfo) GetNodeInfo(nodeID string) (*api.Node, error) {
return nodes.Nodes().Get(nodeID)
}
func isVolumeConflict(volume api.Volume, pod *api.Pod) bool {

View File

@@ -25,10 +25,10 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
type FakeNodeInfo api.Minion
type FakeNodeInfo api.Node
func (n FakeNodeInfo) GetNodeInfo(nodeName string) (*api.Minion, error) {
node := api.Minion(n)
func (n FakeNodeInfo) GetNodeInfo(nodeName string) (*api.Node, error) {
node := api.Node(n)
return &node, nil
}
@@ -111,7 +111,7 @@ func TestPodFitsResources(t *testing.T) {
},
}
for _, test := range tests {
node := api.Minion{Spec: api.NodeSpec{Capacity: makeResources(10, 20).Capacity}}
node := api.Node{Spec: api.NodeSpec{Capacity: makeResources(10, 20).Capacity}}
fit := ResourceFit{FakeNodeInfo(node)}
fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
@@ -335,7 +335,7 @@ func TestPodFitsSelector(t *testing.T) {
},
}
for _, test := range tests {
node := api.Minion{ObjectMeta: api.ObjectMeta{Labels: test.labels}}
node := api.Node{ObjectMeta: api.ObjectMeta{Labels: test.labels}}
fit := NodeSelector{FakeNodeInfo(node)}
fits, err := fit.PodSelectorMatches(test.pod, []api.Pod{}, "machine")

View File

@@ -37,7 +37,7 @@ func calculateScore(requested, capacity int, node string) int {
// Calculate the occupancy on a node. 'node' has information about the resources on the node.
// 'pods' is a list of pods currently scheduled on the node.
func calculateOccupancy(pod api.Pod, node api.Minion, pods []api.Pod) HostPriority {
func calculateOccupancy(pod api.Pod, node api.Node, pods []api.Pod) HostPriority {
totalCPU := 0
totalMemory := 0
for _, existingPod := range pods {

View File

@@ -25,8 +25,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func makeMinion(node string, cpu, memory int) api.Minion {
return api.Minion{
func makeMinion(node string, cpu, memory int) api.Node {
return api.Node{
ObjectMeta: api.ObjectMeta{Name: node},
Spec: api.NodeSpec{
Capacity: api.ResourceList{
@@ -70,7 +70,7 @@ func TestLeastRequested(t *testing.T) {
tests := []struct {
pod api.Pod
pods []api.Pod
nodes []api.Minion
nodes []api.Node
expectedList HostPriorityList
test string
}{
@@ -87,7 +87,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (10 + 10) / 2 = 10
*/
pod: api.Pod{Spec: noResources},
nodes: []api.Minion{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
expectedList: []HostPriority{{"machine1", 10}, {"machine2", 10}},
test: "nothing scheduled, nothing requested",
},
@@ -104,7 +104,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (5 + 5) / 2 = 5
*/
pod: api.Pod{Spec: cpuAndMemory},
nodes: []api.Minion{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 6000, 10000)},
nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 6000, 10000)},
expectedList: []HostPriority{{"machine1", 3}, {"machine2", 5}},
test: "nothing scheduled, resources requested, differently sized machines",
},
@@ -121,7 +121,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (10 + 10) / 2 = 10
*/
pod: api.Pod{Spec: noResources},
nodes: []api.Minion{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
expectedList: []HostPriority{{"machine1", 10}, {"machine2", 10}},
test: "no resources requested, pods scheduled",
pods: []api.Pod{
@@ -144,7 +144,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (4 + 7.5) / 2 = 5
*/
pod: api.Pod{Spec: noResources},
nodes: []api.Minion{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)},
nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)},
expectedList: []HostPriority{{"machine1", 7}, {"machine2", 5}},
test: "no resources requested, pods scheduled with resources",
pods: []api.Pod{
@@ -167,7 +167,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (4 + 5) / 2 = 4
*/
pod: api.Pod{Spec: cpuAndMemory},
nodes: []api.Minion{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)},
nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)},
expectedList: []HostPriority{{"machine1", 5}, {"machine2", 4}},
test: "resources requested, pods scheduled with resources",
pods: []api.Pod{
@@ -188,7 +188,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (4 + 8) / 2 = 6
*/
pod: api.Pod{Spec: cpuAndMemory},
nodes: []api.Minion{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 50000)},
nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 50000)},
expectedList: []HostPriority{{"machine1", 5}, {"machine2", 6}},
test: "resources requested, pods scheduled with resources, differently sized machines",
pods: []api.Pod{
@@ -209,7 +209,7 @@ func TestLeastRequested(t *testing.T) {
Minion2 Score: (0 + 5) / 2 = 2
*/
pod: api.Pod{Spec: cpuOnly},
nodes: []api.Minion{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)},
expectedList: []HostPriority{{"machine1", 5}, {"machine2", 2}},
test: "requested resources exceed minion capacity",
pods: []api.Pod{
@@ -219,7 +219,7 @@ func TestLeastRequested(t *testing.T) {
},
{
pod: api.Pod{Spec: noResources},
nodes: []api.Minion{makeMinion("machine1", 0, 0), makeMinion("machine2", 0, 0)},
nodes: []api.Node{makeMinion("machine1", 0, 0), makeMinion("machine2", 0, 0)},
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}},
test: "zero minion resources, pods scheduled with resources",
pods: []api.Pod{
@@ -230,7 +230,7 @@ func TestLeastRequested(t *testing.T) {
}
for _, test := range tests {
list, err := LeastRequestedPriority(test.pod, FakePodLister(test.pods), FakeMinionLister(api.MinionList{Items: test.nodes}))
list, err := LeastRequestedPriority(test.pod, FakePodLister(test.pods), FakeMinionLister(api.NodeList{Items: test.nodes}))
if err != nil {
t.Errorf("unexpected error: %v", err)
}

View File

@@ -45,7 +45,7 @@ type ConfigFactory struct {
// a means to list all scheduled pods
PodLister *storeToPodLister
// a means to list all minions
MinionLister *storeToMinionLister
MinionLister *storeToNodeLister
// map of strings to predicate functions to be used
// to filter the minions for scheduling pods
PredicateMap map[string]algorithm.FitPredicate
@@ -61,7 +61,7 @@ func NewConfigFactory(client *client.Client) *ConfigFactory {
Client: client,
PodQueue: cache.NewFIFO(),
PodLister: &storeToPodLister{cache.NewStore()},
MinionLister: &storeToMinionLister{cache.NewStore()},
MinionLister: &storeToNodeLister{cache.NewStore()},
PredicateMap: make(map[string]algorithm.FitPredicate),
PriorityMap: make(map[string]algorithm.PriorityConfig),
}
@@ -103,7 +103,7 @@ func (factory *ConfigFactory) Create(predicateKeys, priorityKeys []string) (*sch
// Minions may be listed frequently, so provide a local up-to-date cache.
if false {
// Disable this code until minions support watches.
cache.NewReflector(factory.createMinionLW(), &api.Minion{}, factory.MinionLister.Store).Run()
cache.NewReflector(factory.createMinionLW(), &api.Node{}, factory.MinionLister.Store).Run()
} else {
cache.NewPoller(factory.pollMinions, 10*time.Second, factory.MinionLister.Store).Run()
}
@@ -255,12 +255,12 @@ func (factory *ConfigFactory) createMinionLW() *listWatch {
// pollMinions lists all minions and returns an enumerator for cache.Poller.
func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) {
list := &api.MinionList{}
list := &api.NodeList{}
err := factory.Client.Get().Path("minions").Do().Into(list)
if err != nil {
return nil, err
}
return &minionEnumerator{list}, nil
return &nodeEnumerator{list}, nil
}
func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue *cache.FIFO) func(pod *api.Pod, err error) {
@@ -288,22 +288,22 @@ func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue
}
}
// storeToMinionLister turns a store into a minion lister. The store must contain (only) minions.
type storeToMinionLister struct {
// storeToNodeLister turns a store into a minion lister. The store must contain (only) minions.
type storeToNodeLister struct {
cache.Store
}
func (s *storeToMinionLister) List() (machines api.MinionList, err error) {
func (s *storeToNodeLister) List() (machines api.NodeList, err error) {
for _, m := range s.Store.List() {
machines.Items = append(machines.Items, *(m.(*api.Minion)))
machines.Items = append(machines.Items, *(m.(*api.Node)))
}
return machines, nil
}
// GetNodeInfo returns cached data for the minion 'id'.
func (s *storeToMinionLister) GetNodeInfo(id string) (*api.Minion, error) {
func (s *storeToNodeLister) GetNodeInfo(id string) (*api.Node, error) {
if minion, ok := s.Get(id); ok {
return minion.(*api.Minion), nil
return minion.(*api.Node), nil
}
return nil, fmt.Errorf("minion '%v' is not in cache", id)
}
@@ -323,22 +323,22 @@ func (s *storeToPodLister) ListPods(selector labels.Selector) (pods []api.Pod, e
return pods, nil
}
// minionEnumerator allows a cache.Poller to enumerate items in an api.PodList
type minionEnumerator struct {
*api.MinionList
// nodeEnumerator allows a cache.Poller to enumerate items in an api.NodeList
type nodeEnumerator struct {
*api.NodeList
}
// Len returns the number of items in the pod list.
func (me *minionEnumerator) Len() int {
if me.MinionList == nil {
// Len returns the number of items in the node list.
func (ne *nodeEnumerator) Len() int {
if ne.NodeList == nil {
return 0
}
return len(me.Items)
return len(ne.Items)
}
// Get returns the item (and ID) with the particular index.
func (me *minionEnumerator) Get(index int) (string, interface{}) {
return me.Items[index].Name, &me.Items[index]
func (ne *nodeEnumerator) Get(index int) (string, interface{}) {
return ne.Items[index].Name, &ne.Items[index]
}
type binder struct {

View File

@@ -145,10 +145,10 @@ func TestCreateWatches(t *testing.T) {
func TestPollMinions(t *testing.T) {
table := []struct {
minions []api.Minion
minions []api.Node
}{
{
minions: []api.Minion{
minions: []api.Node{
{ObjectMeta: api.ObjectMeta{Name: "foo"}},
{ObjectMeta: api.ObjectMeta{Name: "bar"}},
},
@@ -156,7 +156,7 @@ func TestPollMinions(t *testing.T) {
}
for _, item := range table {
ml := &api.MinionList{Items: item.minions}
ml := &api.NodeList{Items: item.minions}
handler := util.FakeHandler{
StatusCode: 200,
ResponseBody: runtime.EncodeOrDie(latest.Codec, ml),
@@ -225,9 +225,9 @@ func TestStoreToMinionLister(t *testing.T) {
store := cache.NewStore()
ids := util.NewStringSet("foo", "bar", "baz")
for id := range ids {
store.Add(id, &api.Minion{ObjectMeta: api.ObjectMeta{Name: id}})
store.Add(id, &api.Node{ObjectMeta: api.ObjectMeta{Name: id}})
}
sml := storeToMinionLister{store}
sml := storeToNodeLister{store}
gotNodes, err := sml.List()
if err != nil {
@@ -273,14 +273,14 @@ func TestStoreToPodLister(t *testing.T) {
}
func TestMinionEnumerator(t *testing.T) {
testList := &api.MinionList{
Items: []api.Minion{
testList := &api.NodeList{
Items: []api.Node{
{ObjectMeta: api.ObjectMeta{Name: "foo"}},
{ObjectMeta: api.ObjectMeta{Name: "bar"}},
{ObjectMeta: api.ObjectMeta{Name: "baz"}},
},
}
me := minionEnumerator{testList}
me := nodeEnumerator{testList}
if e, a := 3, me.Len(); e != a {
t.Fatalf("expected %v, got %v", e, a)

View File

@@ -88,7 +88,7 @@ func TestScheduler(t *testing.T) {
var gotBinding *api.Binding
c := &Config{
MinionLister: scheduler.FakeMinionLister(
api.MinionList{Items: []api.Minion{{ObjectMeta: api.ObjectMeta{Name: "machine1"}}}},
api.NodeList{Items: []api.Node{{ObjectMeta: api.ObjectMeta{Name: "machine1"}}}},
),
Algorithm: item.algo,
Binder: fakeBinder{func(b *api.Binding) error {

View File

@@ -72,7 +72,14 @@ func TestWhoAmI(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -82,9 +89,6 @@ func TestWhoAmI(t *testing.T) {
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
})
s := httptest.NewServer(m.Handler)
defer s.Close()
// TODO: also test TLS, using e.g NewUnsafeTLSTransport() and NewClientCertTLSTransport() (see pkg/client/helper.go)
transport := http.DefaultTransport
@@ -363,7 +367,14 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -372,8 +383,6 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
for _, r := range getTestRequests() {
@@ -408,7 +417,14 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -417,8 +433,6 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
Authorizer: apiserver.NewAlwaysDenyAuthorizer(),
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
for _, r := range getTestRequests() {
@@ -467,7 +481,14 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -477,8 +498,6 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
Authorizer: allowAliceAuthorizer{},
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
for _, r := range getTestRequests() {
@@ -499,6 +518,8 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
}
if _, ok := r.statusCodes[resp.StatusCode]; !ok {
t.Errorf("Expected status one of %v, but got %v", r.statusCodes, resp.StatusCode)
b, _ := ioutil.ReadAll(resp.Body)
t.Errorf("Body: %v", string(b))
}
}()
}
@@ -519,7 +540,14 @@ func TestBobIsForbidden(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -529,8 +557,6 @@ func TestBobIsForbidden(t *testing.T) {
Authorizer: allowAliceAuthorizer{},
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
for _, r := range getTestRequests() {
@@ -573,7 +599,14 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -583,8 +616,6 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
Authorizer: allowAliceAuthorizer{},
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
for _, r := range getTestRequests() {
@@ -645,7 +676,15 @@ func TestNamespaceAuthorization(t *testing.T) {
a := newAuthorizerWithContents(t, `{"namespace": "foo"}
`)
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -655,8 +694,6 @@ func TestNamespaceAuthorization(t *testing.T) {
Authorizer: a,
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
requests := []struct {
@@ -699,6 +736,8 @@ func TestNamespaceAuthorization(t *testing.T) {
}
if _, ok := r.statusCodes[resp.StatusCode]; !ok {
t.Errorf("Expected status one of %v, but got %v", r.statusCodes, resp.StatusCode)
b, _ := ioutil.ReadAll(resp.Body)
t.Errorf("Body: %v", string(b))
}
}()
}
@@ -720,7 +759,15 @@ func TestKindAuthorization(t *testing.T) {
a := newAuthorizerWithContents(t, `{"kind": "services"}
`)
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -730,8 +777,6 @@ func TestKindAuthorization(t *testing.T) {
Authorizer: a,
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
requests := []struct {
@@ -768,6 +813,8 @@ func TestKindAuthorization(t *testing.T) {
}
if _, ok := r.statusCodes[resp.StatusCode]; !ok {
t.Errorf("Expected status one of %v, but got %v", r.statusCodes, resp.StatusCode)
b, _ := ioutil.ReadAll(resp.Body)
t.Errorf("Body: %v", string(b))
}
}
}
@@ -789,7 +836,15 @@ func TestReadOnlyAuthorization(t *testing.T) {
a := newAuthorizerWithContents(t, `{"readonly": true}
`)
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -799,8 +854,6 @@ func TestReadOnlyAuthorization(t *testing.T) {
Authorizer: a,
})
s := httptest.NewServer(m.Handler)
defer s.Close()
transport := http.DefaultTransport
requests := []struct {
@@ -831,6 +884,8 @@ func TestReadOnlyAuthorization(t *testing.T) {
}
if _, ok := r.statusCodes[resp.StatusCode]; !ok {
t.Errorf("Expected status one of %v, but got %v", r.statusCodes, resp.StatusCode)
b, _ := ioutil.ReadAll(resp.Body)
t.Errorf("Body: %v", string(b))
}
}()
}

View File

@@ -19,6 +19,7 @@ limitations under the License.
package integration
import (
"net/http"
"net/http/httptest"
"reflect"
"testing"
@@ -40,7 +41,15 @@ func TestClient(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
m := master.New(&master.Config{
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
m = master.New(&master.Config{
Client: client.NewOrDie(&client.Config{Host: s.URL}),
EtcdHelper: helper,
KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false,
@@ -49,9 +58,6 @@ func TestClient(t *testing.T) {
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
})
s := httptest.NewServer(m.Handler)
defer s.Close()
testCases := []string{
"v1beta1",
"v1beta2",