mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-11 04:52:08 +00:00
Added field CollisionCount to StatefulSetStatus
This commit is contained in:
parent
5ce3b359f1
commit
68983201bf
@ -187,6 +187,12 @@ type StatefulSetStatus struct {
|
|||||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||||
// [replicas-updatedReplicas,replicas)
|
// [replicas-updatedReplicas,replicas)
|
||||||
UpdateRevision string
|
UpdateRevision string
|
||||||
|
|
||||||
|
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
|
||||||
|
// uses this field as a collision avoidance mechanism when it needs to create the name for the
|
||||||
|
// newest ControllerRevision.
|
||||||
|
// +optional
|
||||||
|
CollisionCount *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
@ -163,9 +163,39 @@ func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet *apps.StatefulSet) fi
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidateStatefulSetStatus validates a StatefulSetStatus.
|
||||||
|
func ValidateStatefulSetStatus(status *apps.StatefulSetStatus, fieldPath *field.Path) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fieldPath.Child("replicas"))...)
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ReadyReplicas), fieldPath.Child("readyReplicas"))...)
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.CurrentReplicas), fieldPath.Child("currentReplicas"))...)
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedReplicas), fieldPath.Child("updatedReplicas"))...)
|
||||||
|
if status.ObservedGeneration != nil {
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.ObservedGeneration), fieldPath.Child("observedGeneration"))...)
|
||||||
|
}
|
||||||
|
if status.CollisionCount != nil {
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.CollisionCount), fieldPath.Child("collisionCount"))...)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := "cannot be greater than status.replicas"
|
||||||
|
if status.ReadyReplicas > status.Replicas {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fieldPath.Child("readyReplicas"), status.ReadyReplicas, msg))
|
||||||
|
}
|
||||||
|
if status.CurrentReplicas > status.Replicas {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fieldPath.Child("currentReplicas"), status.CurrentReplicas, msg))
|
||||||
|
}
|
||||||
|
if status.UpdatedReplicas > status.Replicas {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fieldPath.Child("updatedReplicas"), status.UpdatedReplicas, msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
// ValidateStatefulSetStatusUpdate tests if required fields in the StatefulSet are set.
|
// ValidateStatefulSetStatusUpdate tests if required fields in the StatefulSet are set.
|
||||||
func ValidateStatefulSetStatusUpdate(statefulSet, oldStatefulSet *apps.StatefulSet) field.ErrorList {
|
func ValidateStatefulSetStatusUpdate(statefulSet, oldStatefulSet *apps.StatefulSet) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
allErrs = append(allErrs, ValidateStatefulSetStatus(&statefulSet.Status, field.NewPath("status"))...)
|
||||||
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&statefulSet.ObjectMeta, &oldStatefulSet.ObjectMeta, field.NewPath("metadata"))...)
|
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&statefulSet.ObjectMeta, &oldStatefulSet.ObjectMeta, field.NewPath("metadata"))...)
|
||||||
// TODO: Validate status.
|
// TODO: Validate status.
|
||||||
return allErrs
|
return allErrs
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/apis/apps"
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
)
|
)
|
||||||
@ -300,6 +301,119 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateStatefulSetStatus(t *testing.T) {
|
||||||
|
minusOne := int64(-1)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
replicas int32
|
||||||
|
readyReplicas int32
|
||||||
|
currentReplicas int32
|
||||||
|
updatedReplicas int32
|
||||||
|
observedGeneration *int64
|
||||||
|
collisionCount *int64
|
||||||
|
expectedErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid status",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid replicas",
|
||||||
|
replicas: -1,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid readyReplicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: -1,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid currentReplicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: -1,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid updatedReplicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: -1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid observedGeneration",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
observedGeneration: &minusOne,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid collisionCount",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
collisionCount: &minusOne,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "readyReplicas greater than replicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 4,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "currentReplicas greater than replicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 4,
|
||||||
|
updatedReplicas: 1,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "updatedReplicas greater than replicas",
|
||||||
|
replicas: 3,
|
||||||
|
readyReplicas: 3,
|
||||||
|
currentReplicas: 2,
|
||||||
|
updatedReplicas: 4,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
status := apps.StatefulSetStatus{
|
||||||
|
Replicas: test.replicas,
|
||||||
|
ReadyReplicas: test.readyReplicas,
|
||||||
|
CurrentReplicas: test.currentReplicas,
|
||||||
|
UpdatedReplicas: test.updatedReplicas,
|
||||||
|
ObservedGeneration: test.observedGeneration,
|
||||||
|
CollisionCount: test.collisionCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := ValidateStatefulSetStatus(&status, field.NewPath("status"))
|
||||||
|
if hasErr := len(errs) > 0; hasErr != test.expectedErr {
|
||||||
|
t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errs.ToAggregate().Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateStatefulSetUpdate(t *testing.T) {
|
func TestValidateStatefulSetUpdate(t *testing.T) {
|
||||||
validLabels := map[string]string{"a": "b"}
|
validLabels := map[string]string{"a": "b"}
|
||||||
validPodTemplate := api.PodTemplate{
|
validPodTemplate := api.PodTemplate{
|
||||||
|
@ -239,6 +239,12 @@ type StatefulSetStatus struct {
|
|||||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||||
// [replicas-updatedReplicas,replicas)
|
// [replicas-updatedReplicas,replicas)
|
||||||
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
||||||
|
|
||||||
|
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
|
||||||
|
// uses this field as a collision avoidance mechanism when it needs to create the name for the
|
||||||
|
// newest ControllerRevision.
|
||||||
|
// +optional
|
||||||
|
CollisionCount *int64 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
@ -246,6 +246,12 @@ type StatefulSetStatus struct {
|
|||||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||||
// [replicas-updatedReplicas,replicas)
|
// [replicas-updatedReplicas,replicas)
|
||||||
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
||||||
|
|
||||||
|
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
|
||||||
|
// uses this field as a collision avoidance mechanism when it needs to create the name for the
|
||||||
|
// newest ControllerRevision.
|
||||||
|
// +optional
|
||||||
|
CollisionCount *int64 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
Loading…
Reference in New Issue
Block a user