Merge pull request #21754 from kargakis/use-generation-for-deployments

Use generation for deployments
This commit is contained in:
Dawn Chen 2016-02-23 16:42:16 -08:00
commit a8c0ac88fc
21 changed files with 275 additions and 112 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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",
@ -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",

View File

@ -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",

View File

@ -442,6 +442,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">observedGeneration</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The generation observed by the deployment controller.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">replicas</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Total number of non-terminated pods targeted by this deployment (their labels match the selector).</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -2486,7 +2493,7 @@ Populated by the system. Read-only. Value must be treated as opaque by clients a
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">generation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
<td class="tableblock halign-left valign-top"></td>
@ -5577,7 +5584,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-02-18 07:15:38 UTC
Last updated 2016-02-23 18:41:56 UTC
</div>
</div>
</body>

View File

@ -1854,7 +1854,7 @@ Populated by the system. Read-only. Value must be treated as opaque by clients a
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">generation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A sequence number representing a specific generation of the desired state. Currently only implemented by replication controllers. Populated by the system. Read-only.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
<td class="tableblock halign-left valign-top"></td>
@ -7477,7 +7477,7 @@ The resulting set of endpoints can be viewed as:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-02-16 23:43:33 UTC
Last updated 2016-02-23 18:41:48 UTC
</div>
</div>
</body>

View File

@ -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

View File

@ -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

View File

@ -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.",

View File

@ -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]

View File

@ -332,6 +332,9 @@ type RollingUpdateDeployment struct {
}
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 int `json:"replicas,omitempty"`

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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"`

View File

@ -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.",

View File

@ -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(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"))...)

View File

@ -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.Generation > d.Status.ObservedGeneration || d.Status.Replicas != totalReplicas || d.Status.UpdatedReplicas != updatedReplicas || d.Status.AvailableReplicas != availableReplicas {
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: deployment.Generation,
Replicas: totalReplicas,
UpdatedReplicas: updatedReplicas,
AvailableReplicas: availableReplicas,

View File

@ -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.

View File

@ -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())

View File

@ -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 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 {