diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 4433d7addb..055822d27c 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 2ae7e3bc35..1327712c66 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 864f2b1177..860af4090d 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 8dd49b4665..8ac06701da 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 3138696a51..4bb885567b 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 fa9b1b6166..79785a58df 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 734def2689..7f2ed0d601 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 4cd4c0ab2d..79389a01cd 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 42640c46a9..acdb472746 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 1a9b7ebb19..18652ba19a 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 38e112d1e0..9384b16fbc 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 a4b8ca6725..c535e96368 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\".",