diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 4433d7addbc..055822d27c3 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -87324,7 +87324,7 @@ "format": "int32" }, "revisionHistoryLimit": { - "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.", + "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. This is set to the max value of int32 (i.e. 2147483647) by default, which means \"retaining all old RelicaSets\".", "type": "integer", "format": "int32" }, diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index 2ae7e3bc358..1327712c664 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -10082,7 +10082,7 @@ "revisionHistoryLimit": { "type": "integer", "format": "int32", - "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified." + "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. This is set to the max value of int32 (i.e. 2147483647) by default, which means \"retaining all old RelicaSets\"." }, "paused": { "type": "boolean", diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 864f2b1177c..860af4090db 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -4316,7 +4316,7 @@ When an object is created, the system will populate this list with the current s

revisionHistoryLimit

-

The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.

+

The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. This is set to the max value of int32 (i.e. 2147483647) by default, which means "retaining all old RelicaSets".

false

integer (int32)

diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index 8dd49b46654..8ac06701daa 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -110,6 +110,8 @@ type DeploymentSpec struct { // The number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. + // This is set to the max value of int32 (i.e. 2147483647) by default, which means + // "retaining all old ReplicaSets". // +optional RevisionHistoryLimit *int32 diff --git a/pkg/apis/extensions/v1beta1/defaults.go b/pkg/apis/extensions/v1beta1/defaults.go index 3138696a518..4bb885567b7 100644 --- a/pkg/apis/extensions/v1beta1/defaults.go +++ b/pkg/apis/extensions/v1beta1/defaults.go @@ -118,6 +118,12 @@ func SetDefaults_Deployment(obj *extensionsv1beta1.Deployment) { obj.Spec.ProgressDeadlineSeconds = new(int32) *obj.Spec.ProgressDeadlineSeconds = math.MaxInt32 } + // Set extensionsv1beta1.DeploymentSpec.RevisionHistoryLimit to MaxInt32, + // which has the same meaning as unset. + if obj.Spec.RevisionHistoryLimit == nil { + obj.Spec.RevisionHistoryLimit = new(int32) + *obj.Spec.RevisionHistoryLimit = math.MaxInt32 + } } func SetDefaults_ReplicaSet(obj *extensionsv1beta1.ReplicaSet) { diff --git a/pkg/apis/extensions/v1beta1/defaults_test.go b/pkg/apis/extensions/v1beta1/defaults_test.go index fa9b1b6166e..79785a58dfa 100644 --- a/pkg/apis/extensions/v1beta1/defaults_test.go +++ b/pkg/apis/extensions/v1beta1/defaults_test.go @@ -196,6 +196,7 @@ func TestSetDefaultDeployment(t *testing.T) { }, Template: defaultTemplate, ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32), + RevisionHistoryLimit: utilpointer.Int32Ptr(math.MaxInt32), }, }, }, @@ -222,6 +223,7 @@ func TestSetDefaultDeployment(t *testing.T) { }, Template: defaultTemplate, ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32), + RevisionHistoryLimit: utilpointer.Int32Ptr(math.MaxInt32), }, }, }, @@ -247,6 +249,7 @@ func TestSetDefaultDeployment(t *testing.T) { }, Template: defaultTemplate, ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32), + RevisionHistoryLimit: utilpointer.Int32Ptr(math.MaxInt32), }, }, }, @@ -267,6 +270,7 @@ func TestSetDefaultDeployment(t *testing.T) { }, Template: defaultTemplate, ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32), + RevisionHistoryLimit: utilpointer.Int32Ptr(math.MaxInt32), }, }, }, @@ -288,6 +292,7 @@ func TestSetDefaultDeployment(t *testing.T) { }, Template: defaultTemplate, ProgressDeadlineSeconds: utilpointer.Int32Ptr(30), + RevisionHistoryLimit: utilpointer.Int32Ptr(math.MaxInt32), }, }, }, diff --git a/pkg/controller/deployment/sync.go b/pkg/controller/deployment/sync.go index 734def26894..7f2ed0d6016 100644 --- a/pkg/controller/deployment/sync.go +++ b/pkg/controller/deployment/sync.go @@ -424,7 +424,7 @@ func (dc *DeploymentController) scaleReplicaSet(rs *apps.ReplicaSet, newScale in // where N=d.Spec.RevisionHistoryLimit. Old replica sets are older versions of the podtemplate of a deployment kept // around by default 1) for historical reasons and 2) for the ability to rollback a deployment. func (dc *DeploymentController) cleanupDeployment(oldRSs []*apps.ReplicaSet, deployment *apps.Deployment) error { - if deployment.Spec.RevisionHistoryLimit == nil { + if !deploymentutil.HasRevisionHistoryLimit(deployment) { return nil } diff --git a/pkg/controller/deployment/sync_test.go b/pkg/controller/deployment/sync_test.go index 4cd4c0ab2d9..79389a01cd3 100644 --- a/pkg/controller/deployment/sync_test.go +++ b/pkg/controller/deployment/sync_test.go @@ -17,6 +17,7 @@ limitations under the License. package deployment import ( + "math" "testing" "time" @@ -393,6 +394,16 @@ func TestDeploymentController_cleanupDeployment(t *testing.T) { revisionHistoryLimit: 0, expectedDeletions: 0, }, + { + // with unlimited revisionHistoryLimit + oldRSs: []*apps.ReplicaSet{ + newRSWithStatus("foo-1", 0, 0, selector), + newRSWithStatus("foo-2", 0, 0, selector), + newRSWithStatus("foo-3", 0, 0, selector), + }, + revisionHistoryLimit: math.MaxInt32, + expectedDeletions: 0, + }, } for i := range tests { @@ -418,6 +429,7 @@ func TestDeploymentController_cleanupDeployment(t *testing.T) { defer close(stopCh) informers.Start(stopCh) + t.Logf(" &test.revisionHistoryLimit: %d", test.revisionHistoryLimit) d := newDeployment("foo", 1, &test.revisionHistoryLimit, nil, nil, map[string]string{"foo": "bar"}) controller.cleanupDeployment(test.oldRSs, d) diff --git a/pkg/controller/deployment/util/deployment_util.go b/pkg/controller/deployment/util/deployment_util.go index 42640c46a9f..acdb472746d 100644 --- a/pkg/controller/deployment/util/deployment_util.go +++ b/pkg/controller/deployment/util/deployment_util.go @@ -886,3 +886,6 @@ func ResolveFenceposts(maxSurge, maxUnavailable *intstrutil.IntOrString, desired func HasProgressDeadline(d *apps.Deployment) bool { return d.Spec.ProgressDeadlineSeconds != nil && *d.Spec.ProgressDeadlineSeconds != math.MaxInt32 } +func HasRevisionHistoryLimit(d *apps.Deployment) bool { + return d.Spec.RevisionHistoryLimit != nil && *d.Spec.RevisionHistoryLimit != math.MaxInt32 +} diff --git a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto index 1a9b7ebb194..18652ba19a0 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto @@ -335,6 +335,8 @@ message DeploymentSpec { // The number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. + // This is set to the max value of int32 (i.e. 2147483647) by default, which + // means "retaining all old RelicaSets". // +optional optional int32 revisionHistoryLimit = 6; diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types.go b/staging/src/k8s.io/api/extensions/v1beta1/types.go index 38e112d1e0e..9384b16fbca 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types.go @@ -151,6 +151,8 @@ type DeploymentSpec struct { // The number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. + // This is set to the max value of int32 (i.e. 2147483647) by default, which + // means "retaining all old RelicaSets". // +optional RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,6,opt,name=revisionHistoryLimit"` diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index a4b8ca67251..c535e96368d 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -193,7 +193,7 @@ var map_DeploymentSpec = map[string]string{ "template": "Template describes the pods that will be created.", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", - "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.", + "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. This is set to the max value of int32 (i.e. 2147483647) by default, which means \"retaining all old RelicaSets\".", "paused": "Indicates that the deployment is paused and will not be processed by the deployment controller.", "rollbackTo": "DEPRECATED. The config this deployment is rolling back to. Will be cleared after rollback is done.", "progressDeadlineSeconds": "The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. This is set to the max value of int32 (i.e. 2147483647) by default, which means \"no deadline\".",