Move Capacity from NodeSpec to NodeStatus

This commit is contained in:
gmarek
2015-03-25 14:44:40 +01:00
parent 8183a4805e
commit 5a11748018
20 changed files with 136 additions and 115 deletions

View File

@@ -951,9 +951,6 @@ type EndpointsList struct {
// NodeSpec describes the attributes that a node is created with.
type NodeSpec struct {
// Capacity represents the available resources of a node.
Capacity ResourceList `json:"capacity,omitempty"`
// PodCIDR represents the pod IP range assigned to the node
// Note: assigning IP ranges to nodes might need to be revisited when we support migratable IPs.
PodCIDR string `json:"podCIDR,omitempty"`
@@ -977,6 +974,8 @@ type NodeSystemInfo struct {
// NodeStatus is information about the current status of a node.
type NodeStatus struct {
// Capacity represents the available resources of a node.
Capacity ResourceList `json:"capacity,omitempty"`
// NodePhase is the current lifecycle phase of the node.
Phase NodePhase `json:"phase,omitempty"`
// Conditions is an array of current node conditions.

View File

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

View File

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

View File

@@ -952,9 +952,6 @@ type EndpointsList struct {
// NodeSpec describes the attributes that a node is created with.
type NodeSpec struct {
// Capacity represents the available resources of a node.
// see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md for more details.
Capacity ResourceList `json:"capacity,omitempty" description:"compute resource capacity of the node; https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md"`
// PodCIDR represents the pod IP range assigned to the node
PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"`
// External ID of the node assigned by some machine database (e.g. a cloud provider)
@@ -975,6 +972,9 @@ type NodeSystemInfo struct {
// NodeStatus is information about the current status of a node.
type NodeStatus struct {
// Capacity represents the available resources of a node.
// see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md for more details.
Capacity ResourceList `json:"capacity,omitempty" description:"compute resource capacity of the node; https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md"`
// NodePhase is the current lifecycle phase of the node.
Phase NodePhase `json:"phase,omitempty" description:"most recently observed lifecycle phase of the node"`
// Conditions is an array of current node conditions.

View File

@@ -910,18 +910,18 @@ func ValidateMinion(node *api.Node) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
allErrs = append(allErrs, ValidateObjectMeta(&node.ObjectMeta, false, ValidateNodeName).Prefix("metadata")...)
// Capacity is required. Within capacity, memory and cpu resources are required.
if len(node.Spec.Capacity) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("spec.Capacity"))
if len(node.Status.Capacity) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity"))
} else {
if val, ok := node.Spec.Capacity[api.ResourceMemory]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("spec.Capacity[memory]"))
if val, ok := node.Status.Capacity[api.ResourceMemory]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity[memory]"))
} else if val.Value() < 0 {
allErrs = append(allErrs, errs.NewFieldInvalid("spec.Capacity[memory]", val, "memory capacity cannot be negative"))
allErrs = append(allErrs, errs.NewFieldInvalid("status.Capacity[memory]", val, "memory capacity cannot be negative"))
}
if val, ok := node.Spec.Capacity[api.ResourceCPU]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("spec.Capacity[cpu]"))
if val, ok := node.Status.Capacity[api.ResourceCPU]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity[cpu]"))
} else if val.Value() < 0 {
allErrs = append(allErrs, errs.NewFieldInvalid("spec.Capacity[cpu]", val, "cpu capacity cannot be negative"))
allErrs = append(allErrs, errs.NewFieldInvalid("status.Capacity[cpu]", val, "cpu capacity cannot be negative"))
}
}
@@ -949,7 +949,7 @@ func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.Validation
// Ignore metadata changes now that they have been tested
oldMinion.ObjectMeta = minion.ObjectMeta
// Allow users to update capacity
oldMinion.Spec.Capacity = minion.Spec.Capacity
oldMinion.Status.Capacity = minion.Status.Capacity
// Allow users to unschedule node
oldMinion.Spec.Unschedulable = minion.Spec.Unschedulable
// Clear status

View File

@@ -1822,15 +1822,15 @@ func TestValidateMinion(t *testing.T) {
Addresses: []api.NodeAddress{
{Type: api.NodeLegacyHostIP, Address: "something"},
},
},
Spec: api.NodeSpec{
ExternalID: "external",
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
api.ResourceName("my.org/gpu"): resource.MustParse("10"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
{
ObjectMeta: api.ObjectMeta{
@@ -1840,14 +1840,14 @@ func TestValidateMinion(t *testing.T) {
Addresses: []api.NodeAddress{
{Type: api.NodeLegacyHostIP, Address: "something"},
},
},
Spec: api.NodeSpec{
ExternalID: "external",
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("0"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
}
for _, successCase := range successCases {
@@ -1864,34 +1864,36 @@ func TestValidateMinion(t *testing.T) {
},
Status: api.NodeStatus{
Addresses: []api.NodeAddress{},
},
Spec: api.NodeSpec{
ExternalID: "external",
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"invalid-labels": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: invalidSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"missing-external-id": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
@@ -1912,50 +1914,58 @@ func TestValidateMinion(t *testing.T) {
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"missing-cpu": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"invalid-memory": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("-10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"invalid-cpu": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("-10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
}
for k, v := range errorCases {
@@ -1966,14 +1976,14 @@ func TestValidateMinion(t *testing.T) {
for i := range errs {
field := errs[i].(*errors.ValidationError).Field
expectedFields := map[string]bool{
"metadata.name": true,
"metadata.labels": true,
"metadata.annotations": true,
"metadata.namespace": true,
"spec.Capacity": true,
"spec.Capacity[memory]": true,
"spec.Capacity[cpu]": true,
"spec.ExternalID": true,
"metadata.name": true,
"metadata.labels": true,
"metadata.annotations": true,
"metadata.namespace": true,
"status.Capacity": true,
"status.Capacity[memory]": true,
"status.Capacity[cpu]": true,
"spec.ExternalID": true,
}
if expectedFields[field] == false {
t.Errorf("%s: missing prefix for: %v", k, errs[i])
@@ -2032,7 +2042,7 @@ func TestValidateMinionUpdate(t *testing.T) {
ObjectMeta: api.ObjectMeta{
Name: "foo",
},
Spec: api.NodeSpec{
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceCPU: resource.MustParse("10000"),
api.ResourceMemory: resource.MustParse("100"),
@@ -2042,7 +2052,7 @@ func TestValidateMinionUpdate(t *testing.T) {
ObjectMeta: api.ObjectMeta{
Name: "foo",
},
Spec: api.NodeSpec{
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceCPU: resource.MustParse("100"),
api.ResourceMemory: resource.MustParse("10000"),
@@ -2054,7 +2064,7 @@ func TestValidateMinionUpdate(t *testing.T) {
Name: "foo",
Labels: map[string]string{"bar": "foo"},
},
Spec: api.NodeSpec{
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceCPU: resource.MustParse("10000"),
api.ResourceMemory: resource.MustParse("100"),
@@ -2065,7 +2075,7 @@ func TestValidateMinionUpdate(t *testing.T) {
Name: "foo",
Labels: map[string]string{"bar": "fooobaz"},
},
Spec: api.NodeSpec{
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceCPU: resource.MustParse("100"),
api.ResourceMemory: resource.MustParse("10000"),