From 418d79cb78c1c02f1a73bc133bd8d78d0b918957 Mon Sep 17 00:00:00 2001 From: kargakis Date: Tue, 23 Feb 2016 15:23:14 +0100 Subject: [PATCH 1/4] extensions: add observedGeneration for deployments --- pkg/apis/extensions/types.go | 3 +++ pkg/apis/extensions/v1beta1/types.go | 3 +++ pkg/apis/extensions/validation/validation.go | 17 +++++++++++++++++ .../deployment/deployment_controller.go | 10 ++++++---- pkg/registry/deployment/strategy.go | 12 +++++++++++- test/e2e/deployment.go | 8 ++++++++ test/e2e/util.go | 10 ++++++++++ 7 files changed, 58 insertions(+), 5 deletions(-) diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index 4bfbef8d0fc..b061a333a9b 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -332,6 +332,9 @@ type RollingUpdateDeployment struct { } type DeploymentStatus struct { + // The generation observed by the deployment controller. + ObservedGeneration int `json:"observedGeneration,omitempty"` + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). Replicas int `json:"replicas,omitempty"` diff --git a/pkg/apis/extensions/v1beta1/types.go b/pkg/apis/extensions/v1beta1/types.go index 4de157e3c6e..9de6cb1f395 100644 --- a/pkg/apis/extensions/v1beta1/types.go +++ b/pkg/apis/extensions/v1beta1/types.go @@ -328,6 +328,9 @@ type RollingUpdateDeployment struct { // DeploymentStatus is the most recently observed status of the Deployment. type DeploymentStatus struct { + // The generation observed by the deployment controller. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). Replicas int32 `json:"replicas,omitempty"` diff --git a/pkg/apis/extensions/validation/validation.go b/pkg/apis/extensions/validation/validation.go index 8a12486f576..42f317bde75 100644 --- a/pkg/apis/extensions/validation/validation.go +++ b/pkg/apis/extensions/validation/validation.go @@ -329,12 +329,29 @@ func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path return allErrs } +// Validates given deployment status. +func ValidateDeploymentStatus(status *extensions.DeploymentStatus, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ObservedGeneration), fldPath.Child("observedGeneration"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedReplicas), fldPath.Child("updatedReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UnavailableReplicas), fldPath.Child("unavailableReplicas"))...) + return allErrs +} + func ValidateDeploymentUpdate(update, old *extensions.Deployment) field.ErrorList { allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec, field.NewPath("spec"))...) return allErrs } +func ValidateDeploymentStatusUpdate(update, old *extensions.Deployment) field.ErrorList { + allErrs := apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateDeploymentStatus(&update.Status, field.NewPath("status"))...) + return allErrs +} + func ValidateDeployment(obj *extensions.Deployment) field.ErrorList { allErrs := apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName, field.NewPath("metadata")) allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec, field.NewPath("spec"))...) diff --git a/pkg/controller/deployment/deployment_controller.go b/pkg/controller/deployment/deployment_controller.go index 060dfc8a44f..939e5536b6a 100644 --- a/pkg/controller/deployment/deployment_controller.go +++ b/pkg/controller/deployment/deployment_controller.go @@ -577,13 +577,13 @@ func (dc *DeploymentController) syncRollingUpdateDeployment(deployment extension } // syncDeploymentStatus checks if the status is up-to-date and sync it if necessary -func (dc *DeploymentController) syncDeploymentStatus(allRSs []*extensions.ReplicaSet, newRS *extensions.ReplicaSet, deployment extensions.Deployment) error { - totalReplicas, updatedReplicas, availableReplicas, _, err := dc.calculateStatus(allRSs, newRS, deployment) +func (dc *DeploymentController) syncDeploymentStatus(allRSs []*extensions.ReplicaSet, newRS *extensions.ReplicaSet, d extensions.Deployment) error { + totalReplicas, updatedReplicas, availableReplicas, _, err := dc.calculateStatus(allRSs, newRS, d) if err != nil { return err } - if deployment.Status.Replicas != totalReplicas || deployment.Status.UpdatedReplicas != updatedReplicas || deployment.Status.AvailableReplicas != availableReplicas { - return dc.updateDeploymentStatus(allRSs, newRS, deployment) + if d.Status.Replicas != totalReplicas || d.Status.UpdatedReplicas != updatedReplicas || d.Status.AvailableReplicas != availableReplicas || int(d.Generation) > d.Status.ObservedGeneration { + return dc.updateDeploymentStatus(allRSs, newRS, d) } return nil } @@ -1036,6 +1036,8 @@ func (dc *DeploymentController) updateDeploymentStatus(allRSs []*extensions.Repl newDeployment := deployment // TODO: Reconcile this with API definition. API definition talks about ready pods, while this just computes created pods. newDeployment.Status = extensions.DeploymentStatus{ + // TODO: Ensure that if we start retrying status updates, we won't pick up a new Generation value. + ObservedGeneration: int(deployment.Generation), Replicas: totalReplicas, UpdatedReplicas: updatedReplicas, AvailableReplicas: availableReplicas, diff --git a/pkg/registry/deployment/strategy.go b/pkg/registry/deployment/strategy.go index 0130e92f613..574cc0583a6 100644 --- a/pkg/registry/deployment/strategy.go +++ b/pkg/registry/deployment/strategy.go @@ -18,6 +18,7 @@ package deployment import ( "fmt" + "reflect" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" @@ -48,6 +49,7 @@ func (deploymentStrategy) NamespaceScoped() bool { func (deploymentStrategy) PrepareForCreate(obj runtime.Object) { deployment := obj.(*extensions.Deployment) deployment.Status = extensions.DeploymentStatus{} + deployment.Generation = 1 } // Validate validates a new deployment. @@ -70,6 +72,14 @@ func (deploymentStrategy) PrepareForUpdate(obj, old runtime.Object) { newDeployment := obj.(*extensions.Deployment) oldDeployment := old.(*extensions.Deployment) newDeployment.Status = oldDeployment.Status + + // Spec updates bump the generation so that we can distinguish between + // scaling events and template changes, annotation updates bump the generation + // because annotations are copied from deployments to their replica sets. + if !reflect.DeepEqual(newDeployment.Spec, oldDeployment.Spec) || + !reflect.DeepEqual(newDeployment.Annotations, oldDeployment.Annotations) { + newDeployment.Generation = oldDeployment.Generation + 1 + } } // ValidateUpdate is the default update validation for an end user. @@ -97,7 +107,7 @@ func (deploymentStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { // ValidateUpdate is the default update validation for an end user updating status func (deploymentStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateDeploymentUpdate(obj.(*extensions.Deployment), old.(*extensions.Deployment)) + return validation.ValidateDeploymentStatusUpdate(obj.(*extensions.Deployment), old.(*extensions.Deployment)) } // DeploymentToSelectableFields returns a field set that represents the object. diff --git a/test/e2e/deployment.go b/test/e2e/deployment.go index 342932f4966..44b28e9a637 100644 --- a/test/e2e/deployment.go +++ b/test/e2e/deployment.go @@ -541,6 +541,10 @@ func testPausedDeployment(f *Framework) { }) Expect(err).NotTo(HaveOccurred()) + // Use observedGeneration to determine if the controller noticed the resume. + err = waitForObservedDeployment(c, ns, deploymentName) + Expect(err).NotTo(HaveOccurred()) + selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector) if err != nil { Expect(err).NotTo(HaveOccurred()) @@ -564,6 +568,10 @@ func testPausedDeployment(f *Framework) { }) Expect(err).NotTo(HaveOccurred()) + // Use observedGeneration to determine if the controller noticed the pause. + err = waitForObservedDeployment(c, ns, deploymentName) + Expect(err).NotTo(HaveOccurred()) + newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c) Expect(err).NotTo(HaveOccurred()) Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred()) diff --git a/test/e2e/util.go b/test/e2e/util.go index e422bfb2b99..617433f5df0 100644 --- a/test/e2e/util.go +++ b/test/e2e/util.go @@ -2186,6 +2186,16 @@ func waitForDeploymentOldRSsNum(c *clientset.Clientset, ns, deploymentName strin }) } +func waitForObservedDeployment(c *clientset.Clientset, ns, deploymentName string) error { + return wait.Poll(poll, 1*time.Minute, func() (bool, error) { + deployment, err := c.Extensions().Deployments(ns).Get(deploymentName) + if err != nil { + return false, err + } + return int(deployment.Generation) == deployment.Status.ObservedGeneration, nil + }) +} + func logReplicaSetsOfDeployment(deployment *extensions.Deployment, oldRSs []*extensions.ReplicaSet, newRS *extensions.ReplicaSet) { Logf("Deployment = %+v", deployment) for i := range oldRSs { From 2cb37f3500a8a05e5b016e8e3a6805f1e6877ccc Mon Sep 17 00:00:00 2001 From: kargakis Date: Tue, 23 Feb 2016 19:03:43 +0100 Subject: [PATCH 2/4] update generation api comments --- api/swagger-spec/autoscaling_v1.json | 2 +- api/swagger-spec/batch_v1.json | 2 +- api/swagger-spec/extensions_v1beta1.json | 2 +- api/swagger-spec/v1.json | 2 +- pkg/api/types.go | 2 +- pkg/api/v1/types.go | 4 +--- pkg/api/v1/types_swagger_doc_generated.go | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/api/swagger-spec/autoscaling_v1.json b/api/swagger-spec/autoscaling_v1.json index 094685992b4..ddb9e5064c7 100644 --- a/api/swagger-spec/autoscaling_v1.json +++ b/api/swagger-spec/autoscaling_v1.json @@ -951,7 +951,7 @@ "generation": { "type": "integer", "format": "int64", - "description": "A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only." + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only." }, "creationTimestamp": { "type": "string", diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json index f015b2b41fc..85fda7525e3 100644 --- a/api/swagger-spec/batch_v1.json +++ b/api/swagger-spec/batch_v1.json @@ -951,7 +951,7 @@ "generation": { "type": "integer", "format": "int64", - "description": "A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only." + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only." }, "creationTimestamp": { "type": "string", diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index 1f2d68a42c9..ffe010bb5fa 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -5298,7 +5298,7 @@ "generation": { "type": "integer", "format": "int64", - "description": "A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only." + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only." }, "creationTimestamp": { "type": "string", diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index 71243116188..68b572200d7 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -14633,7 +14633,7 @@ "generation": { "type": "integer", "format": "int64", - "description": "A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only." + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only." }, "creationTimestamp": { "type": "string", diff --git a/pkg/api/types.go b/pkg/api/types.go index 1312ef08691..d632a2090ee 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -98,7 +98,7 @@ type ObjectMeta struct { ResourceVersion string `json:"resourceVersion,omitempty"` // A sequence number representing a specific generation of the desired state. - // Currently only implemented by replication controllers. + // Populated by the system. Read-only. Generation int64 `json:"generation,omitempty"` // CreationTimestamp is a timestamp representing the server time when this object was diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index ad4686ec94b..05e3cefbcb7 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -128,9 +128,7 @@ type ObjectMeta struct { ResourceVersion string `json:"resourceVersion,omitempty"` // A sequence number representing a specific generation of the desired state. - // Currently only implemented by replication controllers. - // Populated by the system. - // Read-only. + // Populated by the system. Read-only. Generation int64 `json:"generation,omitempty"` // CreationTimestamp is a timestamp representing the server time when this object was diff --git a/pkg/api/v1/types_swagger_doc_generated.go b/pkg/api/v1/types_swagger_doc_generated.go index c6106c5df4b..ae9ebaf5ddf 100644 --- a/pkg/api/v1/types_swagger_doc_generated.go +++ b/pkg/api/v1/types_swagger_doc_generated.go @@ -913,7 +913,7 @@ var map_ObjectMeta = map[string]string{ "selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.", "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids", "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", - "generation": "A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only.", + "generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", "creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", "deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource will be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field. Once set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet will send a hard termination signal to the container. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", "deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", From 7a3d40786b4b5c716dc122fc92e1b21d417bda24 Mon Sep 17 00:00:00 2001 From: kargakis Date: Tue, 23 Feb 2016 19:30:14 +0100 Subject: [PATCH 3/4] switch internal field to int64 --- pkg/apis/extensions/types.go | 2 +- pkg/apis/extensions/validation/validation.go | 2 +- pkg/controller/deployment/deployment_controller.go | 4 ++-- test/e2e/util.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index b061a333a9b..6b46cb6074e 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -333,7 +333,7 @@ type RollingUpdateDeployment struct { type DeploymentStatus struct { // The generation observed by the deployment controller. - ObservedGeneration int `json:"observedGeneration,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty"` // Total number of non-terminated pods targeted by this deployment (their labels match the selector). Replicas int `json:"replicas,omitempty"` diff --git a/pkg/apis/extensions/validation/validation.go b/pkg/apis/extensions/validation/validation.go index 42f317bde75..157dc87dacc 100644 --- a/pkg/apis/extensions/validation/validation.go +++ b/pkg/apis/extensions/validation/validation.go @@ -332,7 +332,7 @@ func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path // Validates given deployment status. func ValidateDeploymentStatus(status *extensions.DeploymentStatus, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.ObservedGeneration), fldPath.Child("observedGeneration"))...) + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(status.ObservedGeneration, fldPath.Child("observedGeneration"))...) allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Replicas), fldPath.Child("replicas"))...) allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.UpdatedReplicas), fldPath.Child("updatedReplicas"))...) allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.AvailableReplicas), fldPath.Child("availableReplicas"))...) diff --git a/pkg/controller/deployment/deployment_controller.go b/pkg/controller/deployment/deployment_controller.go index 939e5536b6a..8b6a4205807 100644 --- a/pkg/controller/deployment/deployment_controller.go +++ b/pkg/controller/deployment/deployment_controller.go @@ -582,7 +582,7 @@ func (dc *DeploymentController) syncDeploymentStatus(allRSs []*extensions.Replic if err != nil { return err } - if d.Status.Replicas != totalReplicas || d.Status.UpdatedReplicas != updatedReplicas || d.Status.AvailableReplicas != availableReplicas || int(d.Generation) > d.Status.ObservedGeneration { + if d.Generation > d.Status.ObservedGeneration || d.Status.Replicas != totalReplicas || d.Status.UpdatedReplicas != updatedReplicas || d.Status.AvailableReplicas != availableReplicas { return dc.updateDeploymentStatus(allRSs, newRS, d) } return nil @@ -1037,7 +1037,7 @@ func (dc *DeploymentController) updateDeploymentStatus(allRSs []*extensions.Repl // TODO: Reconcile this with API definition. API definition talks about ready pods, while this just computes created pods. newDeployment.Status = extensions.DeploymentStatus{ // TODO: Ensure that if we start retrying status updates, we won't pick up a new Generation value. - ObservedGeneration: int(deployment.Generation), + ObservedGeneration: deployment.Generation, Replicas: totalReplicas, UpdatedReplicas: updatedReplicas, AvailableReplicas: availableReplicas, diff --git a/test/e2e/util.go b/test/e2e/util.go index 617433f5df0..849ef8bd81d 100644 --- a/test/e2e/util.go +++ b/test/e2e/util.go @@ -2192,7 +2192,7 @@ func waitForObservedDeployment(c *clientset.Clientset, ns, deploymentName string if err != nil { return false, err } - return int(deployment.Generation) == deployment.Status.ObservedGeneration, nil + return deployment.Generation == deployment.Status.ObservedGeneration, nil }) } From 6506d76f76b89211cf32dea87bada2e924713aac Mon Sep 17 00:00:00 2001 From: kargakis Date: Tue, 23 Feb 2016 19:42:35 +0100 Subject: [PATCH 4/4] update-all changes for deployment's observedGeneration --- api/swagger-spec/extensions_v1beta1.json | 5 + .../extensions/v1beta1/definitions.html | 11 +- docs/api-reference/v1/definitions.html | 4 +- pkg/apis/extensions/types.generated.go | 142 ++++++++++++------ .../v1beta1/conversion_generated.go | 2 + .../extensions/v1beta1/deep_copy_generated.go | 1 + .../extensions/v1beta1/types.generated.go | 142 ++++++++++++------ .../v1beta1/types_swagger_doc_generated.go | 1 + 8 files changed, 210 insertions(+), 98 deletions(-) diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index ffe010bb5fa..56eb9eadc36 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -6853,6 +6853,11 @@ "id": "v1beta1.DeploymentStatus", "description": "DeploymentStatus is the most recently observed status of the Deployment.", "properties": { + "observedGeneration": { + "type": "integer", + "format": "int64", + "description": "The generation observed by the deployment controller." + }, "replicas": { "type": "integer", "format": "int32", diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 72f1ce728d7..46b3aec66e4 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -442,6 +442,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } +

observedGeneration

+

The generation observed by the deployment controller.

+

false

+

integer (int64)

+ + +

replicas

Total number of non-terminated pods targeted by this deployment (their labels match the selector).

false

@@ -2486,7 +2493,7 @@ Populated by the system. Read-only. Value must be treated as opaque by clients a

generation

-

A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only.

+

A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.

false

integer (int64)

@@ -5577,7 +5584,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html index 6ff5b296c56..5c82050f0aa 100755 --- a/docs/api-reference/v1/definitions.html +++ b/docs/api-reference/v1/definitions.html @@ -1854,7 +1854,7 @@ Populated by the system. Read-only. Value must be treated as opaque by clients a

generation

-

A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only.

+

A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.

false

integer (int64)

@@ -7477,7 +7477,7 @@ The resulting set of endpoints can be viewed as:
diff --git a/pkg/apis/extensions/types.generated.go b/pkg/apis/extensions/types.generated.go index fabe00c2f9f..719562774b6 100644 --- a/pkg/apis/extensions/types.generated.go +++ b/pkg/apis/extensions/types.generated.go @@ -7022,16 +7022,17 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [4]bool + var yyq2 [5]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[0] = x.Replicas != 0 - yyq2[1] = x.UpdatedReplicas != 0 - yyq2[2] = x.AvailableReplicas != 0 - yyq2[3] = x.UnavailableReplicas != 0 + yyq2[0] = x.ObservedGeneration != 0 + yyq2[1] = x.Replicas != 0 + yyq2[2] = x.UpdatedReplicas != 0 + yyq2[3] = x.AvailableReplicas != 0 + yyq2[4] = x.UnavailableReplicas != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(4) + r.EncodeArrayStart(5) } else { yynn2 = 0 for _, b := range yyq2 { @@ -7049,7 +7050,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym4 if false { } else { - r.EncodeInt(int64(x.Replicas)) + r.EncodeInt(int64(x.ObservedGeneration)) } } else { r.EncodeInt(0) @@ -7057,13 +7058,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[0] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("replicas")) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym5 := z.EncBinary() _ = yym5 if false { } else { - r.EncodeInt(int64(x.Replicas)) + r.EncodeInt(int64(x.ObservedGeneration)) } } } @@ -7074,7 +7075,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.UpdatedReplicas)) + r.EncodeInt(int64(x.Replicas)) } } else { r.EncodeInt(0) @@ -7082,13 +7083,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("updatedReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("replicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { } else { - r.EncodeInt(int64(x.UpdatedReplicas)) + r.EncodeInt(int64(x.Replicas)) } } } @@ -7099,7 +7100,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym10 if false { } else { - r.EncodeInt(int64(x.AvailableReplicas)) + r.EncodeInt(int64(x.UpdatedReplicas)) } } else { r.EncodeInt(0) @@ -7107,13 +7108,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[2] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("availableReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("updatedReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym11 := z.EncBinary() _ = yym11 if false { } else { - r.EncodeInt(int64(x.AvailableReplicas)) + r.EncodeInt(int64(x.UpdatedReplicas)) } } } @@ -7124,7 +7125,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym13 if false { } else { - r.EncodeInt(int64(x.UnavailableReplicas)) + r.EncodeInt(int64(x.AvailableReplicas)) } } else { r.EncodeInt(0) @@ -7132,11 +7133,36 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[3] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("unavailableReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("availableReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym14 := z.EncBinary() _ = yym14 if false { + } else { + r.EncodeInt(int64(x.AvailableReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[4] { + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeInt(int64(x.UnavailableReplicas)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[4] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("unavailableReplicas")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym17 := z.EncBinary() + _ = yym17 + if false { } else { r.EncodeInt(int64(x.UnavailableReplicas)) } @@ -7203,6 +7229,12 @@ func (x *DeploymentStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { + case "observedGeneration": + if r.TryDecodeAsNil() { + x.ObservedGeneration = 0 + } else { + x.ObservedGeneration = int64(r.DecodeInt(64)) + } case "replicas": if r.TryDecodeAsNil() { x.Replicas = 0 @@ -7238,16 +7270,32 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj8 int - var yyb8 bool - var yyhl8 bool = l >= 0 - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + var yyj9 int + var yyb9 bool + var yyhl9 bool = l >= 0 + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ObservedGeneration = 0 + } else { + x.ObservedGeneration = int64(r.DecodeInt(64)) + } + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l + } else { + yyb9 = r.CheckBreak() + } + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7257,13 +7305,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.Replicas = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7273,13 +7321,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.UpdatedReplicas = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7289,13 +7337,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.AvailableReplicas = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7306,17 +7354,17 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) x.UnavailableReplicas = int(r.DecodeInt(codecSelferBitsize1234)) } for { - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj8-1, "") + z.DecStructFieldNotFound(yyj9-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -18881,7 +18929,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 624) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 632) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/pkg/apis/extensions/v1beta1/conversion_generated.go b/pkg/apis/extensions/v1beta1/conversion_generated.go index f1c50ad2a46..6d4d3dc59fc 100644 --- a/pkg/apis/extensions/v1beta1/conversion_generated.go +++ b/pkg/apis/extensions/v1beta1/conversion_generated.go @@ -2979,6 +2979,7 @@ func autoConvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *ext if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*extensions.DeploymentStatus))(in) } + out.ObservedGeneration = in.ObservedGeneration out.Replicas = int32(in.Replicas) out.UpdatedReplicas = int32(in.UpdatedReplicas) out.AvailableReplicas = int32(in.AvailableReplicas) @@ -4265,6 +4266,7 @@ func autoConvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *Dep if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DeploymentStatus))(in) } + out.ObservedGeneration = in.ObservedGeneration out.Replicas = int(in.Replicas) out.UpdatedReplicas = int(in.UpdatedReplicas) out.AvailableReplicas = int(in.AvailableReplicas) diff --git a/pkg/apis/extensions/v1beta1/deep_copy_generated.go b/pkg/apis/extensions/v1beta1/deep_copy_generated.go index d1ba9f6de3c..447f17a5466 100644 --- a/pkg/apis/extensions/v1beta1/deep_copy_generated.go +++ b/pkg/apis/extensions/v1beta1/deep_copy_generated.go @@ -1233,6 +1233,7 @@ func deepCopy_v1beta1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c * } func deepCopy_v1beta1_DeploymentStatus(in DeploymentStatus, out *DeploymentStatus, c *conversion.Cloner) error { + out.ObservedGeneration = in.ObservedGeneration out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas out.AvailableReplicas = in.AvailableReplicas diff --git a/pkg/apis/extensions/v1beta1/types.generated.go b/pkg/apis/extensions/v1beta1/types.generated.go index 1e2b081eccc..5bd64943027 100644 --- a/pkg/apis/extensions/v1beta1/types.generated.go +++ b/pkg/apis/extensions/v1beta1/types.generated.go @@ -7056,16 +7056,17 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [4]bool + var yyq2 [5]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[0] = x.Replicas != 0 - yyq2[1] = x.UpdatedReplicas != 0 - yyq2[2] = x.AvailableReplicas != 0 - yyq2[3] = x.UnavailableReplicas != 0 + yyq2[0] = x.ObservedGeneration != 0 + yyq2[1] = x.Replicas != 0 + yyq2[2] = x.UpdatedReplicas != 0 + yyq2[3] = x.AvailableReplicas != 0 + yyq2[4] = x.UnavailableReplicas != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(4) + r.EncodeArrayStart(5) } else { yynn2 = 0 for _, b := range yyq2 { @@ -7083,7 +7084,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym4 if false { } else { - r.EncodeInt(int64(x.Replicas)) + r.EncodeInt(int64(x.ObservedGeneration)) } } else { r.EncodeInt(0) @@ -7091,13 +7092,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[0] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("replicas")) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym5 := z.EncBinary() _ = yym5 if false { } else { - r.EncodeInt(int64(x.Replicas)) + r.EncodeInt(int64(x.ObservedGeneration)) } } } @@ -7108,7 +7109,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.UpdatedReplicas)) + r.EncodeInt(int64(x.Replicas)) } } else { r.EncodeInt(0) @@ -7116,13 +7117,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("updatedReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("replicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { } else { - r.EncodeInt(int64(x.UpdatedReplicas)) + r.EncodeInt(int64(x.Replicas)) } } } @@ -7133,7 +7134,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym10 if false { } else { - r.EncodeInt(int64(x.AvailableReplicas)) + r.EncodeInt(int64(x.UpdatedReplicas)) } } else { r.EncodeInt(0) @@ -7141,13 +7142,13 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[2] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("availableReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("updatedReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym11 := z.EncBinary() _ = yym11 if false { } else { - r.EncodeInt(int64(x.AvailableReplicas)) + r.EncodeInt(int64(x.UpdatedReplicas)) } } } @@ -7158,7 +7159,7 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym13 if false { } else { - r.EncodeInt(int64(x.UnavailableReplicas)) + r.EncodeInt(int64(x.AvailableReplicas)) } } else { r.EncodeInt(0) @@ -7166,11 +7167,36 @@ func (x *DeploymentStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[3] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("unavailableReplicas")) + r.EncodeString(codecSelferC_UTF81234, string("availableReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym14 := z.EncBinary() _ = yym14 if false { + } else { + r.EncodeInt(int64(x.AvailableReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[4] { + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeInt(int64(x.UnavailableReplicas)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[4] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("unavailableReplicas")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym17 := z.EncBinary() + _ = yym17 + if false { } else { r.EncodeInt(int64(x.UnavailableReplicas)) } @@ -7237,6 +7263,12 @@ func (x *DeploymentStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { + case "observedGeneration": + if r.TryDecodeAsNil() { + x.ObservedGeneration = 0 + } else { + x.ObservedGeneration = int64(r.DecodeInt(64)) + } case "replicas": if r.TryDecodeAsNil() { x.Replicas = 0 @@ -7272,16 +7304,32 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj8 int - var yyb8 bool - var yyhl8 bool = l >= 0 - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + var yyj9 int + var yyb9 bool + var yyhl9 bool = l >= 0 + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ObservedGeneration = 0 + } else { + x.ObservedGeneration = int64(r.DecodeInt(64)) + } + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l + } else { + yyb9 = r.CheckBreak() + } + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7291,13 +7339,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.Replicas = int32(r.DecodeInt(32)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7307,13 +7355,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.UpdatedReplicas = int32(r.DecodeInt(32)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7323,13 +7371,13 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.AvailableReplicas = int32(r.DecodeInt(32)) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7340,17 +7388,17 @@ func (x *DeploymentStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) x.UnavailableReplicas = int32(r.DecodeInt(32)) } for { - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj9++ + if yyhl9 { + yyb9 = yyj9 > l } else { - yyb8 = r.CheckBreak() + yyb9 = r.CheckBreak() } - if yyb8 { + if yyb9 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj8-1, "") + z.DecStructFieldNotFound(yyj9-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -20210,7 +20258,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 632) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 640) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go b/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go index 44329c8c0a0..3f29ee3fea9 100644 --- a/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go +++ b/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go @@ -185,6 +185,7 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", + "observedGeneration": "The generation observed by the deployment controller.", "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.",