From 27e6ceed88d2aee09c77b7d37c65cadb5ae01071 Mon Sep 17 00:00:00 2001 From: Anirudh Date: Fri, 4 Aug 2017 15:03:14 -0700 Subject: [PATCH 1/2] Change default update strategy to rolling update --- pkg/apis/apps/v1beta2/defaults.go | 22 +-- pkg/apis/apps/v1beta2/defaults_test.go | 150 ++++++++++++++++++- staging/src/k8s.io/api/apps/v1beta2/types.go | 8 +- 3 files changed, 163 insertions(+), 17 deletions(-) diff --git a/pkg/apis/apps/v1beta2/defaults.go b/pkg/apis/apps/v1beta2/defaults.go index f1046b16ff5..db73c3e73ec 100644 --- a/pkg/apis/apps/v1beta2/defaults.go +++ b/pkg/apis/apps/v1beta2/defaults.go @@ -43,7 +43,7 @@ func SetDefaults_DaemonSet(obj *appsv1beta2.DaemonSet) { } updateStrategy := &obj.Spec.UpdateStrategy if updateStrategy.Type == "" { - updateStrategy.Type = appsv1beta2.OnDeleteDaemonSetStrategyType + updateStrategy.Type = appsv1beta2.RollingUpdateDaemonSetStrategyType } if updateStrategy.Type == appsv1beta2.RollingUpdateDaemonSetStrategyType { if updateStrategy.RollingUpdate == nil { @@ -68,8 +68,19 @@ func SetDefaults_StatefulSet(obj *appsv1beta2.StatefulSet) { } if obj.Spec.UpdateStrategy.Type == "" { - obj.Spec.UpdateStrategy.Type = appsv1beta2.OnDeleteStatefulSetStrategyType + obj.Spec.UpdateStrategy.Type = appsv1beta2.RollingUpdateStatefulSetStrategyType + + // UpdateStrategy.RollingUpdate will take default values below. + obj.Spec.UpdateStrategy.RollingUpdate = &appsv1beta2.RollingUpdateStatefulSetStrategy{} } + + if obj.Spec.UpdateStrategy.Type == appsv1beta2.RollingUpdateStatefulSetStrategyType && + obj.Spec.UpdateStrategy.RollingUpdate != nil && + obj.Spec.UpdateStrategy.RollingUpdate.Partition == nil { + obj.Spec.UpdateStrategy.RollingUpdate.Partition = new(int32) + *obj.Spec.UpdateStrategy.RollingUpdate.Partition = 0 + } + labels := obj.Spec.Template.Labels if labels != nil { if obj.Spec.Selector == nil { @@ -89,13 +100,6 @@ func SetDefaults_StatefulSet(obj *appsv1beta2.StatefulSet) { obj.Spec.RevisionHistoryLimit = new(int32) *obj.Spec.RevisionHistoryLimit = 10 } - if obj.Spec.UpdateStrategy.Type == appsv1beta2.RollingUpdateStatefulSetStrategyType && - obj.Spec.UpdateStrategy.RollingUpdate != nil && - obj.Spec.UpdateStrategy.RollingUpdate.Partition == nil { - obj.Spec.UpdateStrategy.RollingUpdate.Partition = new(int32) - *obj.Spec.UpdateStrategy.RollingUpdate.Partition = 0 - } - } // SetDefaults_Deployment sets additional defaults compared to its counterpart diff --git a/pkg/apis/apps/v1beta2/defaults_test.go b/pkg/apis/apps/v1beta2/defaults_test.go index d017a52688c..3a24c811b73 100644 --- a/pkg/apis/apps/v1beta2/defaults_test.go +++ b/pkg/apis/apps/v1beta2/defaults_test.go @@ -21,7 +21,6 @@ import ( "testing" appsv1beta2 "k8s.io/api/apps/v1beta2" - "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/resource" @@ -36,6 +35,7 @@ import ( func TestSetDefaultDaemonSetSpec(t *testing.T) { defaultLabels := map[string]string{"foo": "bar"} + maxUnavailable := intstr.FromInt(1) period := int64(v1.DefaultTerminationGracePeriodSeconds) defaultTemplate := v1.PodTemplateSpec{ Spec: v1.PodSpec{ @@ -78,7 +78,10 @@ func TestSetDefaultDaemonSetSpec(t *testing.T) { }, Template: defaultTemplate, UpdateStrategy: appsv1beta2.DaemonSetUpdateStrategy{ - Type: appsv1beta2.OnDeleteDaemonSetStrategyType, + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateDaemonSet{ + MaxUnavailable: &maxUnavailable, + }, }, RevisionHistoryLimit: newInt32(10), }, @@ -108,14 +111,24 @@ func TestSetDefaultDaemonSetSpec(t *testing.T) { }, Template: defaultTemplate, UpdateStrategy: appsv1beta2.DaemonSetUpdateStrategy{ - Type: appsv1beta2.OnDeleteDaemonSetStrategyType, + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateDaemonSet{ + MaxUnavailable: &maxUnavailable, + }, }, RevisionHistoryLimit: newInt32(1), }, }, }, - { // Update strategy. - original: &appsv1beta2.DaemonSet{}, + { // OnDeleteDaemonSetStrategyType update strategy. + original: &appsv1beta2.DaemonSet{ + Spec: appsv1beta2.DaemonSetSpec{ + Template: templateNoLabel, + UpdateStrategy: appsv1beta2.DaemonSetUpdateStrategy{ + Type: appsv1beta2.OnDeleteDaemonSetStrategyType, + }, + }, + }, expected: &appsv1beta2.DaemonSet{ Spec: appsv1beta2.DaemonSetSpec{ Template: templateNoLabel, @@ -134,7 +147,10 @@ func TestSetDefaultDaemonSetSpec(t *testing.T) { Spec: appsv1beta2.DaemonSetSpec{ Template: templateNoLabel, UpdateStrategy: appsv1beta2.DaemonSetUpdateStrategy{ - Type: appsv1beta2.OnDeleteDaemonSetStrategyType, + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateDaemonSet{ + MaxUnavailable: &maxUnavailable, + }, }, RevisionHistoryLimit: newInt32(10), }, @@ -157,6 +173,128 @@ func TestSetDefaultDaemonSetSpec(t *testing.T) { } } +func TestSetDefaultStatefulSet(t *testing.T) { + defaultLabels := map[string]string{"foo": "bar"} + var defaultPartition int32 = 0 + var defaultReplicas int32 = 1 + + period := int64(v1.DefaultTerminationGracePeriodSeconds) + defaultTemplate := v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + DNSPolicy: v1.DNSClusterFirst, + RestartPolicy: v1.RestartPolicyAlways, + SecurityContext: &v1.PodSecurityContext{}, + TerminationGracePeriodSeconds: &period, + SchedulerName: api.DefaultSchedulerName, + }, + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + } + + tests := []struct { + original *appsv1beta2.StatefulSet + expected *appsv1beta2.StatefulSet + }{ + { // Selector, labels and default update strategy + original: &appsv1beta2.StatefulSet{ + Spec: appsv1beta2.StatefulSetSpec{ + Template: defaultTemplate, + }, + }, + expected: &appsv1beta2.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1beta2.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: defaultLabels, + }, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, + UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateStatefulSetStrategy{ + Partition: &defaultPartition, + }, + }, + RevisionHistoryLimit: newInt32(10), + }, + }, + }, + { // Alternate update strategy + original: &appsv1beta2.StatefulSet{ + Spec: appsv1beta2.StatefulSetSpec{ + Template: defaultTemplate, + UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ + Type: appsv1beta2.OnDeleteStatefulSetStrategyType, + }, + }, + }, + expected: &appsv1beta2.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1beta2.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: defaultLabels, + }, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PodManagementPolicy: appsv1beta2.OrderedReadyPodManagement, + UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ + Type: appsv1beta2.OnDeleteStatefulSetStrategyType, + }, + RevisionHistoryLimit: newInt32(10), + }, + }, + }, + { // Parallel pod management policy. + original: &appsv1beta2.StatefulSet{ + Spec: appsv1beta2.StatefulSetSpec{ + Template: defaultTemplate, + PodManagementPolicy: appsv1beta2.ParallelPodManagement, + }, + }, + expected: &appsv1beta2.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Labels: defaultLabels, + }, + Spec: appsv1beta2.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: defaultLabels, + }, + Replicas: &defaultReplicas, + Template: defaultTemplate, + PodManagementPolicy: appsv1beta2.ParallelPodManagement, + UpdateStrategy: appsv1beta2.StatefulSetUpdateStrategy{ + Type: appsv1beta2.RollingUpdateStatefulSetStrategyType, + RollingUpdate: &appsv1beta2.RollingUpdateStatefulSetStrategy{ + Partition: &defaultPartition, + }, + }, + RevisionHistoryLimit: newInt32(10), + }, + }, + }, + } + + for i, test := range tests { + original := test.original + expected := test.expected + obj2 := roundTrip(t, runtime.Object(original)) + got, ok := obj2.(*appsv1beta2.StatefulSet) + if !ok { + t.Errorf("(%d) unexpected object: %v", i, got) + t.FailNow() + } + if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) { + t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec) + } + } +} + func TestSetDefaultDeployment(t *testing.T) { defaultIntOrString := intstr.FromString("25%") differentIntOrString := intstr.FromInt(5) diff --git a/staging/src/k8s.io/api/apps/v1beta2/types.go b/staging/src/k8s.io/api/apps/v1beta2/types.go index 84244b46408..f9ab8cc0b7c 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types.go @@ -122,8 +122,11 @@ const ( // necessary to perform the update for the indicated strategy. type StatefulSetUpdateStrategy struct { // Type indicates the type of the StatefulSetUpdateStrategy. + // Default is RollingUpdate. + // +optional Type StatefulSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetStrategyType"` // RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType. + // +optional RollingUpdate *RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty" protobuf:"bytes,2,opt,name=rollingUpdate"` } @@ -151,6 +154,8 @@ const ( type RollingUpdateStatefulSetStrategy struct { // Partition indicates the ordinal at which the StatefulSet should be // partitioned. + // Default value is 0. + // +optional Partition *int32 `json:"partition,omitempty" protobuf:"varint,1,opt,name=partition"` } @@ -504,8 +509,7 @@ type DeploymentList struct { // WIP: This is not ready to be used and we plan to make breaking changes to it. type DaemonSetUpdateStrategy struct { - // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". - // Default is OnDelete. + // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate. // +optional Type DaemonSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"` From 37091c3744fd3631ef207e7887d7edf68e390cee Mon Sep 17 00:00:00 2001 From: Anirudh Date: Tue, 8 Aug 2017 15:17:48 -0700 Subject: [PATCH 2/2] Autogenerated --- api/openapi-spec/swagger.json | 6 +++--- api/swagger-spec/apps_v1beta2.json | 6 +++--- docs/api-reference/apps/v1beta2/definitions.html | 6 +++--- staging/src/k8s.io/api/apps/v1beta2/generated.proto | 8 ++++++-- .../api/apps/v1beta2/types_swagger_doc_generated.go | 6 +++--- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 9684eb25e16..dec73507f49 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -51838,7 +51838,7 @@ "$ref": "#/definitions/io.k8s.api.apps.v1beta2.RollingUpdateDaemonSet" }, "type": { - "description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is OnDelete.", + "description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is RollingUpdate.", "type": "string" } } @@ -52287,7 +52287,7 @@ "description": "WIP: This is not ready to be used and we plan to make breaking changes to it. RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.", "properties": { "partition": { - "description": "Partition indicates the ordinal at which the StatefulSet should be partitioned.", + "description": "Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0.", "type": "integer", "format": "int32" } @@ -52517,7 +52517,7 @@ "$ref": "#/definitions/io.k8s.api.apps.v1beta2.RollingUpdateStatefulSetStrategy" }, "type": { - "description": "Type indicates the type of the StatefulSetUpdateStrategy.", + "description": "Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.", "type": "string" } } diff --git a/api/swagger-spec/apps_v1beta2.json b/api/swagger-spec/apps_v1beta2.json index 0dd7d9ae7e4..5cd57c21291 100644 --- a/api/swagger-spec/apps_v1beta2.json +++ b/api/swagger-spec/apps_v1beta2.json @@ -7046,7 +7046,7 @@ "properties": { "type": { "type": "string", - "description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is OnDelete." + "description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is RollingUpdate." }, "rollingUpdate": { "$ref": "v1beta2.RollingUpdateDaemonSet", @@ -7836,7 +7836,7 @@ "properties": { "type": { "type": "string", - "description": "Type indicates the type of the StatefulSetUpdateStrategy." + "description": "Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate." }, "rollingUpdate": { "$ref": "v1beta2.RollingUpdateStatefulSetStrategy", @@ -7851,7 +7851,7 @@ "partition": { "type": "integer", "format": "int32", - "description": "Partition indicates the ordinal at which the StatefulSet should be partitioned." + "description": "Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0." } } }, diff --git a/docs/api-reference/apps/v1beta2/definitions.html b/docs/api-reference/apps/v1beta2/definitions.html index e358e64569d..1ee4d12e7ff 100755 --- a/docs/api-reference/apps/v1beta2/definitions.html +++ b/docs/api-reference/apps/v1beta2/definitions.html @@ -2191,7 +2191,7 @@ When an object is created, the system will populate this list with the current s

partition

-

Partition indicates the ordinal at which the StatefulSet should be partitioned.

+

Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0.

false

integer (int32)

@@ -7105,7 +7105,7 @@ Examples:

type

-

Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is OnDelete.

+

Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.

false

string

@@ -7335,7 +7335,7 @@ Examples:

type

-

Type indicates the type of the StatefulSetUpdateStrategy.

+

Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.

false

string

diff --git a/staging/src/k8s.io/api/apps/v1beta2/generated.proto b/staging/src/k8s.io/api/apps/v1beta2/generated.proto index 1bc58370a3a..54fb7f56c58 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/generated.proto +++ b/staging/src/k8s.io/api/apps/v1beta2/generated.proto @@ -157,8 +157,7 @@ message DaemonSetStatus { // WIP: This is not ready to be used and we plan to make breaking changes to it. message DaemonSetUpdateStrategy { - // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". - // Default is OnDelete. + // Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate. // +optional optional string type = 1; @@ -521,6 +520,8 @@ message RollingUpdateDeployment { message RollingUpdateStatefulSetStrategy { // Partition indicates the ordinal at which the StatefulSet should be // partitioned. + // Default value is 0. + // +optional optional int32 partition = 1; } @@ -698,9 +699,12 @@ message StatefulSetStatus { // necessary to perform the update for the indicated strategy. message StatefulSetUpdateStrategy { // Type indicates the type of the StatefulSetUpdateStrategy. + // Default is RollingUpdate. + // +optional optional string type = 1; // RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType. + // +optional optional RollingUpdateStatefulSetStrategy rollingUpdate = 2; } diff --git a/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go index c6f97f6c719..2f65eee83ad 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go @@ -81,7 +81,7 @@ func (DaemonSetStatus) SwaggerDoc() map[string]string { var map_DaemonSetUpdateStrategy = map[string]string{ "": "WIP: This is not ready to be used and we plan to make breaking changes to it.", - "type": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is OnDelete.", + "type": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is RollingUpdate.", "rollingUpdate": "Rolling update config params. Present only if type = \"RollingUpdate\".", } @@ -268,7 +268,7 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { var map_RollingUpdateStatefulSetStrategy = map[string]string{ "": "WIP: This is not ready to be used and we plan to make breaking changes to it. RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.", - "partition": "Partition indicates the ordinal at which the StatefulSet should be partitioned.", + "partition": "Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0.", } func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { @@ -357,7 +357,7 @@ func (StatefulSetStatus) SwaggerDoc() map[string]string { var map_StatefulSetUpdateStrategy = map[string]string{ "": "WIP: This is not ready to be used and we plan to make breaking changes to it. StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.", - "type": "Type indicates the type of the StatefulSetUpdateStrategy.", + "type": "Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate.", "rollingUpdate": "RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.", }