mirror of https://github.com/k3s-io/k3s
Merge pull request #46669 from kow3ns/statefulset-update
Automatic merge from submit-queue (batch tested with PRs 46235, 44786, 46833, 46756, 46669) implements StatefulSet update **What this PR does / why we need it**: 1. Implements rolling update for StatefulSets 2. Implements controller history for StatefulSets. 3. Makes StatefulSet status reporting consistent with DaemonSet and ReplicaSet. https://github.com/kubernetes/features/issues/188 **Special notes for your reviewer**: **Release note**: ```release-note Implements rolling update for StatefulSets. Updates can be performed using the RollingUpdate, Paritioned, or OnDelete strategies. OnDelete implements the manual behavior from 1.6. status now tracks replicas, readyReplicas, currentReplicas, and updatedReplicas. The semantics of replicas is now consistent with DaemonSet and ReplicaSet, and readyReplicas has the semantics that replicas did prior to this release. ```pull/6/head
commit
0613ae5077
|
@ -51580,6 +51580,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.PartitionStatefulSetStrategy": {
|
||||
"description": "PartitionStatefulSetStrategy contains the parameters used with the PartitionStatefulSetStrategyType.",
|
||||
"required": [
|
||||
"ordinal"
|
||||
],
|
||||
"properties": {
|
||||
"ordinal": {
|
||||
"description": "Ordinal indicates the ordinal at which the StatefulSet should be partitioned.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.RollbackConfig": {
|
||||
"properties": {
|
||||
"revision": {
|
||||
|
@ -51747,6 +51760,11 @@
|
|||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"revisionHistoryLimit": {
|
||||
"description": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"selector": {
|
||||
"description": "selector is a label query over pods that should match the replica count. If empty, defaulted to labels on the pod template. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors",
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector"
|
||||
|
@ -51759,6 +51777,10 @@
|
|||
"description": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.",
|
||||
"$ref": "#/definitions/io.k8s.kubernetes.pkg.api.v1.PodTemplateSpec"
|
||||
},
|
||||
"updateStrategy": {
|
||||
"description": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.",
|
||||
"$ref": "#/definitions/io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetUpdateStrategy"
|
||||
},
|
||||
"volumeClaimTemplates": {
|
||||
"description": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.",
|
||||
"type": "array",
|
||||
|
@ -51774,15 +51796,51 @@
|
|||
"replicas"
|
||||
],
|
||||
"properties": {
|
||||
"currentReplicas": {
|
||||
"description": "currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by currentRevision.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"currentRevision": {
|
||||
"description": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).",
|
||||
"type": "string"
|
||||
},
|
||||
"observedGeneration": {
|
||||
"description": "observedGeneration is the most recent generation observed by this StatefulSet.",
|
||||
"description": "observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the StatefulSet's generation, which is updated on mutation by the API Server.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"replicas": {
|
||||
"description": "replicas is the number of actual replicas.",
|
||||
"readyReplicas": {
|
||||
"description": "readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"replicas": {
|
||||
"description": "replicas is the number of Pods created by the StatefulSet controller.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"updateRevision": {
|
||||
"description": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedReplicas": {
|
||||
"description": "updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by updateRevision.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetUpdateStrategy": {
|
||||
"description": "StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.",
|
||||
"properties": {
|
||||
"partition": {
|
||||
"description": "Partition is used to communicate the ordinal at which to partition the StatefulSet when Type is PartitionStatefulSetStrategyType. This value must be set when Type is PartitionStatefulSetStrategyType, and it must be nil otherwise.",
|
||||
"$ref": "#/definitions/io.k8s.kubernetes.pkg.apis.apps.v1beta1.PartitionStatefulSetStrategy"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type indicates the type of the StatefulSetUpdateStrategy.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -5915,6 +5915,15 @@
|
|||
"podManagementPolicy": {
|
||||
"type": "string",
|
||||
"description": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once."
|
||||
},
|
||||
"updateStrategy": {
|
||||
"$ref": "v1beta1.StatefulSetUpdateStrategy",
|
||||
"description": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template."
|
||||
},
|
||||
"revisionHistoryLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5998,6 +6007,34 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.StatefulSetUpdateStrategy": {
|
||||
"id": "v1beta1.StatefulSetUpdateStrategy",
|
||||
"description": "StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type indicates the type of the StatefulSetUpdateStrategy."
|
||||
},
|
||||
"partition": {
|
||||
"$ref": "v1beta1.PartitionStatefulSetStrategy",
|
||||
"description": "Partition is used to communicate the ordinal at which to partition the StatefulSet when Type is PartitionStatefulSetStrategyType. This value must be set when Type is PartitionStatefulSetStrategyType, and it must be nil otherwise."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.PartitionStatefulSetStrategy": {
|
||||
"id": "v1beta1.PartitionStatefulSetStrategy",
|
||||
"description": "PartitionStatefulSetStrategy contains the parameters used with the PartitionStatefulSetStrategyType.",
|
||||
"required": [
|
||||
"ordinal"
|
||||
],
|
||||
"properties": {
|
||||
"ordinal": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Ordinal indicates the ordinal at which the StatefulSet should be partitioned."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.StatefulSetStatus": {
|
||||
"id": "v1beta1.StatefulSetStatus",
|
||||
"description": "StatefulSetStatus represents the current state of a StatefulSet.",
|
||||
|
@ -6008,12 +6045,35 @@
|
|||
"observedGeneration": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "observedGeneration is the most recent generation observed by this StatefulSet."
|
||||
"description": "observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the StatefulSet's generation, which is updated on mutation by the API Server."
|
||||
},
|
||||
"replicas": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "replicas is the number of actual replicas."
|
||||
"description": "replicas is the number of Pods created by the StatefulSet controller."
|
||||
},
|
||||
"readyReplicas": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition."
|
||||
},
|
||||
"currentReplicas": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by currentRevision."
|
||||
},
|
||||
"updatedReplicas": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by updateRevision."
|
||||
},
|
||||
"currentRevision": {
|
||||
"type": "string",
|
||||
"description": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas)."
|
||||
},
|
||||
"updateRevision": {
|
||||
"type": "string",
|
||||
"description": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -33,6 +33,7 @@ func startStatefulSetController(ctx ControllerContext) (bool, error) {
|
|||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Apps().V1beta1().StatefulSets(),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ctx.InformerFactory.Apps().V1beta1().ControllerRevisions(),
|
||||
ctx.ClientBuilder.ClientOrDie("statefulset-controller"),
|
||||
).Run(1, ctx.Stop)
|
||||
return true, nil
|
||||
|
|
|
@ -1564,6 +1564,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updateStrategy</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.</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"><a href="#_v1beta1_statefulsetupdatestrategy">v1beta1.StatefulSetUpdateStrategy</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">revisionHistoryLimit</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet’s revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.</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 (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -1818,6 +1832,40 @@ When an object is created, the system will populate this list with the current s
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_partitionstatefulsetstrategy">v1beta1.PartitionStatefulSetStrategy</h3>
|
||||
<div class="paragraph">
|
||||
<p>PartitionStatefulSetStrategy contains the parameters used with the PartitionStatefulSetStrategyType.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">ordinal</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Ordinal indicates the ordinal at which the StatefulSet should be partitioned.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_azurefilevolumesource">v1.AzureFileVolumeSource</h3>
|
||||
|
@ -5017,18 +5065,53 @@ Examples:<br>
|
|||
<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">observedGeneration is the most recent generation observed by this StatefulSet.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the StatefulSet’s generation, which is updated on mutation by the API Server.</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">replicas is the number of actual replicas.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">replicas is the number of Pods created by the StatefulSet controller.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">readyReplicas</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.</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 (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">currentReplicas</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by currentRevision.</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 (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updatedReplicas</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by updateRevision.</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 (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">currentRevision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).</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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updateRevision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)</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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -6464,6 +6547,47 @@ Examples:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_statefulsetupdatestrategy">v1beta1.StatefulSetUpdateStrategy</h3>
|
||||
<div class="paragraph">
|
||||
<p>StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">type</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Type indicates the type of the StatefulSetUpdateStrategy.</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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">partition</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Partition is used to communicate the ordinal at which to partition the StatefulSet when Type is PartitionStatefulSetStrategyType. This value must be set when Type is PartitionStatefulSetStrategyType, and it must be nil otherwise.</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"><a href="#_v1beta1_partitionstatefulsetstrategy">v1beta1.PartitionStatefulSetStrategy</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_nodeaffinity">v1.NodeAffinity</h3>
|
||||
|
@ -6614,7 +6738,7 @@ Examples:<br>
|
|||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-06-06 04:24:56 UTC
|
||||
Last updated 2017-06-06 19:37:03 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -194,6 +194,7 @@ pkg/client/unversioned
|
|||
pkg/cloudprovider/providers
|
||||
pkg/cloudprovider/providers/azure
|
||||
pkg/cloudprovider/providers/cloudstack
|
||||
pkg/controller/history
|
||||
pkg/controller/volume/attachdetach/cache
|
||||
pkg/controller/volume/attachdetach/populator
|
||||
pkg/controller/volume/attachdetach/reconciler
|
||||
|
|
|
@ -723,6 +723,13 @@ func appsFuncs(t apitesting.TestingCommon) []interface{} {
|
|||
if len(s.Spec.PodManagementPolicy) == 0 {
|
||||
s.Spec.PodManagementPolicy = apps.OrderedReadyPodManagement
|
||||
}
|
||||
if len(s.Spec.UpdateStrategy.Type) == 0 {
|
||||
s.Spec.UpdateStrategy.Type = apps.RollingUpdateStatefulSetStrategyType
|
||||
}
|
||||
if s.Spec.RevisionHistoryLimit == nil {
|
||||
s.Spec.RevisionHistoryLimit = new(int32)
|
||||
*s.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,54 @@ const (
|
|||
ParallelPodManagement = "Parallel"
|
||||
)
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
type StatefulSetUpdateStrategy struct {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Type StatefulSetUpdateStrategyType
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
Partition *PartitionStatefulSetStrategy
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
|
||||
// all possible update strategies for the StatefulSet controller.
|
||||
type StatefulSetUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// PartitionStatefulSetStrategyType indicates that updates will only be
|
||||
// applied to a partition of the StatefulSet. This is useful for canaries
|
||||
// and phased roll outs. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's currentRevision if there ordinal is less than the supplied
|
||||
// Partition's ordinal. Otherwise, they will be created from the specification
|
||||
// version indicated by the StatefulSet's updateRevision.
|
||||
PartitionStatefulSetStrategyType StatefulSetUpdateStrategyType = "Partition"
|
||||
// RollingUpdateStatefulSetStrategyType indicates that update will be
|
||||
// applied to all Pods in the StatefulSet with respect to the StatefulSet
|
||||
// ordering constraints. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's updateRevision.
|
||||
RollingUpdateStatefulSetStrategyType = "RollingUpdate"
|
||||
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
|
||||
// tracking and ordered rolling restarts are disabled. Pods are recreated
|
||||
// from the StatefulSetSpec when they are manually deleted. When a scale
|
||||
// operation is performed with this strategy,specification version indicated
|
||||
// by the StatefulSet's currentRevision.
|
||||
OnDeleteStatefulSetStrategyType = "OnDelete"
|
||||
)
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
type PartitionStatefulSetStrategy struct {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
Ordinal int32
|
||||
}
|
||||
|
||||
// A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type StatefulSetSpec struct {
|
||||
// Replicas is the desired number of replicas of the given Template.
|
||||
|
@ -109,16 +157,47 @@ type StatefulSetSpec struct {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
PodManagementPolicy PodManagementPolicyType
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
UpdateStrategy StatefulSetUpdateStrategy
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
type StatefulSetStatus struct {
|
||||
// most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
ObservedGeneration *int64
|
||||
|
||||
// Replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
Replicas int32
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
ReadyReplicas int32
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
CurrentReplicas int32
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
UpdatedReplicas int32
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
CurrentRevision string
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
UpdateRevision string
|
||||
}
|
||||
|
||||
// StatefulSetList is a collection of StatefulSets.
|
||||
|
|
|
@ -37,6 +37,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||
err := scheme.AddConversionFuncs(
|
||||
Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec,
|
||||
Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec,
|
||||
Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy,
|
||||
Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy,
|
||||
// extensions
|
||||
// TODO: below conversions should be dropped in favor of auto-generated
|
||||
// ones, see https://github.com/kubernetes/kubernetextensionsssues/39865
|
||||
|
@ -109,6 +111,15 @@ func Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(in *StatefulSetSpec
|
|||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if err := Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = apps.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
return nil
|
||||
|
@ -140,8 +151,39 @@ func Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(in *apps.StatefulSe
|
|||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(in *StatefulSetUpdateStrategy, out *apps.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = apps.StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.Partition != nil {
|
||||
out.Partition = new(apps.PartitionStatefulSetStrategy)
|
||||
out.Partition.Ordinal = in.Partition.Ordinal
|
||||
} else {
|
||||
out.Partition = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(in *apps.StatefulSetUpdateStrategy, out *StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.Partition != nil {
|
||||
out.Partition = new(PartitionStatefulSetStrategy)
|
||||
out.Partition.Ordinal = in.Partition.Ordinal
|
||||
} else {
|
||||
out.Partition = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ func SetDefaults_StatefulSet(obj *StatefulSet) {
|
|||
if len(obj.Spec.PodManagementPolicy) == 0 {
|
||||
obj.Spec.PodManagementPolicy = OrderedReadyPodManagement
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == "" {
|
||||
obj.Spec.UpdateStrategy.Type = OnDeleteStatefulSetStrategyType
|
||||
}
|
||||
labels := obj.Spec.Template.Labels
|
||||
if labels != nil {
|
||||
if obj.Spec.Selector == nil {
|
||||
|
@ -45,6 +49,11 @@ func SetDefaults_StatefulSet(obj *StatefulSet) {
|
|||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
if obj.Spec.RevisionHistoryLimit == nil {
|
||||
obj.Spec.RevisionHistoryLimit = new(int32)
|
||||
*obj.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SetDefaults_Deployment sets additional defaults compared to its counterpart
|
||||
|
|
|
@ -34,6 +34,7 @@ limitations under the License.
|
|||
DeploymentSpec
|
||||
DeploymentStatus
|
||||
DeploymentStrategy
|
||||
PartitionStatefulSetStrategy
|
||||
RollbackConfig
|
||||
RollingUpdateDeployment
|
||||
Scale
|
||||
|
@ -43,6 +44,7 @@ limitations under the License.
|
|||
StatefulSetList
|
||||
StatefulSetSpec
|
||||
StatefulSetStatus
|
||||
StatefulSetUpdateStrategy
|
||||
*/
|
||||
package v1beta1
|
||||
|
||||
|
@ -108,43 +110,55 @@ func (m *DeploymentStrategy) Reset() { *m = DeploymentStrateg
|
|||
func (*DeploymentStrategy) ProtoMessage() {}
|
||||
func (*DeploymentStrategy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} }
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Reset() { *m = PartitionStatefulSetStrategy{} }
|
||||
func (*PartitionStatefulSetStrategy) ProtoMessage() {}
|
||||
func (*PartitionStatefulSetStrategy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{9}
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Reset() { *m = RollbackConfig{} }
|
||||
func (*RollbackConfig) ProtoMessage() {}
|
||||
func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} }
|
||||
func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} }
|
||||
|
||||
func (m *RollingUpdateDeployment) Reset() { *m = RollingUpdateDeployment{} }
|
||||
func (*RollingUpdateDeployment) ProtoMessage() {}
|
||||
func (*RollingUpdateDeployment) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{10}
|
||||
return fileDescriptorGenerated, []int{11}
|
||||
}
|
||||
|
||||
func (m *Scale) Reset() { *m = Scale{} }
|
||||
func (*Scale) ProtoMessage() {}
|
||||
func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} }
|
||||
func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} }
|
||||
|
||||
func (m *ScaleSpec) Reset() { *m = ScaleSpec{} }
|
||||
func (*ScaleSpec) ProtoMessage() {}
|
||||
func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} }
|
||||
func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} }
|
||||
|
||||
func (m *ScaleStatus) Reset() { *m = ScaleStatus{} }
|
||||
func (*ScaleStatus) ProtoMessage() {}
|
||||
func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} }
|
||||
func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} }
|
||||
|
||||
func (m *StatefulSet) Reset() { *m = StatefulSet{} }
|
||||
func (*StatefulSet) ProtoMessage() {}
|
||||
func (*StatefulSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} }
|
||||
func (*StatefulSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} }
|
||||
|
||||
func (m *StatefulSetList) Reset() { *m = StatefulSetList{} }
|
||||
func (*StatefulSetList) ProtoMessage() {}
|
||||
func (*StatefulSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} }
|
||||
func (*StatefulSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} }
|
||||
|
||||
func (m *StatefulSetSpec) Reset() { *m = StatefulSetSpec{} }
|
||||
func (*StatefulSetSpec) ProtoMessage() {}
|
||||
func (*StatefulSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} }
|
||||
func (*StatefulSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} }
|
||||
|
||||
func (m *StatefulSetStatus) Reset() { *m = StatefulSetStatus{} }
|
||||
func (*StatefulSetStatus) ProtoMessage() {}
|
||||
func (*StatefulSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} }
|
||||
func (*StatefulSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{18} }
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Reset() { *m = StatefulSetUpdateStrategy{} }
|
||||
func (*StatefulSetUpdateStrategy) ProtoMessage() {}
|
||||
func (*StatefulSetUpdateStrategy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{19}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ControllerRevision)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.ControllerRevision")
|
||||
|
@ -156,6 +170,7 @@ func init() {
|
|||
proto.RegisterType((*DeploymentSpec)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.DeploymentSpec")
|
||||
proto.RegisterType((*DeploymentStatus)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.DeploymentStatus")
|
||||
proto.RegisterType((*DeploymentStrategy)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.DeploymentStrategy")
|
||||
proto.RegisterType((*PartitionStatefulSetStrategy)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.PartitionStatefulSetStrategy")
|
||||
proto.RegisterType((*RollbackConfig)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.RollbackConfig")
|
||||
proto.RegisterType((*RollingUpdateDeployment)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.RollingUpdateDeployment")
|
||||
proto.RegisterType((*Scale)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.Scale")
|
||||
|
@ -165,6 +180,7 @@ func init() {
|
|||
proto.RegisterType((*StatefulSetList)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.StatefulSetList")
|
||||
proto.RegisterType((*StatefulSetSpec)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.StatefulSetSpec")
|
||||
proto.RegisterType((*StatefulSetStatus)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.StatefulSetStatus")
|
||||
proto.RegisterType((*StatefulSetUpdateStrategy)(nil), "k8s.io.kubernetes.pkg.apis.apps.v1beta1.StatefulSetUpdateStrategy")
|
||||
}
|
||||
func (m *ControllerRevision) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
|
@ -583,6 +599,27 @@ func (m *DeploymentStrategy) MarshalTo(dAtA []byte) (int, error) {
|
|||
return i, nil
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Ordinal))
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
|
@ -885,6 +922,19 @@ func (m *StatefulSetSpec) MarshalTo(dAtA []byte) (int, error) {
|
|||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.PodManagementPolicy)))
|
||||
i += copy(dAtA[i:], m.PodManagementPolicy)
|
||||
dAtA[i] = 0x3a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.UpdateStrategy.Size()))
|
||||
n27, err := m.UpdateStrategy.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n27
|
||||
if m.RevisionHistoryLimit != nil {
|
||||
dAtA[i] = 0x40
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(*m.RevisionHistoryLimit))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -911,6 +961,55 @@ func (m *StatefulSetStatus) MarshalTo(dAtA []byte) (int, error) {
|
|||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas))
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.ReadyReplicas))
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentReplicas))
|
||||
dAtA[i] = 0x28
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.UpdatedReplicas))
|
||||
dAtA[i] = 0x32
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.CurrentRevision)))
|
||||
i += copy(dAtA[i:], m.CurrentRevision)
|
||||
dAtA[i] = 0x3a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.UpdateRevision)))
|
||||
i += copy(dAtA[i:], m.UpdateRevision)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type)))
|
||||
i += copy(dAtA[i:], m.Type)
|
||||
if m.Partition != nil {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Partition.Size()))
|
||||
n28, err := m.Partition.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n28
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -1090,6 +1189,13 @@ func (m *DeploymentStrategy) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
n += 1 + sovGenerated(uint64(m.Ordinal))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
@ -1195,6 +1301,11 @@ func (m *StatefulSetSpec) Size() (n int) {
|
|||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.PodManagementPolicy)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = m.UpdateStrategy.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
if m.RevisionHistoryLimit != nil {
|
||||
n += 1 + sovGenerated(uint64(*m.RevisionHistoryLimit))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1205,6 +1316,25 @@ func (m *StatefulSetStatus) Size() (n int) {
|
|||
n += 1 + sovGenerated(uint64(*m.ObservedGeneration))
|
||||
}
|
||||
n += 1 + sovGenerated(uint64(m.Replicas))
|
||||
n += 1 + sovGenerated(uint64(m.ReadyReplicas))
|
||||
n += 1 + sovGenerated(uint64(m.CurrentReplicas))
|
||||
n += 1 + sovGenerated(uint64(m.UpdatedReplicas))
|
||||
l = len(m.CurrentRevision)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.UpdateRevision)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Type)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
if m.Partition != nil {
|
||||
l = m.Partition.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1350,6 +1480,16 @@ func (this *DeploymentStrategy) String() string {
|
|||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *PartitionStatefulSetStrategy) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&PartitionStatefulSetStrategy{`,
|
||||
`Ordinal:` + fmt.Sprintf("%v", this.Ordinal) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *RollbackConfig) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
|
@ -1449,6 +1589,8 @@ func (this *StatefulSetSpec) String() string {
|
|||
`VolumeClaimTemplates:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VolumeClaimTemplates), "PersistentVolumeClaim", "k8s_io_kubernetes_pkg_api_v1.PersistentVolumeClaim", 1), `&`, ``, 1) + `,`,
|
||||
`ServiceName:` + fmt.Sprintf("%v", this.ServiceName) + `,`,
|
||||
`PodManagementPolicy:` + fmt.Sprintf("%v", this.PodManagementPolicy) + `,`,
|
||||
`UpdateStrategy:` + strings.Replace(strings.Replace(this.UpdateStrategy.String(), "StatefulSetUpdateStrategy", "StatefulSetUpdateStrategy", 1), `&`, ``, 1) + `,`,
|
||||
`RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -1460,6 +1602,22 @@ func (this *StatefulSetStatus) String() string {
|
|||
s := strings.Join([]string{`&StatefulSetStatus{`,
|
||||
`ObservedGeneration:` + valueToStringGenerated(this.ObservedGeneration) + `,`,
|
||||
`Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`,
|
||||
`ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`,
|
||||
`CurrentReplicas:` + fmt.Sprintf("%v", this.CurrentReplicas) + `,`,
|
||||
`UpdatedReplicas:` + fmt.Sprintf("%v", this.UpdatedReplicas) + `,`,
|
||||
`CurrentRevision:` + fmt.Sprintf("%v", this.CurrentRevision) + `,`,
|
||||
`UpdateRevision:` + fmt.Sprintf("%v", this.UpdateRevision) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *StatefulSetUpdateStrategy) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&StatefulSetUpdateStrategy{`,
|
||||
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
|
||||
`Partition:` + strings.Replace(fmt.Sprintf("%v", this.Partition), "PartitionStatefulSetStrategy", "PartitionStatefulSetStrategy", 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -3016,6 +3174,75 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *PartitionStatefulSetStrategy) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: PartitionStatefulSetStrategy: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: PartitionStatefulSetStrategy: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Ordinal", wireType)
|
||||
}
|
||||
m.Ordinal = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Ordinal |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *RollbackConfig) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -4076,6 +4303,56 @@ func (m *StatefulSetSpec) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
m.PodManagementPolicy = PodManagementPolicyType(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdateStrategy", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.UpdateStrategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType)
|
||||
}
|
||||
var v int32
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.RevisionHistoryLimit = &v
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -4165,6 +4442,233 @@ func (m *StatefulSetStatus) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType)
|
||||
}
|
||||
m.ReadyReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ReadyReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CurrentReplicas", wireType)
|
||||
}
|
||||
m.CurrentReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.CurrentReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdatedReplicas", wireType)
|
||||
}
|
||||
m.UpdatedReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.UpdatedReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CurrentRevision", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.CurrentRevision = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdateRevision", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.UpdateRevision = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *StatefulSetUpdateStrategy) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: StatefulSetUpdateStrategy: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: StatefulSetUpdateStrategy: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Type = StatefulSetUpdateStrategyType(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Partition", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Partition == nil {
|
||||
m.Partition = &PartitionStatefulSetStrategy{}
|
||||
}
|
||||
if err := m.Partition.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -4296,108 +4800,119 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 1647 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcf, 0x4f, 0x1b, 0xc7,
|
||||
0x17, 0x67, 0x8d, 0x0d, 0x66, 0x08, 0x26, 0x0c, 0x7c, 0xc1, 0x5f, 0x52, 0x19, 0xe4, 0x43, 0x42,
|
||||
0xaa, 0x64, 0xdd, 0x90, 0x34, 0x3f, 0xa0, 0x8a, 0x8a, 0x49, 0x9a, 0xa6, 0x82, 0x82, 0xc6, 0x10,
|
||||
0x35, 0x69, 0x2a, 0x65, 0xbc, 0x9e, 0x2c, 0x1b, 0xf6, 0x97, 0x76, 0xc6, 0x6e, 0x7c, 0xeb, 0xa5,
|
||||
0x87, 0x4a, 0x3d, 0xf4, 0x1f, 0xa8, 0xda, 0x73, 0x55, 0xa9, 0xff, 0x06, 0x6a, 0x2f, 0x51, 0x4f,
|
||||
0x51, 0x0f, 0xa8, 0x90, 0xbf, 0xa1, 0x97, 0x9c, 0xaa, 0x99, 0x9d, 0xfd, 0xe5, 0xb5, 0xc1, 0x50,
|
||||
0x95, 0x4b, 0x6f, 0xde, 0x79, 0xef, 0x7d, 0xde, 0x8f, 0x79, 0xef, 0xcd, 0x7b, 0x06, 0xb7, 0x76,
|
||||
0x6f, 0x53, 0xd5, 0x70, 0x2a, 0xbb, 0xcd, 0x3a, 0xf1, 0x6c, 0xc2, 0x08, 0xad, 0xb8, 0xbb, 0x7a,
|
||||
0x05, 0xbb, 0x06, 0xad, 0x60, 0xd7, 0xa5, 0x95, 0xd6, 0xb5, 0x3a, 0x61, 0xf8, 0x5a, 0x45, 0x27,
|
||||
0x36, 0xf1, 0x30, 0x23, 0x0d, 0xd5, 0xf5, 0x1c, 0xe6, 0xc0, 0x4b, 0xbe, 0xa0, 0x1a, 0x09, 0xaa,
|
||||
0xee, 0xae, 0xae, 0x72, 0x41, 0x95, 0x0b, 0xaa, 0x52, 0x70, 0xf6, 0xaa, 0x6e, 0xb0, 0x9d, 0x66,
|
||||
0x5d, 0xd5, 0x1c, 0xab, 0xa2, 0x3b, 0xba, 0x53, 0x11, 0xf2, 0xf5, 0xe6, 0x73, 0xf1, 0x25, 0x3e,
|
||||
0xc4, 0x2f, 0x1f, 0x77, 0xf6, 0x86, 0x34, 0x08, 0xbb, 0x86, 0x85, 0xb5, 0x1d, 0xc3, 0x26, 0x5e,
|
||||
0x3b, 0x32, 0xc9, 0x22, 0x0c, 0x57, 0x5a, 0x29, 0x6b, 0x66, 0x2b, 0xbd, 0xa4, 0xbc, 0xa6, 0xcd,
|
||||
0x0c, 0x8b, 0xa4, 0x04, 0x6e, 0x1e, 0x27, 0x40, 0xb5, 0x1d, 0x62, 0xe1, 0x94, 0xdc, 0xf5, 0x5e,
|
||||
0x72, 0x4d, 0x66, 0x98, 0x15, 0xc3, 0x66, 0x94, 0x79, 0x29, 0xa1, 0x2b, 0x3d, 0x83, 0xdc, 0xcd,
|
||||
0x97, 0x3b, 0x47, 0x5c, 0x89, 0xeb, 0x98, 0x86, 0xd6, 0xee, 0x75, 0x29, 0xe5, 0xbf, 0x14, 0x00,
|
||||
0x57, 0x1d, 0x9b, 0x79, 0x8e, 0x69, 0x12, 0x0f, 0x91, 0x96, 0x41, 0x0d, 0xc7, 0x86, 0xcf, 0x40,
|
||||
0x9e, 0x07, 0xae, 0x81, 0x19, 0x2e, 0x2a, 0xf3, 0xca, 0xc2, 0xe8, 0xe2, 0x7b, 0xaa, 0xbc, 0xbe,
|
||||
0xb8, 0x1f, 0xd1, 0x05, 0x72, 0x6e, 0xb5, 0x75, 0x4d, 0xdd, 0xa8, 0xbf, 0x20, 0x1a, 0x5b, 0x27,
|
||||
0x0c, 0x57, 0xe1, 0xde, 0xfe, 0xdc, 0xc0, 0xe1, 0xfe, 0x1c, 0x88, 0xce, 0x50, 0x88, 0x0a, 0x37,
|
||||
0x40, 0x56, 0xa0, 0x67, 0x04, 0xfa, 0xd5, 0x9e, 0xe8, 0x32, 0xba, 0x2a, 0xc2, 0x5f, 0xde, 0x7f,
|
||||
0xc9, 0x88, 0xcd, 0xcd, 0xab, 0x9e, 0x93, 0xd0, 0xd9, 0x7b, 0x98, 0x61, 0x24, 0x80, 0xe0, 0x15,
|
||||
0x90, 0xf7, 0xa4, 0xf9, 0xc5, 0xc1, 0x79, 0x65, 0x61, 0xb0, 0x7a, 0x5e, 0x72, 0xe5, 0x03, 0xb7,
|
||||
0x50, 0xc8, 0x51, 0x7e, 0xad, 0x80, 0xe9, 0xb4, 0xdf, 0x6b, 0x06, 0x65, 0xf0, 0x69, 0xca, 0x77,
|
||||
0xb5, 0x3f, 0xdf, 0xb9, 0xb4, 0xf0, 0x3c, 0x54, 0x1c, 0x9c, 0xc4, 0xfc, 0x7e, 0x06, 0x72, 0x06,
|
||||
0x23, 0x16, 0x2d, 0x66, 0xe6, 0x07, 0x17, 0x46, 0x17, 0x97, 0xd5, 0x3e, 0xab, 0x42, 0x4d, 0x5b,
|
||||
0x5b, 0x1d, 0x93, 0x7a, 0x72, 0x0f, 0x39, 0x22, 0xf2, 0x81, 0xcb, 0x3f, 0x67, 0x00, 0xb8, 0x47,
|
||||
0x5c, 0xd3, 0x69, 0x5b, 0xc4, 0x66, 0x67, 0x70, 0x95, 0x8f, 0x41, 0x96, 0xba, 0x44, 0x93, 0x57,
|
||||
0x79, 0xab, 0x6f, 0x8f, 0x22, 0x23, 0x6b, 0x2e, 0xd1, 0xa2, 0x4b, 0xe5, 0x5f, 0x48, 0x40, 0x42,
|
||||
0x0c, 0x86, 0x28, 0xc3, 0xac, 0x49, 0xc5, 0x95, 0x8e, 0x2e, 0xde, 0x39, 0x0d, 0xb8, 0x00, 0xa8,
|
||||
0x16, 0x24, 0xfc, 0x90, 0xff, 0x8d, 0x24, 0x70, 0xf9, 0x60, 0x10, 0x4c, 0x46, 0xcc, 0xab, 0x8e,
|
||||
0xdd, 0x30, 0x18, 0x2f, 0x81, 0x65, 0x90, 0x65, 0x6d, 0x97, 0x88, 0x98, 0x8d, 0x54, 0x2f, 0x05,
|
||||
0xc6, 0x6d, 0xb5, 0x5d, 0xf2, 0x76, 0x7f, 0x6e, 0xa6, 0x8b, 0x08, 0x27, 0x21, 0x21, 0x04, 0x1f,
|
||||
0x85, 0x76, 0x67, 0x84, 0xf8, 0xdd, 0xa4, 0xf2, 0xb7, 0xfb, 0x73, 0x47, 0x56, 0xb8, 0x1a, 0x62,
|
||||
0x26, 0x8d, 0x85, 0x17, 0xc1, 0x90, 0x47, 0x30, 0x75, 0xec, 0x62, 0x56, 0xe0, 0x86, 0x4e, 0x21,
|
||||
0x71, 0x8a, 0x24, 0x15, 0x5e, 0x06, 0xc3, 0x16, 0xa1, 0x14, 0xeb, 0xa4, 0x98, 0x13, 0x8c, 0xe3,
|
||||
0x92, 0x71, 0x78, 0xdd, 0x3f, 0x46, 0x01, 0x1d, 0xbe, 0x00, 0x05, 0x13, 0x53, 0xb6, 0xed, 0x36,
|
||||
0x30, 0x23, 0x5b, 0x86, 0x45, 0x8a, 0x43, 0x22, 0xd4, 0xef, 0xf6, 0x97, 0x25, 0x5c, 0xa2, 0x3a,
|
||||
0x2d, 0xd1, 0x0b, 0x6b, 0x09, 0x24, 0xd4, 0x81, 0x0c, 0x5b, 0x00, 0xf2, 0x93, 0x2d, 0x0f, 0xdb,
|
||||
0xd4, 0x0f, 0x19, 0xd7, 0x37, 0x7c, 0x62, 0x7d, 0xb3, 0x52, 0x1f, 0x5c, 0x4b, 0xa1, 0xa1, 0x2e,
|
||||
0x1a, 0xca, 0x7b, 0x0a, 0x28, 0x44, 0x17, 0x76, 0x06, 0x55, 0xfe, 0x59, 0xb2, 0xca, 0xaf, 0x9f,
|
||||
0x22, 0x6d, 0x7b, 0x54, 0xf7, 0xb7, 0x83, 0x00, 0x46, 0x4c, 0xc8, 0x31, 0xcd, 0x3a, 0xd6, 0x76,
|
||||
0xe1, 0x3c, 0xc8, 0xda, 0xd8, 0x0a, 0xb2, 0x35, 0x2c, 0xa5, 0x4f, 0xb1, 0x45, 0x90, 0xa0, 0xc0,
|
||||
0x1f, 0x14, 0x00, 0x9b, 0xe2, 0x2a, 0x1a, 0x2b, 0xb6, 0xed, 0x30, 0xcc, 0xa3, 0x13, 0x18, 0x58,
|
||||
0x3b, 0x85, 0x81, 0x81, 0x6e, 0x75, 0x3b, 0x85, 0x7a, 0xdf, 0x66, 0x5e, 0x3b, 0xba, 0xa5, 0x34,
|
||||
0x03, 0xea, 0x62, 0x0a, 0xdc, 0x05, 0xc0, 0x93, 0x98, 0x5b, 0x8e, 0x2c, 0xf8, 0xfe, 0xbb, 0x49,
|
||||
0x60, 0xce, 0xaa, 0x63, 0x3f, 0x37, 0xf4, 0xa8, 0x65, 0xa1, 0x10, 0x12, 0xc5, 0xe0, 0x67, 0xef,
|
||||
0x83, 0x99, 0x1e, 0x76, 0xc3, 0xf3, 0x60, 0x70, 0x97, 0xb4, 0xfd, 0x50, 0x22, 0xfe, 0x13, 0x4e,
|
||||
0x81, 0x5c, 0x0b, 0x9b, 0x4d, 0xe2, 0x57, 0x33, 0xf2, 0x3f, 0x96, 0x32, 0xb7, 0x95, 0xf2, 0x1f,
|
||||
0xb9, 0x78, 0x66, 0xf1, 0xce, 0x05, 0x17, 0xf8, 0x43, 0xe4, 0x9a, 0x86, 0x86, 0xa9, 0xc0, 0xc8,
|
||||
0x55, 0xcf, 0xf9, 0x8f, 0x90, 0x7f, 0x86, 0x42, 0x2a, 0xfc, 0x02, 0xe4, 0x29, 0x31, 0x89, 0xc6,
|
||||
0x1c, 0x4f, 0x36, 0xcf, 0xeb, 0x7d, 0xe6, 0x20, 0xae, 0x13, 0xb3, 0x26, 0x45, 0x7d, 0xf8, 0xe0,
|
||||
0x0b, 0x85, 0x90, 0xf0, 0x73, 0x90, 0x67, 0xc4, 0x72, 0x4d, 0xcc, 0x88, 0x8c, 0xe6, 0xd5, 0xde,
|
||||
0xd1, 0xe4, 0xb0, 0x9b, 0x4e, 0x63, 0x4b, 0x0a, 0x88, 0x8e, 0x1c, 0x66, 0x78, 0x70, 0x8a, 0x42,
|
||||
0x40, 0x68, 0x80, 0x3c, 0x65, 0x7c, 0x92, 0xd0, 0xdb, 0xa2, 0x17, 0x9d, 0xe4, 0x29, 0x8b, 0xf7,
|
||||
0x66, 0x1f, 0x22, 0x52, 0x15, 0x9c, 0xa0, 0x10, 0x1e, 0xae, 0x80, 0x71, 0xcb, 0xb0, 0x11, 0xc1,
|
||||
0x8d, 0x76, 0x8d, 0x68, 0x8e, 0xdd, 0xa0, 0xa2, 0xa9, 0xe5, 0xaa, 0x33, 0x52, 0x68, 0x7c, 0x3d,
|
||||
0x49, 0x46, 0x9d, 0xfc, 0x70, 0x0d, 0x4c, 0x05, 0x4f, 0xff, 0xc7, 0x06, 0x65, 0x8e, 0xd7, 0x5e,
|
||||
0x33, 0x2c, 0x83, 0x89, 0x56, 0x97, 0xab, 0x16, 0x0f, 0xf7, 0xe7, 0xa6, 0x50, 0x17, 0x3a, 0xea,
|
||||
0x2a, 0xc5, 0xbb, 0xb0, 0x8b, 0x9b, 0x94, 0x34, 0x44, 0xeb, 0xca, 0x47, 0x5d, 0x78, 0x53, 0x9c,
|
||||
0x22, 0x49, 0x85, 0x7a, 0x22, 0xa1, 0xf3, 0xff, 0x2c, 0xa1, 0x0b, 0xbd, 0x93, 0x19, 0x6e, 0x83,
|
||||
0x19, 0xd7, 0x73, 0x74, 0x8f, 0x50, 0x7a, 0x8f, 0xe0, 0x86, 0x69, 0xd8, 0x24, 0x88, 0xd4, 0x88,
|
||||
0xf0, 0xf0, 0xc2, 0xe1, 0xfe, 0xdc, 0xcc, 0x66, 0x77, 0x16, 0xd4, 0x4b, 0xb6, 0xfc, 0x7b, 0x16,
|
||||
0x9c, 0xef, 0x7c, 0x47, 0xe1, 0x27, 0x00, 0x3a, 0x75, 0x4a, 0xbc, 0x16, 0x69, 0x3c, 0xf0, 0x87,
|
||||
0x49, 0x3e, 0x71, 0x29, 0x62, 0xe2, 0x0a, 0x2b, 0x7e, 0x23, 0xc5, 0x81, 0xba, 0x48, 0xf9, 0x33,
|
||||
0x9b, 0x2c, 0x95, 0x8c, 0x30, 0x34, 0x36, 0xb3, 0xa5, 0xca, 0x65, 0x05, 0x8c, 0xcb, 0xae, 0x11,
|
||||
0x10, 0x45, 0x5a, 0xc7, 0xf2, 0x60, 0x3b, 0x49, 0x46, 0x9d, 0xfc, 0xf0, 0x01, 0x98, 0xc0, 0x2d,
|
||||
0x6c, 0x98, 0xb8, 0x6e, 0x92, 0x10, 0x24, 0x2b, 0x40, 0xfe, 0x2f, 0x41, 0x26, 0x56, 0x3a, 0x19,
|
||||
0x50, 0x5a, 0x06, 0xae, 0x83, 0xc9, 0xa6, 0x9d, 0x86, 0xf2, 0xf3, 0xf2, 0x82, 0x84, 0x9a, 0xdc,
|
||||
0x4e, 0xb3, 0xa0, 0x6e, 0x72, 0xd0, 0x05, 0x40, 0x0b, 0x9e, 0x7c, 0x5a, 0x1c, 0x12, 0x3d, 0xf9,
|
||||
0x83, 0x53, 0xd4, 0x53, 0x38, 0x37, 0x44, 0xfd, 0x2f, 0x3c, 0xa2, 0x28, 0xa6, 0x03, 0x2e, 0x83,
|
||||
0x31, 0x8f, 0x57, 0x48, 0x68, 0xfa, 0xb0, 0x30, 0xfd, 0x7f, 0x52, 0x6c, 0x0c, 0xc5, 0x89, 0x28,
|
||||
0xc9, 0x0b, 0x97, 0x40, 0x41, 0x73, 0x4c, 0x53, 0x54, 0xc6, 0xaa, 0xd3, 0xb4, 0x99, 0x48, 0xee,
|
||||
0xc1, 0x2a, 0xe4, 0x33, 0xc0, 0x6a, 0x82, 0x82, 0x3a, 0x38, 0xcb, 0xbf, 0x29, 0xf1, 0x07, 0x2c,
|
||||
0x28, 0x77, 0xb8, 0x94, 0x18, 0xb7, 0x2e, 0x76, 0x8c, 0x5b, 0xd3, 0x69, 0x89, 0xd8, 0xb4, 0xd5,
|
||||
0x06, 0x63, 0xbc, 0x18, 0x0c, 0x5b, 0xf7, 0x13, 0x40, 0x36, 0xd3, 0x0f, 0x4f, 0x54, 0x6a, 0xa1,
|
||||
0x74, 0xec, 0x09, 0x9e, 0x10, 0x91, 0x88, 0x13, 0x51, 0x52, 0x53, 0xf9, 0x2e, 0x28, 0x24, 0xeb,
|
||||
0x34, 0xb1, 0x87, 0x28, 0xc7, 0xee, 0x21, 0x6f, 0x14, 0x30, 0xd3, 0x43, 0x3b, 0x34, 0x41, 0xc1,
|
||||
0xc2, 0x2f, 0x63, 0x39, 0x74, 0xec, 0xfc, 0xce, 0x57, 0x4a, 0xd5, 0x5f, 0x29, 0xd5, 0x87, 0x36,
|
||||
0xdb, 0xf0, 0x6a, 0xcc, 0x33, 0x6c, 0xdd, 0xbf, 0x97, 0xf5, 0x04, 0x16, 0xea, 0xc0, 0x86, 0x4f,
|
||||
0x40, 0xde, 0xc2, 0x2f, 0x6b, 0x4d, 0x4f, 0x0f, 0xe2, 0x77, 0x72, 0x3d, 0xe2, 0x25, 0x5a, 0x97,
|
||||
0x28, 0x28, 0xc4, 0x2b, 0x7f, 0x9f, 0x01, 0xb9, 0x9a, 0x86, 0x4d, 0x72, 0x06, 0xdb, 0xc8, 0x56,
|
||||
0x62, 0x1b, 0x59, 0xec, 0x3b, 0x07, 0x84, 0x7d, 0x3d, 0x17, 0x91, 0xa7, 0x1d, 0x8b, 0xc8, 0x8d,
|
||||
0x13, 0xe2, 0x1e, 0xbd, 0x83, 0xdc, 0x01, 0x23, 0xa1, 0xfa, 0x44, 0x53, 0x54, 0x8e, 0x6b, 0x8a,
|
||||
0xe5, 0x9f, 0x32, 0x60, 0x34, 0xa6, 0xe2, 0x64, 0xd2, 0xd0, 0x4d, 0x4c, 0x20, 0xbc, 0xeb, 0x54,
|
||||
0x4f, 0xe3, 0x98, 0x1a, 0x4c, 0x1f, 0xfe, 0xe0, 0x17, 0x3d, 0xe6, 0xe9, 0xa1, 0xe4, 0x2e, 0x28,
|
||||
0x30, 0xec, 0xe9, 0x84, 0x05, 0x34, 0x11, 0xd0, 0x91, 0x68, 0x85, 0xd8, 0x4a, 0x50, 0x51, 0x07,
|
||||
0xf7, 0xec, 0x32, 0x18, 0x4b, 0x28, 0x3b, 0xd1, 0xb4, 0xf6, 0x0b, 0x0f, 0x16, 0xc3, 0x8c, 0x3c,
|
||||
0x6f, 0x9a, 0x35, 0x72, 0x16, 0xbb, 0xf1, 0x93, 0x44, 0x36, 0xde, 0xee, 0x3f, 0xb8, 0x91, 0x95,
|
||||
0x3d, 0x73, 0xb2, 0xde, 0x91, 0x93, 0x4b, 0xa7, 0x42, 0x3f, 0x3a, 0x33, 0x7f, 0x55, 0xc0, 0x78,
|
||||
0x8c, 0xfb, 0x0c, 0x56, 0xa7, 0xc7, 0xc9, 0xd5, 0xe9, 0xc6, 0x69, 0x9c, 0xea, 0xb1, 0x3b, 0xfd,
|
||||
0x98, 0x4d, 0x38, 0xf3, 0x1f, 0x9a, 0xd6, 0xbf, 0x56, 0xc0, 0x54, 0xcb, 0x31, 0x9b, 0x16, 0x59,
|
||||
0x35, 0xb1, 0x61, 0x05, 0x1c, 0x7c, 0xf6, 0x39, 0x66, 0x3f, 0x15, 0x9a, 0x88, 0x47, 0x0d, 0xca,
|
||||
0x88, 0xcd, 0x1e, 0x45, 0x18, 0xd5, 0x77, 0xa4, 0xbe, 0xa9, 0x47, 0x5d, 0x80, 0x51, 0x57, 0x75,
|
||||
0xf0, 0x7d, 0x30, 0xca, 0x87, 0x40, 0x43, 0x23, 0x7c, 0x33, 0x95, 0xff, 0x4d, 0x4c, 0x4a, 0xa0,
|
||||
0xd1, 0x5a, 0x44, 0x42, 0x71, 0x3e, 0xb8, 0x03, 0x26, 0x5d, 0xa7, 0xb1, 0x8e, 0x6d, 0xac, 0x13,
|
||||
0xfe, 0x34, 0x6e, 0x8a, 0x3f, 0x35, 0xc5, 0xf4, 0x3e, 0x52, 0xbd, 0x19, 0x4c, 0x5b, 0x9b, 0x69,
|
||||
0x96, 0xb7, 0x7c, 0xec, 0x4d, 0x1f, 0x8b, 0xd9, 0xa1, 0x1b, 0x64, 0xf9, 0x1b, 0x05, 0x4c, 0xa4,
|
||||
0xaa, 0x03, 0x7e, 0x74, 0xc4, 0xcc, 0x3b, 0xfd, 0x6f, 0xcd, 0xbb, 0xd5, 0xcb, 0x7b, 0x07, 0xa5,
|
||||
0x81, 0x57, 0x07, 0xa5, 0x81, 0xd7, 0x07, 0xa5, 0x81, 0xaf, 0x0e, 0x4b, 0xca, 0xde, 0x61, 0x49,
|
||||
0x79, 0x75, 0x58, 0x52, 0xfe, 0x3c, 0x2c, 0x29, 0xdf, 0xbd, 0x29, 0x0d, 0x3c, 0x19, 0x96, 0xb9,
|
||||
0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x5b, 0xd8, 0xe7, 0x95, 0x17, 0x00, 0x00,
|
||||
// 1818 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4f, 0x4f, 0x23, 0xc9,
|
||||
0x15, 0xa7, 0xfd, 0x07, 0x4c, 0xb1, 0x98, 0xa1, 0x20, 0xe0, 0x65, 0x37, 0x06, 0xf9, 0xb0, 0xcb,
|
||||
0x44, 0x4b, 0x3b, 0xc3, 0x4c, 0x76, 0x67, 0x20, 0x1a, 0x85, 0x66, 0xc8, 0x66, 0x22, 0x08, 0xa8,
|
||||
0x0c, 0xa3, 0xec, 0x64, 0x23, 0x6d, 0xb9, 0x5d, 0xd3, 0xf4, 0xd2, 0xff, 0xd4, 0x5d, 0x76, 0xc6,
|
||||
0xb7, 0x28, 0x52, 0x6e, 0x39, 0xe4, 0x0b, 0x44, 0xb9, 0x47, 0x91, 0xf2, 0x35, 0x50, 0x72, 0xc8,
|
||||
0x6a, 0x4f, 0xa3, 0x1c, 0x50, 0xf0, 0x7c, 0x84, 0x28, 0x97, 0x39, 0x45, 0x55, 0x5d, 0xfd, 0xdf,
|
||||
0x0d, 0xb6, 0xa3, 0x70, 0xc9, 0xcd, 0x5d, 0xef, 0xbd, 0xdf, 0x7b, 0x55, 0xf5, 0xde, 0xab, 0xdf,
|
||||
0x33, 0xf8, 0xec, 0xe2, 0xb1, 0x27, 0xeb, 0x76, 0xf3, 0xa2, 0xdb, 0x26, 0xae, 0x45, 0x28, 0xf1,
|
||||
0x9a, 0xce, 0x85, 0xd6, 0xc4, 0x8e, 0xee, 0x35, 0xb1, 0xe3, 0x78, 0xcd, 0xde, 0x83, 0x36, 0xa1,
|
||||
0xf8, 0x41, 0x53, 0x23, 0x16, 0x71, 0x31, 0x25, 0x1d, 0xd9, 0x71, 0x6d, 0x6a, 0xc3, 0x8f, 0x7d,
|
||||
0x43, 0x39, 0x32, 0x94, 0x9d, 0x0b, 0x4d, 0x66, 0x86, 0x32, 0x33, 0x94, 0x85, 0xe1, 0xda, 0x96,
|
||||
0xa6, 0xd3, 0xf3, 0x6e, 0x5b, 0x56, 0x6d, 0xb3, 0xa9, 0xd9, 0x9a, 0xdd, 0xe4, 0xf6, 0xed, 0xee,
|
||||
0x2b, 0xfe, 0xc5, 0x3f, 0xf8, 0x2f, 0x1f, 0x77, 0xed, 0x91, 0x08, 0x08, 0x3b, 0xba, 0x89, 0xd5,
|
||||
0x73, 0xdd, 0x22, 0x6e, 0x3f, 0x0a, 0xc9, 0x24, 0x14, 0x37, 0x7b, 0x99, 0x68, 0xd6, 0x9a, 0x79,
|
||||
0x56, 0x6e, 0xd7, 0xa2, 0xba, 0x49, 0x32, 0x06, 0x9f, 0xde, 0x66, 0xe0, 0xa9, 0xe7, 0xc4, 0xc4,
|
||||
0x19, 0xbb, 0x87, 0x79, 0x76, 0x5d, 0xaa, 0x1b, 0x4d, 0xdd, 0xa2, 0x1e, 0x75, 0x33, 0x46, 0x9f,
|
||||
0xe4, 0x1e, 0xf2, 0xb0, 0xbd, 0x3c, 0xb9, 0xe1, 0x4a, 0x1c, 0xdb, 0xd0, 0xd5, 0x7e, 0xde, 0xa5,
|
||||
0x34, 0xfe, 0x2d, 0x01, 0xb8, 0x6f, 0x5b, 0xd4, 0xb5, 0x0d, 0x83, 0xb8, 0x88, 0xf4, 0x74, 0x4f,
|
||||
0xb7, 0x2d, 0xf8, 0x15, 0xa8, 0xb0, 0x83, 0xeb, 0x60, 0x8a, 0x6b, 0xd2, 0x86, 0xb4, 0x39, 0xb7,
|
||||
0xfd, 0x7d, 0x59, 0x5c, 0x5f, 0x7c, 0x1f, 0xd1, 0x05, 0x32, 0x6d, 0xb9, 0xf7, 0x40, 0x3e, 0x6e,
|
||||
0x7f, 0x4d, 0x54, 0x7a, 0x44, 0x28, 0x56, 0xe0, 0xe5, 0xd5, 0xfa, 0xd4, 0xe0, 0x6a, 0x1d, 0x44,
|
||||
0x6b, 0x28, 0x44, 0x85, 0xc7, 0xa0, 0xc4, 0xd1, 0x0b, 0x1c, 0x7d, 0x2b, 0x17, 0x5d, 0x9c, 0xae,
|
||||
0x8c, 0xf0, 0xaf, 0x0e, 0x5e, 0x53, 0x62, 0xb1, 0xf0, 0x94, 0xf7, 0x04, 0x74, 0xe9, 0x19, 0xa6,
|
||||
0x18, 0x71, 0x20, 0xf8, 0x09, 0xa8, 0xb8, 0x22, 0xfc, 0x5a, 0x71, 0x43, 0xda, 0x2c, 0x2a, 0xf7,
|
||||
0x84, 0x56, 0x25, 0xd8, 0x16, 0x0a, 0x35, 0x1a, 0x6f, 0x24, 0xb0, 0x92, 0xdd, 0xf7, 0xa1, 0xee,
|
||||
0x51, 0xf8, 0x65, 0x66, 0xef, 0xf2, 0x68, 0x7b, 0x67, 0xd6, 0x7c, 0xe7, 0xa1, 0xe3, 0x60, 0x25,
|
||||
0xb6, 0xef, 0xaf, 0x40, 0x59, 0xa7, 0xc4, 0xf4, 0x6a, 0x85, 0x8d, 0xe2, 0xe6, 0xdc, 0xf6, 0xae,
|
||||
0x3c, 0x62, 0x55, 0xc8, 0xd9, 0x68, 0x95, 0x79, 0xe1, 0xa7, 0xfc, 0x9c, 0x21, 0x22, 0x1f, 0xb8,
|
||||
0xf1, 0xe7, 0x02, 0x00, 0xcf, 0x88, 0x63, 0xd8, 0x7d, 0x93, 0x58, 0xf4, 0x0e, 0xae, 0xf2, 0x0b,
|
||||
0x50, 0xf2, 0x1c, 0xa2, 0x8a, 0xab, 0xfc, 0x6c, 0xe4, 0x1d, 0x45, 0x41, 0xb6, 0x1c, 0xa2, 0x46,
|
||||
0x97, 0xca, 0xbe, 0x10, 0x87, 0x84, 0x18, 0x4c, 0x7b, 0x14, 0xd3, 0xae, 0xc7, 0xaf, 0x74, 0x6e,
|
||||
0xfb, 0xc9, 0x24, 0xe0, 0x1c, 0x40, 0xa9, 0x0a, 0xf8, 0x69, 0xff, 0x1b, 0x09, 0xe0, 0xc6, 0x75,
|
||||
0x11, 0x2c, 0x45, 0xca, 0xfb, 0xb6, 0xd5, 0xd1, 0x29, 0x2b, 0x81, 0x5d, 0x50, 0xa2, 0x7d, 0x87,
|
||||
0xf0, 0x33, 0x9b, 0x55, 0x3e, 0x0e, 0x82, 0x3b, 0xed, 0x3b, 0xe4, 0xdd, 0xd5, 0xfa, 0xea, 0x10,
|
||||
0x13, 0x26, 0x42, 0xdc, 0x08, 0xbe, 0x08, 0xe3, 0x2e, 0x70, 0xf3, 0xa7, 0x49, 0xe7, 0xef, 0xae,
|
||||
0xd6, 0x6f, 0xac, 0x70, 0x39, 0xc4, 0x4c, 0x06, 0x0b, 0x3f, 0x02, 0xd3, 0x2e, 0xc1, 0x9e, 0x6d,
|
||||
0xd5, 0x4a, 0x1c, 0x37, 0xdc, 0x14, 0xe2, 0xab, 0x48, 0x48, 0xe1, 0x7d, 0x30, 0x63, 0x12, 0xcf,
|
||||
0xc3, 0x1a, 0xa9, 0x95, 0xb9, 0xe2, 0x82, 0x50, 0x9c, 0x39, 0xf2, 0x97, 0x51, 0x20, 0x87, 0x5f,
|
||||
0x83, 0xaa, 0x81, 0x3d, 0x7a, 0xe6, 0x74, 0x30, 0x25, 0xa7, 0xba, 0x49, 0x6a, 0xd3, 0xfc, 0xa8,
|
||||
0xbf, 0x37, 0x5a, 0x96, 0x30, 0x0b, 0x65, 0x45, 0xa0, 0x57, 0x0f, 0x13, 0x48, 0x28, 0x85, 0x0c,
|
||||
0x7b, 0x00, 0xb2, 0x95, 0x53, 0x17, 0x5b, 0x9e, 0x7f, 0x64, 0xcc, 0xdf, 0xcc, 0xd8, 0xfe, 0xd6,
|
||||
0x84, 0x3f, 0x78, 0x98, 0x41, 0x43, 0x43, 0x3c, 0x34, 0x2e, 0x25, 0x50, 0x8d, 0x2e, 0xec, 0x0e,
|
||||
0xaa, 0xfc, 0xe7, 0xc9, 0x2a, 0x7f, 0x38, 0x41, 0xda, 0xe6, 0x54, 0xf7, 0xef, 0x8a, 0x00, 0x46,
|
||||
0x4a, 0xc8, 0x36, 0x8c, 0x36, 0x56, 0x2f, 0xe0, 0x06, 0x28, 0x59, 0xd8, 0x0c, 0xb2, 0x35, 0x2c,
|
||||
0xa5, 0x9f, 0x61, 0x93, 0x20, 0x2e, 0x81, 0x7f, 0x94, 0x00, 0xec, 0xf2, 0xab, 0xe8, 0xec, 0x59,
|
||||
0x96, 0x4d, 0x31, 0x3b, 0x9d, 0x20, 0xc0, 0xd6, 0x04, 0x01, 0x06, 0xbe, 0xe5, 0xb3, 0x0c, 0xea,
|
||||
0x81, 0x45, 0xdd, 0x7e, 0x74, 0x4b, 0x59, 0x05, 0x34, 0x24, 0x14, 0x78, 0x01, 0x80, 0x2b, 0x30,
|
||||
0x4f, 0x6d, 0x51, 0xf0, 0xa3, 0x77, 0x93, 0x20, 0x9c, 0x7d, 0xdb, 0x7a, 0xa5, 0x6b, 0x51, 0xcb,
|
||||
0x42, 0x21, 0x24, 0x8a, 0xc1, 0xaf, 0x1d, 0x80, 0xd5, 0x9c, 0xb8, 0xe1, 0x3d, 0x50, 0xbc, 0x20,
|
||||
0x7d, 0xff, 0x28, 0x11, 0xfb, 0x09, 0x97, 0x41, 0xb9, 0x87, 0x8d, 0x2e, 0xf1, 0xab, 0x19, 0xf9,
|
||||
0x1f, 0x3b, 0x85, 0xc7, 0x52, 0xe3, 0x1f, 0xe5, 0x78, 0x66, 0xb1, 0xce, 0x05, 0x37, 0xd9, 0x43,
|
||||
0xe4, 0x18, 0xba, 0x8a, 0x3d, 0x8e, 0x51, 0x56, 0xde, 0xf3, 0x1f, 0x21, 0x7f, 0x0d, 0x85, 0x52,
|
||||
0xf8, 0x4b, 0x50, 0xf1, 0x88, 0x41, 0x54, 0x6a, 0xbb, 0xa2, 0x79, 0x3e, 0x1c, 0x31, 0x07, 0x71,
|
||||
0x9b, 0x18, 0x2d, 0x61, 0xea, 0xc3, 0x07, 0x5f, 0x28, 0x84, 0x84, 0xbf, 0x00, 0x15, 0x4a, 0x4c,
|
||||
0xc7, 0xc0, 0x94, 0x88, 0xd3, 0xdc, 0xca, 0x3f, 0x4d, 0x06, 0x7b, 0x62, 0x77, 0x4e, 0x85, 0x01,
|
||||
0xef, 0xc8, 0x61, 0x86, 0x07, 0xab, 0x28, 0x04, 0x84, 0x3a, 0xa8, 0x78, 0x94, 0x31, 0x09, 0xad,
|
||||
0xcf, 0x7b, 0xd1, 0x38, 0x4f, 0x59, 0xbc, 0x37, 0xfb, 0x10, 0x91, 0xab, 0x60, 0x05, 0x85, 0xf0,
|
||||
0x70, 0x0f, 0x2c, 0x98, 0xba, 0x85, 0x08, 0xee, 0xf4, 0x5b, 0x44, 0xb5, 0xad, 0x8e, 0xc7, 0x9b,
|
||||
0x5a, 0x59, 0x59, 0x15, 0x46, 0x0b, 0x47, 0x49, 0x31, 0x4a, 0xeb, 0xc3, 0x43, 0xb0, 0x1c, 0x3c,
|
||||
0xfd, 0x3f, 0xd1, 0x3d, 0x6a, 0xbb, 0xfd, 0x43, 0xdd, 0xd4, 0x29, 0x6f, 0x75, 0x65, 0xa5, 0x36,
|
||||
0xb8, 0x5a, 0x5f, 0x46, 0x43, 0xe4, 0x68, 0xa8, 0x15, 0xeb, 0xc2, 0x0e, 0xee, 0x7a, 0xa4, 0xc3,
|
||||
0x5b, 0x57, 0x25, 0xea, 0xc2, 0x27, 0x7c, 0x15, 0x09, 0x29, 0xd4, 0x12, 0x09, 0x5d, 0xf9, 0xef,
|
||||
0x12, 0xba, 0x9a, 0x9f, 0xcc, 0xf0, 0x0c, 0xac, 0x3a, 0xae, 0xad, 0xb9, 0xc4, 0xf3, 0x9e, 0x11,
|
||||
0xdc, 0x31, 0x74, 0x8b, 0x04, 0x27, 0x35, 0xcb, 0x77, 0xf8, 0xc1, 0xe0, 0x6a, 0x7d, 0xf5, 0x64,
|
||||
0xb8, 0x0a, 0xca, 0xb3, 0x6d, 0x7c, 0x5b, 0x02, 0xf7, 0xd2, 0xef, 0x28, 0xfc, 0x29, 0x80, 0x76,
|
||||
0xdb, 0x23, 0x6e, 0x8f, 0x74, 0x3e, 0xf7, 0xc9, 0x24, 0x63, 0x5c, 0x12, 0x67, 0x5c, 0x61, 0xc5,
|
||||
0x1f, 0x67, 0x34, 0xd0, 0x10, 0x2b, 0x9f, 0xb3, 0x89, 0x52, 0x29, 0xf0, 0x40, 0x63, 0x9c, 0x2d,
|
||||
0x53, 0x2e, 0x7b, 0x60, 0x41, 0x74, 0x8d, 0x40, 0xc8, 0xd3, 0x3a, 0x96, 0x07, 0x67, 0x49, 0x31,
|
||||
0x4a, 0xeb, 0xc3, 0xcf, 0xc1, 0x22, 0xee, 0x61, 0xdd, 0xc0, 0x6d, 0x83, 0x84, 0x20, 0x25, 0x0e,
|
||||
0xf2, 0xbe, 0x00, 0x59, 0xdc, 0x4b, 0x2b, 0xa0, 0xac, 0x0d, 0x3c, 0x02, 0x4b, 0x5d, 0x2b, 0x0b,
|
||||
0xe5, 0xe7, 0xe5, 0x07, 0x02, 0x6a, 0xe9, 0x2c, 0xab, 0x82, 0x86, 0xd9, 0x41, 0x07, 0x00, 0x35,
|
||||
0x78, 0xf2, 0xbd, 0xda, 0x34, 0xef, 0xc9, 0x3f, 0x9c, 0xa0, 0x9e, 0x42, 0xde, 0x10, 0xf5, 0xbf,
|
||||
0x70, 0xc9, 0x43, 0x31, 0x1f, 0x70, 0x17, 0xcc, 0xbb, 0xac, 0x42, 0xc2, 0xd0, 0x67, 0x78, 0xe8,
|
||||
0xdf, 0x11, 0x66, 0xf3, 0x28, 0x2e, 0x44, 0x49, 0x5d, 0xb8, 0x03, 0xaa, 0xaa, 0x6d, 0x18, 0xbc,
|
||||
0x32, 0xf6, 0xed, 0xae, 0x45, 0x79, 0x72, 0x17, 0x15, 0xc8, 0x38, 0xc0, 0x7e, 0x42, 0x82, 0x52,
|
||||
0x9a, 0x8d, 0xbf, 0x49, 0xf1, 0x07, 0x2c, 0x28, 0x77, 0xb8, 0x93, 0xa0, 0x5b, 0x1f, 0xa5, 0xe8,
|
||||
0xd6, 0x4a, 0xd6, 0x22, 0xc6, 0xb6, 0xfa, 0x60, 0x9e, 0x15, 0x83, 0x6e, 0x69, 0x7e, 0x02, 0x88,
|
||||
0x66, 0xfa, 0xa3, 0xb1, 0x4a, 0x2d, 0xb4, 0x8e, 0x3d, 0xc1, 0x8b, 0xfc, 0x24, 0xe2, 0x42, 0x94,
|
||||
0xf4, 0xd4, 0x78, 0x0e, 0x3e, 0x3c, 0xc1, 0x2e, 0x0d, 0xb9, 0x1a, 0x79, 0xd5, 0x35, 0x5a, 0x24,
|
||||
0xda, 0xd6, 0x7d, 0x30, 0x63, 0xbb, 0x1d, 0xdd, 0xc2, 0x86, 0x78, 0x0b, 0x42, 0x22, 0x76, 0xec,
|
||||
0x2f, 0xa3, 0x40, 0xde, 0x78, 0x0a, 0xaa, 0xc9, 0x92, 0x4f, 0x8c, 0x34, 0xd2, 0xad, 0x23, 0xcd,
|
||||
0x5b, 0x09, 0xac, 0xe6, 0x6c, 0x04, 0x1a, 0xa0, 0x6a, 0xe2, 0xd7, 0xb1, 0x74, 0xbc, 0x75, 0x14,
|
||||
0x60, 0xd3, 0xa9, 0xec, 0x4f, 0xa7, 0xf2, 0x73, 0x8b, 0x1e, 0xbb, 0x2d, 0xea, 0xea, 0x96, 0xe6,
|
||||
0x5f, 0xf1, 0x51, 0x02, 0x0b, 0xa5, 0xb0, 0xe1, 0x4b, 0x50, 0x31, 0xf1, 0xeb, 0x56, 0xd7, 0xd5,
|
||||
0x82, 0xab, 0x18, 0xdf, 0x0f, 0x7f, 0xd4, 0x8e, 0x04, 0x0a, 0x0a, 0xf1, 0x1a, 0x7f, 0x28, 0x80,
|
||||
0x72, 0x4b, 0xc5, 0x06, 0xb9, 0x83, 0xc1, 0xe6, 0x34, 0x31, 0xd8, 0x6c, 0x8f, 0x9c, 0x4e, 0x3c,
|
||||
0xbe, 0xdc, 0x99, 0xe6, 0xcb, 0xd4, 0x4c, 0xf3, 0x68, 0x4c, 0xdc, 0x9b, 0xc7, 0x99, 0x27, 0x60,
|
||||
0x36, 0x74, 0x9f, 0xe8, 0xaf, 0xd2, 0x6d, 0xfd, 0xb5, 0xf1, 0xa7, 0x02, 0x98, 0x8b, 0xb9, 0x18,
|
||||
0xcf, 0x1a, 0x3a, 0x09, 0x32, 0xc3, 0x1a, 0x98, 0x32, 0xc9, 0xc6, 0xe4, 0x80, 0xc8, 0xf8, 0x1c,
|
||||
0x32, 0xe2, 0x05, 0x59, 0x7e, 0xf3, 0x14, 0x54, 0x29, 0x76, 0x35, 0x42, 0x03, 0x19, 0x3f, 0xd0,
|
||||
0xd9, 0x68, 0x1a, 0x39, 0x4d, 0x48, 0x51, 0x4a, 0x7b, 0x6d, 0x17, 0xcc, 0x27, 0x9c, 0x8d, 0x45,
|
||||
0xfc, 0xfe, 0xc2, 0x0e, 0x2b, 0x2a, 0xf8, 0x3b, 0xc8, 0xc6, 0x97, 0x89, 0x6c, 0x7c, 0x3c, 0xfa,
|
||||
0xe1, 0xc6, 0xda, 0x52, 0x5e, 0x4e, 0xb6, 0x53, 0x39, 0xb9, 0x33, 0x11, 0xfa, 0xcd, 0x99, 0xf9,
|
||||
0x57, 0x09, 0x2c, 0xc4, 0xb4, 0xef, 0x60, 0x0a, 0xfb, 0x22, 0x39, 0x85, 0x3d, 0x9a, 0x64, 0x53,
|
||||
0x39, 0x63, 0xd8, 0xbf, 0xca, 0x89, 0xcd, 0xfc, 0x1f, 0x11, 0xff, 0xdf, 0x4a, 0x60, 0xb9, 0x67,
|
||||
0x1b, 0x5d, 0x93, 0xec, 0x1b, 0x58, 0x37, 0x03, 0x0d, 0x46, 0xa3, 0x6e, 0x19, 0x75, 0xb9, 0x27,
|
||||
0xe2, 0x7a, 0xba, 0x47, 0x89, 0x45, 0x5f, 0x44, 0x18, 0xca, 0x87, 0xc2, 0xdf, 0xf2, 0x8b, 0x21,
|
||||
0xc0, 0x68, 0xa8, 0x3b, 0xf8, 0x03, 0x30, 0xc7, 0xf8, 0xa4, 0xae, 0x12, 0x36, 0xe4, 0x8a, 0xbf,
|
||||
0x39, 0x96, 0x04, 0xd0, 0x5c, 0x2b, 0x12, 0xa1, 0xb8, 0x1e, 0x3c, 0x07, 0x4b, 0x8e, 0xdd, 0x39,
|
||||
0xc2, 0x16, 0xd6, 0x08, 0x7b, 0x1a, 0x4f, 0xf8, 0xff, 0xa3, 0x7c, 0x10, 0x98, 0x55, 0x3e, 0x0d,
|
||||
0x88, 0xdb, 0x49, 0x56, 0xe5, 0x1d, 0x63, 0xd0, 0xd9, 0x65, 0x4e, 0x43, 0x86, 0x41, 0xc2, 0xdf,
|
||||
0x48, 0xa0, 0xea, 0xf3, 0xcf, 0x80, 0x0d, 0x88, 0x7f, 0x3a, 0x94, 0x49, 0xf2, 0xf0, 0x2c, 0x81,
|
||||
0x14, 0xf5, 0xb8, 0xe4, 0x3a, 0x4a, 0x79, 0xcc, 0x1d, 0x7c, 0x2a, 0x93, 0x0c, 0x3e, 0x8d, 0xbf,
|
||||
0x17, 0xc1, 0x62, 0xa6, 0xe0, 0xe1, 0x8f, 0x6f, 0x98, 0x08, 0x56, 0xfe, 0x67, 0xd3, 0x40, 0x86,
|
||||
0xc0, 0x16, 0xc7, 0x20, 0xb0, 0x7b, 0x60, 0x41, 0xed, 0xba, 0x2e, 0xb1, 0x68, 0x6a, 0x0a, 0x08,
|
||||
0x47, 0x89, 0xfd, 0xa4, 0x18, 0xa5, 0xf5, 0x87, 0x4d, 0x23, 0xe5, 0x31, 0xa7, 0x91, 0x78, 0x14,
|
||||
0x82, 0xe6, 0xf9, 0x79, 0x98, 0x8d, 0x42, 0xb0, 0xbd, 0xb4, 0x3e, 0x7b, 0x03, 0x7d, 0xd4, 0x10,
|
||||
0x61, 0x26, 0xf9, 0x06, 0x9e, 0x25, 0xa4, 0x28, 0xa5, 0xdd, 0xf8, 0x56, 0x02, 0xef, 0xe7, 0x66,
|
||||
0x19, 0xdc, 0x4b, 0x90, 0xf2, 0xad, 0x14, 0x29, 0xff, 0x6e, 0xae, 0x61, 0x8c, 0x9b, 0xbb, 0x60,
|
||||
0xd6, 0x09, 0x08, 0xb2, 0xe8, 0x75, 0x07, 0x23, 0xe7, 0xff, 0x4d, 0xd4, 0x5a, 0x99, 0x1f, 0x5c,
|
||||
0xad, 0xcf, 0x86, 0x1a, 0x28, 0x72, 0xa3, 0xdc, 0xbf, 0xbc, 0xae, 0x4f, 0x7d, 0x73, 0x5d, 0x9f,
|
||||
0x7a, 0x73, 0x5d, 0x9f, 0xfa, 0xf5, 0xa0, 0x2e, 0x5d, 0x0e, 0xea, 0xd2, 0x37, 0x83, 0xba, 0xf4,
|
||||
0xcf, 0x41, 0x5d, 0xfa, 0xfd, 0xdb, 0xfa, 0xd4, 0xcb, 0x19, 0xe1, 0xe1, 0x3f, 0x01, 0x00, 0x00,
|
||||
0xff, 0xff, 0x4f, 0x0f, 0xec, 0xcc, 0xce, 0x1a, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -224,6 +224,14 @@ message DeploymentStrategy {
|
|||
optional RollingUpdateDeployment rollingUpdate = 2;
|
||||
}
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
message PartitionStatefulSetStrategy {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
optional int32 ordinal = 1;
|
||||
}
|
||||
|
||||
message RollbackConfig {
|
||||
// The revision to rollback to. If set to 0, rollback to the last revision.
|
||||
// +optional
|
||||
|
@ -378,15 +386,60 @@ message StatefulSetSpec {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
optional string podManagementPolicy = 6;
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
optional StatefulSetUpdateStrategy updateStrategy = 7;
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
optional int32 revisionHistoryLimit = 8;
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
message StatefulSetStatus {
|
||||
// observedGeneration is the most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
optional int64 observedGeneration = 1;
|
||||
|
||||
// replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
optional int32 replicas = 2;
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
optional int32 readyReplicas = 3;
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
optional int32 currentReplicas = 4;
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
optional int32 updatedReplicas = 5;
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
optional string currentRevision = 6;
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
optional string updateRevision = 7;
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
message StatefulSetUpdateStrategy {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
optional string type = 1;
|
||||
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
optional PartitionStatefulSetStrategy partition = 2;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,7 @@ import (
|
|||
const (
|
||||
// StatefulSetInitAnnotation if present, and set to false, indicates that a Pod's readiness should be ignored.
|
||||
StatefulSetInitAnnotation = "pod.alpha.kubernetes.io/initialized"
|
||||
StatefulSetRevisionLabel = "statefulset.beta.kubernetes.io/revision"
|
||||
)
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource
|
||||
|
@ -111,6 +112,54 @@ const (
|
|||
ParallelPodManagement = "Parallel"
|
||||
)
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
type StatefulSetUpdateStrategy struct {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Type StatefulSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetStrategyType"`
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
Partition *PartitionStatefulSetStrategy `json:"partition,omitempty" protobuf:"bytes,2,opt,name=partition"`
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
|
||||
// all possible update strategies for the StatefulSet controller.
|
||||
type StatefulSetUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// PartitionStatefulSetStrategyType indicates that updates will only be
|
||||
// applied to a partition of the StatefulSet. This is useful for canaries
|
||||
// and phased roll outs. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's currentRevision if there ordinal is less than the supplied
|
||||
// Partition's ordinal. Otherwise, they will be created from the specification
|
||||
// version indicated by the StatefulSet's updateRevision.
|
||||
PartitionStatefulSetStrategyType StatefulSetUpdateStrategyType = "Partition"
|
||||
// RollingUpdateStatefulSetStrategyType indicates that update will be
|
||||
// applied to all Pods in the StatefulSet with respect to the StatefulSet
|
||||
// ordering constraints. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's updateRevision.
|
||||
RollingUpdateStatefulSetStrategyType = "RollingUpdate"
|
||||
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
|
||||
// tracking and ordered rolling restarts are disabled. Pods are recreated
|
||||
// from the StatefulSetSpec when they are manually deleted. When a scale
|
||||
// operation is performed with this strategy,specification version indicated
|
||||
// by the StatefulSet's currentRevision.
|
||||
OnDeleteStatefulSetStrategyType = "OnDelete"
|
||||
)
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
type PartitionStatefulSetStrategy struct {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
Ordinal int32 `json:"ordinal" protobuf:"varint,1,opt,name=ordinal"`
|
||||
}
|
||||
|
||||
// A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type StatefulSetSpec struct {
|
||||
// replicas is the desired number of replicas of the given Template.
|
||||
|
@ -160,16 +209,47 @@ type StatefulSetSpec struct {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
PodManagementPolicy PodManagementPolicyType `json:"podManagementPolicy,omitempty" protobuf:"bytes,6,opt,name=podManagementPolicy,casttype=PodManagementPolicyType"`
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
UpdateStrategy StatefulSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,7,opt,name=updateStrategy"`
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,8,opt,name=revisionHistoryLimit"`
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
type StatefulSetStatus struct {
|
||||
// observedGeneration is the most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
|
||||
|
||||
// replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
Replicas int32 `json:"replicas" protobuf:"varint,2,opt,name=replicas"`
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,3,opt,name=readyReplicas"`
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
CurrentReplicas int32 `json:"currentReplicas,omitempty" protobuf:"varint,4,opt,name=currentReplicas"`
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,5,opt,name=updatedReplicas"`
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
CurrentRevision string `json:"currentRevision,omitempty" protobuf:"bytes,6,opt,name=currentRevision"`
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
||||
}
|
||||
|
||||
// StatefulSetList is a collection of StatefulSets.
|
||||
|
|
|
@ -137,6 +137,15 @@ func (DeploymentStrategy) SwaggerDoc() map[string]string {
|
|||
return map_DeploymentStrategy
|
||||
}
|
||||
|
||||
var map_PartitionStatefulSetStrategy = map[string]string{
|
||||
"": "PartitionStatefulSetStrategy contains the parameters used with the PartitionStatefulSetStrategyType.",
|
||||
"ordinal": "Ordinal indicates the ordinal at which the StatefulSet should be partitioned.",
|
||||
}
|
||||
|
||||
func (PartitionStatefulSetStrategy) SwaggerDoc() map[string]string {
|
||||
return map_PartitionStatefulSetStrategy
|
||||
}
|
||||
|
||||
var map_RollbackConfig = map[string]string{
|
||||
"revision": "The revision to rollback to. If set to 0, rollback to the last revision.",
|
||||
}
|
||||
|
@ -212,6 +221,8 @@ var map_StatefulSetSpec = map[string]string{
|
|||
"volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.",
|
||||
"serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.",
|
||||
"podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.",
|
||||
"updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.",
|
||||
"revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.",
|
||||
}
|
||||
|
||||
func (StatefulSetSpec) SwaggerDoc() map[string]string {
|
||||
|
@ -220,12 +231,27 @@ func (StatefulSetSpec) SwaggerDoc() map[string]string {
|
|||
|
||||
var map_StatefulSetStatus = map[string]string{
|
||||
"": "StatefulSetStatus represents the current state of a StatefulSet.",
|
||||
"observedGeneration": "observedGeneration is the most recent generation observed by this StatefulSet.",
|
||||
"replicas": "replicas is the number of actual replicas.",
|
||||
"observedGeneration": "observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the StatefulSet's generation, which is updated on mutation by the API Server.",
|
||||
"replicas": "replicas is the number of Pods created by the StatefulSet controller.",
|
||||
"readyReplicas": "readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.",
|
||||
"currentReplicas": "currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by currentRevision.",
|
||||
"updatedReplicas": "updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by updateRevision.",
|
||||
"currentRevision": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).",
|
||||
"updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)",
|
||||
}
|
||||
|
||||
func (StatefulSetStatus) SwaggerDoc() map[string]string {
|
||||
return map_StatefulSetStatus
|
||||
}
|
||||
|
||||
var map_StatefulSetUpdateStrategy = map[string]string{
|
||||
"": "StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.",
|
||||
"type": "Type indicates the type of the StatefulSetUpdateStrategy.",
|
||||
"partition": "Partition is used to communicate the ordinal at which to partition the StatefulSet when Type is PartitionStatefulSetStrategyType. This value must be set when Type is PartitionStatefulSetStrategyType, and it must be nil otherwise.",
|
||||
}
|
||||
|
||||
func (StatefulSetUpdateStrategy) SwaggerDoc() map[string]string {
|
||||
return map_StatefulSetUpdateStrategy
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
|
|
|
@ -42,6 +42,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_apps_ControllerRevision_To_v1beta1_ControllerRevision,
|
||||
Convert_v1beta1_ControllerRevisionList_To_apps_ControllerRevisionList,
|
||||
Convert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList,
|
||||
Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy,
|
||||
Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy,
|
||||
Convert_v1beta1_StatefulSet_To_apps_StatefulSet,
|
||||
Convert_apps_StatefulSet_To_v1beta1_StatefulSet,
|
||||
Convert_v1beta1_StatefulSetList_To_apps_StatefulSetList,
|
||||
|
@ -50,6 +52,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec,
|
||||
Convert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus,
|
||||
Convert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus,
|
||||
Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy,
|
||||
Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -123,6 +127,26 @@ func Convert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in *a
|
|||
return autoConvert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in *PartitionStatefulSetStrategy, out *apps.PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
out.Ordinal = in.Ordinal
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy is an autogenerated conversion function.
|
||||
func Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in *PartitionStatefulSetStrategy, out *apps.PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in *apps.PartitionStatefulSetStrategy, out *PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
out.Ordinal = in.Ordinal
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy is an autogenerated conversion function.
|
||||
func Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in *apps.PartitionStatefulSetStrategy, out *PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
return autoConvert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSet_To_apps_StatefulSet(in *StatefulSet, out *apps.StatefulSet, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
|
@ -208,6 +232,10 @@ func autoConvert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(in *StatefulSet
|
|||
out.VolumeClaimTemplates = *(*[]api.PersistentVolumeClaim)(unsafe.Pointer(&in.VolumeClaimTemplates))
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = apps.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -222,12 +250,21 @@ func autoConvert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(in *apps.Statef
|
|||
out.VolumeClaimTemplates = *(*[]api_v1.PersistentVolumeClaim)(unsafe.Pointer(&in.VolumeClaimTemplates))
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit))
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus(in *StatefulSetStatus, out *apps.StatefulSetStatus, s conversion.Scope) error {
|
||||
out.ObservedGeneration = (*int64)(unsafe.Pointer(in.ObservedGeneration))
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -239,6 +276,11 @@ func Convert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus(in *StatefulSet
|
|||
func autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.StatefulSetStatus, out *StatefulSetStatus, s conversion.Scope) error {
|
||||
out.ObservedGeneration = (*int64)(unsafe.Pointer(in.ObservedGeneration))
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -246,3 +288,15 @@ func autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.St
|
|||
func Convert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.StatefulSetStatus, out *StatefulSetStatus, s conversion.Scope) error {
|
||||
return autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(in *StatefulSetUpdateStrategy, out *apps.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = apps.StatefulSetUpdateStrategyType(in.Type)
|
||||
out.Partition = (*apps.PartitionStatefulSetStrategy)(unsafe.Pointer(in.Partition))
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(in *apps.StatefulSetUpdateStrategy, out *StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = StatefulSetUpdateStrategyType(in.Type)
|
||||
out.Partition = (*PartitionStatefulSetStrategy)(unsafe.Pointer(in.Partition))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentSpec, InType: reflect.TypeOf(&DeploymentSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentStatus, InType: reflect.TypeOf(&DeploymentStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentStrategy, InType: reflect.TypeOf(&DeploymentStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_PartitionStatefulSetStrategy, InType: reflect.TypeOf(&PartitionStatefulSetStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_RollbackConfig, InType: reflect.TypeOf(&RollbackConfig{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_RollingUpdateDeployment, InType: reflect.TypeOf(&RollingUpdateDeployment{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_Scale, InType: reflect.TypeOf(&Scale{})},
|
||||
|
@ -55,6 +56,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetList, InType: reflect.TypeOf(&StatefulSetList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetSpec, InType: reflect.TypeOf(&StatefulSetSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetStatus, InType: reflect.TypeOf(&StatefulSetStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetUpdateStrategy, InType: reflect.TypeOf(&StatefulSetUpdateStrategy{})},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -251,6 +253,16 @@ func DeepCopy_v1beta1_DeploymentStrategy(in interface{}, out interface{}, c *con
|
|||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_PartitionStatefulSetStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_PartitionStatefulSetStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*PartitionStatefulSetStrategy)
|
||||
out := out.(*PartitionStatefulSetStrategy)
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_RollbackConfig is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_RollbackConfig(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
|
@ -397,6 +409,14 @@ func DeepCopy_v1beta1_StatefulSetSpec(in interface{}, out interface{}, c *conver
|
|||
}
|
||||
}
|
||||
}
|
||||
if err := DeepCopy_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -415,3 +435,18 @@ func DeepCopy_v1beta1_StatefulSetStatus(in interface{}, out interface{}, c *conv
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_StatefulSetUpdateStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_StatefulSetUpdateStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatefulSetUpdateStrategy)
|
||||
out := out.(*StatefulSetUpdateStrategy)
|
||||
*out = *in
|
||||
if in.Partition != nil {
|
||||
in, out := &in.Partition, &out.Partition
|
||||
*out = new(PartitionStatefulSetStrategy)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,40 @@ func ValidateStatefulSetSpec(spec *apps.StatefulSetSpec, fldPath *field.Path) fi
|
|||
allErrs = append(allErrs, field.Invalid(fldPath.Child("podManagementPolicy"), spec.PodManagementPolicy, fmt.Sprintf("must be '%s' or '%s'", apps.OrderedReadyPodManagement, apps.ParallelPodManagement)))
|
||||
}
|
||||
|
||||
switch spec.UpdateStrategy.Type {
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("updateStrategy"), ""))
|
||||
case apps.OnDeleteStatefulSetStrategyType, apps.RollingUpdateStatefulSetStrategyType:
|
||||
if spec.UpdateStrategy.Partition != nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Invalid(
|
||||
fldPath.Child("updateStrategy").Child("partition"),
|
||||
spec.UpdateStrategy.Partition.Ordinal,
|
||||
fmt.Sprintf("only allowed for updateStrategy '%s'", apps.PartitionStatefulSetStrategyType)))
|
||||
}
|
||||
case apps.PartitionStatefulSetStrategyType:
|
||||
if spec.UpdateStrategy.Partition == nil {
|
||||
allErrs = append(
|
||||
allErrs,
|
||||
field.Required(
|
||||
fldPath.Child("updateStrategy").Child("partition"),
|
||||
fmt.Sprintf("required for updateStrategy '%s'", apps.PartitionStatefulSetStrategyType)))
|
||||
break
|
||||
}
|
||||
allErrs = append(allErrs,
|
||||
apivalidation.ValidateNonnegativeField(
|
||||
int64(spec.UpdateStrategy.Partition.Ordinal),
|
||||
fldPath.Child("updateStrategy").Child("partition").Child("ordinal"))...)
|
||||
default:
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(fldPath.Child("updateStrategy"), spec.UpdateStrategy,
|
||||
fmt.Sprintf("must be '%s', '%s', or '%s'",
|
||||
apps.RollingUpdateStatefulSetStrategyType,
|
||||
apps.OnDeleteStatefulSetStrategyType,
|
||||
apps.PartitionStatefulSetStrategyType)))
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
||||
if spec.Selector == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("selector"), ""))
|
||||
|
@ -113,20 +147,21 @@ func ValidateStatefulSet(statefulSet *apps.StatefulSet) field.ErrorList {
|
|||
func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet *apps.StatefulSet) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&statefulSet.ObjectMeta, &oldStatefulSet.ObjectMeta, field.NewPath("metadata"))
|
||||
|
||||
// TODO: For now we're taking the safe route and disallowing all updates to
|
||||
// spec except for Replicas, for scaling, and Template.Spec.containers.image
|
||||
// for rolling-update. Enable others on a case by case basis.
|
||||
restoreReplicas := statefulSet.Spec.Replicas
|
||||
statefulSet.Spec.Replicas = oldStatefulSet.Spec.Replicas
|
||||
|
||||
restoreContainers := statefulSet.Spec.Template.Spec.Containers
|
||||
statefulSet.Spec.Template.Spec.Containers = oldStatefulSet.Spec.Template.Spec.Containers
|
||||
restoreTemplate := statefulSet.Spec.Template
|
||||
statefulSet.Spec.Template = oldStatefulSet.Spec.Template
|
||||
|
||||
restoreStrategy := statefulSet.Spec.UpdateStrategy
|
||||
statefulSet.Spec.UpdateStrategy = oldStatefulSet.Spec.UpdateStrategy
|
||||
|
||||
if !reflect.DeepEqual(statefulSet.Spec, oldStatefulSet.Spec) {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to statefulset spec for fields other than 'replicas' and 'containers' are forbidden."))
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden."))
|
||||
}
|
||||
statefulSet.Spec.Replicas = restoreReplicas
|
||||
statefulSet.Spec.Template.Spec.Containers = restoreContainers
|
||||
statefulSet.Spec.Template = restoreTemplate
|
||||
statefulSet.Spec.UpdateStrategy = restoreStrategy
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(statefulSet.Spec.Replicas), field.NewPath("spec", "replicas"))...)
|
||||
containerErrs, _ := apivalidation.ValidateContainerUpdates(statefulSet.Spec.Template.Spec.Containers, oldStatefulSet.Spec.Template.Spec.Containers, field.NewPath("spec").Child("template").Child("containers"))
|
||||
|
|
|
@ -59,6 +59,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -67,6 +68,39 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.ParallelPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{
|
||||
Type: apps.PartitionStatefulSetStrategyType,
|
||||
Partition: func() *apps.PartitionStatefulSetStrategy {
|
||||
return &apps.PartitionStatefulSetStrategy{Ordinal: 2}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -83,6 +117,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"missing-namespace": {
|
||||
|
@ -91,6 +126,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
|
@ -98,6 +134,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"selector_doesnt_match": {
|
||||
|
@ -106,6 +143,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid manifest": {
|
||||
|
@ -113,6 +151,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"negative_replicas": {
|
||||
|
@ -121,6 +160,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Replicas: -1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_label": {
|
||||
|
@ -135,6 +175,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_label 2": {
|
||||
|
@ -148,6 +189,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Template: invalidPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_annotation": {
|
||||
|
@ -162,6 +204,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 1": {
|
||||
|
@ -182,6 +225,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Labels: validLabels,
|
||||
},
|
||||
},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 2": {
|
||||
|
@ -202,6 +246,42 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Labels: validLabels,
|
||||
},
|
||||
},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid udpate strategy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: "foo"},
|
||||
},
|
||||
},
|
||||
"partitioned rolling update": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
Partition: func() *apps.PartitionStatefulSetStrategy {
|
||||
return &apps.PartitionStatefulSetStrategy{Ordinal: 2}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
"empty partition": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{
|
||||
Type: apps.PartitionStatefulSetStrategyType,
|
||||
Partition: nil},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -222,7 +302,10 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
field != "spec.template.labels" &&
|
||||
field != "metadata.annotations" &&
|
||||
field != "metadata.labels" &&
|
||||
field != "status.replicas" {
|
||||
field != "status.replicas" &&
|
||||
field != "spec.updateStrategy" &&
|
||||
field != "spec.updateStrategy.partition" &&
|
||||
field != "spec.updateStrategy.partition.ordinal" {
|
||||
t.Errorf("%s: missing prefix for: %v", k, errs[i])
|
||||
}
|
||||
}
|
||||
|
@ -280,6 +363,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
|
@ -289,6 +373,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -305,8 +390,9 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
old: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
|
@ -316,6 +402,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
Replicas: 2,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: readWriteVolumePodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -323,16 +410,18 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
old: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -340,8 +429,9 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
old: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
|
@ -351,24 +441,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
},
|
||||
"updates to a field other than spec.Replicas": {
|
||||
old: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Replicas: 1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: readWriteVolumePodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -376,8 +449,9 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
old: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
|
@ -387,6 +461,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
Replicas: 2,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: invalidLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -397,14 +472,16 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
update: apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Replicas: 2,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: invalidPodTemplate.Template,
|
||||
Replicas: 2,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: invalidPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -423,6 +500,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||
Replicas: -1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -38,10 +38,12 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_ControllerRevision, InType: reflect.TypeOf(&ControllerRevision{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_ControllerRevisionList, InType: reflect.TypeOf(&ControllerRevisionList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_PartitionStatefulSetStrategy, InType: reflect.TypeOf(&PartitionStatefulSetStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSet, InType: reflect.TypeOf(&StatefulSet{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetList, InType: reflect.TypeOf(&StatefulSetList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetSpec, InType: reflect.TypeOf(&StatefulSetSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetStatus, InType: reflect.TypeOf(&StatefulSetStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetUpdateStrategy, InType: reflect.TypeOf(&StatefulSetUpdateStrategy{})},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -87,6 +89,16 @@ func DeepCopy_apps_ControllerRevisionList(in interface{}, out interface{}, c *co
|
|||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_PartitionStatefulSetStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_PartitionStatefulSetStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*PartitionStatefulSetStrategy)
|
||||
out := out.(*PartitionStatefulSetStrategy)
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_StatefulSet is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_StatefulSet(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
|
@ -153,6 +165,14 @@ func DeepCopy_apps_StatefulSetSpec(in interface{}, out interface{}, c *conversio
|
|||
}
|
||||
}
|
||||
}
|
||||
if err := DeepCopy_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -171,3 +191,18 @@ func DeepCopy_apps_StatefulSetStatus(in interface{}, out interface{}, c *convers
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_StatefulSetUpdateStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_StatefulSetUpdateStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatefulSetUpdateStrategy)
|
||||
out := out.(*StatefulSetUpdateStrategy)
|
||||
*out = *in
|
||||
if in.Partition != nil {
|
||||
in, out := &in.Partition, &out.Partition
|
||||
*out = new(PartitionStatefulSetStrategy)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ filegroup(
|
|||
"//pkg/controller/disruption:all-srcs",
|
||||
"//pkg/controller/endpoint:all-srcs",
|
||||
"//pkg/controller/garbagecollector:all-srcs",
|
||||
"//pkg/controller/history:all-srcs",
|
||||
"//pkg/controller/job:all-srcs",
|
||||
"//pkg/controller/namespace:all-srcs",
|
||||
"//pkg/controller/node:all-srcs",
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["controller_history_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/apps/v1beta1:go_default_library",
|
||||
"//pkg/client/clientset_generated/clientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/externalversions:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controller_history.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/apps/v1beta1:go_default_library",
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/externalversions/apps/v1beta1:go_default_library",
|
||||
"//pkg/client/listers/apps/v1beta1:go_default_library",
|
||||
"//pkg/client/retry:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/hash:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
approvers:
|
||||
- bprashanth
|
||||
- enisoc
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kargakis
|
||||
- kow3ns
|
||||
- smarterclayton
|
||||
reviewers:
|
||||
- bprashanth
|
||||
- enisoc
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kargakis
|
||||
- kow3ns
|
||||
- smarterclayton
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package history
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
appsinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/apps/v1beta1"
|
||||
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/kubernetes/pkg/client/retry"
|
||||
)
|
||||
|
||||
// ControllerRevisionHashLabel is the label used to indicate the hash value of a ControllerRevision's Data.
|
||||
const ControllerRevisionHashLabel = "controller.kubernetes.io/hash"
|
||||
|
||||
// ControllerRevisionName returns the Name for a ControllerRevision in the form prefix-hash. If the length
|
||||
// of prefix is greater than 223 bytes, it is truncated to allow for a name that is no larger than 253 bytes.
|
||||
func ControllerRevisionName(prefix string, hash uint32) string {
|
||||
if len(prefix) > 223 {
|
||||
prefix = prefix[:223]
|
||||
}
|
||||
return fmt.Sprintf("%s-%d", prefix, hash)
|
||||
}
|
||||
|
||||
// NewControllerRevision returns the a ControllerRevision with a ControllerRef pointing parent and indicating that
|
||||
// parent is of parentKind. The ControllerRevision has labels matching selector, contains Data equal to data, and
|
||||
// has a Revision equal to revision. If the returned error is nil, the returned ControllerRevision is valid. If the
|
||||
// returned error is not nil, the returned ControllerRevision is invalid for use.
|
||||
func NewControllerRevision(parent metav1.Object,
|
||||
parentKind schema.GroupVersionKind,
|
||||
selector labels.Selector,
|
||||
data runtime.RawExtension,
|
||||
revision int64) (*apps.ControllerRevision, error) {
|
||||
labelMap, err := labels.ConvertSelectorToLabelsMap(selector.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockOwnerDeletion := true
|
||||
isController := true
|
||||
cr := &apps.ControllerRevision{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: labelMap,
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: parentKind.GroupVersion().String(),
|
||||
Kind: parentKind.Kind,
|
||||
Name: parent.GetName(),
|
||||
UID: parent.GetUID(),
|
||||
BlockOwnerDeletion: &blockOwnerDeletion,
|
||||
Controller: &isController,
|
||||
},
|
||||
},
|
||||
},
|
||||
Data: data,
|
||||
Revision: revision,
|
||||
}
|
||||
hash := HashControllerRevision(cr, nil)
|
||||
cr.Name = ControllerRevisionName(parent.GetName(), hash)
|
||||
cr.Labels[ControllerRevisionHashLabel] = strconv.FormatInt(int64(hash), 10)
|
||||
return cr, nil
|
||||
}
|
||||
|
||||
// HashControllerRevision hashes the contents of revision's Data using FNV hashing. If probe is not nil, the byte value
|
||||
// of probe is added written to the hash as well.
|
||||
func HashControllerRevision(revision *apps.ControllerRevision, probe *uint32) uint32 {
|
||||
hf := fnv.New32()
|
||||
if len(revision.Data.Raw) > 0 {
|
||||
hf.Write(revision.Data.Raw)
|
||||
}
|
||||
if revision.Data.Object != nil {
|
||||
hashutil.DeepHashObject(hf, revision.Data.Object)
|
||||
}
|
||||
if probe != nil {
|
||||
hf.Write([]byte(strconv.FormatInt(int64(*probe), 10)))
|
||||
}
|
||||
return hf.Sum32()
|
||||
|
||||
}
|
||||
|
||||
// SortControllerRevisions sorts revisions by their Revision.
|
||||
func SortControllerRevisions(revisions []*apps.ControllerRevision) {
|
||||
sort.Sort(byRevision(revisions))
|
||||
}
|
||||
|
||||
// EqualRevision returns true if lhs and rhs are either both nil, or both point to non-nil ControllerRevisions that
|
||||
// contain semantically equivalent data. Otherwise this method returns false.
|
||||
func EqualRevision(lhs *apps.ControllerRevision, rhs *apps.ControllerRevision) bool {
|
||||
var lhsHash, rhsHash *uint32
|
||||
if lhs == nil || rhs == nil {
|
||||
return lhs == rhs
|
||||
}
|
||||
if hs, found := lhs.Labels[ControllerRevisionHashLabel]; found {
|
||||
hash, err := strconv.ParseInt(hs, 10, 32)
|
||||
if err == nil {
|
||||
lhsHash = new(uint32)
|
||||
*lhsHash = uint32(hash)
|
||||
}
|
||||
}
|
||||
if hs, found := rhs.Labels[ControllerRevisionHashLabel]; found {
|
||||
hash, err := strconv.ParseInt(hs, 10, 32)
|
||||
if err == nil {
|
||||
rhsHash = new(uint32)
|
||||
*rhsHash = uint32(hash)
|
||||
}
|
||||
}
|
||||
if lhsHash != nil && rhsHash != nil && *lhsHash != *rhsHash {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(lhs.Data.Raw, rhs.Data.Raw) && apiequality.Semantic.DeepEqual(lhs.Data.Object, rhs.Data.Object)
|
||||
}
|
||||
|
||||
// FindEqualRevisions returns all ControllerRevisions in revisions that are equal to needle using EqualRevision as the
|
||||
// equality test. The returned slice preserves the order of revisions.
|
||||
func FindEqualRevisions(revisions []*apps.ControllerRevision, needle *apps.ControllerRevision) []*apps.ControllerRevision {
|
||||
var eq []*apps.ControllerRevision
|
||||
for i := range revisions {
|
||||
if EqualRevision(revisions[i], needle) {
|
||||
eq = append(eq, revisions[i])
|
||||
}
|
||||
}
|
||||
return eq
|
||||
}
|
||||
|
||||
// byRevision implements sort.Interface to allow ControllerRevisions to be sorted by Revision.
|
||||
type byRevision []*apps.ControllerRevision
|
||||
|
||||
func (br byRevision) Len() int {
|
||||
return len(br)
|
||||
}
|
||||
|
||||
func (br byRevision) Less(i, j int) bool {
|
||||
return br[i].Revision < br[j].Revision
|
||||
}
|
||||
|
||||
func (br byRevision) Swap(i, j int) {
|
||||
br[i], br[j] = br[j], br[i]
|
||||
}
|
||||
|
||||
// Interface provides an interface allowing for management of a Controller's history as realized by recorded
|
||||
// ControllerRevisions. An instance of Interface can be retrieved from NewHistory. Implementations must treat all
|
||||
// pointer parameters as "in" parameter, and they must not be mutated.
|
||||
type Interface interface {
|
||||
// ListControllerRevisions lists all ControllerRevisions matching selector and owned by parent or no other
|
||||
// controller. If the returned error is nil the returned slice of ControllerRevisions is valid. If the
|
||||
// returned error is not nil, the returned slice is not valid.
|
||||
ListControllerRevisions(parent metav1.Object, selector labels.Selector) ([]*apps.ControllerRevision, error)
|
||||
// CreateControllerRevision attempts to create the revision as owned by parent via a ControllerRef. If name
|
||||
// collision occurs, a unique identifier is added to the hash of the revision and it is renamed using
|
||||
// ControllerRevisionName. Implementations may cease to attempt to retry creation after some number of attempts
|
||||
// and return an error. If the returned error is not nil, creation failed. If the returned error is nil, the
|
||||
// returned ControllerRevision has been created.
|
||||
CreateControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error)
|
||||
// DeleteControllerRevision attempts to delete revision. If the returned error is not nil, deletion has failed.
|
||||
DeleteControllerRevision(revision *apps.ControllerRevision) error
|
||||
// UpdateControllerRevision updates revision such that its Revision is equal to newRevision. Implementations
|
||||
// may retry on conflict. If the returned error is nil, the update was successful and returned ControllerRevision
|
||||
// is valid. If the returned error is not nil, the update failed and the returned ControllerRevision is invalid.
|
||||
UpdateControllerRevision(revision *apps.ControllerRevision, newRevision int64) (*apps.ControllerRevision, error)
|
||||
// AdoptControllerRevision attempts to adopt revision by adding a ControllerRef indicating that the parent
|
||||
// Object of parentKind is the owner of revision. If revision is already owned, an error is returned. If the
|
||||
// resource patch fails, an error is returned. If no error is returned, the returned ControllerRevision is
|
||||
// valid.
|
||||
AdoptControllerRevision(parent metav1.Object, parentKind schema.GroupVersionKind, revision *apps.ControllerRevision) (*apps.ControllerRevision, error)
|
||||
// ReleaseControllerRevision attempts to release parent's ownership of revision by removing parent from the
|
||||
// OwnerReferences of revision. If an error is returned, parent remains the owner of revision. If no error is
|
||||
// returned, the returned ControllerRevision is valid.
|
||||
ReleaseControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error)
|
||||
}
|
||||
|
||||
// NewHistory returns an instance of Interface that uses client to communicate with the API Server and lister to list
|
||||
// ControllerRevisions. This method should be used to create an Interface for all scenarios other than testing.
|
||||
func NewHistory(client clientset.Interface, lister appslisters.ControllerRevisionLister) Interface {
|
||||
return &realHistory{client, lister}
|
||||
}
|
||||
|
||||
// NewFakeHistory returns an instance of Interface that uses informer to create, update, list, and delete
|
||||
// ControllerRevisions. This method should be used to create an Interface for testing purposes.
|
||||
func NewFakeHistory(informer appsinformers.ControllerRevisionInformer) Interface {
|
||||
return &fakeHistory{informer.Informer().GetIndexer(), informer.Lister()}
|
||||
}
|
||||
|
||||
type realHistory struct {
|
||||
client clientset.Interface
|
||||
lister appslisters.ControllerRevisionLister
|
||||
}
|
||||
|
||||
func (rh *realHistory) ListControllerRevisions(parent metav1.Object, selector labels.Selector) ([]*apps.ControllerRevision, error) {
|
||||
// List all revisions in the namespace that match the selector
|
||||
history, err := rh.lister.ControllerRevisions(parent.GetNamespace()).List(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var owned []*apps.ControllerRevision
|
||||
for i := range history {
|
||||
ref := controller.GetControllerOf(history[i])
|
||||
if ref == nil || ref.UID == parent.GetUID() {
|
||||
owned = append(owned, history[i])
|
||||
}
|
||||
|
||||
}
|
||||
return owned, err
|
||||
}
|
||||
|
||||
func (rh *realHistory) CreateControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
// Initialize the probe to 0
|
||||
probe := uint32(0)
|
||||
|
||||
// Clone the input
|
||||
any, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := any.(*apps.ControllerRevision)
|
||||
|
||||
// Continue to attempt to create the revision updating the name with a new hash on each iteration
|
||||
for {
|
||||
var hash uint32
|
||||
// The first attempt uses no probe to resolve collisions
|
||||
if probe > 0 {
|
||||
hash = HashControllerRevision(revision, &probe)
|
||||
} else {
|
||||
hash = HashControllerRevision(revision, nil)
|
||||
}
|
||||
// Update the revisions name and labels
|
||||
clone.Name = ControllerRevisionName(parent.GetName(), hash)
|
||||
created, err := rh.client.Apps().ControllerRevisions(parent.GetNamespace()).Create(clone)
|
||||
if errors.IsAlreadyExists(err) {
|
||||
probe++
|
||||
continue
|
||||
}
|
||||
return created, err
|
||||
}
|
||||
}
|
||||
|
||||
func (rh *realHistory) UpdateControllerRevision(revision *apps.ControllerRevision, newRevision int64) (*apps.ControllerRevision, error) {
|
||||
obj, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := obj.(*apps.ControllerRevision)
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
if clone.Revision == newRevision {
|
||||
return nil
|
||||
}
|
||||
clone.Revision = newRevision
|
||||
updated, updateErr := rh.client.Apps().ControllerRevisions(clone.Namespace).Update(clone)
|
||||
if updateErr == nil {
|
||||
return nil
|
||||
}
|
||||
if updated != nil {
|
||||
clone = updated
|
||||
}
|
||||
if updated, err := rh.lister.ControllerRevisions(clone.Namespace).Get(clone.Name); err == nil {
|
||||
// make a copy so we don't mutate the shared cache
|
||||
obj, err := scheme.Scheme.DeepCopy(updated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clone = obj.(*apps.ControllerRevision)
|
||||
}
|
||||
return updateErr
|
||||
})
|
||||
return clone, err
|
||||
}
|
||||
|
||||
func (rh *realHistory) DeleteControllerRevision(revision *apps.ControllerRevision) error {
|
||||
return rh.client.Apps().ControllerRevisions(revision.Namespace).Delete(revision.Name, nil)
|
||||
}
|
||||
|
||||
func (rh *realHistory) AdoptControllerRevision(parent metav1.Object, parentKind schema.GroupVersionKind, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
// Return an error if the parent does not own the revision
|
||||
if owner := controller.GetControllerOf(revision); owner != nil {
|
||||
return nil, fmt.Errorf("attempt to adopt revision owned by %v", owner)
|
||||
}
|
||||
// Use strategic merge patch to add an owner reference indicating a controller ref
|
||||
return rh.client.Apps().ControllerRevisions(parent.GetNamespace()).Patch(revision.GetName(),
|
||||
types.StrategicMergePatchType, []byte(fmt.Sprintf(
|
||||
`{"metadata":{"ownerReferences":[{"apiVersion":"%s","kind":"%s","name":"%s","uid":"%s","controller":true,"blockOwnerDeletion":true}],"uid":"%s"}}`,
|
||||
parentKind.GroupVersion().String(), parentKind.Kind,
|
||||
parent.GetName(), parent.GetUID(), revision.UID)))
|
||||
}
|
||||
|
||||
func (rh *realHistory) ReleaseControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
// Use strategic merge patch to add an owner reference indicating a controller ref
|
||||
released, err := rh.client.Apps().ControllerRevisions(revision.GetNamespace()).Patch(revision.GetName(),
|
||||
types.StrategicMergePatchType,
|
||||
[]byte(fmt.Sprintf(`{"metadata":{"ownerReferences":[{"$patch":"delete","uid":"%s"}],"uid":"%s"}}`, parent.GetUID(), revision.UID)))
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
// We ignore deleted revisions
|
||||
return nil, nil
|
||||
}
|
||||
if errors.IsInvalid(err) {
|
||||
// We ignore cases where the parent no longer owns the revision or where the revision has no
|
||||
// owner.
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return released, err
|
||||
}
|
||||
|
||||
type fakeHistory struct {
|
||||
indexer cache.Indexer
|
||||
lister appslisters.ControllerRevisionLister
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) ListControllerRevisions(parent metav1.Object, selector labels.Selector) ([]*apps.ControllerRevision, error) {
|
||||
history, err := fh.lister.ControllerRevisions(parent.GetNamespace()).List(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var owned []*apps.ControllerRevision
|
||||
for i := range history {
|
||||
ref := controller.GetControllerOf(history[i])
|
||||
if ref == nil || ref.UID == parent.GetUID() {
|
||||
owned = append(owned, history[i])
|
||||
}
|
||||
|
||||
}
|
||||
return owned, err
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) addRevision(revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj, found, err := fh.indexer.GetByKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if found {
|
||||
foundRevision := obj.(*apps.ControllerRevision)
|
||||
return foundRevision, errors.NewAlreadyExists(apps.Resource("controllerrevision"), revision.Name)
|
||||
}
|
||||
return revision, fh.indexer.Update(revision)
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) CreateControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
// Initialize the probe to 0
|
||||
probe := uint32(0)
|
||||
|
||||
// Clone the input
|
||||
any, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := any.(*apps.ControllerRevision)
|
||||
clone.Namespace = parent.GetNamespace()
|
||||
|
||||
// Continue to attempt to create the revision updating the name with a new hash on each iteration
|
||||
for {
|
||||
var hash uint32
|
||||
// The first attempt uses no probe to resolve collisions
|
||||
if probe > 0 {
|
||||
hash = HashControllerRevision(revision, &probe)
|
||||
} else {
|
||||
hash = HashControllerRevision(revision, nil)
|
||||
}
|
||||
// Update the revisions name and labels
|
||||
clone.Name = ControllerRevisionName(parent.GetName(), hash)
|
||||
created, err := fh.addRevision(clone)
|
||||
if errors.IsAlreadyExists(err) {
|
||||
probe++
|
||||
continue
|
||||
}
|
||||
return created, err
|
||||
}
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) DeleteControllerRevision(revision *apps.ControllerRevision) error {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj, found, err := fh.indexer.GetByKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !found {
|
||||
return errors.NewNotFound(apps.Resource("controllerrevisions"), revision.Name)
|
||||
}
|
||||
return fh.indexer.Delete(obj)
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) UpdateControllerRevision(revision *apps.ControllerRevision, newRevision int64) (*apps.ControllerRevision, error) {
|
||||
obj, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := obj.(*apps.ControllerRevision)
|
||||
clone.Revision = newRevision
|
||||
return clone, fh.indexer.Update(clone)
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) AdoptControllerRevision(parent metav1.Object, parentKind schema.GroupVersionKind, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
blockOwnerDeletion := true
|
||||
isController := true
|
||||
if owner := controller.GetControllerOf(revision); owner != nil {
|
||||
return nil, fmt.Errorf("attempt to adopt revision owned by %v", owner)
|
||||
}
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, found, err := fh.indexer.GetByKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !found {
|
||||
return nil, errors.NewNotFound(apps.Resource("controllerrevisions"), revision.Name)
|
||||
}
|
||||
obj2, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := obj2.(*apps.ControllerRevision)
|
||||
clone.OwnerReferences = append(clone.OwnerReferences, metav1.OwnerReference{
|
||||
APIVersion: parentKind.GroupVersion().String(),
|
||||
Kind: parentKind.Kind,
|
||||
Name: parent.GetName(),
|
||||
UID: parent.GetUID(),
|
||||
BlockOwnerDeletion: &blockOwnerDeletion,
|
||||
Controller: &isController,
|
||||
})
|
||||
return clone, fh.indexer.Update(clone)
|
||||
|
||||
}
|
||||
|
||||
func (fh *fakeHistory) ReleaseControllerRevision(parent metav1.Object, revision *apps.ControllerRevision) (*apps.ControllerRevision, error) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, found, err := fh.indexer.GetByKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
obj2, err := scheme.Scheme.DeepCopy(revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := obj2.(*apps.ControllerRevision)
|
||||
refs := clone.OwnerReferences
|
||||
clone.OwnerReferences = nil
|
||||
for i := range refs {
|
||||
if refs[i].UID != parent.GetUID() {
|
||||
clone.OwnerReferences = append(clone.OwnerReferences, refs[i])
|
||||
}
|
||||
}
|
||||
return clone, fh.indexer.Update(clone)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,7 @@ go_library(
|
|||
"stateful_pod_control.go",
|
||||
"stateful_set.go",
|
||||
"stateful_set_control.go",
|
||||
"stateful_set_status_updater.go",
|
||||
"stateful_set_utils.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
@ -29,12 +30,15 @@ go_library(
|
|||
"//pkg/client/listers/core/v1:go_default_library",
|
||||
"//pkg/client/retry:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/history:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
|
@ -50,6 +54,7 @@ go_test(
|
|||
srcs = [
|
||||
"stateful_pod_control_test.go",
|
||||
"stateful_set_control_test.go",
|
||||
"stateful_set_status_updater_test.go",
|
||||
"stateful_set_test.go",
|
||||
"stateful_set_utils_test.go",
|
||||
],
|
||||
|
@ -68,6 +73,7 @@ go_test(
|
|||
"//pkg/client/listers/apps/v1beta1:go_default_library",
|
||||
"//pkg/client/listers/core/v1:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/history:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
|
@ -77,6 +83,7 @@ go_test(
|
|||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -49,10 +49,6 @@ type StatefulPodControlInterface interface {
|
|||
// DeleteStatefulPod deletes a Pod in a StatefulSet. The pods PVCs are not deleted. If the delete is successful,
|
||||
// the returned error is nil.
|
||||
DeleteStatefulPod(set *apps.StatefulSet, pod *v1.Pod) error
|
||||
// UpdateStatefulSetStatus updates the status of a StatefulSet. set is an in-out parameter, and any
|
||||
// updates made to the set are made visible as mutations to the parameter. If the method is successful, the
|
||||
// returned error is nil, and set has its status updated.
|
||||
UpdateStatefulSetStatus(set *apps.StatefulSet, replicas int32, generation int64) error
|
||||
}
|
||||
|
||||
func NewRealStatefulPodControl(
|
||||
|
@ -93,7 +89,6 @@ func (spc *realStatefulPodControl) CreateStatefulPod(set *apps.StatefulSet, pod
|
|||
|
||||
func (spc *realStatefulPodControl) UpdateStatefulPod(set *apps.StatefulSet, pod *v1.Pod) error {
|
||||
attemptedUpdate := false
|
||||
|
||||
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
// assume the Pod is consistent
|
||||
consistent := true
|
||||
|
@ -149,30 +144,6 @@ func (spc *realStatefulPodControl) DeleteStatefulPod(set *apps.StatefulSet, pod
|
|||
return err
|
||||
}
|
||||
|
||||
func (spc *realStatefulPodControl) UpdateStatefulSetStatus(set *apps.StatefulSet, replicas int32, generation int64) error {
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
set.Status.Replicas = replicas
|
||||
set.Status.ObservedGeneration = &generation
|
||||
_, updateErr := spc.client.Apps().StatefulSets(set.Namespace).UpdateStatus(set)
|
||||
if updateErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if updated, err := spc.setLister.StatefulSets(set.Namespace).Get(set.Name); err == nil {
|
||||
// make a copy so we don't mutate the shared cache
|
||||
if copy, err := scheme.Scheme.DeepCopy(updated); err == nil {
|
||||
set = copy.(*apps.StatefulSet)
|
||||
} else {
|
||||
utilruntime.HandleError(fmt.Errorf("error copying updated StatefulSet: %v", err))
|
||||
}
|
||||
} else {
|
||||
utilruntime.HandleError(fmt.Errorf("error getting updated StatefulSet %s/%s from lister: %v", set.Namespace, set.Name, err))
|
||||
}
|
||||
|
||||
return updateErr
|
||||
})
|
||||
}
|
||||
|
||||
// recordPodEvent records an event for verb applied to a Pod in a StatefulSet. If err is nil the generated event will
|
||||
// have a reason of v1.EventTypeNormal. If err is not nil the generated event will have a reason of v1.EventTypeWarning.
|
||||
func (spc *realStatefulPodControl) recordPodEvent(verb string, set *apps.StatefulSet, pod *v1.Pod, err error) {
|
||||
|
|
|
@ -29,9 +29,7 @@ import (
|
|||
"k8s.io/client-go/tools/record"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
|
||||
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
|
||||
corelisters "k8s.io/kubernetes/pkg/client/listers/core/v1"
|
||||
)
|
||||
|
||||
|
@ -461,116 +459,6 @@ func TestStatefulPodControlDeleteFailure(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStatefulPodControlUpdatesSetStatus(t *testing.T) {
|
||||
recorder := record.NewFakeRecorder(10)
|
||||
set := newStatefulSet(3)
|
||||
fakeClient := &fake.Clientset{}
|
||||
control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
return true, update.GetObject(), nil
|
||||
})
|
||||
if err := control.UpdateStatefulSetStatus(set, 2, 1); err != nil {
|
||||
t.Errorf("Error returned on successful status update: %s", err)
|
||||
}
|
||||
if set.Status.Replicas != 2 {
|
||||
t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas)
|
||||
}
|
||||
events := collectEvents(recorder.Events)
|
||||
if eventCount := len(events); eventCount != 0 {
|
||||
t.Errorf("Expected 0 events for successful status update %d", eventCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulPodControlUpdatesObservedGeneration(t *testing.T) {
|
||||
recorder := record.NewFakeRecorder(10)
|
||||
set := newStatefulSet(3)
|
||||
fakeClient := &fake.Clientset{}
|
||||
control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
sts := update.GetObject().(*apps.StatefulSet)
|
||||
if sts.Status.ObservedGeneration == nil || *sts.Status.ObservedGeneration != int64(3) {
|
||||
t.Errorf("expected observedGeneration to be synced with generation for statefulset %q", sts.Name)
|
||||
}
|
||||
return true, sts, nil
|
||||
})
|
||||
if err := control.UpdateStatefulSetStatus(set, 2, 3); err != nil {
|
||||
t.Errorf("Error returned on successful status update: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulPodControlUpdateReplicasFailure(t *testing.T) {
|
||||
recorder := record.NewFakeRecorder(10)
|
||||
set := newStatefulSet(3)
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewInternalError(errors.New("API server down"))
|
||||
})
|
||||
if err := control.UpdateStatefulSetStatus(set, 2, 1); err == nil {
|
||||
t.Error("Failed update did not return error")
|
||||
}
|
||||
events := collectEvents(recorder.Events)
|
||||
if eventCount := len(events); eventCount != 0 {
|
||||
t.Errorf("Expected 0 events for successful status update %d", eventCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulPodControlUpdateReplicasConflict(t *testing.T) {
|
||||
recorder := record.NewFakeRecorder(10)
|
||||
set := newStatefulSet(3)
|
||||
conflict := false
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
if !conflict {
|
||||
conflict = true
|
||||
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists"))
|
||||
} else {
|
||||
return true, update.GetObject(), nil
|
||||
}
|
||||
})
|
||||
if err := control.UpdateStatefulSetStatus(set, 2, 1); err != nil {
|
||||
t.Errorf("UpdateStatefulSetStatus returned an error: %s", err)
|
||||
}
|
||||
if set.Status.Replicas != 2 {
|
||||
t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas)
|
||||
}
|
||||
events := collectEvents(recorder.Events)
|
||||
if eventCount := len(events); eventCount != 0 {
|
||||
t.Errorf("Expected 0 events for successful status update %d", eventCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulPodControlUpdateReplicasConflictFailure(t *testing.T) {
|
||||
recorder := record.NewFakeRecorder(10)
|
||||
set := newStatefulSet(3)
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists"))
|
||||
})
|
||||
if err := control.UpdateStatefulSetStatus(set, 2, 1); err == nil {
|
||||
t.Error("UpdateStatefulSetStatus failed to return an error on get failure")
|
||||
}
|
||||
events := collectEvents(recorder.Events)
|
||||
if eventCount := len(events); eventCount != 0 {
|
||||
t.Errorf("Expected 0 events for successful status update %d", eventCount)
|
||||
}
|
||||
}
|
||||
|
||||
func collectEvents(source <-chan string) []string {
|
||||
done := false
|
||||
events := make([]string, 0)
|
||||
|
|
|
@ -40,6 +40,7 @@ import (
|
|||
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
|
||||
corelisters "k8s.io/kubernetes/pkg/client/listers/core/v1"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@ -80,6 +81,7 @@ func NewStatefulSetController(
|
|||
podInformer coreinformers.PodInformer,
|
||||
setInformer appsinformers.StatefulSetInformer,
|
||||
pvcInformer coreinformers.PersistentVolumeClaimInformer,
|
||||
revInformer appsinformers.ControllerRevisionInformer,
|
||||
kubeClient clientset.Interface,
|
||||
) *StatefulSetController {
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
|
@ -95,8 +97,9 @@ func NewStatefulSetController(
|
|||
setInformer.Lister(),
|
||||
podInformer.Lister(),
|
||||
pvcInformer.Lister(),
|
||||
recorder,
|
||||
),
|
||||
recorder),
|
||||
NewRealStatefulSetStatusUpdater(kubeClient, setInformer.Lister()),
|
||||
history.NewHistory(kubeClient, revInformer.Lister()),
|
||||
),
|
||||
pvcListerSynced: pvcInformer.Informer().HasSynced,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "statefulset"),
|
||||
|
@ -305,6 +308,32 @@ func (ssc *StatefulSetController) getPodsForStatefulSet(set *apps.StatefulSet, s
|
|||
return cm.ClaimPods(pods, filter)
|
||||
}
|
||||
|
||||
// adoptOrphanRevisions adopts any orphaned ControllerRevisions matched by set's Selector.
|
||||
func (ssc *StatefulSetController) adoptOrphanRevisions(set *apps.StatefulSet) error {
|
||||
revisions, err := ssc.control.ListRevisions(set)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hasOrphans := false
|
||||
for i := range revisions {
|
||||
if controller.GetControllerOf(revisions[i]) == nil {
|
||||
hasOrphans = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasOrphans {
|
||||
fresh, err := ssc.kubeClient.AppsV1beta1().StatefulSets(set.Namespace).Get(set.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fresh.UID != set.UID {
|
||||
return fmt.Errorf("original StatefulSet %v/%v is gone: got uid %v, wanted %v", set.Namespace, set.Name, fresh.UID, set.UID)
|
||||
}
|
||||
return ssc.control.AdoptOrphanRevisions(set, revisions)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getStatefulSetsForPod returns a list of StatefulSets that potentially match
|
||||
// a given pod.
|
||||
func (ssc *StatefulSetController) getStatefulSetsForPod(pod *v1.Pod) []*apps.StatefulSet {
|
||||
|
@ -406,6 +435,10 @@ func (ssc *StatefulSetController) sync(key string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if err := ssc.adoptOrphanRevisions(set); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pods, err := ssc.getPodsForStatefulSet(set, selector)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -17,12 +17,14 @@ limitations under the License.
|
|||
package statefulset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@ -36,18 +38,30 @@ type StatefulSetControlInterface interface {
|
|||
// Implementors should sink any errors that they do not wish to trigger a retry, and they may feel free to
|
||||
// exit exceptionally at any point provided they wish the update to be re-run at a later point in time.
|
||||
UpdateStatefulSet(set *apps.StatefulSet, pods []*v1.Pod) error
|
||||
// ListRevisions returns a array of the ControllerRevisions that represent the revisions of set. If the returned
|
||||
// error is nil, the returns slice of ControllerRevisions is valid.
|
||||
ListRevisions(set *apps.StatefulSet) ([]*apps.ControllerRevision, error)
|
||||
// AdoptOrphanRevisions adopts any orphaned ControllerRevisions that match set's Selector. If all adoptions are
|
||||
// successful the returned error is nil.
|
||||
AdoptOrphanRevisions(set *apps.StatefulSet, revisions []*apps.ControllerRevision) error
|
||||
}
|
||||
|
||||
// NewDefaultStatefulSetControl returns a new instance of the default implementation StatefulSetControlInterface that
|
||||
// implements the documented semantics for StatefulSets. podControl is the PodControlInterface used to create, update,
|
||||
// and delete Pods and to create PersistentVolumeClaims. You should use an instance returned from
|
||||
// NewRealStatefulPodControl() for any scenario other than testing.
|
||||
func NewDefaultStatefulSetControl(podControl StatefulPodControlInterface) StatefulSetControlInterface {
|
||||
return &defaultStatefulSetControl{podControl}
|
||||
// and delete Pods and to create PersistentVolumeClaims. statusUpdater is the StatefulSetStatusUpdaterInterface used
|
||||
// to update the status of StatefulSets. You should use an instance returned from NewRealStatefulPodControl() for any
|
||||
// scenario other than testing.
|
||||
func NewDefaultStatefulSetControl(
|
||||
podControl StatefulPodControlInterface,
|
||||
statusUpdater StatefulSetStatusUpdaterInterface,
|
||||
controllerHistory history.Interface) StatefulSetControlInterface {
|
||||
return &defaultStatefulSetControl{podControl, statusUpdater, controllerHistory}
|
||||
}
|
||||
|
||||
type defaultStatefulSetControl struct {
|
||||
podControl StatefulPodControlInterface
|
||||
podControl StatefulPodControlInterface
|
||||
statusUpdater StatefulSetStatusUpdaterInterface
|
||||
controllerHistory history.Interface
|
||||
}
|
||||
|
||||
// UpdateStatefulSet executes the core logic loop for a stateful set, applying the predictable and
|
||||
|
@ -57,20 +71,223 @@ type defaultStatefulSetControl struct {
|
|||
// in no particular order. Clients using the burst strategy should be careful to ensure they
|
||||
// understand the consistency implications of having unpredictable numbers of pods available.
|
||||
func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, pods []*v1.Pod) error {
|
||||
|
||||
// list all revisions and sort them
|
||||
revisions, err := ssc.ListRevisions(set)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
history.SortControllerRevisions(revisions)
|
||||
|
||||
// get the current, and update revisions
|
||||
currentRevision, updateRevision, err := ssc.getStatefulSetRevisions(set, revisions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// perform the main update function and get the status
|
||||
status, err := ssc.updateStatefulSet(set, currentRevision, updateRevision, pods)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update the set's status
|
||||
err = ssc.updateStatefulSetStatus(set, status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
glog.V(4).Infof("StatefulSet %s/%s pod status replicas=%d ready=%d current=%d updated=%d",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
status.Replicas,
|
||||
status.ReadyReplicas,
|
||||
status.CurrentReplicas,
|
||||
status.UpdatedReplicas)
|
||||
|
||||
glog.V(4).Infof("StatefulSet %s/%s revisions current=%s update=%s",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
status.CurrentRevision,
|
||||
status.UpdateRevision)
|
||||
|
||||
// maintain the set's revision history limit
|
||||
return ssc.truncateHistory(set, pods, revisions, currentRevision, updateRevision)
|
||||
}
|
||||
|
||||
func (ssc *defaultStatefulSetControl) ListRevisions(set *apps.StatefulSet) ([]*apps.ControllerRevision, error) {
|
||||
selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ssc.controllerHistory.ListControllerRevisions(set, selector)
|
||||
}
|
||||
|
||||
func (ssc *defaultStatefulSetControl) AdoptOrphanRevisions(
|
||||
set *apps.StatefulSet,
|
||||
revisions []*apps.ControllerRevision) error {
|
||||
for i := range revisions {
|
||||
adopted, err := ssc.controllerHistory.AdoptControllerRevision(set, controllerKind, revisions[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
revisions[i] = adopted
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// truncateHistory truncates any non-live ControllerRevisions in revisions from set's history. The UpdateRevision and
|
||||
// CurrentRevision in set's Status are considered to be live. Any revisions associated with the Pods in pods are also
|
||||
// considered to be live. Non-live revisions are deleted, starting with the revision with the lowest Revision, until
|
||||
// only RevisionHistoryLimit revisions remain. If the returned error is nil the operation was successful. This method
|
||||
// expects that revisions is sorted when supplied.
|
||||
func (ssc *defaultStatefulSetControl) truncateHistory(
|
||||
set *apps.StatefulSet,
|
||||
pods []*v1.Pod,
|
||||
revisions []*apps.ControllerRevision,
|
||||
current *apps.ControllerRevision,
|
||||
update *apps.ControllerRevision) error {
|
||||
history := make([]*apps.ControllerRevision, 0, len(revisions))
|
||||
// mark all live revisions
|
||||
live := map[string]bool{current.Name: true, update.Name: true}
|
||||
for i := range pods {
|
||||
live[getPodRevision(pods[i])] = true
|
||||
}
|
||||
// collect live revisions and historic revisions
|
||||
for i := range revisions {
|
||||
if !live[revisions[i].Name] {
|
||||
history = append(history, revisions[i])
|
||||
}
|
||||
}
|
||||
historyLen := len(history)
|
||||
historyLimit := int(*set.Spec.RevisionHistoryLimit)
|
||||
if historyLen <= historyLimit {
|
||||
return nil
|
||||
}
|
||||
// delete any non-live history to maintain the revision limit.
|
||||
history = history[:(historyLen - historyLimit)]
|
||||
for i := 0; i < len(history); i++ {
|
||||
if err := ssc.controllerHistory.DeleteControllerRevision(history[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getStatefulSetRevisions returns the current and update ControllerRevisions for set. This method may create a new revision,
|
||||
// or modify the Revision of an existing revision if an update to set is detected. This method expects that revisions
|
||||
// is sorted when supplied.
|
||||
func (ssc *defaultStatefulSetControl) getStatefulSetRevisions(
|
||||
set *apps.StatefulSet,
|
||||
revisions []*apps.ControllerRevision) (*apps.ControllerRevision, *apps.ControllerRevision, error) {
|
||||
var currentRevision, updateRevision *apps.ControllerRevision
|
||||
|
||||
revisionCount := len(revisions)
|
||||
history.SortControllerRevisions(revisions)
|
||||
|
||||
// create a new revision from the current set
|
||||
updateRevision, err := newRevision(set, nextRevision(revisions))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// find any equivalent revisions
|
||||
equalRevisions := history.FindEqualRevisions(revisions, updateRevision)
|
||||
equalCount := len(equalRevisions)
|
||||
|
||||
if equalCount > 0 && history.EqualRevision(revisions[revisionCount-1], equalRevisions[equalCount-1]) {
|
||||
// if the equivalent revision is immediately prior the update revision has not changed
|
||||
updateRevision = revisions[revisionCount-1]
|
||||
} else if equalCount > 0 {
|
||||
// if the equivalent revision is not immediately prior we will roll back by incrementing the
|
||||
// Revision of the equivalent revision
|
||||
updateRevision, err = ssc.controllerHistory.UpdateControllerRevision(
|
||||
equalRevisions[equalCount-1],
|
||||
updateRevision.Revision)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
//if there is no equivalent revision we create a new one
|
||||
updateRevision, err = ssc.controllerHistory.CreateControllerRevision(set, updateRevision)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to find the revision that corresponds to the current revision
|
||||
for i := range revisions {
|
||||
if revisions[i].Name == set.Status.CurrentRevision {
|
||||
currentRevision = revisions[i]
|
||||
}
|
||||
}
|
||||
|
||||
// if the current revision is nil we initialize the history by setting it to the update revision
|
||||
if currentRevision == nil {
|
||||
currentRevision = updateRevision
|
||||
}
|
||||
|
||||
return currentRevision, updateRevision, nil
|
||||
}
|
||||
|
||||
// updateStatefulSet performs the update function for a StatefulSet. This method creates, updates, and deletes Pods in
|
||||
// the set in order to conform the system to the target state for the set. The target state always contains
|
||||
// set.Spec.Replicas Pods with a Ready Condition. If the UpdateStrategy.Type for the set is
|
||||
// RollingUpdateStatefulSetStrategyType then all Pods in the set must be at set.Status.CurrentRevision.
|
||||
// If the UpdateStrategy.Type for the set is OnDeleteStatefulSetStrategyType, the target state implies nothing about
|
||||
// the revisions of Pods in the set. If the UpdateStrategy.Type for the set is PartitionStatefulSetStrategyType, then
|
||||
// all Pods with ordinal less than UpdateStrategy.Partition.Ordinal must be at Status.CurrentRevision and all other
|
||||
// Pods must be at Status.UpdateRevision. If the returned error is nil, the returned StatefulSetStatus is valid and the
|
||||
// update must be recorded. If the error is not nil, the method should be retried until successful.
|
||||
func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
||||
set *apps.StatefulSet,
|
||||
currentRevision *apps.ControllerRevision,
|
||||
updateRevision *apps.ControllerRevision,
|
||||
pods []*v1.Pod) (*apps.StatefulSetStatus, error) {
|
||||
// get the current and update revisions of the set.
|
||||
currentSet, err := applyRevision(set, currentRevision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updateSet, err := applyRevision(set, updateRevision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set the generation, and revisions in the returned status
|
||||
status := apps.StatefulSetStatus{}
|
||||
status.ObservedGeneration = new(int64)
|
||||
*status.ObservedGeneration = set.Generation
|
||||
status.CurrentRevision = currentRevision.Name
|
||||
status.UpdateRevision = updateRevision.Name
|
||||
|
||||
replicaCount := int(*set.Spec.Replicas)
|
||||
// slice that will contain all Pods such that 0 <= getOrdinal(pod) < set.Spec.Replicas
|
||||
replicas := make([]*v1.Pod, replicaCount)
|
||||
// slice that will contain all Pods such that set.Spec.Replicas <= getOrdinal(pod)
|
||||
condemned := make([]*v1.Pod, 0, len(pods))
|
||||
ready := 0
|
||||
unhealthy := 0
|
||||
firstUnhealthyOrdinal := math.MaxInt32
|
||||
var firstUnhealthyPod *v1.Pod
|
||||
|
||||
// First we partition pods into two lists valid replicas and condemned Pods
|
||||
for i := range pods {
|
||||
//count the number of running and ready replicas
|
||||
status.Replicas++
|
||||
|
||||
// count the number of running and ready replicas
|
||||
if isRunningAndReady(pods[i]) {
|
||||
ready++
|
||||
status.ReadyReplicas++
|
||||
}
|
||||
|
||||
// count the number of current and update replicas
|
||||
if isCreated(pods[i]) && !isTerminating(pods[i]) {
|
||||
if getPodRevision(pods[i]) == currentRevision.Name {
|
||||
status.CurrentReplicas++
|
||||
} else if getPodRevision(pods[i]) == updateRevision.Name {
|
||||
status.UpdatedReplicas++
|
||||
}
|
||||
}
|
||||
|
||||
if ord := getOrdinal(pods[i]); 0 <= ord && ord < replicaCount {
|
||||
// if the ordinal of the pod is within the range of the current number of replicas,
|
||||
// insert it at the indirection of its ordinal
|
||||
|
@ -83,45 +300,53 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
|
|||
// If the ordinal could not be parsed (ord < 0), ignore the Pod.
|
||||
}
|
||||
|
||||
// for any empty indices in the sequence [0,set.Spec.Replicas) create a new Pod
|
||||
// for any empty indices in the sequence [0,set.Spec.Replicas) create a new Pod at the correct revision
|
||||
for ord := 0; ord < replicaCount; ord++ {
|
||||
if replicas[ord] == nil {
|
||||
replicas[ord] = newStatefulSetPod(set, ord)
|
||||
}
|
||||
}
|
||||
|
||||
// count the number of unhealthy pods
|
||||
for i := range replicas {
|
||||
if !isHealthy(replicas[i]) {
|
||||
unhealthy++
|
||||
}
|
||||
}
|
||||
for i := range condemned {
|
||||
if !isHealthy(condemned[i]) {
|
||||
unhealthy++
|
||||
replicas[ord] = newVersionedStatefulSetPod(
|
||||
currentSet,
|
||||
updateSet,
|
||||
currentRevision.Name,
|
||||
updateRevision.Name, ord)
|
||||
}
|
||||
}
|
||||
|
||||
// sort the condemned Pods by their ordinals
|
||||
sort.Sort(ascendingOrdinal(condemned))
|
||||
|
||||
// if the current number of replicas has changed update the statefulSets replicas
|
||||
if set.Status.Replicas != int32(ready) || set.Status.ObservedGeneration == nil || set.Generation > *set.Status.ObservedGeneration {
|
||||
obj, err := scheme.Scheme.Copy(set)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to copy set: %v", err)
|
||||
// find the first unhealthy Pod
|
||||
for i := range replicas {
|
||||
if !isHealthy(replicas[i]) {
|
||||
unhealthy++
|
||||
if ord := getOrdinal(replicas[i]); ord < firstUnhealthyOrdinal {
|
||||
firstUnhealthyOrdinal = ord
|
||||
firstUnhealthyPod = replicas[i]
|
||||
}
|
||||
}
|
||||
set = obj.(*apps.StatefulSet)
|
||||
}
|
||||
|
||||
if err := ssc.podControl.UpdateStatefulSetStatus(set, int32(ready), set.Generation); err != nil {
|
||||
return err
|
||||
for i := range condemned {
|
||||
if !isHealthy(condemned[i]) {
|
||||
unhealthy++
|
||||
if ord := getOrdinal(condemned[i]); ord < firstUnhealthyOrdinal {
|
||||
firstUnhealthyOrdinal = ord
|
||||
firstUnhealthyPod = condemned[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if unhealthy > 0 {
|
||||
glog.V(4).Infof("StatefulSet %s/%s has %d unhealthy Pods starting with %s",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
unhealthy,
|
||||
firstUnhealthyPod.Name)
|
||||
}
|
||||
|
||||
// If the StatefulSet is being deleted, don't do anything other than updating
|
||||
// status.
|
||||
if set.DeletionTimestamp != nil {
|
||||
return nil
|
||||
return &status, nil
|
||||
}
|
||||
|
||||
monotonic := !allowsBurst(set)
|
||||
|
@ -130,20 +355,41 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
|
|||
for i := range replicas {
|
||||
// delete and recreate failed pods
|
||||
if isFailed(replicas[i]) {
|
||||
glog.V(2).Infof("StatefulSet %s is recreating failed Pod %s", set.Name, replicas[i].Name)
|
||||
glog.V(4).Infof("StatefulSet %s/%s is recreating failed Pod %s",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
replicas[i].Name)
|
||||
if err := ssc.podControl.DeleteStatefulPod(set, replicas[i]); err != nil {
|
||||
return err
|
||||
return &status, err
|
||||
}
|
||||
replicas[i] = newStatefulSetPod(set, i)
|
||||
if getPodRevision(replicas[i]) == currentRevision.Name {
|
||||
status.CurrentReplicas--
|
||||
} else if getPodRevision(replicas[i]) == updateRevision.Name {
|
||||
status.UpdatedReplicas--
|
||||
}
|
||||
status.Replicas--
|
||||
replicas[i] = newVersionedStatefulSetPod(
|
||||
currentSet,
|
||||
updateSet,
|
||||
currentRevision.Name,
|
||||
updateRevision.Name,
|
||||
i)
|
||||
}
|
||||
// If we find a Pod that has not been created we create the Pod
|
||||
if !isCreated(replicas[i]) {
|
||||
if err := ssc.podControl.CreateStatefulPod(set, replicas[i]); err != nil {
|
||||
return err
|
||||
return &status, err
|
||||
}
|
||||
status.Replicas++
|
||||
if getPodRevision(replicas[i]) == currentRevision.Name {
|
||||
status.CurrentReplicas++
|
||||
} else if getPodRevision(replicas[i]) == updateRevision.Name {
|
||||
status.UpdatedReplicas++
|
||||
}
|
||||
|
||||
// if the set does not allow bursting, return immediately
|
||||
if monotonic {
|
||||
return nil
|
||||
return &status, nil
|
||||
}
|
||||
// pod created, no more work possible for this round
|
||||
continue
|
||||
|
@ -151,15 +397,23 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
|
|||
// If we find a Pod that is currently terminating, we must wait until graceful deletion
|
||||
// completes before we continue to make progress.
|
||||
if isTerminating(replicas[i]) && monotonic {
|
||||
glog.V(2).Infof("StatefulSet %s is waiting for Pod %s to Terminate", set.Name, replicas[i].Name)
|
||||
return nil
|
||||
glog.V(4).Infof(
|
||||
"StatefulSet %s/%s is waiting for Pod %s to Terminate",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
replicas[i].Name)
|
||||
return &status, nil
|
||||
}
|
||||
// If we have a Pod that has been created but is not running and ready we can not make progress.
|
||||
// We must ensure that all for each Pod, when we create it, all of its predecessors, with respect to its
|
||||
// ordinal, are Running and Ready.
|
||||
if !isRunningAndReady(replicas[i]) && monotonic {
|
||||
glog.V(2).Infof("StatefulSet %s is waiting for Pod %s to be Running and Ready", set.Name, replicas[i].Name)
|
||||
return nil
|
||||
glog.V(4).Infof(
|
||||
"StatefulSet %s/%s is waiting for Pod %s to be Running and Ready",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
replicas[i].Name)
|
||||
return &status, nil
|
||||
}
|
||||
// Enforce the StatefulSet invariants
|
||||
if identityMatches(set, replicas[i]) && storageMatches(set, replicas[i]) {
|
||||
|
@ -168,31 +422,120 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
|
|||
// Make a deep copy so we don't mutate the shared cache
|
||||
copy, err := scheme.Scheme.DeepCopy(replicas[i])
|
||||
if err != nil {
|
||||
return err
|
||||
return &status, err
|
||||
}
|
||||
replica := copy.(*v1.Pod)
|
||||
if err := ssc.podControl.UpdateStatefulPod(set, replica); err != nil {
|
||||
return err
|
||||
if err := ssc.podControl.UpdateStatefulPod(updateSet, replica); err != nil {
|
||||
return &status, err
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, all of the current Replicas are Running and Ready, we can consider termination.
|
||||
// We will wait for all predecessors to be Running and Ready prior to attempting a deletion.
|
||||
// We will terminate Pods in a monotonically decreasing order over [len(pods),set.Spec.Replicas).
|
||||
// Note that we do not resurrect Pods in this interval.
|
||||
if unhealthy > 0 && monotonic {
|
||||
glog.V(2).Infof("StatefulSet %s is waiting on %d Pods", set.Name, unhealthy)
|
||||
return nil
|
||||
}
|
||||
// Note that we do not resurrect Pods in this interval. Also not that scaling will take precedence over
|
||||
// updates.
|
||||
for target := len(condemned) - 1; target >= 0; target-- {
|
||||
glog.V(2).Infof("StatefulSet %s terminating Pod %s", set.Name, condemned[target])
|
||||
// wait for terminating pods to expire
|
||||
if isTerminating(condemned[target]) {
|
||||
glog.V(4).Infof(
|
||||
"StatefulSet %s/%s is waiting for Pod %s to Terminate prior to scale down",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
condemned[target].Name)
|
||||
// block if we are in monotonic mode
|
||||
if monotonic {
|
||||
return &status, nil
|
||||
}
|
||||
continue
|
||||
}
|
||||
// if we are in monotonic mode and the condemned target is not the first unhealthy Pod block
|
||||
if !isRunningAndReady(condemned[target]) && monotonic && condemned[target] != firstUnhealthyPod {
|
||||
glog.V(4).Infof(
|
||||
"StatefulSet %s/%s is waiting for Pod %s to be Running and Ready prior to scale down",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
firstUnhealthyPod.Name)
|
||||
return &status, nil
|
||||
}
|
||||
glog.V(4).Infof("StatefulSet %s/%s terminating Pod %s for scale dowm",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
condemned[target].Name)
|
||||
|
||||
if err := ssc.podControl.DeleteStatefulPod(set, condemned[target]); err != nil {
|
||||
return err
|
||||
return &status, err
|
||||
}
|
||||
if getPodRevision(condemned[target]) == currentRevision.Name {
|
||||
status.CurrentReplicas--
|
||||
} else if getPodRevision(condemned[target]) == updateRevision.Name {
|
||||
status.UpdatedReplicas--
|
||||
}
|
||||
if monotonic {
|
||||
return nil
|
||||
return &status, nil
|
||||
}
|
||||
}
|
||||
|
||||
// for the OnDelete strategy we short circuit. Pods will be updated when they are manually deleted.
|
||||
if set.Spec.UpdateStrategy.Type == apps.OnDeleteStatefulSetStrategyType {
|
||||
return &status, nil
|
||||
}
|
||||
|
||||
// we compute the minimum ordinal of the target sequence for a destructive update based on the strategy.
|
||||
updateMin := 0
|
||||
if set.Spec.UpdateStrategy.Type == apps.PartitionStatefulSetStrategyType {
|
||||
updateMin = int(set.Spec.UpdateStrategy.Partition.Ordinal)
|
||||
}
|
||||
// we terminate the Pod with the largest ordinal that does not match the update revision.
|
||||
for target := len(replicas) - 1; target >= updateMin; target-- {
|
||||
// all replicas should be healthy before an update progresses we allow termination of the firstUnhealthy
|
||||
// Pod in any state allow for rolling back a failed update.
|
||||
if !isRunningAndReady(replicas[target]) && replicas[target] != firstUnhealthyPod {
|
||||
glog.V(4).Infof(
|
||||
"StatefulSet %s/%s is waiting for Pod %s to be Running and Ready prior to update",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
firstUnhealthyPod.Name)
|
||||
return &status, nil
|
||||
}
|
||||
if getPodRevision(replicas[target]) != updateRevision.Name {
|
||||
glog.V(4).Infof("StatefulSet %s/%s terminating Pod %s for update",
|
||||
set.Namespace,
|
||||
set.Name,
|
||||
replicas[target].Name)
|
||||
err := ssc.podControl.DeleteStatefulPod(set, replicas[target])
|
||||
status.CurrentReplicas--
|
||||
return &status, err
|
||||
}
|
||||
}
|
||||
return &status, nil
|
||||
}
|
||||
|
||||
// updateStatefulSetStatus updates set's Status to be equal to status. If status indicates a complete update, it is
|
||||
// mutated to indicate completion. If status is semantically equivalent to set's Status no update is performed. If the
|
||||
// returned error is nil, the update is successful.
|
||||
func (ssc *defaultStatefulSetControl) updateStatefulSetStatus(
|
||||
set *apps.StatefulSet,
|
||||
status *apps.StatefulSetStatus) error {
|
||||
|
||||
// complete any in progress rolling update if necessary
|
||||
completeRollingUpdate(set, status)
|
||||
|
||||
// if the status is not inconsistent do not perform an update
|
||||
if !inconsistentStatus(set, status) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// copy set and update its status
|
||||
obj, err := scheme.Scheme.Copy(set)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set = obj.(*apps.StatefulSet)
|
||||
if err := ssc.statusUpdater.UpdateStatefulSetStatus(set, status); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package statefulset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
|
||||
|
||||
"k8s.io/kubernetes/pkg/client/retry"
|
||||
)
|
||||
|
||||
// StatefulSetStatusUpdaterInterface is an interface used to update the StatefulSetStatus associated with a StatefulSet.
|
||||
// For any use other than testing, clients should create an instance using NewRealStatefulSetStatusUpdater.
|
||||
type StatefulSetStatusUpdaterInterface interface {
|
||||
// UpdateStatefulSetStatus sets the set's Status to status. Implementations are required to retry on conflicts,
|
||||
// but fail on other errors. If the returned error is nil set's Status has been successfully set to status.
|
||||
UpdateStatefulSetStatus(set *apps.StatefulSet, status *apps.StatefulSetStatus) error
|
||||
}
|
||||
|
||||
// NewRealStatefulSetStatusUpdater returns a StatefulSetStatusUpdaterInterface that updates the Status of a StatefulSet,
|
||||
// using the supplied client and setLister.
|
||||
func NewRealStatefulSetStatusUpdater(
|
||||
client clientset.Interface,
|
||||
setLister appslisters.StatefulSetLister) StatefulSetStatusUpdaterInterface {
|
||||
return &realStatefulSetStatusUpdater{client, setLister}
|
||||
}
|
||||
|
||||
type realStatefulSetStatusUpdater struct {
|
||||
client clientset.Interface
|
||||
setLister appslisters.StatefulSetLister
|
||||
}
|
||||
|
||||
func (ssu *realStatefulSetStatusUpdater) UpdateStatefulSetStatus(
|
||||
set *apps.StatefulSet,
|
||||
status *apps.StatefulSetStatus) error {
|
||||
// don't wait due to limited number of clients, but backoff after the default number of steps
|
||||
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
set.Status = *status
|
||||
_, updateErr := ssu.client.Apps().StatefulSets(set.Namespace).UpdateStatus(set)
|
||||
if updateErr == nil {
|
||||
return nil
|
||||
}
|
||||
if updated, err := ssu.setLister.StatefulSets(set.Namespace).Get(set.Name); err == nil {
|
||||
// make a copy so we don't mutate the shared cache
|
||||
if copy, err := scheme.Scheme.DeepCopy(updated); err == nil {
|
||||
set = copy.(*apps.StatefulSet)
|
||||
} else {
|
||||
utilruntime.HandleError(fmt.Errorf("error copying updated StatefulSet: %v", err))
|
||||
}
|
||||
} else {
|
||||
utilruntime.HandleError(fmt.Errorf("error getting updated StatefulSet %s/%s from lister: %v", set.Namespace, set.Name, err))
|
||||
}
|
||||
|
||||
return updateErr
|
||||
})
|
||||
}
|
||||
|
||||
var _ StatefulSetStatusUpdaterInterface = &realStatefulSetStatusUpdater{}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package statefulset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
|
||||
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
|
||||
)
|
||||
|
||||
func TestStatefulSetUpdaterUpdatesSetStatus(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := apps.StatefulSetStatus{ObservedGeneration: func() *int64 {
|
||||
i := int64(1)
|
||||
return &i
|
||||
}(), Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, nil)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
return true, update.GetObject(), nil
|
||||
})
|
||||
if err := updater.UpdateStatefulSetStatus(set, &status); err != nil {
|
||||
t.Errorf("Error returned on successful status update: %s", err)
|
||||
}
|
||||
if set.Status.Replicas != 2 {
|
||||
t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulSetStatusUpdaterUpdatesObservedGeneration(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := apps.StatefulSetStatus{ObservedGeneration: func() *int64 {
|
||||
i := int64(3)
|
||||
return &i
|
||||
}(), Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, nil)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
sts := update.GetObject().(*apps.StatefulSet)
|
||||
if sts.Status.ObservedGeneration == nil || *sts.Status.ObservedGeneration != int64(3) {
|
||||
t.Errorf("expected observedGeneration to be synced with generation for statefulset %q", sts.Name)
|
||||
}
|
||||
return true, sts, nil
|
||||
})
|
||||
if err := updater.UpdateStatefulSetStatus(set, &status); err != nil {
|
||||
t.Errorf("Error returned on successful status update: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasFailure(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := apps.StatefulSetStatus{ObservedGeneration: func() *int64 {
|
||||
i := int64(3)
|
||||
return &i
|
||||
}(), Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewInternalError(errors.New("API server down"))
|
||||
})
|
||||
if err := updater.UpdateStatefulSetStatus(set, &status); err == nil {
|
||||
t.Error("Failed update did not return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasConflict(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := apps.StatefulSetStatus{ObservedGeneration: func() *int64 {
|
||||
i := int64(3)
|
||||
return &i
|
||||
}(), Replicas: 2}
|
||||
conflict := false
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
if !conflict {
|
||||
conflict = true
|
||||
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists"))
|
||||
} else {
|
||||
return true, update.GetObject(), nil
|
||||
}
|
||||
})
|
||||
if err := updater.UpdateStatefulSetStatus(set, &status); err != nil {
|
||||
t.Errorf("UpdateStatefulSetStatus returned an error: %s", err)
|
||||
}
|
||||
if set.Status.Replicas != 2 {
|
||||
t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasConflictFailure(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := apps.StatefulSetStatus{ObservedGeneration: func() *int64 {
|
||||
i := int64(3)
|
||||
return &i
|
||||
}(), Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
setLister := appslisters.NewStatefulSetLister(indexer)
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists"))
|
||||
})
|
||||
if err := updater.UpdateStatefulSetStatus(set, &status); err == nil {
|
||||
t.Error("UpdateStatefulSetStatus failed to return an error on get failure")
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
)
|
||||
|
||||
func alwaysReady() bool { return true }
|
||||
|
@ -578,15 +579,18 @@ func newFakeStatefulSetController(initialObjects ...runtime.Object) (*StatefulSe
|
|||
client := fake.NewSimpleClientset(initialObjects...)
|
||||
informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
|
||||
fpc := newFakeStatefulPodControl(informerFactory.Core().V1().Pods(), informerFactory.Apps().V1beta1().StatefulSets())
|
||||
ssu := newFakeStatefulSetStatusUpdater(informerFactory.Apps().V1beta1().StatefulSets())
|
||||
ssc := NewStatefulSetController(
|
||||
informerFactory.Core().V1().Pods(),
|
||||
informerFactory.Apps().V1beta1().StatefulSets(),
|
||||
informerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
informerFactory.Apps().V1beta1().ControllerRevisions(),
|
||||
client,
|
||||
)
|
||||
ssh := history.NewFakeHistory(informerFactory.Apps().V1beta1().ControllerRevisions())
|
||||
ssc.podListerSynced = alwaysReady
|
||||
ssc.setListerSynced = alwaysReady
|
||||
ssc.control = NewDefaultStatefulSetControl(fpc)
|
||||
ssc.control = NewDefaultStatefulSetControl(fpc, ssu, ssh)
|
||||
|
||||
return ssc, fpc
|
||||
}
|
||||
|
@ -614,7 +618,7 @@ func scaleUpStatefulSetController(set *apps.StatefulSet, ssc *StatefulSetControl
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for set.Status.Replicas < *set.Spec.Replicas {
|
||||
for set.Status.ReadyReplicas < *set.Spec.Replicas {
|
||||
pods, err := spc.podsLister.Pods(set.Namespace).List(selector)
|
||||
ord := len(pods) - 1
|
||||
pod := getPodAtOrdinal(pods, ord)
|
||||
|
|
|
@ -17,15 +17,23 @@ limitations under the License.
|
|||
package statefulset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@ -36,6 +44,7 @@ const maxUpdateRetries = 10
|
|||
// updateConflictError is the error used to indicate that the maximum number of retries against the API server have
|
||||
// been attempted and we need to back off
|
||||
var updateConflictError = fmt.Errorf("aborting update after %d attempts", maxUpdateRetries)
|
||||
var patchCodec = api.Codecs.LegacyCodec(apps.SchemeGroupVersion)
|
||||
|
||||
// overlappingStatefulSets sorts a list of StatefulSets by creation timestamp, using their names as a tie breaker.
|
||||
// Generally used to tie break between StatefulSets that have overlapping selectors.
|
||||
|
@ -246,6 +255,23 @@ func newControllerRef(set *apps.StatefulSet) *metav1.OwnerReference {
|
|||
}
|
||||
}
|
||||
|
||||
// setPodRevision sets the revision of Pod to revision by adding the StatefulSetRevisionLabel
|
||||
func setPodRevision(pod *v1.Pod, revision string) {
|
||||
if pod.Labels == nil {
|
||||
pod.Labels = make(map[string]string)
|
||||
}
|
||||
pod.Labels[apps.StatefulSetRevisionLabel] = revision
|
||||
}
|
||||
|
||||
// getPodRevision gets the revision of Pod by inspecting the StatefulSetRevisionLabel. If pod has no revision the empty
|
||||
// string is returned.
|
||||
func getPodRevision(pod *v1.Pod) string {
|
||||
if pod.Labels == nil {
|
||||
return ""
|
||||
}
|
||||
return pod.Labels[apps.StatefulSetRevisionLabel]
|
||||
}
|
||||
|
||||
// newStatefulSetPod returns a new Pod conforming to the set's Spec with an identity generated from ordinal.
|
||||
func newStatefulSetPod(set *apps.StatefulSet, ordinal int) *v1.Pod {
|
||||
pod, _ := controller.GetPodFromTemplate(&set.Spec.Template, set, newControllerRef(set))
|
||||
|
@ -255,6 +281,122 @@ func newStatefulSetPod(set *apps.StatefulSet, ordinal int) *v1.Pod {
|
|||
return pod
|
||||
}
|
||||
|
||||
// newVersionedStatefulSetPod creates a new Pod for a StatefulSet. currentSet is the representation of the set at the
|
||||
// current revision. updateSet is the representation of the set at the updateRevision. currentRevision is the name of
|
||||
// the current revision. updateRevision is the name of the update revision. ordinal is the ordinal of the Pod. If the
|
||||
// returned error is nil, the returned Pod is valid.
|
||||
func newVersionedStatefulSetPod(currentSet, updateSet *apps.StatefulSet, currentRevision, updateRevision string, ordinal int) *v1.Pod {
|
||||
if (currentSet.Spec.UpdateStrategy.Type == apps.RollingUpdateStatefulSetStrategyType &&
|
||||
ordinal < int(currentSet.Status.CurrentReplicas)) ||
|
||||
(currentSet.Spec.UpdateStrategy.Type == apps.PartitionStatefulSetStrategyType &&
|
||||
ordinal < int(currentSet.Spec.UpdateStrategy.Partition.Ordinal)) {
|
||||
pod := newStatefulSetPod(currentSet, ordinal)
|
||||
setPodRevision(pod, currentRevision)
|
||||
return pod
|
||||
}
|
||||
pod := newStatefulSetPod(updateSet, ordinal)
|
||||
setPodRevision(pod, updateRevision)
|
||||
return pod
|
||||
}
|
||||
|
||||
// getPatch returns a strategic merge patch that can be applied to restore a StatefulSet to a
|
||||
// previous version. If the returned error is nil the patch is valid. The current state that we save is just the
|
||||
// PodSpecTemplate. We can modify this later to encompass more state (or less) and remain compatible with previously
|
||||
// recorded patches.
|
||||
func getPatch(set *apps.StatefulSet) ([]byte, error) {
|
||||
str, err := runtime.Encode(patchCodec, set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var raw map[string]interface{}
|
||||
json.Unmarshal([]byte(str), &raw)
|
||||
objCopy := make(map[string]interface{})
|
||||
specCopy := make(map[string]interface{})
|
||||
spec := raw["spec"].(map[string]interface{})
|
||||
template := spec["template"].(map[string]interface{})
|
||||
specCopy["template"] = template
|
||||
template["$patch"] = "replace"
|
||||
objCopy["spec"] = specCopy
|
||||
patch, err := json.Marshal(objCopy)
|
||||
return patch, err
|
||||
}
|
||||
|
||||
// newRevision creates a new ControllerRevision containing a patch that reapplies the target state of set.
|
||||
// The Revision of the returned ControllerRevision is set to revision. If the returned error is nil, the returned
|
||||
// ControllerRevision is valid. StatefulSet revisions are stored as patches that re-apply the current state of set
|
||||
// to a new StatefulSet using a strategic merge patch to replace the saved state of the new StatefulSet.
|
||||
func newRevision(set *apps.StatefulSet, revision int64) (*apps.ControllerRevision, error) {
|
||||
patch, err := getPatch(set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return history.NewControllerRevision(set,
|
||||
controllerKind,
|
||||
selector,
|
||||
runtime.RawExtension{Raw: patch},
|
||||
revision)
|
||||
}
|
||||
|
||||
// applyRevision returns a new StatefulSet constructed by restoring the state in revision to set. If the returned error
|
||||
// is nil, the returned StatefulSet is valid.
|
||||
func applyRevision(set *apps.StatefulSet, revision *apps.ControllerRevision) (*apps.StatefulSet, error) {
|
||||
obj, err := scheme.Scheme.DeepCopy(set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clone := obj.(*apps.StatefulSet)
|
||||
patched, err := strategicpatch.StrategicMergePatch([]byte(runtime.EncodeOrDie(patchCodec, clone)), revision.Data.Raw, clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(patched, clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clone, nil
|
||||
}
|
||||
|
||||
// nextRevision finds the next valid revision number based on revisions. If the length of revisions
|
||||
// is 0 this is 1. Otherwise, it is 1 greater than the largest revision's Revision. This method
|
||||
// assumes that revisions has been sorted by Revision.
|
||||
func nextRevision(revisions []*apps.ControllerRevision) int64 {
|
||||
count := len(revisions)
|
||||
if count <= 0 {
|
||||
return 1
|
||||
}
|
||||
return revisions[count-1].Revision + 1
|
||||
}
|
||||
|
||||
// inconsistentStatus returns true if the ObservedGeneration of status is greater than set's
|
||||
// Generation or if any of the status's fields do not match those of set's status.
|
||||
func inconsistentStatus(set *apps.StatefulSet, status *apps.StatefulSetStatus) bool {
|
||||
return set.Status.ObservedGeneration == nil ||
|
||||
*status.ObservedGeneration > *set.Status.ObservedGeneration ||
|
||||
status.Replicas != set.Status.Replicas ||
|
||||
status.CurrentReplicas != set.Status.CurrentReplicas ||
|
||||
status.ReadyReplicas != set.Status.ReadyReplicas ||
|
||||
status.UpdatedReplicas != set.Status.UpdatedReplicas ||
|
||||
status.CurrentRevision != set.Status.CurrentRevision ||
|
||||
status.UpdateRevision != set.Status.UpdateRevision
|
||||
}
|
||||
|
||||
// completeRollingUpdate completes a rolling update when all of set's replica Pods have been updated
|
||||
// to the updateRevision. status's currentRevision is set to updateRevision and its' updateRevision
|
||||
// is set to the empty string. status's currentReplicas is set to updateReplicas and its updateReplicas
|
||||
// are set to 0.
|
||||
func completeRollingUpdate(set *apps.StatefulSet, status *apps.StatefulSetStatus) {
|
||||
if set.Spec.UpdateStrategy.Type == apps.RollingUpdateStatefulSetStrategyType &&
|
||||
status.UpdatedReplicas == status.Replicas &&
|
||||
status.ReadyReplicas == status.Replicas {
|
||||
status.CurrentReplicas = status.UpdatedReplicas
|
||||
status.CurrentRevision = status.UpdateRevision
|
||||
}
|
||||
}
|
||||
|
||||
// ascendingOrdinal is a sort.Interface that Sorts a list of Pods based on the ordinals extracted
|
||||
// from the Pod. Pod's that have not been constructed by StatefulSet's have an ordinal of -1, and are therefore pushed
|
||||
// to the front of the list.
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
)
|
||||
|
||||
func TestGetParentNameAndOrdinal(t *testing.T) {
|
||||
|
@ -287,6 +288,26 @@ func TestNewPodControllerRef(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreateApplyRevision(t *testing.T) {
|
||||
set := newStatefulSet(1)
|
||||
revision, err := newRevision(set, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
set.Spec.Template.Spec.Containers[0].Name = "foo"
|
||||
restoredSet, err := applyRevision(set, revision)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
restoredRevision, err := newRevision(restoredSet, 2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !history.EqualRevision(revision, restoredRevision) {
|
||||
t.Errorf("wanted %v got %v", string(revision.Data.Raw), string(restoredRevision.Data.Raw))
|
||||
}
|
||||
}
|
||||
|
||||
func newPVC(name string) v1.PersistentVolumeClaim {
|
||||
return v1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
@ -354,6 +375,11 @@ func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeM
|
|||
Template: template,
|
||||
VolumeClaimTemplates: claims,
|
||||
ServiceName: "governingsvc",
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
RevisionHistoryLimit: func() *int32 {
|
||||
limit := int32(2)
|
||||
return &limit
|
||||
}(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ go_test(
|
|||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/apps/v1beta1:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/batch/v1:go_default_library",
|
||||
|
|
|
@ -52,6 +52,8 @@ func HistoryViewerFor(kind schema.GroupKind, c clientset.Interface) (HistoryView
|
|||
switch kind {
|
||||
case extensions.Kind("Deployment"), apps.Kind("Deployment"):
|
||||
return &DeploymentHistoryViewer{c}, nil
|
||||
case apps.Kind("StatefulSet"):
|
||||
return &StatefulSetHistoryViewer{c}, nil
|
||||
case extensions.Kind("DaemonSet"):
|
||||
return &DaemonSetHistoryViewer{c}, nil
|
||||
}
|
||||
|
@ -200,6 +202,58 @@ func (h *DaemonSetHistoryViewer) ViewHistory(namespace, name string, revision in
|
|||
})
|
||||
}
|
||||
|
||||
type StatefulSetHistoryViewer struct {
|
||||
c clientset.Interface
|
||||
}
|
||||
|
||||
func getOwner(revision apps.ControllerRevision) *metav1.OwnerReference {
|
||||
ownerRefs := revision.GetOwnerReferences()
|
||||
for i := range ownerRefs {
|
||||
owner := &ownerRefs[i]
|
||||
if owner.Controller != nil && *owner.Controller == true {
|
||||
return owner
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ViewHistory returns a list of the revision history of a statefulset
|
||||
// TODO: this should be a describer
|
||||
// TODO: needs to implement detailed revision view
|
||||
func (h *StatefulSetHistoryViewer) ViewHistory(namespace, name string, revision int64) (string, error) {
|
||||
|
||||
sts, err := h.c.Apps().StatefulSets(namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve statefulset %s", err)
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(sts.Spec.Selector)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve statefulset history %s", err)
|
||||
}
|
||||
revisions, err := h.c.Apps().ControllerRevisions(namespace).List(metav1.ListOptions{LabelSelector: selector.String()})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve statefulset history %s", err)
|
||||
}
|
||||
if len(revisions.Items) <= 0 {
|
||||
return "No rollout history found.", nil
|
||||
}
|
||||
revisionNumbers := make([]int64, len(revisions.Items))
|
||||
for i := range revisions.Items {
|
||||
if owner := getOwner(revisions.Items[i]); owner != nil && owner.UID == sts.UID {
|
||||
revisionNumbers[i] = revisions.Items[i].Revision
|
||||
}
|
||||
}
|
||||
sliceutil.SortInts64(revisionNumbers)
|
||||
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "REVISION\n")
|
||||
for _, r := range revisionNumbers {
|
||||
fmt.Fprintf(out, "%d\n", r)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// controlledHistories returns all ControllerRevisions controlled by the given DaemonSet
|
||||
// TODO: Use external version DaemonSet instead when #3955 is fixed
|
||||
func controlledHistories(c clientset.Interface, ds *extensions.DaemonSet) ([]*appsv1beta1.ControllerRevision, error) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
appsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion"
|
||||
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
)
|
||||
|
@ -39,6 +40,8 @@ func StatusViewerFor(kind schema.GroupKind, c internalclientset.Interface) (Stat
|
|||
return &DeploymentStatusViewer{c.Extensions()}, nil
|
||||
case extensions.Kind("DaemonSet"):
|
||||
return &DaemonSetStatusViewer{c.Extensions()}, nil
|
||||
case apps.Kind("StatefulSet"):
|
||||
return &StatefulSetStatusViewer{c.Apps()}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("no status viewer has been implemented for %v", kind)
|
||||
}
|
||||
|
@ -51,6 +54,10 @@ type DaemonSetStatusViewer struct {
|
|||
c extensionsclient.DaemonSetsGetter
|
||||
}
|
||||
|
||||
type StatefulSetStatusViewer struct {
|
||||
c appsclient.StatefulSetsGetter
|
||||
}
|
||||
|
||||
// Status returns a message describing deployment status, and a bool value indicating if the status is considered done
|
||||
func (s *DeploymentStatusViewer) Status(namespace, name string, revision int64) (string, bool, error) {
|
||||
deployment, err := s.c.Deployments(namespace).Get(name, metav1.GetOptions{})
|
||||
|
@ -107,3 +114,34 @@ func (s *DaemonSetStatusViewer) Status(namespace, name string, revision int64) (
|
|||
}
|
||||
return fmt.Sprintf("Waiting for daemon set spec update to be observed...\n"), false, nil
|
||||
}
|
||||
|
||||
// Status returns a message describing statefulset status, and a bool value indicating if the status is considered done
|
||||
func (s *StatefulSetStatusViewer) Status(namespace, name string, revision int64) (string, bool, error) {
|
||||
sts, err := s.c.StatefulSets(namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
if sts.Spec.UpdateStrategy.Type == apps.OnDeleteStatefulSetStrategyType {
|
||||
return "", true, fmt.Errorf("%s updateStrategy does not have a Status`", apps.OnDeleteStatefulSetStrategyType)
|
||||
}
|
||||
if sts.Status.ObservedGeneration == nil || sts.Generation > *sts.Status.ObservedGeneration {
|
||||
return "Waiting for statefulset spec update to be observed...\n", false, nil
|
||||
}
|
||||
if sts.Status.ReadyReplicas < sts.Spec.Replicas {
|
||||
return fmt.Sprintf("Waiting for %d pods to be ready...\n", sts.Spec.Replicas-sts.Status.ReadyReplicas), false, nil
|
||||
}
|
||||
if sts.Spec.UpdateStrategy.Type == apps.PartitionStatefulSetStrategyType {
|
||||
if sts.Status.UpdatedReplicas < (sts.Spec.Replicas - sts.Spec.UpdateStrategy.Partition.Ordinal) {
|
||||
return fmt.Sprintf("Waiting for partitioned roll out to finish: %d out of %d new pods have been updated...\n",
|
||||
sts.Status.UpdatedReplicas, (sts.Spec.Replicas - sts.Spec.UpdateStrategy.Partition.Ordinal)), false, nil
|
||||
}
|
||||
return fmt.Sprintf("partitioned roll out complete: %d new pods have been updated...\n",
|
||||
sts.Status.UpdatedReplicas), false, nil
|
||||
}
|
||||
if sts.Status.UpdateRevision != sts.Status.CurrentRevision {
|
||||
return fmt.Sprintf("waiting for statefulset rolling update to complete %d pods at revision %s...\n",
|
||||
sts.Status.UpdatedReplicas, sts.Status.UpdateRevision), false, nil
|
||||
}
|
||||
return fmt.Sprintf("statefulset rolling update complete %d pods at revision %s...\n", sts.Status.CurrentReplicas, sts.Status.CurrentRevision), true, nil
|
||||
|
||||
}
|
||||
|
|
|
@ -17,9 +17,12 @@ limitations under the License.
|
|||
package kubectl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
)
|
||||
|
@ -231,6 +234,163 @@ func TestDaemonSetStatusViewerStatus(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStatefulSetStatusViewerStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
generation int64
|
||||
strategy apps.StatefulSetUpdateStrategy
|
||||
status apps.StatefulSetStatus
|
||||
msg string
|
||||
done bool
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "on delete returns an error",
|
||||
generation: 1,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(1)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 0,
|
||||
ReadyReplicas: 1,
|
||||
CurrentReplicas: 0,
|
||||
UpdatedReplicas: 0,
|
||||
},
|
||||
|
||||
msg: "",
|
||||
done: true,
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "unobserved update is not complete",
|
||||
generation: 2,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(1)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 3,
|
||||
ReadyReplicas: 3,
|
||||
CurrentReplicas: 3,
|
||||
UpdatedReplicas: 0,
|
||||
},
|
||||
|
||||
msg: "Waiting for statefulset spec update to be observed...\n",
|
||||
done: false,
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "if all pods are not ready the update is not complete",
|
||||
generation: 1,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(2)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 3,
|
||||
ReadyReplicas: 2,
|
||||
CurrentReplicas: 3,
|
||||
UpdatedReplicas: 0,
|
||||
},
|
||||
|
||||
msg: fmt.Sprintf("Waiting for %d pods to be ready...\n", 1),
|
||||
done: false,
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "partition update completes when all replicas above the partition are updated",
|
||||
generation: 1,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.PartitionStatefulSetStrategyType,
|
||||
Partition: func() *apps.PartitionStatefulSetStrategy {
|
||||
return &apps.PartitionStatefulSetStrategy{Ordinal: 2}
|
||||
}()},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(2)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 3,
|
||||
ReadyReplicas: 3,
|
||||
CurrentReplicas: 2,
|
||||
UpdatedReplicas: 1,
|
||||
},
|
||||
|
||||
msg: fmt.Sprintf("partitioned roll out complete: %d new pods have been updated...\n", 1),
|
||||
done: true,
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "partition update is in progress if all pods above the partition have not been updated",
|
||||
generation: 1,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.PartitionStatefulSetStrategyType,
|
||||
Partition: func() *apps.PartitionStatefulSetStrategy {
|
||||
return &apps.PartitionStatefulSetStrategy{Ordinal: 2}
|
||||
}()},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(2)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 3,
|
||||
ReadyReplicas: 3,
|
||||
CurrentReplicas: 3,
|
||||
UpdatedReplicas: 0,
|
||||
},
|
||||
|
||||
msg: fmt.Sprintf("Waiting for partitioned roll out to finish: %d out of %d new pods have been updated...\n", 0, 1),
|
||||
done: true,
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "update completes when all replicas are current",
|
||||
generation: 1,
|
||||
strategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
status: apps.StatefulSetStatus{
|
||||
ObservedGeneration: func() *int64 {
|
||||
generation := int64(2)
|
||||
return &generation
|
||||
}(),
|
||||
Replicas: 3,
|
||||
ReadyReplicas: 3,
|
||||
CurrentReplicas: 3,
|
||||
UpdatedReplicas: 3,
|
||||
CurrentRevision: "foo",
|
||||
UpdateRevision: "foo",
|
||||
},
|
||||
|
||||
msg: fmt.Sprintf("statefulset rolling update complete %d pods at revision %s...\n", 3, "foo"),
|
||||
done: true,
|
||||
err: false,
|
||||
},
|
||||
}
|
||||
for i := range tests {
|
||||
test := tests[i]
|
||||
s := newStatefulSet(3)
|
||||
s.Status = test.status
|
||||
s.Spec.UpdateStrategy = test.strategy
|
||||
s.Generation = test.generation
|
||||
client := fake.NewSimpleClientset(s).Apps()
|
||||
dsv := &StatefulSetStatusViewer{c: client}
|
||||
msg, done, err := dsv.Status(s.Namespace, s.Name, 0)
|
||||
if test.err && err == nil {
|
||||
t.Fatalf("%s: expected error", test.name)
|
||||
}
|
||||
if !test.err && err != nil {
|
||||
t.Fatalf("%s: %s", test.name, err)
|
||||
}
|
||||
if done && !test.done {
|
||||
t.Errorf("%s: want done %v got %v", test.name, done, test.done)
|
||||
}
|
||||
if msg != test.msg {
|
||||
t.Errorf("%s: want message %s got %s", test.name, test.msg, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDaemonSetStatusViewerStatusWithWrongUpdateStrategyType(t *testing.T) {
|
||||
d := &extensions.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
@ -252,3 +412,36 @@ func TestDaemonSetStatusViewerStatusWithWrongUpdateStrategyType(t *testing.T) {
|
|||
t.Errorf("Status for daemon sets with UpdateStrategy type different than RollingUpdate should return error. Instead got: msg: %s\ndone: %t\n err: %v", msg, done, err)
|
||||
}
|
||||
}
|
||||
|
||||
func newStatefulSet(replicas int32) *apps.StatefulSet {
|
||||
return &apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: "test",
|
||||
Image: "test_image",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
},
|
||||
},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
Replicas: replicas,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ func validNewStatefulSet() *apps.StatefulSet {
|
|||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
Replicas: 7,
|
||||
Replicas: 7,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{},
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ func TestStatefulSetStrategy(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{Replicas: 3},
|
||||
}
|
||||
|
@ -74,6 +75,7 @@ func TestStatefulSetStrategy(t *testing.T) {
|
|||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: ps.Spec.Selector,
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{Replicas: 4},
|
||||
}
|
||||
|
@ -122,9 +124,10 @@ func TestStatefulSetStatusStrategy(t *testing.T) {
|
|||
oldPS := &apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "10"},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 3,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{
|
||||
Replicas: 1,
|
||||
|
@ -133,9 +136,10 @@ func TestStatefulSetStatusStrategy(t *testing.T) {
|
|||
newPS := &apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "9"},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
Replicas: 1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: 1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
Status: apps.StatefulSetStatus{
|
||||
Replicas: 2,
|
||||
|
|
|
@ -264,6 +264,7 @@ func init() {
|
|||
rbac.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
|
||||
rbac.NewRule("update").Groups(appsGroup).Resources("statefulsets/status").RuleOrDie(),
|
||||
rbac.NewRule("get", "create", "delete", "update", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
|
||||
rbac.NewRule("get", "create", "delete", "update", "patch", "list", "watch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
|
||||
rbac.NewRule("get", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
|
||||
eventsRule(),
|
||||
},
|
||||
|
|
|
@ -975,6 +975,18 @@ items:
|
|||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- controllerrevisions
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
|
|
@ -60,6 +60,54 @@ const (
|
|||
ParallelPodManagement = "Parallel"
|
||||
)
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
type StatefulSetUpdateStrategy struct {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Type StatefulSetUpdateStrategyType
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
Partition *PartitionStatefulSetStrategy
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
|
||||
// all possible update strategies for the StatefulSet controller.
|
||||
type StatefulSetUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// PartitionStatefulSetStrategyType indicates that updates will only be
|
||||
// applied to a partition of the StatefulSet. This is useful for canaries
|
||||
// and phased roll outs. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's currentRevision if there ordinal is less than the supplied
|
||||
// Partition's ordinal. Otherwise, they will be created from the specification
|
||||
// version indicated by the StatefulSet's updateRevision.
|
||||
PartitionStatefulSetStrategyType StatefulSetUpdateStrategyType = "Partition"
|
||||
// RollingUpdateStatefulSetStrategyType indicates that update will be
|
||||
// applied to all Pods in the StatefulSet with respect to the StatefulSet
|
||||
// ordering constraints. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's updateRevision.
|
||||
RollingUpdateStatefulSetStrategyType = "RollingUpdate"
|
||||
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
|
||||
// tracking and ordered rolling restarts are disabled. Pods are recreated
|
||||
// from the StatefulSetSpec when they are manually deleted. When a scale
|
||||
// operation is performed with this strategy,specification version indicated
|
||||
// by the StatefulSet's currentRevision.
|
||||
OnDeleteStatefulSetStrategyType = "OnDelete"
|
||||
)
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
type PartitionStatefulSetStrategy struct {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
Ordinal int32
|
||||
}
|
||||
|
||||
// A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type StatefulSetSpec struct {
|
||||
// Replicas is the desired number of replicas of the given Template.
|
||||
|
@ -109,16 +157,47 @@ type StatefulSetSpec struct {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
PodManagementPolicy PodManagementPolicyType
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
UpdateStrategy StatefulSetUpdateStrategy
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
type StatefulSetStatus struct {
|
||||
// most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
ObservedGeneration *int64
|
||||
|
||||
// Replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
Replicas int32
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
ReadyReplicas int32
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
CurrentReplicas int32
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
UpdatedReplicas int32
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
CurrentRevision string
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
UpdateRevision string
|
||||
}
|
||||
|
||||
// StatefulSetList is a collection of StatefulSets.
|
||||
|
|
|
@ -37,6 +37,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||
err := scheme.AddConversionFuncs(
|
||||
Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec,
|
||||
Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec,
|
||||
Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy,
|
||||
Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy,
|
||||
// extensions
|
||||
// TODO: below conversions should be dropped in favor of auto-generated
|
||||
// ones, see https://github.com/kubernetes/kubernetextensionsssues/39865
|
||||
|
@ -109,6 +111,15 @@ func Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(in *StatefulSetSpec
|
|||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if err := Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = apps.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
return nil
|
||||
|
@ -140,8 +151,39 @@ func Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(in *apps.StatefulSe
|
|||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(in *StatefulSetUpdateStrategy, out *apps.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = apps.StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.Partition != nil {
|
||||
out.Partition = new(apps.PartitionStatefulSetStrategy)
|
||||
out.Partition.Ordinal = in.Partition.Ordinal
|
||||
} else {
|
||||
out.Partition = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(in *apps.StatefulSetUpdateStrategy, out *StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.Partition != nil {
|
||||
out.Partition = new(PartitionStatefulSetStrategy)
|
||||
out.Partition.Ordinal = in.Partition.Ordinal
|
||||
} else {
|
||||
out.Partition = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ func SetDefaults_StatefulSet(obj *StatefulSet) {
|
|||
if len(obj.Spec.PodManagementPolicy) == 0 {
|
||||
obj.Spec.PodManagementPolicy = OrderedReadyPodManagement
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == "" {
|
||||
obj.Spec.UpdateStrategy.Type = OnDeleteStatefulSetStrategyType
|
||||
}
|
||||
labels := obj.Spec.Template.Labels
|
||||
if labels != nil {
|
||||
if obj.Spec.Selector == nil {
|
||||
|
@ -45,6 +49,11 @@ func SetDefaults_StatefulSet(obj *StatefulSet) {
|
|||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
if obj.Spec.RevisionHistoryLimit == nil {
|
||||
obj.Spec.RevisionHistoryLimit = new(int32)
|
||||
*obj.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SetDefaults_Deployment sets additional defaults compared to its counterpart
|
||||
|
|
|
@ -34,6 +34,7 @@ limitations under the License.
|
|||
DeploymentSpec
|
||||
DeploymentStatus
|
||||
DeploymentStrategy
|
||||
PartitionStatefulSetStrategy
|
||||
RollbackConfig
|
||||
RollingUpdateDeployment
|
||||
Scale
|
||||
|
@ -43,6 +44,7 @@ limitations under the License.
|
|||
StatefulSetList
|
||||
StatefulSetSpec
|
||||
StatefulSetStatus
|
||||
StatefulSetUpdateStrategy
|
||||
*/
|
||||
package v1beta1
|
||||
|
||||
|
@ -108,43 +110,55 @@ func (m *DeploymentStrategy) Reset() { *m = DeploymentStrateg
|
|||
func (*DeploymentStrategy) ProtoMessage() {}
|
||||
func (*DeploymentStrategy) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} }
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Reset() { *m = PartitionStatefulSetStrategy{} }
|
||||
func (*PartitionStatefulSetStrategy) ProtoMessage() {}
|
||||
func (*PartitionStatefulSetStrategy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{9}
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Reset() { *m = RollbackConfig{} }
|
||||
func (*RollbackConfig) ProtoMessage() {}
|
||||
func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} }
|
||||
func (*RollbackConfig) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} }
|
||||
|
||||
func (m *RollingUpdateDeployment) Reset() { *m = RollingUpdateDeployment{} }
|
||||
func (*RollingUpdateDeployment) ProtoMessage() {}
|
||||
func (*RollingUpdateDeployment) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{10}
|
||||
return fileDescriptorGenerated, []int{11}
|
||||
}
|
||||
|
||||
func (m *Scale) Reset() { *m = Scale{} }
|
||||
func (*Scale) ProtoMessage() {}
|
||||
func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} }
|
||||
func (*Scale) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} }
|
||||
|
||||
func (m *ScaleSpec) Reset() { *m = ScaleSpec{} }
|
||||
func (*ScaleSpec) ProtoMessage() {}
|
||||
func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} }
|
||||
func (*ScaleSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} }
|
||||
|
||||
func (m *ScaleStatus) Reset() { *m = ScaleStatus{} }
|
||||
func (*ScaleStatus) ProtoMessage() {}
|
||||
func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} }
|
||||
func (*ScaleStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} }
|
||||
|
||||
func (m *StatefulSet) Reset() { *m = StatefulSet{} }
|
||||
func (*StatefulSet) ProtoMessage() {}
|
||||
func (*StatefulSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} }
|
||||
func (*StatefulSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} }
|
||||
|
||||
func (m *StatefulSetList) Reset() { *m = StatefulSetList{} }
|
||||
func (*StatefulSetList) ProtoMessage() {}
|
||||
func (*StatefulSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{15} }
|
||||
func (*StatefulSetList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} }
|
||||
|
||||
func (m *StatefulSetSpec) Reset() { *m = StatefulSetSpec{} }
|
||||
func (*StatefulSetSpec) ProtoMessage() {}
|
||||
func (*StatefulSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{16} }
|
||||
func (*StatefulSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} }
|
||||
|
||||
func (m *StatefulSetStatus) Reset() { *m = StatefulSetStatus{} }
|
||||
func (*StatefulSetStatus) ProtoMessage() {}
|
||||
func (*StatefulSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{17} }
|
||||
func (*StatefulSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{18} }
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Reset() { *m = StatefulSetUpdateStrategy{} }
|
||||
func (*StatefulSetUpdateStrategy) ProtoMessage() {}
|
||||
func (*StatefulSetUpdateStrategy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptorGenerated, []int{19}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ControllerRevision)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.ControllerRevision")
|
||||
|
@ -156,6 +170,7 @@ func init() {
|
|||
proto.RegisterType((*DeploymentSpec)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.DeploymentSpec")
|
||||
proto.RegisterType((*DeploymentStatus)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.DeploymentStatus")
|
||||
proto.RegisterType((*DeploymentStrategy)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.DeploymentStrategy")
|
||||
proto.RegisterType((*PartitionStatefulSetStrategy)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.PartitionStatefulSetStrategy")
|
||||
proto.RegisterType((*RollbackConfig)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.RollbackConfig")
|
||||
proto.RegisterType((*RollingUpdateDeployment)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.RollingUpdateDeployment")
|
||||
proto.RegisterType((*Scale)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.Scale")
|
||||
|
@ -165,6 +180,7 @@ func init() {
|
|||
proto.RegisterType((*StatefulSetList)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.StatefulSetList")
|
||||
proto.RegisterType((*StatefulSetSpec)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.StatefulSetSpec")
|
||||
proto.RegisterType((*StatefulSetStatus)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.StatefulSetStatus")
|
||||
proto.RegisterType((*StatefulSetUpdateStrategy)(nil), "k8s.io.client-go.pkg.apis.apps.v1beta1.StatefulSetUpdateStrategy")
|
||||
}
|
||||
func (m *ControllerRevision) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
|
@ -583,6 +599,27 @@ func (m *DeploymentStrategy) MarshalTo(dAtA []byte) (int, error) {
|
|||
return i, nil
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Ordinal))
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
|
@ -885,6 +922,19 @@ func (m *StatefulSetSpec) MarshalTo(dAtA []byte) (int, error) {
|
|||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.PodManagementPolicy)))
|
||||
i += copy(dAtA[i:], m.PodManagementPolicy)
|
||||
dAtA[i] = 0x3a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.UpdateStrategy.Size()))
|
||||
n27, err := m.UpdateStrategy.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n27
|
||||
if m.RevisionHistoryLimit != nil {
|
||||
dAtA[i] = 0x40
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(*m.RevisionHistoryLimit))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -911,6 +961,55 @@ func (m *StatefulSetStatus) MarshalTo(dAtA []byte) (int, error) {
|
|||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas))
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.ReadyReplicas))
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentReplicas))
|
||||
dAtA[i] = 0x28
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.UpdatedReplicas))
|
||||
dAtA[i] = 0x32
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.CurrentRevision)))
|
||||
i += copy(dAtA[i:], m.CurrentRevision)
|
||||
dAtA[i] = 0x3a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.UpdateRevision)))
|
||||
i += copy(dAtA[i:], m.UpdateRevision)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type)))
|
||||
i += copy(dAtA[i:], m.Type)
|
||||
if m.Partition != nil {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Partition.Size()))
|
||||
n28, err := m.Partition.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n28
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -1090,6 +1189,13 @@ func (m *DeploymentStrategy) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *PartitionStatefulSetStrategy) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
n += 1 + sovGenerated(uint64(m.Ordinal))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *RollbackConfig) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
@ -1195,6 +1301,11 @@ func (m *StatefulSetSpec) Size() (n int) {
|
|||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.PodManagementPolicy)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = m.UpdateStrategy.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
if m.RevisionHistoryLimit != nil {
|
||||
n += 1 + sovGenerated(uint64(*m.RevisionHistoryLimit))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1205,6 +1316,25 @@ func (m *StatefulSetStatus) Size() (n int) {
|
|||
n += 1 + sovGenerated(uint64(*m.ObservedGeneration))
|
||||
}
|
||||
n += 1 + sovGenerated(uint64(m.Replicas))
|
||||
n += 1 + sovGenerated(uint64(m.ReadyReplicas))
|
||||
n += 1 + sovGenerated(uint64(m.CurrentReplicas))
|
||||
n += 1 + sovGenerated(uint64(m.UpdatedReplicas))
|
||||
l = len(m.CurrentRevision)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.UpdateRevision)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *StatefulSetUpdateStrategy) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Type)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
if m.Partition != nil {
|
||||
l = m.Partition.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1350,6 +1480,16 @@ func (this *DeploymentStrategy) String() string {
|
|||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *PartitionStatefulSetStrategy) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&PartitionStatefulSetStrategy{`,
|
||||
`Ordinal:` + fmt.Sprintf("%v", this.Ordinal) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *RollbackConfig) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
|
@ -1449,6 +1589,8 @@ func (this *StatefulSetSpec) String() string {
|
|||
`VolumeClaimTemplates:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VolumeClaimTemplates), "PersistentVolumeClaim", "k8s_io_kubernetes_pkg_api_v1.PersistentVolumeClaim", 1), `&`, ``, 1) + `,`,
|
||||
`ServiceName:` + fmt.Sprintf("%v", this.ServiceName) + `,`,
|
||||
`PodManagementPolicy:` + fmt.Sprintf("%v", this.PodManagementPolicy) + `,`,
|
||||
`UpdateStrategy:` + strings.Replace(strings.Replace(this.UpdateStrategy.String(), "StatefulSetUpdateStrategy", "StatefulSetUpdateStrategy", 1), `&`, ``, 1) + `,`,
|
||||
`RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -1460,6 +1602,22 @@ func (this *StatefulSetStatus) String() string {
|
|||
s := strings.Join([]string{`&StatefulSetStatus{`,
|
||||
`ObservedGeneration:` + valueToStringGenerated(this.ObservedGeneration) + `,`,
|
||||
`Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`,
|
||||
`ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`,
|
||||
`CurrentReplicas:` + fmt.Sprintf("%v", this.CurrentReplicas) + `,`,
|
||||
`UpdatedReplicas:` + fmt.Sprintf("%v", this.UpdatedReplicas) + `,`,
|
||||
`CurrentRevision:` + fmt.Sprintf("%v", this.CurrentRevision) + `,`,
|
||||
`UpdateRevision:` + fmt.Sprintf("%v", this.UpdateRevision) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *StatefulSetUpdateStrategy) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&StatefulSetUpdateStrategy{`,
|
||||
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
|
||||
`Partition:` + strings.Replace(fmt.Sprintf("%v", this.Partition), "PartitionStatefulSetStrategy", "PartitionStatefulSetStrategy", 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -3016,6 +3174,75 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *PartitionStatefulSetStrategy) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: PartitionStatefulSetStrategy: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: PartitionStatefulSetStrategy: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Ordinal", wireType)
|
||||
}
|
||||
m.Ordinal = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Ordinal |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *RollbackConfig) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -4076,6 +4303,56 @@ func (m *StatefulSetSpec) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
m.PodManagementPolicy = PodManagementPolicyType(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdateStrategy", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.UpdateStrategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType)
|
||||
}
|
||||
var v int32
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.RevisionHistoryLimit = &v
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -4165,6 +4442,233 @@ func (m *StatefulSetStatus) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType)
|
||||
}
|
||||
m.ReadyReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ReadyReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CurrentReplicas", wireType)
|
||||
}
|
||||
m.CurrentReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.CurrentReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdatedReplicas", wireType)
|
||||
}
|
||||
m.UpdatedReplicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.UpdatedReplicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CurrentRevision", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.CurrentRevision = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UpdateRevision", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.UpdateRevision = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *StatefulSetUpdateStrategy) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: StatefulSetUpdateStrategy: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: StatefulSetUpdateStrategy: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Type = StatefulSetUpdateStrategyType(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Partition", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Partition == nil {
|
||||
m.Partition = &PartitionStatefulSetStrategy{}
|
||||
}
|
||||
if err := m.Partition.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -4296,108 +4800,119 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 1647 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcf, 0x4f, 0x1b, 0xc7,
|
||||
0x17, 0x67, 0x8d, 0x0d, 0x66, 0x08, 0x26, 0x0c, 0x7c, 0xc1, 0x5f, 0x52, 0x19, 0xe4, 0x43, 0x42,
|
||||
0xaa, 0x64, 0xdd, 0x90, 0x34, 0x3f, 0xa0, 0x8a, 0x8a, 0x49, 0x9a, 0xa6, 0x82, 0x82, 0xc6, 0x10,
|
||||
0x35, 0x69, 0x2a, 0x65, 0xbc, 0x9e, 0x2c, 0x1b, 0xf6, 0x97, 0x76, 0xc6, 0x6e, 0x7c, 0xeb, 0xa5,
|
||||
0x87, 0x4a, 0x3d, 0xf4, 0x1f, 0xa8, 0xda, 0x73, 0x55, 0xa9, 0xff, 0x06, 0x6a, 0x2f, 0x51, 0x4f,
|
||||
0x51, 0x0f, 0xa8, 0x90, 0xbf, 0xa1, 0x97, 0x9c, 0xaa, 0x99, 0x9d, 0xfd, 0xe5, 0xb5, 0xc1, 0x50,
|
||||
0x95, 0x4b, 0x6f, 0xde, 0x79, 0xef, 0x7d, 0xde, 0x8f, 0x79, 0xef, 0xcd, 0x7b, 0x06, 0xb7, 0x76,
|
||||
0x6f, 0x53, 0xd5, 0x70, 0x2a, 0xbb, 0xcd, 0x3a, 0xf1, 0x6c, 0xc2, 0x08, 0xad, 0xb8, 0xbb, 0x7a,
|
||||
0x05, 0xbb, 0x06, 0xad, 0x60, 0xd7, 0xa5, 0x95, 0xd6, 0xb5, 0x3a, 0x61, 0xf8, 0x5a, 0x45, 0x27,
|
||||
0x36, 0xf1, 0x30, 0x23, 0x0d, 0xd5, 0xf5, 0x1c, 0xe6, 0xc0, 0x4b, 0xbe, 0xa0, 0x1a, 0x09, 0xaa,
|
||||
0xee, 0xae, 0xae, 0x72, 0x41, 0x95, 0x0b, 0xaa, 0x52, 0x70, 0xf6, 0xaa, 0x6e, 0xb0, 0x9d, 0x66,
|
||||
0x5d, 0xd5, 0x1c, 0xab, 0xa2, 0x3b, 0xba, 0x53, 0x11, 0xf2, 0xf5, 0xe6, 0x73, 0xf1, 0x25, 0x3e,
|
||||
0xc4, 0x2f, 0x1f, 0x77, 0xf6, 0x86, 0x34, 0x08, 0xbb, 0x86, 0x85, 0xb5, 0x1d, 0xc3, 0x26, 0x5e,
|
||||
0x3b, 0x32, 0xc9, 0x22, 0x0c, 0x57, 0x5a, 0x29, 0x6b, 0x66, 0x2b, 0xbd, 0xa4, 0xbc, 0xa6, 0xcd,
|
||||
0x0c, 0x8b, 0xa4, 0x04, 0x6e, 0x1e, 0x27, 0x40, 0xb5, 0x1d, 0x62, 0xe1, 0x94, 0xdc, 0xf5, 0x5e,
|
||||
0x72, 0x4d, 0x66, 0x98, 0x15, 0xc3, 0x66, 0x94, 0x79, 0x29, 0xa1, 0x2b, 0x3d, 0x83, 0xdc, 0xcd,
|
||||
0x97, 0x3b, 0x47, 0x5c, 0x89, 0xeb, 0x98, 0x86, 0xd6, 0xee, 0x75, 0x29, 0xe5, 0xbf, 0x14, 0x00,
|
||||
0x57, 0x1d, 0x9b, 0x79, 0x8e, 0x69, 0x12, 0x0f, 0x91, 0x96, 0x41, 0x0d, 0xc7, 0x86, 0xcf, 0x40,
|
||||
0x9e, 0x07, 0xae, 0x81, 0x19, 0x2e, 0x2a, 0xf3, 0xca, 0xc2, 0xe8, 0xe2, 0x7b, 0xaa, 0xbc, 0xbe,
|
||||
0xb8, 0x1f, 0xd1, 0x05, 0x72, 0x6e, 0xb5, 0x75, 0x4d, 0xdd, 0xa8, 0xbf, 0x20, 0x1a, 0x5b, 0x27,
|
||||
0x0c, 0x57, 0xe1, 0xde, 0xfe, 0xdc, 0xc0, 0xe1, 0xfe, 0x1c, 0x88, 0xce, 0x50, 0x88, 0x0a, 0x37,
|
||||
0x40, 0x56, 0xa0, 0x67, 0x04, 0xfa, 0xd5, 0x9e, 0xe8, 0x32, 0xba, 0x2a, 0xc2, 0x5f, 0xde, 0x7f,
|
||||
0xc9, 0x88, 0xcd, 0xcd, 0xab, 0x9e, 0x93, 0xd0, 0xd9, 0x7b, 0x98, 0x61, 0x24, 0x80, 0xe0, 0x15,
|
||||
0x90, 0xf7, 0xa4, 0xf9, 0xc5, 0xc1, 0x79, 0x65, 0x61, 0xb0, 0x7a, 0x5e, 0x72, 0xe5, 0x03, 0xb7,
|
||||
0x50, 0xc8, 0x51, 0x7e, 0xad, 0x80, 0xe9, 0xb4, 0xdf, 0x6b, 0x06, 0x65, 0xf0, 0x69, 0xca, 0x77,
|
||||
0xb5, 0x3f, 0xdf, 0xb9, 0xb4, 0xf0, 0x3c, 0x54, 0x1c, 0x9c, 0xc4, 0xfc, 0x7e, 0x06, 0x72, 0x06,
|
||||
0x23, 0x16, 0x2d, 0x66, 0xe6, 0x07, 0x17, 0x46, 0x17, 0x97, 0xd5, 0x3e, 0xab, 0x42, 0x4d, 0x5b,
|
||||
0x5b, 0x1d, 0x93, 0x7a, 0x72, 0x0f, 0x39, 0x22, 0xf2, 0x81, 0xcb, 0x3f, 0x67, 0x00, 0xb8, 0x47,
|
||||
0x5c, 0xd3, 0x69, 0x5b, 0xc4, 0x66, 0x67, 0x70, 0x95, 0x8f, 0x41, 0x96, 0xba, 0x44, 0x93, 0x57,
|
||||
0x79, 0xab, 0x6f, 0x8f, 0x22, 0x23, 0x6b, 0x2e, 0xd1, 0xa2, 0x4b, 0xe5, 0x5f, 0x48, 0x40, 0x42,
|
||||
0x0c, 0x86, 0x28, 0xc3, 0xac, 0x49, 0xc5, 0x95, 0x8e, 0x2e, 0xde, 0x39, 0x0d, 0xb8, 0x00, 0xa8,
|
||||
0x16, 0x24, 0xfc, 0x90, 0xff, 0x8d, 0x24, 0x70, 0xf9, 0x60, 0x10, 0x4c, 0x46, 0xcc, 0xab, 0x8e,
|
||||
0xdd, 0x30, 0x18, 0x2f, 0x81, 0x65, 0x90, 0x65, 0x6d, 0x97, 0x88, 0x98, 0x8d, 0x54, 0x2f, 0x05,
|
||||
0xc6, 0x6d, 0xb5, 0x5d, 0xf2, 0x76, 0x7f, 0x6e, 0xa6, 0x8b, 0x08, 0x27, 0x21, 0x21, 0x04, 0x1f,
|
||||
0x85, 0x76, 0x67, 0x84, 0xf8, 0xdd, 0xa4, 0xf2, 0xb7, 0xfb, 0x73, 0x47, 0x56, 0xb8, 0x1a, 0x62,
|
||||
0x26, 0x8d, 0x85, 0x17, 0xc1, 0x90, 0x47, 0x30, 0x75, 0xec, 0x62, 0x56, 0xe0, 0x86, 0x4e, 0x21,
|
||||
0x71, 0x8a, 0x24, 0x15, 0x5e, 0x06, 0xc3, 0x16, 0xa1, 0x14, 0xeb, 0xa4, 0x98, 0x13, 0x8c, 0xe3,
|
||||
0x92, 0x71, 0x78, 0xdd, 0x3f, 0x46, 0x01, 0x1d, 0xbe, 0x00, 0x05, 0x13, 0x53, 0xb6, 0xed, 0x36,
|
||||
0x30, 0x23, 0x5b, 0x86, 0x45, 0x8a, 0x43, 0x22, 0xd4, 0xef, 0xf6, 0x97, 0x25, 0x5c, 0xa2, 0x3a,
|
||||
0x2d, 0xd1, 0x0b, 0x6b, 0x09, 0x24, 0xd4, 0x81, 0x0c, 0x5b, 0x00, 0xf2, 0x93, 0x2d, 0x0f, 0xdb,
|
||||
0xd4, 0x0f, 0x19, 0xd7, 0x37, 0x7c, 0x62, 0x7d, 0xb3, 0x52, 0x1f, 0x5c, 0x4b, 0xa1, 0xa1, 0x2e,
|
||||
0x1a, 0xca, 0x7b, 0x0a, 0x28, 0x44, 0x17, 0x76, 0x06, 0x55, 0xfe, 0x59, 0xb2, 0xca, 0xaf, 0x9f,
|
||||
0x22, 0x6d, 0x7b, 0x54, 0xf7, 0xb7, 0x83, 0x00, 0x46, 0x4c, 0xc8, 0x31, 0xcd, 0x3a, 0xd6, 0x76,
|
||||
0xe1, 0x3c, 0xc8, 0xda, 0xd8, 0x0a, 0xb2, 0x35, 0x2c, 0xa5, 0x4f, 0xb1, 0x45, 0x90, 0xa0, 0xc0,
|
||||
0x1f, 0x14, 0x00, 0x9b, 0xe2, 0x2a, 0x1a, 0x2b, 0xb6, 0xed, 0x30, 0xcc, 0xa3, 0x13, 0x18, 0x58,
|
||||
0x3b, 0x85, 0x81, 0x81, 0x6e, 0x75, 0x3b, 0x85, 0x7a, 0xdf, 0x66, 0x5e, 0x3b, 0xba, 0xa5, 0x34,
|
||||
0x03, 0xea, 0x62, 0x0a, 0xdc, 0x05, 0xc0, 0x93, 0x98, 0x5b, 0x8e, 0x2c, 0xf8, 0xfe, 0xbb, 0x49,
|
||||
0x60, 0xce, 0xaa, 0x63, 0x3f, 0x37, 0xf4, 0xa8, 0x65, 0xa1, 0x10, 0x12, 0xc5, 0xe0, 0x67, 0xef,
|
||||
0x83, 0x99, 0x1e, 0x76, 0xc3, 0xf3, 0x60, 0x70, 0x97, 0xb4, 0xfd, 0x50, 0x22, 0xfe, 0x13, 0x4e,
|
||||
0x81, 0x5c, 0x0b, 0x9b, 0x4d, 0xe2, 0x57, 0x33, 0xf2, 0x3f, 0x96, 0x32, 0xb7, 0x95, 0xf2, 0x1f,
|
||||
0xb9, 0x78, 0x66, 0xf1, 0xce, 0x05, 0x17, 0xf8, 0x43, 0xe4, 0x9a, 0x86, 0x86, 0xa9, 0xc0, 0xc8,
|
||||
0x55, 0xcf, 0xf9, 0x8f, 0x90, 0x7f, 0x86, 0x42, 0x2a, 0xfc, 0x02, 0xe4, 0x29, 0x31, 0x89, 0xc6,
|
||||
0x1c, 0x4f, 0x36, 0xcf, 0xeb, 0x7d, 0xe6, 0x20, 0xae, 0x13, 0xb3, 0x26, 0x45, 0x7d, 0xf8, 0xe0,
|
||||
0x0b, 0x85, 0x90, 0xf0, 0x73, 0x90, 0x67, 0xc4, 0x72, 0x4d, 0xcc, 0x88, 0x8c, 0xe6, 0xd5, 0xde,
|
||||
0xd1, 0xe4, 0xb0, 0x9b, 0x4e, 0x63, 0x4b, 0x0a, 0x88, 0x8e, 0x1c, 0x66, 0x78, 0x70, 0x8a, 0x42,
|
||||
0x40, 0x68, 0x80, 0x3c, 0x65, 0x7c, 0x92, 0xd0, 0xdb, 0xa2, 0x17, 0x9d, 0xe4, 0x29, 0x8b, 0xf7,
|
||||
0x66, 0x1f, 0x22, 0x52, 0x15, 0x9c, 0xa0, 0x10, 0x1e, 0xae, 0x80, 0x71, 0xcb, 0xb0, 0x11, 0xc1,
|
||||
0x8d, 0x76, 0x8d, 0x68, 0x8e, 0xdd, 0xa0, 0xa2, 0xa9, 0xe5, 0xaa, 0x33, 0x52, 0x68, 0x7c, 0x3d,
|
||||
0x49, 0x46, 0x9d, 0xfc, 0x70, 0x0d, 0x4c, 0x05, 0x4f, 0xff, 0xc7, 0x06, 0x65, 0x8e, 0xd7, 0x5e,
|
||||
0x33, 0x2c, 0x83, 0x89, 0x56, 0x97, 0xab, 0x16, 0x0f, 0xf7, 0xe7, 0xa6, 0x50, 0x17, 0x3a, 0xea,
|
||||
0x2a, 0xc5, 0xbb, 0xb0, 0x8b, 0x9b, 0x94, 0x34, 0x44, 0xeb, 0xca, 0x47, 0x5d, 0x78, 0x53, 0x9c,
|
||||
0x22, 0x49, 0x85, 0x7a, 0x22, 0xa1, 0xf3, 0xff, 0x2c, 0xa1, 0x0b, 0xbd, 0x93, 0x19, 0x6e, 0x83,
|
||||
0x19, 0xd7, 0x73, 0x74, 0x8f, 0x50, 0x7a, 0x8f, 0xe0, 0x86, 0x69, 0xd8, 0x24, 0x88, 0xd4, 0x88,
|
||||
0xf0, 0xf0, 0xc2, 0xe1, 0xfe, 0xdc, 0xcc, 0x66, 0x77, 0x16, 0xd4, 0x4b, 0xb6, 0xfc, 0x7b, 0x16,
|
||||
0x9c, 0xef, 0x7c, 0x47, 0xe1, 0x27, 0x00, 0x3a, 0x75, 0x4a, 0xbc, 0x16, 0x69, 0x3c, 0xf0, 0x87,
|
||||
0x49, 0x3e, 0x71, 0x29, 0x62, 0xe2, 0x0a, 0x2b, 0x7e, 0x23, 0xc5, 0x81, 0xba, 0x48, 0xf9, 0x33,
|
||||
0x9b, 0x2c, 0x95, 0x8c, 0x30, 0x34, 0x36, 0xb3, 0xa5, 0xca, 0x65, 0x05, 0x8c, 0xcb, 0xae, 0x11,
|
||||
0x10, 0x45, 0x5a, 0xc7, 0xf2, 0x60, 0x3b, 0x49, 0x46, 0x9d, 0xfc, 0xf0, 0x01, 0x98, 0xc0, 0x2d,
|
||||
0x6c, 0x98, 0xb8, 0x6e, 0x92, 0x10, 0x24, 0x2b, 0x40, 0xfe, 0x2f, 0x41, 0x26, 0x56, 0x3a, 0x19,
|
||||
0x50, 0x5a, 0x06, 0xae, 0x83, 0xc9, 0xa6, 0x9d, 0x86, 0xf2, 0xf3, 0xf2, 0x82, 0x84, 0x9a, 0xdc,
|
||||
0x4e, 0xb3, 0xa0, 0x6e, 0x72, 0xd0, 0x05, 0x40, 0x0b, 0x9e, 0x7c, 0x5a, 0x1c, 0x12, 0x3d, 0xf9,
|
||||
0x83, 0x53, 0xd4, 0x53, 0x38, 0x37, 0x44, 0xfd, 0x2f, 0x3c, 0xa2, 0x28, 0xa6, 0x03, 0x2e, 0x83,
|
||||
0x31, 0x8f, 0x57, 0x48, 0x68, 0xfa, 0xb0, 0x30, 0xfd, 0x7f, 0x52, 0x6c, 0x0c, 0xc5, 0x89, 0x28,
|
||||
0xc9, 0x0b, 0x97, 0x40, 0x41, 0x73, 0x4c, 0x53, 0x54, 0xc6, 0xaa, 0xd3, 0xb4, 0x99, 0x48, 0xee,
|
||||
0xc1, 0x2a, 0xe4, 0x33, 0xc0, 0x6a, 0x82, 0x82, 0x3a, 0x38, 0xcb, 0xbf, 0x29, 0xf1, 0x07, 0x2c,
|
||||
0x28, 0x77, 0xb8, 0x94, 0x18, 0xb7, 0x2e, 0x76, 0x8c, 0x5b, 0xd3, 0x69, 0x89, 0xd8, 0xb4, 0xd5,
|
||||
0x06, 0x63, 0xbc, 0x18, 0x0c, 0x5b, 0xf7, 0x13, 0x40, 0x36, 0xd3, 0x0f, 0x4f, 0x54, 0x6a, 0xa1,
|
||||
0x74, 0xec, 0x09, 0x9e, 0x10, 0x91, 0x88, 0x13, 0x51, 0x52, 0x53, 0xf9, 0x2e, 0x28, 0x24, 0xeb,
|
||||
0x34, 0xb1, 0x87, 0x28, 0xc7, 0xee, 0x21, 0x6f, 0x14, 0x30, 0xd3, 0x43, 0x3b, 0x34, 0x41, 0xc1,
|
||||
0xc2, 0x2f, 0x63, 0x39, 0x74, 0xec, 0xfc, 0xce, 0x57, 0x4a, 0xd5, 0x5f, 0x29, 0xd5, 0x87, 0x36,
|
||||
0xdb, 0xf0, 0x6a, 0xcc, 0x33, 0x6c, 0xdd, 0xbf, 0x97, 0xf5, 0x04, 0x16, 0xea, 0xc0, 0x86, 0x4f,
|
||||
0x40, 0xde, 0xc2, 0x2f, 0x6b, 0x4d, 0x4f, 0x0f, 0xe2, 0x77, 0x72, 0x3d, 0xe2, 0x25, 0x5a, 0x97,
|
||||
0x28, 0x28, 0xc4, 0x2b, 0x7f, 0x9f, 0x01, 0xb9, 0x9a, 0x86, 0x4d, 0x72, 0x06, 0xdb, 0xc8, 0x56,
|
||||
0x62, 0x1b, 0x59, 0xec, 0x3b, 0x07, 0x84, 0x7d, 0x3d, 0x17, 0x91, 0xa7, 0x1d, 0x8b, 0xc8, 0x8d,
|
||||
0x13, 0xe2, 0x1e, 0xbd, 0x83, 0xdc, 0x01, 0x23, 0xa1, 0xfa, 0x44, 0x53, 0x54, 0x8e, 0x6b, 0x8a,
|
||||
0xe5, 0x9f, 0x32, 0x60, 0x34, 0xa6, 0xe2, 0x64, 0xd2, 0xd0, 0x4d, 0x4c, 0x20, 0xbc, 0xeb, 0x54,
|
||||
0x4f, 0xe3, 0x98, 0x1a, 0x4c, 0x1f, 0xfe, 0xe0, 0x17, 0x3d, 0xe6, 0xe9, 0xa1, 0xe4, 0x2e, 0x28,
|
||||
0x30, 0xec, 0xe9, 0x84, 0x05, 0x34, 0x11, 0xd0, 0x91, 0x68, 0x85, 0xd8, 0x4a, 0x50, 0x51, 0x07,
|
||||
0xf7, 0xec, 0x32, 0x18, 0x4b, 0x28, 0x3b, 0xd1, 0xb4, 0xf6, 0x0b, 0x0f, 0x16, 0xc3, 0x8c, 0x3c,
|
||||
0x6f, 0x9a, 0x35, 0x72, 0x16, 0xbb, 0xf1, 0x93, 0x44, 0x36, 0xde, 0xee, 0x3f, 0xb8, 0x91, 0x95,
|
||||
0x3d, 0x73, 0xb2, 0xde, 0x91, 0x93, 0x4b, 0xa7, 0x42, 0x3f, 0x3a, 0x33, 0x7f, 0x55, 0xc0, 0x78,
|
||||
0x8c, 0xfb, 0x0c, 0x56, 0xa7, 0xc7, 0xc9, 0xd5, 0xe9, 0xc6, 0x69, 0x9c, 0xea, 0xb1, 0x3b, 0xfd,
|
||||
0x98, 0x4d, 0x38, 0xf3, 0x1f, 0x9a, 0xd6, 0xbf, 0x56, 0xc0, 0x54, 0xcb, 0x31, 0x9b, 0x16, 0x59,
|
||||
0x35, 0xb1, 0x61, 0x05, 0x1c, 0x7c, 0xf6, 0x39, 0x66, 0x3f, 0x15, 0x9a, 0x88, 0x47, 0x0d, 0xca,
|
||||
0x88, 0xcd, 0x1e, 0x45, 0x18, 0xd5, 0x77, 0xa4, 0xbe, 0xa9, 0x47, 0x5d, 0x80, 0x51, 0x57, 0x75,
|
||||
0xf0, 0x7d, 0x30, 0xca, 0x87, 0x40, 0x43, 0x23, 0x7c, 0x33, 0x95, 0xff, 0x4d, 0x4c, 0x4a, 0xa0,
|
||||
0xd1, 0x5a, 0x44, 0x42, 0x71, 0x3e, 0xb8, 0x03, 0x26, 0x5d, 0xa7, 0xb1, 0x8e, 0x6d, 0xac, 0x13,
|
||||
0xfe, 0x34, 0x6e, 0x8a, 0x3f, 0x35, 0xc5, 0xf4, 0x3e, 0x52, 0xbd, 0x19, 0x4c, 0x5b, 0x9b, 0x69,
|
||||
0x96, 0xb7, 0x7c, 0xec, 0x4d, 0x1f, 0x8b, 0xd9, 0xa1, 0x1b, 0x64, 0xf9, 0x1b, 0x05, 0x4c, 0xa4,
|
||||
0xaa, 0x03, 0x7e, 0x74, 0xc4, 0xcc, 0x3b, 0xfd, 0x6f, 0xcd, 0xbb, 0xd5, 0xcb, 0x7b, 0x07, 0xa5,
|
||||
0x81, 0x57, 0x07, 0xa5, 0x81, 0xd7, 0x07, 0xa5, 0x81, 0xaf, 0x0e, 0x4b, 0xca, 0xde, 0x61, 0x49,
|
||||
0x79, 0x75, 0x58, 0x52, 0xfe, 0x3c, 0x2c, 0x29, 0xdf, 0xbd, 0x29, 0x0d, 0x3c, 0x19, 0x96, 0xb9,
|
||||
0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x5b, 0xd8, 0xe7, 0x95, 0x17, 0x00, 0x00,
|
||||
// 1818 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4f, 0x4f, 0x23, 0xc9,
|
||||
0x15, 0xa7, 0xfd, 0x07, 0x4c, 0xb1, 0x98, 0xa1, 0x20, 0xe0, 0x65, 0x37, 0x06, 0xf9, 0xb0, 0xcb,
|
||||
0x44, 0x4b, 0x3b, 0xc3, 0x4c, 0x76, 0x67, 0x20, 0x1a, 0x85, 0x66, 0xc8, 0x66, 0x22, 0x08, 0xa8,
|
||||
0x0c, 0xa3, 0xec, 0x64, 0x23, 0x6d, 0xb9, 0x5d, 0xd3, 0xf4, 0xd2, 0xff, 0xd4, 0x5d, 0x76, 0xc6,
|
||||
0xb7, 0x28, 0x52, 0x6e, 0x39, 0xe4, 0x0b, 0x44, 0xb9, 0x47, 0x91, 0xf2, 0x35, 0x50, 0x72, 0xc8,
|
||||
0x6a, 0x4f, 0xa3, 0x1c, 0x50, 0xf0, 0x7c, 0x84, 0x28, 0x97, 0x39, 0x45, 0x55, 0x5d, 0xfd, 0xdf,
|
||||
0x0d, 0xb6, 0xa3, 0x70, 0xc9, 0xcd, 0x5d, 0xef, 0xbd, 0xdf, 0x7b, 0x55, 0xf5, 0xde, 0xab, 0xdf,
|
||||
0x33, 0xf8, 0xec, 0xe2, 0xb1, 0x27, 0xeb, 0x76, 0xf3, 0xa2, 0xdb, 0x26, 0xae, 0x45, 0x28, 0xf1,
|
||||
0x9a, 0xce, 0x85, 0xd6, 0xc4, 0x8e, 0xee, 0x35, 0xb1, 0xe3, 0x78, 0xcd, 0xde, 0x83, 0x36, 0xa1,
|
||||
0xf8, 0x41, 0x53, 0x23, 0x16, 0x71, 0x31, 0x25, 0x1d, 0xd9, 0x71, 0x6d, 0x6a, 0xc3, 0x8f, 0x7d,
|
||||
0x43, 0x39, 0x32, 0x94, 0x9d, 0x0b, 0x4d, 0x66, 0x86, 0x32, 0x33, 0x94, 0x85, 0xe1, 0xda, 0x96,
|
||||
0xa6, 0xd3, 0xf3, 0x6e, 0x5b, 0x56, 0x6d, 0xb3, 0xa9, 0xd9, 0x9a, 0xdd, 0xe4, 0xf6, 0xed, 0xee,
|
||||
0x2b, 0xfe, 0xc5, 0x3f, 0xf8, 0x2f, 0x1f, 0x77, 0xed, 0x91, 0x08, 0x08, 0x3b, 0xba, 0x89, 0xd5,
|
||||
0x73, 0xdd, 0x22, 0x6e, 0x3f, 0x0a, 0xc9, 0x24, 0x14, 0x37, 0x7b, 0x99, 0x68, 0xd6, 0x9a, 0x79,
|
||||
0x56, 0x6e, 0xd7, 0xa2, 0xba, 0x49, 0x32, 0x06, 0x9f, 0xde, 0x66, 0xe0, 0xa9, 0xe7, 0xc4, 0xc4,
|
||||
0x19, 0xbb, 0x87, 0x79, 0x76, 0x5d, 0xaa, 0x1b, 0x4d, 0xdd, 0xa2, 0x1e, 0x75, 0x33, 0x46, 0x9f,
|
||||
0xe4, 0x1e, 0xf2, 0xb0, 0xbd, 0x3c, 0xb9, 0xe1, 0x4a, 0x1c, 0xdb, 0xd0, 0xd5, 0x7e, 0xde, 0xa5,
|
||||
0x34, 0xfe, 0x2d, 0x01, 0xb8, 0x6f, 0x5b, 0xd4, 0xb5, 0x0d, 0x83, 0xb8, 0x88, 0xf4, 0x74, 0x4f,
|
||||
0xb7, 0x2d, 0xf8, 0x15, 0xa8, 0xb0, 0x83, 0xeb, 0x60, 0x8a, 0x6b, 0xd2, 0x86, 0xb4, 0x39, 0xb7,
|
||||
0xfd, 0x7d, 0x59, 0x5c, 0x5f, 0x7c, 0x1f, 0xd1, 0x05, 0x32, 0x6d, 0xb9, 0xf7, 0x40, 0x3e, 0x6e,
|
||||
0x7f, 0x4d, 0x54, 0x7a, 0x44, 0x28, 0x56, 0xe0, 0xe5, 0xd5, 0xfa, 0xd4, 0xe0, 0x6a, 0x1d, 0x44,
|
||||
0x6b, 0x28, 0x44, 0x85, 0xc7, 0xa0, 0xc4, 0xd1, 0x0b, 0x1c, 0x7d, 0x2b, 0x17, 0x5d, 0x9c, 0xae,
|
||||
0x8c, 0xf0, 0xaf, 0x0e, 0x5e, 0x53, 0x62, 0xb1, 0xf0, 0x94, 0xf7, 0x04, 0x74, 0xe9, 0x19, 0xa6,
|
||||
0x18, 0x71, 0x20, 0xf8, 0x09, 0xa8, 0xb8, 0x22, 0xfc, 0x5a, 0x71, 0x43, 0xda, 0x2c, 0x2a, 0xf7,
|
||||
0x84, 0x56, 0x25, 0xd8, 0x16, 0x0a, 0x35, 0x1a, 0x6f, 0x24, 0xb0, 0x92, 0xdd, 0xf7, 0xa1, 0xee,
|
||||
0x51, 0xf8, 0x65, 0x66, 0xef, 0xf2, 0x68, 0x7b, 0x67, 0xd6, 0x7c, 0xe7, 0xa1, 0xe3, 0x60, 0x25,
|
||||
0xb6, 0xef, 0xaf, 0x40, 0x59, 0xa7, 0xc4, 0xf4, 0x6a, 0x85, 0x8d, 0xe2, 0xe6, 0xdc, 0xf6, 0xae,
|
||||
0x3c, 0x62, 0x55, 0xc8, 0xd9, 0x68, 0x95, 0x79, 0xe1, 0xa7, 0xfc, 0x9c, 0x21, 0x22, 0x1f, 0xb8,
|
||||
0xf1, 0xe7, 0x02, 0x00, 0xcf, 0x88, 0x63, 0xd8, 0x7d, 0x93, 0x58, 0xf4, 0x0e, 0xae, 0xf2, 0x0b,
|
||||
0x50, 0xf2, 0x1c, 0xa2, 0x8a, 0xab, 0xfc, 0x6c, 0xe4, 0x1d, 0x45, 0x41, 0xb6, 0x1c, 0xa2, 0x46,
|
||||
0x97, 0xca, 0xbe, 0x10, 0x87, 0x84, 0x18, 0x4c, 0x7b, 0x14, 0xd3, 0xae, 0xc7, 0xaf, 0x74, 0x6e,
|
||||
0xfb, 0xc9, 0x24, 0xe0, 0x1c, 0x40, 0xa9, 0x0a, 0xf8, 0x69, 0xff, 0x1b, 0x09, 0xe0, 0xc6, 0x75,
|
||||
0x11, 0x2c, 0x45, 0xca, 0xfb, 0xb6, 0xd5, 0xd1, 0x29, 0x2b, 0x81, 0x5d, 0x50, 0xa2, 0x7d, 0x87,
|
||||
0xf0, 0x33, 0x9b, 0x55, 0x3e, 0x0e, 0x82, 0x3b, 0xed, 0x3b, 0xe4, 0xdd, 0xd5, 0xfa, 0xea, 0x10,
|
||||
0x13, 0x26, 0x42, 0xdc, 0x08, 0xbe, 0x08, 0xe3, 0x2e, 0x70, 0xf3, 0xa7, 0x49, 0xe7, 0xef, 0xae,
|
||||
0xd6, 0x6f, 0xac, 0x70, 0x39, 0xc4, 0x4c, 0x06, 0x0b, 0x3f, 0x02, 0xd3, 0x2e, 0xc1, 0x9e, 0x6d,
|
||||
0xd5, 0x4a, 0x1c, 0x37, 0xdc, 0x14, 0xe2, 0xab, 0x48, 0x48, 0xe1, 0x7d, 0x30, 0x63, 0x12, 0xcf,
|
||||
0xc3, 0x1a, 0xa9, 0x95, 0xb9, 0xe2, 0x82, 0x50, 0x9c, 0x39, 0xf2, 0x97, 0x51, 0x20, 0x87, 0x5f,
|
||||
0x83, 0xaa, 0x81, 0x3d, 0x7a, 0xe6, 0x74, 0x30, 0x25, 0xa7, 0xba, 0x49, 0x6a, 0xd3, 0xfc, 0xa8,
|
||||
0xbf, 0x37, 0x5a, 0x96, 0x30, 0x0b, 0x65, 0x45, 0xa0, 0x57, 0x0f, 0x13, 0x48, 0x28, 0x85, 0x0c,
|
||||
0x7b, 0x00, 0xb2, 0x95, 0x53, 0x17, 0x5b, 0x9e, 0x7f, 0x64, 0xcc, 0xdf, 0xcc, 0xd8, 0xfe, 0xd6,
|
||||
0x84, 0x3f, 0x78, 0x98, 0x41, 0x43, 0x43, 0x3c, 0x34, 0x2e, 0x25, 0x50, 0x8d, 0x2e, 0xec, 0x0e,
|
||||
0xaa, 0xfc, 0xe7, 0xc9, 0x2a, 0x7f, 0x38, 0x41, 0xda, 0xe6, 0x54, 0xf7, 0xef, 0x8a, 0x00, 0x46,
|
||||
0x4a, 0xc8, 0x36, 0x8c, 0x36, 0x56, 0x2f, 0xe0, 0x06, 0x28, 0x59, 0xd8, 0x0c, 0xb2, 0x35, 0x2c,
|
||||
0xa5, 0x9f, 0x61, 0x93, 0x20, 0x2e, 0x81, 0x7f, 0x94, 0x00, 0xec, 0xf2, 0xab, 0xe8, 0xec, 0x59,
|
||||
0x96, 0x4d, 0x31, 0x3b, 0x9d, 0x20, 0xc0, 0xd6, 0x04, 0x01, 0x06, 0xbe, 0xe5, 0xb3, 0x0c, 0xea,
|
||||
0x81, 0x45, 0xdd, 0x7e, 0x74, 0x4b, 0x59, 0x05, 0x34, 0x24, 0x14, 0x78, 0x01, 0x80, 0x2b, 0x30,
|
||||
0x4f, 0x6d, 0x51, 0xf0, 0xa3, 0x77, 0x93, 0x20, 0x9c, 0x7d, 0xdb, 0x7a, 0xa5, 0x6b, 0x51, 0xcb,
|
||||
0x42, 0x21, 0x24, 0x8a, 0xc1, 0xaf, 0x1d, 0x80, 0xd5, 0x9c, 0xb8, 0xe1, 0x3d, 0x50, 0xbc, 0x20,
|
||||
0x7d, 0xff, 0x28, 0x11, 0xfb, 0x09, 0x97, 0x41, 0xb9, 0x87, 0x8d, 0x2e, 0xf1, 0xab, 0x19, 0xf9,
|
||||
0x1f, 0x3b, 0x85, 0xc7, 0x52, 0xe3, 0x1f, 0xe5, 0x78, 0x66, 0xb1, 0xce, 0x05, 0x37, 0xd9, 0x43,
|
||||
0xe4, 0x18, 0xba, 0x8a, 0x3d, 0x8e, 0x51, 0x56, 0xde, 0xf3, 0x1f, 0x21, 0x7f, 0x0d, 0x85, 0x52,
|
||||
0xf8, 0x4b, 0x50, 0xf1, 0x88, 0x41, 0x54, 0x6a, 0xbb, 0xa2, 0x79, 0x3e, 0x1c, 0x31, 0x07, 0x71,
|
||||
0x9b, 0x18, 0x2d, 0x61, 0xea, 0xc3, 0x07, 0x5f, 0x28, 0x84, 0x84, 0xbf, 0x00, 0x15, 0x4a, 0x4c,
|
||||
0xc7, 0xc0, 0x94, 0x88, 0xd3, 0xdc, 0xca, 0x3f, 0x4d, 0x06, 0x7b, 0x62, 0x77, 0x4e, 0x85, 0x01,
|
||||
0xef, 0xc8, 0x61, 0x86, 0x07, 0xab, 0x28, 0x04, 0x84, 0x3a, 0xa8, 0x78, 0x94, 0x31, 0x09, 0xad,
|
||||
0xcf, 0x7b, 0xd1, 0x38, 0x4f, 0x59, 0xbc, 0x37, 0xfb, 0x10, 0x91, 0xab, 0x60, 0x05, 0x85, 0xf0,
|
||||
0x70, 0x0f, 0x2c, 0x98, 0xba, 0x85, 0x08, 0xee, 0xf4, 0x5b, 0x44, 0xb5, 0xad, 0x8e, 0xc7, 0x9b,
|
||||
0x5a, 0x59, 0x59, 0x15, 0x46, 0x0b, 0x47, 0x49, 0x31, 0x4a, 0xeb, 0xc3, 0x43, 0xb0, 0x1c, 0x3c,
|
||||
0xfd, 0x3f, 0xd1, 0x3d, 0x6a, 0xbb, 0xfd, 0x43, 0xdd, 0xd4, 0x29, 0x6f, 0x75, 0x65, 0xa5, 0x36,
|
||||
0xb8, 0x5a, 0x5f, 0x46, 0x43, 0xe4, 0x68, 0xa8, 0x15, 0xeb, 0xc2, 0x0e, 0xee, 0x7a, 0xa4, 0xc3,
|
||||
0x5b, 0x57, 0x25, 0xea, 0xc2, 0x27, 0x7c, 0x15, 0x09, 0x29, 0xd4, 0x12, 0x09, 0x5d, 0xf9, 0xef,
|
||||
0x12, 0xba, 0x9a, 0x9f, 0xcc, 0xf0, 0x0c, 0xac, 0x3a, 0xae, 0xad, 0xb9, 0xc4, 0xf3, 0x9e, 0x11,
|
||||
0xdc, 0x31, 0x74, 0x8b, 0x04, 0x27, 0x35, 0xcb, 0x77, 0xf8, 0xc1, 0xe0, 0x6a, 0x7d, 0xf5, 0x64,
|
||||
0xb8, 0x0a, 0xca, 0xb3, 0x6d, 0x7c, 0x5b, 0x02, 0xf7, 0xd2, 0xef, 0x28, 0xfc, 0x29, 0x80, 0x76,
|
||||
0xdb, 0x23, 0x6e, 0x8f, 0x74, 0x3e, 0xf7, 0xc9, 0x24, 0x63, 0x5c, 0x12, 0x67, 0x5c, 0x61, 0xc5,
|
||||
0x1f, 0x67, 0x34, 0xd0, 0x10, 0x2b, 0x9f, 0xb3, 0x89, 0x52, 0x29, 0xf0, 0x40, 0x63, 0x9c, 0x2d,
|
||||
0x53, 0x2e, 0x7b, 0x60, 0x41, 0x74, 0x8d, 0x40, 0xc8, 0xd3, 0x3a, 0x96, 0x07, 0x67, 0x49, 0x31,
|
||||
0x4a, 0xeb, 0xc3, 0xcf, 0xc1, 0x22, 0xee, 0x61, 0xdd, 0xc0, 0x6d, 0x83, 0x84, 0x20, 0x25, 0x0e,
|
||||
0xf2, 0xbe, 0x00, 0x59, 0xdc, 0x4b, 0x2b, 0xa0, 0xac, 0x0d, 0x3c, 0x02, 0x4b, 0x5d, 0x2b, 0x0b,
|
||||
0xe5, 0xe7, 0xe5, 0x07, 0x02, 0x6a, 0xe9, 0x2c, 0xab, 0x82, 0x86, 0xd9, 0x41, 0x07, 0x00, 0x35,
|
||||
0x78, 0xf2, 0xbd, 0xda, 0x34, 0xef, 0xc9, 0x3f, 0x9c, 0xa0, 0x9e, 0x42, 0xde, 0x10, 0xf5, 0xbf,
|
||||
0x70, 0xc9, 0x43, 0x31, 0x1f, 0x70, 0x17, 0xcc, 0xbb, 0xac, 0x42, 0xc2, 0xd0, 0x67, 0x78, 0xe8,
|
||||
0xdf, 0x11, 0x66, 0xf3, 0x28, 0x2e, 0x44, 0x49, 0x5d, 0xb8, 0x03, 0xaa, 0xaa, 0x6d, 0x18, 0xbc,
|
||||
0x32, 0xf6, 0xed, 0xae, 0x45, 0x79, 0x72, 0x17, 0x15, 0xc8, 0x38, 0xc0, 0x7e, 0x42, 0x82, 0x52,
|
||||
0x9a, 0x8d, 0xbf, 0x49, 0xf1, 0x07, 0x2c, 0x28, 0x77, 0xb8, 0x93, 0xa0, 0x5b, 0x1f, 0xa5, 0xe8,
|
||||
0xd6, 0x4a, 0xd6, 0x22, 0xc6, 0xb6, 0xfa, 0x60, 0x9e, 0x15, 0x83, 0x6e, 0x69, 0x7e, 0x02, 0x88,
|
||||
0x66, 0xfa, 0xa3, 0xb1, 0x4a, 0x2d, 0xb4, 0x8e, 0x3d, 0xc1, 0x8b, 0xfc, 0x24, 0xe2, 0x42, 0x94,
|
||||
0xf4, 0xd4, 0x78, 0x0e, 0x3e, 0x3c, 0xc1, 0x2e, 0x0d, 0xb9, 0x1a, 0x79, 0xd5, 0x35, 0x5a, 0x24,
|
||||
0xda, 0xd6, 0x7d, 0x30, 0x63, 0xbb, 0x1d, 0xdd, 0xc2, 0x86, 0x78, 0x0b, 0x42, 0x22, 0x76, 0xec,
|
||||
0x2f, 0xa3, 0x40, 0xde, 0x78, 0x0a, 0xaa, 0xc9, 0x92, 0x4f, 0x8c, 0x34, 0xd2, 0xad, 0x23, 0xcd,
|
||||
0x5b, 0x09, 0xac, 0xe6, 0x6c, 0x04, 0x1a, 0xa0, 0x6a, 0xe2, 0xd7, 0xb1, 0x74, 0xbc, 0x75, 0x14,
|
||||
0x60, 0xd3, 0xa9, 0xec, 0x4f, 0xa7, 0xf2, 0x73, 0x8b, 0x1e, 0xbb, 0x2d, 0xea, 0xea, 0x96, 0xe6,
|
||||
0x5f, 0xf1, 0x51, 0x02, 0x0b, 0xa5, 0xb0, 0xe1, 0x4b, 0x50, 0x31, 0xf1, 0xeb, 0x56, 0xd7, 0xd5,
|
||||
0x82, 0xab, 0x18, 0xdf, 0x0f, 0x7f, 0xd4, 0x8e, 0x04, 0x0a, 0x0a, 0xf1, 0x1a, 0x7f, 0x28, 0x80,
|
||||
0x72, 0x4b, 0xc5, 0x06, 0xb9, 0x83, 0xc1, 0xe6, 0x34, 0x31, 0xd8, 0x6c, 0x8f, 0x9c, 0x4e, 0x3c,
|
||||
0xbe, 0xdc, 0x99, 0xe6, 0xcb, 0xd4, 0x4c, 0xf3, 0x68, 0x4c, 0xdc, 0x9b, 0xc7, 0x99, 0x27, 0x60,
|
||||
0x36, 0x74, 0x9f, 0xe8, 0xaf, 0xd2, 0x6d, 0xfd, 0xb5, 0xf1, 0xa7, 0x02, 0x98, 0x8b, 0xb9, 0x18,
|
||||
0xcf, 0x1a, 0x3a, 0x09, 0x32, 0xc3, 0x1a, 0x98, 0x32, 0xc9, 0xc6, 0xe4, 0x80, 0xc8, 0xf8, 0x1c,
|
||||
0x32, 0xe2, 0x05, 0x59, 0x7e, 0xf3, 0x14, 0x54, 0x29, 0x76, 0x35, 0x42, 0x03, 0x19, 0x3f, 0xd0,
|
||||
0xd9, 0x68, 0x1a, 0x39, 0x4d, 0x48, 0x51, 0x4a, 0x7b, 0x6d, 0x17, 0xcc, 0x27, 0x9c, 0x8d, 0x45,
|
||||
0xfc, 0xfe, 0xc2, 0x0e, 0x2b, 0x2a, 0xf8, 0x3b, 0xc8, 0xc6, 0x97, 0x89, 0x6c, 0x7c, 0x3c, 0xfa,
|
||||
0xe1, 0xc6, 0xda, 0x52, 0x5e, 0x4e, 0xb6, 0x53, 0x39, 0xb9, 0x33, 0x11, 0xfa, 0xcd, 0x99, 0xf9,
|
||||
0x57, 0x09, 0x2c, 0xc4, 0xb4, 0xef, 0x60, 0x0a, 0xfb, 0x22, 0x39, 0x85, 0x3d, 0x9a, 0x64, 0x53,
|
||||
0x39, 0x63, 0xd8, 0xbf, 0xca, 0x89, 0xcd, 0xfc, 0x1f, 0x11, 0xff, 0xdf, 0x4a, 0x60, 0xb9, 0x67,
|
||||
0x1b, 0x5d, 0x93, 0xec, 0x1b, 0x58, 0x37, 0x03, 0x0d, 0x46, 0xa3, 0x6e, 0x19, 0x75, 0xb9, 0x27,
|
||||
0xe2, 0x7a, 0xba, 0x47, 0x89, 0x45, 0x5f, 0x44, 0x18, 0xca, 0x87, 0xc2, 0xdf, 0xf2, 0x8b, 0x21,
|
||||
0xc0, 0x68, 0xa8, 0x3b, 0xf8, 0x03, 0x30, 0xc7, 0xf8, 0xa4, 0xae, 0x12, 0x36, 0xe4, 0x8a, 0xbf,
|
||||
0x39, 0x96, 0x04, 0xd0, 0x5c, 0x2b, 0x12, 0xa1, 0xb8, 0x1e, 0x3c, 0x07, 0x4b, 0x8e, 0xdd, 0x39,
|
||||
0xc2, 0x16, 0xd6, 0x08, 0x7b, 0x1a, 0x4f, 0xf8, 0xff, 0xa3, 0x7c, 0x10, 0x98, 0x55, 0x3e, 0x0d,
|
||||
0x88, 0xdb, 0x49, 0x56, 0xe5, 0x1d, 0x63, 0xd0, 0xd9, 0x65, 0x4e, 0x43, 0x86, 0x41, 0xc2, 0xdf,
|
||||
0x48, 0xa0, 0xea, 0xf3, 0xcf, 0x80, 0x0d, 0x88, 0x7f, 0x3a, 0x94, 0x49, 0xf2, 0xf0, 0x2c, 0x81,
|
||||
0x14, 0xf5, 0xb8, 0xe4, 0x3a, 0x4a, 0x79, 0xcc, 0x1d, 0x7c, 0x2a, 0x93, 0x0c, 0x3e, 0x8d, 0xbf,
|
||||
0x17, 0xc1, 0x62, 0xa6, 0xe0, 0xe1, 0x8f, 0x6f, 0x98, 0x08, 0x56, 0xfe, 0x67, 0xd3, 0x40, 0x86,
|
||||
0xc0, 0x16, 0xc7, 0x20, 0xb0, 0x7b, 0x60, 0x41, 0xed, 0xba, 0x2e, 0xb1, 0x68, 0x6a, 0x0a, 0x08,
|
||||
0x47, 0x89, 0xfd, 0xa4, 0x18, 0xa5, 0xf5, 0x87, 0x4d, 0x23, 0xe5, 0x31, 0xa7, 0x91, 0x78, 0x14,
|
||||
0x82, 0xe6, 0xf9, 0x79, 0x98, 0x8d, 0x42, 0xb0, 0xbd, 0xb4, 0x3e, 0x7b, 0x03, 0x7d, 0xd4, 0x10,
|
||||
0x61, 0x26, 0xf9, 0x06, 0x9e, 0x25, 0xa4, 0x28, 0xa5, 0xdd, 0xf8, 0x56, 0x02, 0xef, 0xe7, 0x66,
|
||||
0x19, 0xdc, 0x4b, 0x90, 0xf2, 0xad, 0x14, 0x29, 0xff, 0x6e, 0xae, 0x61, 0x8c, 0x9b, 0xbb, 0x60,
|
||||
0xd6, 0x09, 0x08, 0xb2, 0xe8, 0x75, 0x07, 0x23, 0xe7, 0xff, 0x4d, 0xd4, 0x5a, 0x99, 0x1f, 0x5c,
|
||||
0xad, 0xcf, 0x86, 0x1a, 0x28, 0x72, 0xa3, 0xdc, 0xbf, 0xbc, 0xae, 0x4f, 0x7d, 0x73, 0x5d, 0x9f,
|
||||
0x7a, 0x73, 0x5d, 0x9f, 0xfa, 0xf5, 0xa0, 0x2e, 0x5d, 0x0e, 0xea, 0xd2, 0x37, 0x83, 0xba, 0xf4,
|
||||
0xcf, 0x41, 0x5d, 0xfa, 0xfd, 0xdb, 0xfa, 0xd4, 0xcb, 0x19, 0xe1, 0xe1, 0x3f, 0x01, 0x00, 0x00,
|
||||
0xff, 0xff, 0x4f, 0x0f, 0xec, 0xcc, 0xce, 0x1a, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -224,6 +224,14 @@ message DeploymentStrategy {
|
|||
optional RollingUpdateDeployment rollingUpdate = 2;
|
||||
}
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
message PartitionStatefulSetStrategy {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
optional int32 ordinal = 1;
|
||||
}
|
||||
|
||||
message RollbackConfig {
|
||||
// The revision to rollback to. If set to 0, rollback to the last revision.
|
||||
// +optional
|
||||
|
@ -378,15 +386,60 @@ message StatefulSetSpec {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
optional string podManagementPolicy = 6;
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
optional StatefulSetUpdateStrategy updateStrategy = 7;
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
optional int32 revisionHistoryLimit = 8;
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
message StatefulSetStatus {
|
||||
// observedGeneration is the most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
optional int64 observedGeneration = 1;
|
||||
|
||||
// replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
optional int32 replicas = 2;
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
optional int32 readyReplicas = 3;
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
optional int32 currentReplicas = 4;
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
optional int32 updatedReplicas = 5;
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
optional string currentRevision = 6;
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
optional string updateRevision = 7;
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
message StatefulSetUpdateStrategy {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
optional string type = 1;
|
||||
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
optional PartitionStatefulSetStrategy partition = 2;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,7 @@ import (
|
|||
const (
|
||||
// StatefulSetInitAnnotation if present, and set to false, indicates that a Pod's readiness should be ignored.
|
||||
StatefulSetInitAnnotation = "pod.alpha.kubernetes.io/initialized"
|
||||
StatefulSetRevisionLabel = "statefulset.beta.kubernetes.io/revision"
|
||||
)
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource
|
||||
|
@ -111,6 +112,54 @@ const (
|
|||
ParallelPodManagement = "Parallel"
|
||||
)
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
type StatefulSetUpdateStrategy struct {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Type StatefulSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetStrategyType"`
|
||||
// Partition is used to communicate the ordinal at which to partition
|
||||
// the StatefulSet when Type is PartitionStatefulSetStrategyType. This
|
||||
// value must be set when Type is PartitionStatefulSetStrategyType,
|
||||
// and it must be nil otherwise.
|
||||
Partition *PartitionStatefulSetStrategy `json:"partition,omitempty" protobuf:"bytes,2,opt,name=partition"`
|
||||
}
|
||||
|
||||
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
|
||||
// all possible update strategies for the StatefulSet controller.
|
||||
type StatefulSetUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// PartitionStatefulSetStrategyType indicates that updates will only be
|
||||
// applied to a partition of the StatefulSet. This is useful for canaries
|
||||
// and phased roll outs. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's currentRevision if there ordinal is less than the supplied
|
||||
// Partition's ordinal. Otherwise, they will be created from the specification
|
||||
// version indicated by the StatefulSet's updateRevision.
|
||||
PartitionStatefulSetStrategyType StatefulSetUpdateStrategyType = "Partition"
|
||||
// RollingUpdateStatefulSetStrategyType indicates that update will be
|
||||
// applied to all Pods in the StatefulSet with respect to the StatefulSet
|
||||
// ordering constraints. When a scale operation is performed with this
|
||||
// strategy, new Pods will be created from the specification version indicated
|
||||
// by the StatefulSet's updateRevision.
|
||||
RollingUpdateStatefulSetStrategyType = "RollingUpdate"
|
||||
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
|
||||
// tracking and ordered rolling restarts are disabled. Pods are recreated
|
||||
// from the StatefulSetSpec when they are manually deleted. When a scale
|
||||
// operation is performed with this strategy,specification version indicated
|
||||
// by the StatefulSet's currentRevision.
|
||||
OnDeleteStatefulSetStrategyType = "OnDelete"
|
||||
)
|
||||
|
||||
// PartitionStatefulSetStrategy contains the parameters used with the
|
||||
// PartitionStatefulSetStrategyType.
|
||||
type PartitionStatefulSetStrategy struct {
|
||||
// Ordinal indicates the ordinal at which the StatefulSet should be
|
||||
// partitioned.
|
||||
Ordinal int32 `json:"ordinal" protobuf:"varint,1,opt,name=ordinal"`
|
||||
}
|
||||
|
||||
// A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type StatefulSetSpec struct {
|
||||
// replicas is the desired number of replicas of the given Template.
|
||||
|
@ -160,16 +209,47 @@ type StatefulSetSpec struct {
|
|||
// all pods at once.
|
||||
// +optional
|
||||
PodManagementPolicy PodManagementPolicyType `json:"podManagementPolicy,omitempty" protobuf:"bytes,6,opt,name=podManagementPolicy,casttype=PodManagementPolicyType"`
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
UpdateStrategy StatefulSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,7,opt,name=updateStrategy"`
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,8,opt,name=revisionHistoryLimit"`
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
type StatefulSetStatus struct {
|
||||
// observedGeneration is the most recent generation observed by this StatefulSet.
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
|
||||
|
||||
// replicas is the number of actual replicas.
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
Replicas int32 `json:"replicas" protobuf:"varint,2,opt,name=replicas"`
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,3,opt,name=readyReplicas"`
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
CurrentReplicas int32 `json:"currentReplicas,omitempty" protobuf:"varint,4,opt,name=currentReplicas"`
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,5,opt,name=updatedReplicas"`
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
CurrentRevision string `json:"currentRevision,omitempty" protobuf:"bytes,6,opt,name=currentRevision"`
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
||||
}
|
||||
|
||||
// StatefulSetList is a collection of StatefulSets.
|
||||
|
|
|
@ -137,6 +137,15 @@ func (DeploymentStrategy) SwaggerDoc() map[string]string {
|
|||
return map_DeploymentStrategy
|
||||
}
|
||||
|
||||
var map_PartitionStatefulSetStrategy = map[string]string{
|
||||
"": "PartitionStatefulSetStrategy contains the parameters used with the PartitionStatefulSetStrategyType.",
|
||||
"ordinal": "Ordinal indicates the ordinal at which the StatefulSet should be partitioned.",
|
||||
}
|
||||
|
||||
func (PartitionStatefulSetStrategy) SwaggerDoc() map[string]string {
|
||||
return map_PartitionStatefulSetStrategy
|
||||
}
|
||||
|
||||
var map_RollbackConfig = map[string]string{
|
||||
"revision": "The revision to rollback to. If set to 0, rollback to the last revision.",
|
||||
}
|
||||
|
@ -212,6 +221,8 @@ var map_StatefulSetSpec = map[string]string{
|
|||
"volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.",
|
||||
"serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.",
|
||||
"podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.",
|
||||
"updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.",
|
||||
"revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.",
|
||||
}
|
||||
|
||||
func (StatefulSetSpec) SwaggerDoc() map[string]string {
|
||||
|
@ -220,12 +231,27 @@ func (StatefulSetSpec) SwaggerDoc() map[string]string {
|
|||
|
||||
var map_StatefulSetStatus = map[string]string{
|
||||
"": "StatefulSetStatus represents the current state of a StatefulSet.",
|
||||
"observedGeneration": "observedGeneration is the most recent generation observed by this StatefulSet.",
|
||||
"replicas": "replicas is the number of actual replicas.",
|
||||
"observedGeneration": "observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the StatefulSet's generation, which is updated on mutation by the API Server.",
|
||||
"replicas": "replicas is the number of Pods created by the StatefulSet controller.",
|
||||
"readyReplicas": "readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.",
|
||||
"currentReplicas": "currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by currentRevision.",
|
||||
"updatedReplicas": "updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version indicated by updateRevision.",
|
||||
"currentRevision": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).",
|
||||
"updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)",
|
||||
}
|
||||
|
||||
func (StatefulSetStatus) SwaggerDoc() map[string]string {
|
||||
return map_StatefulSetStatus
|
||||
}
|
||||
|
||||
var map_StatefulSetUpdateStrategy = map[string]string{
|
||||
"": "StatefulSetUpdateStrategy indicates the strategy that the StatefulSet controller will use to perform updates. It includes any additional parameters necessary to perform the update for the indicated strategy.",
|
||||
"type": "Type indicates the type of the StatefulSetUpdateStrategy.",
|
||||
"partition": "Partition is used to communicate the ordinal at which to partition the StatefulSet when Type is PartitionStatefulSetStrategyType. This value must be set when Type is PartitionStatefulSetStrategyType, and it must be nil otherwise.",
|
||||
}
|
||||
|
||||
func (StatefulSetUpdateStrategy) SwaggerDoc() map[string]string {
|
||||
return map_StatefulSetUpdateStrategy
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
|
|
|
@ -42,6 +42,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_apps_ControllerRevision_To_v1beta1_ControllerRevision,
|
||||
Convert_v1beta1_ControllerRevisionList_To_apps_ControllerRevisionList,
|
||||
Convert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList,
|
||||
Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy,
|
||||
Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy,
|
||||
Convert_v1beta1_StatefulSet_To_apps_StatefulSet,
|
||||
Convert_apps_StatefulSet_To_v1beta1_StatefulSet,
|
||||
Convert_v1beta1_StatefulSetList_To_apps_StatefulSetList,
|
||||
|
@ -50,6 +52,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec,
|
||||
Convert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus,
|
||||
Convert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus,
|
||||
Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy,
|
||||
Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -123,6 +127,26 @@ func Convert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in *a
|
|||
return autoConvert_apps_ControllerRevisionList_To_v1beta1_ControllerRevisionList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in *PartitionStatefulSetStrategy, out *apps.PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
out.Ordinal = in.Ordinal
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy is an autogenerated conversion function.
|
||||
func Convert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in *PartitionStatefulSetStrategy, out *apps.PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PartitionStatefulSetStrategy_To_apps_PartitionStatefulSetStrategy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in *apps.PartitionStatefulSetStrategy, out *PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
out.Ordinal = in.Ordinal
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy is an autogenerated conversion function.
|
||||
func Convert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in *apps.PartitionStatefulSetStrategy, out *PartitionStatefulSetStrategy, s conversion.Scope) error {
|
||||
return autoConvert_apps_PartitionStatefulSetStrategy_To_v1beta1_PartitionStatefulSetStrategy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSet_To_apps_StatefulSet(in *StatefulSet, out *apps.StatefulSet, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
|
@ -208,6 +232,10 @@ func autoConvert_v1beta1_StatefulSetSpec_To_apps_StatefulSetSpec(in *StatefulSet
|
|||
out.VolumeClaimTemplates = *(*[]api.PersistentVolumeClaim)(unsafe.Pointer(&in.VolumeClaimTemplates))
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = apps.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -222,12 +250,21 @@ func autoConvert_apps_StatefulSetSpec_To_v1beta1_StatefulSetSpec(in *apps.Statef
|
|||
out.VolumeClaimTemplates = *(*[]api_v1.PersistentVolumeClaim)(unsafe.Pointer(&in.VolumeClaimTemplates))
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit))
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus(in *StatefulSetStatus, out *apps.StatefulSetStatus, s conversion.Scope) error {
|
||||
out.ObservedGeneration = (*int64)(unsafe.Pointer(in.ObservedGeneration))
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -239,6 +276,11 @@ func Convert_v1beta1_StatefulSetStatus_To_apps_StatefulSetStatus(in *StatefulSet
|
|||
func autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.StatefulSetStatus, out *StatefulSetStatus, s conversion.Scope) error {
|
||||
out.ObservedGeneration = (*int64)(unsafe.Pointer(in.ObservedGeneration))
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -246,3 +288,15 @@ func autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.St
|
|||
func Convert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in *apps.StatefulSetStatus, out *StatefulSetStatus, s conversion.Scope) error {
|
||||
return autoConvert_apps_StatefulSetStatus_To_v1beta1_StatefulSetStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(in *StatefulSetUpdateStrategy, out *apps.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = apps.StatefulSetUpdateStrategyType(in.Type)
|
||||
out.Partition = (*apps.PartitionStatefulSetStrategy)(unsafe.Pointer(in.Partition))
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy(in *apps.StatefulSetUpdateStrategy, out *StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = StatefulSetUpdateStrategyType(in.Type)
|
||||
out.Partition = (*PartitionStatefulSetStrategy)(unsafe.Pointer(in.Partition))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentSpec, InType: reflect.TypeOf(&DeploymentSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentStatus, InType: reflect.TypeOf(&DeploymentStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_DeploymentStrategy, InType: reflect.TypeOf(&DeploymentStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_PartitionStatefulSetStrategy, InType: reflect.TypeOf(&PartitionStatefulSetStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_RollbackConfig, InType: reflect.TypeOf(&RollbackConfig{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_RollingUpdateDeployment, InType: reflect.TypeOf(&RollingUpdateDeployment{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_Scale, InType: reflect.TypeOf(&Scale{})},
|
||||
|
@ -55,6 +56,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetList, InType: reflect.TypeOf(&StatefulSetList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetSpec, InType: reflect.TypeOf(&StatefulSetSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetStatus, InType: reflect.TypeOf(&StatefulSetStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_StatefulSetUpdateStrategy, InType: reflect.TypeOf(&StatefulSetUpdateStrategy{})},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -251,6 +253,16 @@ func DeepCopy_v1beta1_DeploymentStrategy(in interface{}, out interface{}, c *con
|
|||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_PartitionStatefulSetStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_PartitionStatefulSetStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*PartitionStatefulSetStrategy)
|
||||
out := out.(*PartitionStatefulSetStrategy)
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_RollbackConfig is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_RollbackConfig(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
|
@ -397,6 +409,14 @@ func DeepCopy_v1beta1_StatefulSetSpec(in interface{}, out interface{}, c *conver
|
|||
}
|
||||
}
|
||||
}
|
||||
if err := DeepCopy_v1beta1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -415,3 +435,18 @@ func DeepCopy_v1beta1_StatefulSetStatus(in interface{}, out interface{}, c *conv
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_v1beta1_StatefulSetUpdateStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_v1beta1_StatefulSetUpdateStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatefulSetUpdateStrategy)
|
||||
out := out.(*StatefulSetUpdateStrategy)
|
||||
*out = *in
|
||||
if in.Partition != nil {
|
||||
in, out := &in.Partition, &out.Partition
|
||||
*out = new(PartitionStatefulSetStrategy)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,12 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_ControllerRevision, InType: reflect.TypeOf(&ControllerRevision{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_ControllerRevisionList, InType: reflect.TypeOf(&ControllerRevisionList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_PartitionStatefulSetStrategy, InType: reflect.TypeOf(&PartitionStatefulSetStrategy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSet, InType: reflect.TypeOf(&StatefulSet{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetList, InType: reflect.TypeOf(&StatefulSetList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetSpec, InType: reflect.TypeOf(&StatefulSetSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetStatus, InType: reflect.TypeOf(&StatefulSetStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apps_StatefulSetUpdateStrategy, InType: reflect.TypeOf(&StatefulSetUpdateStrategy{})},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -87,6 +89,16 @@ func DeepCopy_apps_ControllerRevisionList(in interface{}, out interface{}, c *co
|
|||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_PartitionStatefulSetStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_PartitionStatefulSetStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*PartitionStatefulSetStrategy)
|
||||
out := out.(*PartitionStatefulSetStrategy)
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_StatefulSet is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_StatefulSet(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
|
@ -153,6 +165,14 @@ func DeepCopy_apps_StatefulSetSpec(in interface{}, out interface{}, c *conversio
|
|||
}
|
||||
}
|
||||
}
|
||||
if err := DeepCopy_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -171,3 +191,18 @@ func DeepCopy_apps_StatefulSetStatus(in interface{}, out interface{}, c *convers
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy_apps_StatefulSetUpdateStrategy is an autogenerated deepcopy function.
|
||||
func DeepCopy_apps_StatefulSetUpdateStrategy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatefulSetUpdateStrategy)
|
||||
out := out.(*StatefulSetUpdateStrategy)
|
||||
*out = *in
|
||||
if in.Partition != nil {
|
||||
in, out := &in.Partition, &out.Partition
|
||||
*out = new(PartitionStatefulSetStrategy)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,6 +312,22 @@ func (s *StatefulSetTester) waitForRunning(numStatefulPods int32, ss *apps.State
|
|||
}
|
||||
}
|
||||
|
||||
// WaitForState periodically polls for the ss and its pods until the until function returns either true or an error
|
||||
func (s *StatefulSetTester) WaitForState(ss *apps.StatefulSet, until func(*apps.StatefulSet, *v1.PodList) (bool, error)) {
|
||||
pollErr := wait.PollImmediate(StatefulSetPoll, StatefulSetTimeout,
|
||||
func() (bool, error) {
|
||||
ssGet, err := s.c.Apps().StatefulSets(ss.Namespace).Get(ss.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
podList := s.GetPodList(ssGet)
|
||||
return until(ssGet, podList)
|
||||
})
|
||||
if pollErr != nil {
|
||||
Failf("Failed waiting for pods to enter running: %v", pollErr)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForRunningAndReady waits for numStatefulPods in ss to be Running and Ready.
|
||||
func (s *StatefulSetTester) WaitForRunningAndReady(numStatefulPods int32, ss *apps.StatefulSet) {
|
||||
s.waitForRunning(numStatefulPods, ss, true)
|
||||
|
@ -365,8 +381,33 @@ func (s *StatefulSetTester) SetHealthy(ss *apps.StatefulSet) {
|
|||
}
|
||||
}
|
||||
|
||||
// WaitForStatus waits for the ss.Status.Replicas to be equal to expectedReplicas
|
||||
func (s *StatefulSetTester) WaitForStatus(ss *apps.StatefulSet, expectedReplicas int32) {
|
||||
// WaitForStatusReadyReplicas waits for the ss.Status.ReadyReplicas to be equal to expectedReplicas
|
||||
func (s *StatefulSetTester) WaitForStatusReadyReplicas(ss *apps.StatefulSet, expectedReplicas int32) {
|
||||
Logf("Waiting for statefulset status.replicas updated to %d", expectedReplicas)
|
||||
|
||||
ns, name := ss.Namespace, ss.Name
|
||||
pollErr := wait.PollImmediate(StatefulSetPoll, StatefulSetTimeout,
|
||||
func() (bool, error) {
|
||||
ssGet, err := s.c.Apps().StatefulSets(ns).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if *ssGet.Status.ObservedGeneration < ss.Generation {
|
||||
return false, nil
|
||||
}
|
||||
if ssGet.Status.ReadyReplicas != expectedReplicas {
|
||||
Logf("Waiting for stateful set status to become %d, currently %d", expectedReplicas, ssGet.Status.Replicas)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if pollErr != nil {
|
||||
Failf("Failed waiting for stateful set status.readyReplicas updated to %d: %v", expectedReplicas, pollErr)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForStatusReplicas waits for the ss.Status.Replicas to be equal to expectedReplicas
|
||||
func (s *StatefulSetTester) WaitForStatusReplicas(ss *apps.StatefulSet, expectedReplicas int32) {
|
||||
Logf("Waiting for statefulset status.replicas updated to %d", expectedReplicas)
|
||||
|
||||
ns, name := ss.Namespace, ss.Name
|
||||
|
@ -416,7 +457,7 @@ func DeleteAllStatefulSets(c clientset.Interface, ns string) {
|
|||
if err := sst.Scale(&ss, 0); err != nil {
|
||||
errList = append(errList, fmt.Sprintf("%v", err))
|
||||
}
|
||||
sst.WaitForStatus(&ss, 0)
|
||||
sst.WaitForStatusReplicas(&ss, 0)
|
||||
Logf("Deleting statefulset %v", ss.Name)
|
||||
// Use OrphanDependents=false so it's deleted synchronously.
|
||||
// We already made sure the Pods are gone inside Scale().
|
||||
|
@ -561,6 +602,7 @@ func NewStatefulSet(name, ns, governingSvcName string, replicas int32, statefulP
|
|||
Volumes: vols,
|
||||
},
|
||||
},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
VolumeClaimTemplates: claims,
|
||||
ServiceName: governingSvcName,
|
||||
},
|
||||
|
|
|
@ -31,7 +31,6 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
|
@ -250,8 +249,11 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
|
||||
It("should allow template updates", func() {
|
||||
By("Creating stateful set " + ssName + " in namespace " + ns)
|
||||
*(ss.Spec.Replicas) = 2
|
||||
|
||||
testProbe := &v1.Probe{Handler: v1.Handler{HTTPGet: &v1.HTTPGetAction{
|
||||
Path: "/index.html",
|
||||
Port: intstr.IntOrString{IntVal: 80}}}}
|
||||
ss := framework.NewStatefulSet("ss2", ns, headlessSvcName, 2, nil, nil, labels)
|
||||
ss.Spec.Template.Spec.Containers[0].ReadinessProbe = testProbe
|
||||
ss, err := c.Apps().StatefulSets(ns).Create(ss)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -268,79 +270,21 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
updateIndex := 0
|
||||
By(fmt.Sprintf("Deleting stateful pod at index %d", updateIndex))
|
||||
sst.DeleteStatefulPodAtIndex(updateIndex, ss)
|
||||
|
||||
By("Waiting for all stateful pods to be running again")
|
||||
sst.WaitForRunningAndReady(*ss.Spec.Replicas, ss)
|
||||
|
||||
By(fmt.Sprintf("Verifying stateful pod at index %d is updated", updateIndex))
|
||||
verify := func(pod *v1.Pod) {
|
||||
podImage := pod.Spec.Containers[0].Image
|
||||
Expect(podImage).To(Equal(newImage), fmt.Sprintf("Expected stateful pod image %s updated to %s", podImage, newImage))
|
||||
}
|
||||
sst.VerifyPodAtIndex(updateIndex, ss, verify)
|
||||
})
|
||||
|
||||
It("Scaling down before scale up is finished should wait until current pod will be running and ready before it will be removed", func() {
|
||||
By("Creating stateful set " + ssName + " in namespace " + ns + ", and pausing scale operations after each pod")
|
||||
testProbe := &v1.Probe{Handler: v1.Handler{HTTPGet: &v1.HTTPGetAction{
|
||||
Path: "/index.html",
|
||||
Port: intstr.IntOrString{IntVal: 80}}}}
|
||||
ss := framework.NewStatefulSet(ssName, ns, headlessSvcName, 1, nil, nil, labels)
|
||||
ss.Spec.Template.Spec.Containers[0].ReadinessProbe = testProbe
|
||||
framework.SetStatefulSetInitializedAnnotation(ss, "false")
|
||||
ss, err := c.Apps().StatefulSets(ns).Create(ss)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
sst := framework.NewStatefulSetTester(c)
|
||||
sst.WaitForRunningAndReady(1, ss)
|
||||
|
||||
By("Scaling up stateful set " + ssName + " to 3 replicas and pausing after 2nd pod")
|
||||
sst.SetHealthy(ss)
|
||||
sst.UpdateReplicas(ss, 3)
|
||||
sst.WaitForRunningAndReady(2, ss)
|
||||
|
||||
By("Before scale up finished setting 2nd pod to be not ready by breaking readiness probe")
|
||||
sst.BreakProbe(ss, testProbe)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForRunningAndNotReady(2, ss)
|
||||
|
||||
By("Continue scale operation after the 2nd pod, and scaling down to 1 replica")
|
||||
sst.SetHealthy(ss)
|
||||
sst.UpdateReplicas(ss, 1)
|
||||
|
||||
By("Verifying that the 2nd pod wont be removed if it is not running and ready")
|
||||
sst.ConfirmStatefulPodCount(2, ss, 10*time.Second, true)
|
||||
expectedPodName := ss.Name + "-1"
|
||||
expectedPod, err := f.ClientSet.Core().Pods(ns).Get(expectedPodName, metav1.GetOptions{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Verifying the 2nd pod is removed only when it becomes running and ready")
|
||||
sst.RestoreProbe(ss, testProbe)
|
||||
watcher, err := f.ClientSet.Core().Pods(ns).Watch(metav1.SingleObject(
|
||||
metav1.ObjectMeta{
|
||||
Name: expectedPod.Name,
|
||||
ResourceVersion: expectedPod.ResourceVersion,
|
||||
},
|
||||
))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = watch.Until(framework.StatefulSetTimeout, watcher, func(event watch.Event) (bool, error) {
|
||||
pod := event.Object.(*v1.Pod)
|
||||
if event.Type == watch.Deleted && pod.Name == expectedPodName {
|
||||
return false, fmt.Errorf("Pod %v was deleted before enter running", pod.Name)
|
||||
}
|
||||
framework.Logf("Observed event %v for pod %v. Phase %v, Pod is ready %v",
|
||||
event.Type, pod.Name, pod.Status.Phase, podutil.IsPodReady(pod))
|
||||
if pod.Name != expectedPodName {
|
||||
sst.WaitForState(ss, func(set *apps.StatefulSet, pods *v1.PodList) (bool, error) {
|
||||
if len(pods.Items) < 2 {
|
||||
return false, nil
|
||||
}
|
||||
if pod.Status.Phase == v1.PodRunning && podutil.IsPodReady(pod) {
|
||||
return true, nil
|
||||
for i := range pods.Items {
|
||||
if pods.Items[i].Spec.Containers[0].Image != newImage {
|
||||
framework.Logf("Waiting for pod %s to have image %s current image %s",
|
||||
pods.Items[i].Name,
|
||||
newImage,
|
||||
pods.Items[i].Spec.Containers[0].Image)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
return true, nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Scaling should happen in predictable order and halt if any stateful pod is unhealthy", func() {
|
||||
|
@ -367,7 +311,7 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
By("Confirming that stateful set scale up will halt with unhealthy stateful pod")
|
||||
sst.BreakProbe(ss, testProbe)
|
||||
sst.WaitForRunningAndNotReady(*ss.Spec.Replicas, ss)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForStatusReadyReplicas(ss, 0)
|
||||
sst.UpdateReplicas(ss, 3)
|
||||
sst.ConfirmStatefulPodCount(1, ss, 10*time.Second, true)
|
||||
|
||||
|
@ -397,7 +341,7 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
sst.BreakProbe(ss, testProbe)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForStatusReadyReplicas(ss, 0)
|
||||
sst.WaitForRunningAndNotReady(3, ss)
|
||||
sst.UpdateReplicas(ss, 0)
|
||||
sst.ConfirmStatefulPodCount(3, ss, 10*time.Second, true)
|
||||
|
@ -442,7 +386,7 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
By("Confirming that stateful set scale up will not halt with unhealthy stateful pod")
|
||||
sst.BreakProbe(ss, testProbe)
|
||||
sst.WaitForRunningAndNotReady(*ss.Spec.Replicas, ss)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForStatusReadyReplicas(ss, 0)
|
||||
sst.UpdateReplicas(ss, 3)
|
||||
sst.ConfirmStatefulPodCount(3, ss, 10*time.Second, false)
|
||||
|
||||
|
@ -452,7 +396,7 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
|
||||
By("Scale down will not halt with unhealthy stateful pod")
|
||||
sst.BreakProbe(ss, testProbe)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForStatusReadyReplicas(ss, 0)
|
||||
sst.WaitForRunningAndNotReady(3, ss)
|
||||
sst.UpdateReplicas(ss, 0)
|
||||
sst.ConfirmStatefulPodCount(0, ss, 10*time.Second, false)
|
||||
|
@ -460,7 +404,7 @@ var _ = framework.KubeDescribe("StatefulSet", func() {
|
|||
By("Scaling down stateful set " + ssName + " to 0 replicas and waiting until none of pods will run in namespace" + ns)
|
||||
sst.RestoreProbe(ss, testProbe)
|
||||
sst.Scale(ss, 0)
|
||||
sst.WaitForStatus(ss, 0)
|
||||
sst.WaitForStatusReadyReplicas(ss, 0)
|
||||
})
|
||||
|
||||
It("Should recreate evicted statefulset", func() {
|
||||
|
|
Loading…
Reference in New Issue