From cf0b41535fed9128645c124fdf45fa0ae8419367 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Thu, 11 Dec 2014 21:39:56 -0800 Subject: [PATCH] Make it easier to update nodes, make it possible to update capacity. --- pkg/api/types.go | 2 + pkg/api/validation/validation.go | 13 +++++- pkg/api/validation/validation_test.go | 58 +++++++++++++++++++++++++++ pkg/registry/minion/rest.go | 7 ++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/pkg/api/types.go b/pkg/api/types.go index abd6578996b..b7bfd6adca1 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -129,6 +129,8 @@ const ( NamespaceDefault string = "default" // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces NamespaceAll string = "" + // NamespaceNone is the argument for a context when there is no namespace. + NamespaceNone string = "" // TerminationMessagePathDefault means the default path to capture the application termination message running in a container TerminationMessagePathDefault string = "/dev/termination-log" ) diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index eac28edda49..c06b8f2f15e 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -26,6 +26,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + "github.com/golang/glog" ) // ServiceLister is an abstract interface for testing. @@ -565,9 +567,18 @@ func ValidateMinion(minion *api.Node) errs.ValidationErrorList { // ValidateMinionUpdate tests to make sure a minion update can be applied. Modifies oldMinion. func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} + + if !reflect.DeepEqual(minion.Status, api.NodeStatus{}) { + allErrs = append(allErrs, errs.NewFieldInvalid("status", minion.Status, "status must be empty")) + } + + // Allow users to update labels and capacity oldMinion.Labels = minion.Labels + oldMinion.Spec.Capacity = minion.Spec.Capacity + if !reflect.DeepEqual(oldMinion, minion) { - allErrs = append(allErrs, fmt.Errorf("update contains more than labels changes")) + glog.V(4).Infof("Update failed validation %#v vs %#v", oldMinion, minion) + allErrs = append(allErrs, fmt.Errorf("update contains more than labels or capacity changes")) } return allErrs } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index ef323a0c467..2ea06f058ec 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -1178,6 +1178,64 @@ func TestValidateMinionUpdate(t *testing.T) { Labels: map[string]string{"foo": "baz"}, }, }, true}, + {api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + }, + Spec: api.NodeSpec{ + Capacity: api.ResourceList{ + "cpu": util.NewIntOrStringFromInt(10000), + "memory": util.NewIntOrStringFromInt(100), + }, + }, + }, api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + }, + Spec: api.NodeSpec{ + Capacity: api.ResourceList{ + "cpu": util.NewIntOrStringFromInt(100), + "memory": util.NewIntOrStringFromInt(10000), + }, + }, + }, true}, + {api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + Spec: api.NodeSpec{ + Capacity: api.ResourceList{ + "cpu": util.NewIntOrStringFromInt(10000), + "memory": util.NewIntOrStringFromInt(100), + }, + }, + }, api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "fooobaz"}, + }, + Spec: api.NodeSpec{ + Capacity: api.ResourceList{ + "cpu": util.NewIntOrStringFromInt(100), + "memory": util.NewIntOrStringFromInt(10000), + }, + }, + }, true}, + {api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + }, api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "fooobaz"}, + }, + Status: api.NodeStatus{ + HostIP: "1.2.3.4", + }, + }, false}, } for _, test := range tests { errs := ValidateMinionUpdate(&test.oldMinion, &test.minion) diff --git a/pkg/registry/minion/rest.go b/pkg/registry/minion/rest.go index 3a2e52901f6..3e76caf708b 100644 --- a/pkg/registry/minion/rest.go +++ b/pkg/registry/minion/rest.go @@ -101,6 +101,13 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !ok { return nil, fmt.Errorf("not a minion: %#v", obj) } + // This is hacky, but minions don't really have a namespace, but kubectl currently automatically + // stuffs one in there. Fix it here temporarily until we fix kubectl + if minion.Namespace == api.NamespaceDefault { + minion.Namespace = api.NamespaceNone + } + // Clear out the self link, if specified, since it's not in the registry either. + minion.SelfLink = "" // TODO: GetMinion will health check the minion, but we shouldn't require the minion to be // running for updating labels.