mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Merge pull request #19840 from madhusudancs/replicaset-deployment
Auto commit by PR queue bot
This commit is contained in:
commit
41a98b43e4
@ -7,7 +7,8 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
selector:
|
selector:
|
||||||
name: nginx
|
matchLabels:
|
||||||
|
name: nginx
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
|
@ -943,6 +943,7 @@ __EOF__
|
|||||||
kubectl scale --replicas=2 -f examples/guestbook/frontend-controller.yaml "${kube_flags[@]}"
|
kubectl scale --replicas=2 -f examples/guestbook/frontend-controller.yaml "${kube_flags[@]}"
|
||||||
# Post-condition: 2 replicas
|
# Post-condition: 2 replicas
|
||||||
kube::test::get_object_assert 'rc frontend' "{{$rc_replicas_field}}" '2'
|
kube::test::get_object_assert 'rc frontend' "{{$rc_replicas_field}}" '2'
|
||||||
|
kubectl delete rc frontend "${kube_flags[@]}"
|
||||||
|
|
||||||
### Scale multiple replication controllers
|
### Scale multiple replication controllers
|
||||||
kubectl create -f examples/guestbook/redis-master-controller.yaml "${kube_flags[@]}"
|
kubectl create -f examples/guestbook/redis-master-controller.yaml "${kube_flags[@]}"
|
||||||
@ -963,16 +964,17 @@ __EOF__
|
|||||||
kube::test::get_object_assert 'job pi' "{{$job_parallelism_field}}" '2'
|
kube::test::get_object_assert 'job pi' "{{$job_parallelism_field}}" '2'
|
||||||
# Clean-up
|
# Clean-up
|
||||||
kubectl delete job/pi "${kube_flags[@]}"
|
kubectl delete job/pi "${kube_flags[@]}"
|
||||||
### Scale a deployment
|
# TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
kubectl create -f examples/extensions/deployment.yaml "${kube_flags[@]}"
|
# ### Scale a deployment
|
||||||
# Command
|
# kubectl create -f examples/extensions/deployment.yaml "${kube_flags[@]}"
|
||||||
kubectl scale --current-replicas=3 --replicas=1 deployment/nginx-deployment
|
# # Command
|
||||||
# Post-condition: 1 replica for nginx-deployment
|
# kubectl scale --current-replicas=3 --replicas=1 deployment/nginx-deployment
|
||||||
kube::test::get_object_assert 'deployment nginx-deployment' "{{$deployment_replicas}}" '1'
|
# # Post-condition: 1 replica for nginx-deployment
|
||||||
# Clean-up
|
# kube::test::get_object_assert 'deployment nginx-deployment' "{{$deployment_replicas}}" '1'
|
||||||
kubectl delete deployment/nginx-deployment "${kube_flags[@]}"
|
# # Clean-up
|
||||||
# TODO: Remove once deployment reaping is implemented
|
# kubectl delete deployment/nginx-deployment "${kube_flags[@]}"
|
||||||
kubectl delete rc --all "${kube_flags[@]}"
|
# # TODO: Remove once deployment reaping is implemented
|
||||||
|
# kubectl delete rs --all "${kube_flags[@]}"
|
||||||
|
|
||||||
### Expose a deployment as a service
|
### Expose a deployment as a service
|
||||||
kubectl create -f examples/extensions/deployment.yaml "${kube_flags[@]}"
|
kubectl create -f examples/extensions/deployment.yaml "${kube_flags[@]}"
|
||||||
@ -985,7 +987,7 @@ __EOF__
|
|||||||
# Clean-up
|
# Clean-up
|
||||||
kubectl delete deployment/nginx-deployment service/nginx-deployment "${kube_flags[@]}"
|
kubectl delete deployment/nginx-deployment service/nginx-deployment "${kube_flags[@]}"
|
||||||
# TODO: Remove once deployment reaping is implemented
|
# TODO: Remove once deployment reaping is implemented
|
||||||
kubectl delete rc --all "${kube_flags[@]}"
|
kubectl delete rs --all "${kube_flags[@]}"
|
||||||
|
|
||||||
### Expose replication controller as service
|
### Expose replication controller as service
|
||||||
kubectl create -f examples/guestbook/frontend-controller.yaml "${kube_flags[@]}"
|
kubectl create -f examples/guestbook/frontend-controller.yaml "${kube_flags[@]}"
|
||||||
@ -1102,7 +1104,7 @@ __EOF__
|
|||||||
# Clean up
|
# Clean up
|
||||||
kubectl delete hpa nginx-deployment "${kube_flags[@]}"
|
kubectl delete hpa nginx-deployment "${kube_flags[@]}"
|
||||||
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
|
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
|
||||||
kubectl delete rc -l pod-template-hash "${kube_flags[@]}"
|
kubectl delete rs -l pod-template-hash "${kube_flags[@]}"
|
||||||
|
|
||||||
### Rollback a deployment
|
### Rollback a deployment
|
||||||
# Pre-condition: no deployment exists
|
# Pre-condition: no deployment exists
|
||||||
@ -1131,7 +1133,7 @@ __EOF__
|
|||||||
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" 'nginx:latest:'
|
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" 'nginx:latest:'
|
||||||
# Clean up
|
# Clean up
|
||||||
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
|
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
|
||||||
kubectl delete rc -l pod-template-hash "${kube_flags[@]}"
|
kubectl delete rs -l pod-template-hash "${kube_flags[@]}"
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# ConfigMap #
|
# ConfigMap #
|
||||||
|
3
hack/testdata/deployment-revision2.yaml
vendored
3
hack/testdata/deployment-revision2.yaml
vendored
@ -7,7 +7,8 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
selector:
|
selector:
|
||||||
name: nginx
|
matchLabels:
|
||||||
|
name: nginx
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
|
@ -16,24 +16,32 @@ limitations under the License.
|
|||||||
|
|
||||||
package extensions
|
package extensions
|
||||||
|
|
||||||
import (
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
"k8s.io/kubernetes/pkg/api"
|
// import (
|
||||||
)
|
// "fmt"
|
||||||
|
|
||||||
// ScaleFromDeployment returns a scale subresource for a deployment.
|
// "k8s.io/kubernetes/pkg/api"
|
||||||
func ScaleFromDeployment(deployment *Deployment) *Scale {
|
// "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
return &Scale{
|
// )
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: deployment.Name,
|
// // ScaleFromDeployment returns a scale subresource for a deployment.
|
||||||
Namespace: deployment.Namespace,
|
// func ScaleFromDeployment(deployment *Deployment) (*Scale, error) {
|
||||||
CreationTimestamp: deployment.CreationTimestamp,
|
// selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
},
|
// if err != nil {
|
||||||
Spec: ScaleSpec{
|
// return nil, fmt.Errorf("failed to convert label selector to selector: %v", err)
|
||||||
Replicas: deployment.Spec.Replicas,
|
// }
|
||||||
},
|
// return &Scale{
|
||||||
Status: ScaleStatus{
|
// ObjectMeta: api.ObjectMeta{
|
||||||
Replicas: deployment.Status.Replicas,
|
// Name: deployment.Name,
|
||||||
Selector: deployment.Spec.Selector,
|
// Namespace: deployment.Namespace,
|
||||||
},
|
// CreationTimestamp: deployment.CreationTimestamp,
|
||||||
}
|
// },
|
||||||
}
|
// Spec: ScaleSpec{
|
||||||
|
// Replicas: deployment.Spec.Replicas,
|
||||||
|
// },
|
||||||
|
// Status: ScaleStatus{
|
||||||
|
// Replicas: deployment.Status.Replicas,
|
||||||
|
// Selector: selector.String(),
|
||||||
|
// },
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
@ -5430,7 +5430,7 @@ func (x *DeploymentSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
_, _, _ = yysep453, yyq453, yy2arr453
|
_, _, _ = yysep453, yyq453, yy2arr453
|
||||||
const yyr453 bool = false
|
const yyr453 bool = false
|
||||||
yyq453[0] = x.Replicas != 0
|
yyq453[0] = x.Replicas != 0
|
||||||
yyq453[1] = len(x.Selector) != 0
|
yyq453[1] = x.Selector != nil
|
||||||
yyq453[3] = true
|
yyq453[3] = true
|
||||||
yyq453[4] = x.MinReadySeconds != 0
|
yyq453[4] = x.MinReadySeconds != 0
|
||||||
yyq453[5] = x.RevisionHistoryLimit != nil
|
yyq453[5] = x.RevisionHistoryLimit != nil
|
||||||
@ -5483,8 +5483,9 @@ func (x *DeploymentSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
yym458 := z.EncBinary()
|
yym458 := z.EncBinary()
|
||||||
_ = yym458
|
_ = yym458
|
||||||
if false {
|
if false {
|
||||||
|
} else if z.HasExtensions() && z.EncExt(x.Selector) {
|
||||||
} else {
|
} else {
|
||||||
z.F.EncMapStringStringV(x.Selector, false, e)
|
z.EncFallback(x.Selector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -5501,8 +5502,9 @@ func (x *DeploymentSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
yym459 := z.EncBinary()
|
yym459 := z.EncBinary()
|
||||||
_ = yym459
|
_ = yym459
|
||||||
if false {
|
if false {
|
||||||
|
} else if z.HasExtensions() && z.EncExt(x.Selector) {
|
||||||
} else {
|
} else {
|
||||||
z.F.EncMapStringStringV(x.Selector, false, e)
|
z.EncFallback(x.Selector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5712,14 +5714,19 @@ func (x *DeploymentSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
case "selector":
|
case "selector":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Selector = nil
|
if x.Selector != nil {
|
||||||
|
x.Selector = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
yyv482 := &x.Selector
|
if x.Selector == nil {
|
||||||
|
x.Selector = new(pkg1_unversioned.LabelSelector)
|
||||||
|
}
|
||||||
yym483 := z.DecBinary()
|
yym483 := z.DecBinary()
|
||||||
_ = yym483
|
_ = yym483
|
||||||
if false {
|
if false {
|
||||||
|
} else if z.HasExtensions() && z.DecExt(x.Selector) {
|
||||||
} else {
|
} else {
|
||||||
z.F.DecMapStringStringX(yyv482, false, d)
|
z.DecFallback(x.Selector, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "template":
|
case "template":
|
||||||
@ -5817,14 +5824,19 @@ func (x *DeploymentSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Selector = nil
|
if x.Selector != nil {
|
||||||
|
x.Selector = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
yyv493 := &x.Selector
|
if x.Selector == nil {
|
||||||
|
x.Selector = new(pkg1_unversioned.LabelSelector)
|
||||||
|
}
|
||||||
yym494 := z.DecBinary()
|
yym494 := z.DecBinary()
|
||||||
_ = yym494
|
_ = yym494
|
||||||
if false {
|
if false {
|
||||||
|
} else if z.HasExtensions() && z.DecExt(x.Selector) {
|
||||||
} else {
|
} else {
|
||||||
z.F.DecMapStringStringX(yyv493, false, d)
|
z.DecFallback(x.Selector, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yyj491++
|
yyj491++
|
||||||
|
@ -233,9 +233,9 @@ type DeploymentSpec struct {
|
|||||||
// zero and not specified. Defaults to 1.
|
// zero and not specified. Defaults to 1.
|
||||||
Replicas int `json:"replicas,omitempty"`
|
Replicas int `json:"replicas,omitempty"`
|
||||||
|
|
||||||
// Label selector for pods. Existing ReplicationControllers whose pods are
|
// Label selector for pods. Existing ReplicaSets whose pods are
|
||||||
// selected by this will be the ones affected by this deployment.
|
// selected by this will be the ones affected by this deployment.
|
||||||
Selector map[string]string `json:"selector,omitempty"`
|
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||||
|
|
||||||
// Template describes the pods that will be created.
|
// Template describes the pods that will be created.
|
||||||
Template api.PodTemplateSpec `json:"template"`
|
Template api.PodTemplateSpec `json:"template"`
|
||||||
@ -248,7 +248,7 @@ type DeploymentSpec struct {
|
|||||||
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||||
MinReadySeconds int `json:"minReadySeconds,omitempty"`
|
MinReadySeconds int `json:"minReadySeconds,omitempty"`
|
||||||
|
|
||||||
// The number of old ReplicationControllers to retain to allow rollback.
|
// The number of old ReplicaSets to retain to allow rollback.
|
||||||
// This is a pointer to distinguish between explicit zero and not specified.
|
// This is a pointer to distinguish between explicit zero and not specified.
|
||||||
RevisionHistoryLimit *int `json:"revisionHistoryLimit,omitempty"`
|
RevisionHistoryLimit *int `json:"revisionHistoryLimit,omitempty"`
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.
|
|||||||
out.Replicas = new(int32)
|
out.Replicas = new(int32)
|
||||||
*out.Replicas = int32(in.Replicas)
|
*out.Replicas = int32(in.Replicas)
|
||||||
if in.Selector != nil {
|
if in.Selector != nil {
|
||||||
out.Selector = make(map[string]string)
|
out.Selector = new(LabelSelector)
|
||||||
for key, val := range in.Selector {
|
if err := Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||||
out.Selector[key] = val
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.Selector = nil
|
out.Selector = nil
|
||||||
@ -139,10 +139,11 @@ func Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *DeploymentS
|
|||||||
if in.Replicas != nil {
|
if in.Replicas != nil {
|
||||||
out.Replicas = int(*in.Replicas)
|
out.Replicas = int(*in.Replicas)
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.Selector != nil {
|
if in.Selector != nil {
|
||||||
out.Selector = make(map[string]string)
|
out.Selector = new(unversioned.LabelSelector)
|
||||||
for key, val := range in.Selector {
|
if err := Convert_v1beta1_LabelSelector_To_unversioned_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||||
out.Selector[key] = val
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.Selector = nil
|
out.Selector = nil
|
||||||
|
@ -2855,10 +2855,11 @@ func autoConvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensi
|
|||||||
if err := s.Convert(&in.Replicas, &out.Replicas, 0); err != nil {
|
if err := s.Convert(&in.Replicas, &out.Replicas, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// unable to generate simple pointer conversion for unversioned.LabelSelector -> v1beta1.LabelSelector
|
||||||
if in.Selector != nil {
|
if in.Selector != nil {
|
||||||
out.Selector = make(map[string]string)
|
out.Selector = new(LabelSelector)
|
||||||
for key, val := range in.Selector {
|
if err := Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||||
out.Selector[key] = val
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.Selector = nil
|
out.Selector = nil
|
||||||
@ -4170,10 +4171,11 @@ func autoConvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *Deploym
|
|||||||
defaulting.(func(*DeploymentSpec))(in)
|
defaulting.(func(*DeploymentSpec))(in)
|
||||||
}
|
}
|
||||||
// in.Replicas has no peer in out
|
// in.Replicas has no peer in out
|
||||||
|
// unable to generate simple pointer conversion for v1beta1.LabelSelector -> unversioned.LabelSelector
|
||||||
if in.Selector != nil {
|
if in.Selector != nil {
|
||||||
out.Selector = make(map[string]string)
|
out.Selector = new(unversioned.LabelSelector)
|
||||||
for key, val := range in.Selector {
|
if err := Convert_v1beta1_LabelSelector_To_unversioned_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||||
out.Selector[key] = val
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.Selector = nil
|
out.Selector = nil
|
||||||
|
@ -1185,9 +1185,9 @@ func deepCopy_v1beta1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *
|
|||||||
out.Replicas = nil
|
out.Replicas = nil
|
||||||
}
|
}
|
||||||
if in.Selector != nil {
|
if in.Selector != nil {
|
||||||
out.Selector = make(map[string]string)
|
out.Selector = new(LabelSelector)
|
||||||
for key, val := range in.Selector {
|
if err := deepCopy_v1beta1_LabelSelector(*in.Selector, out.Selector, c); err != nil {
|
||||||
out.Selector[key] = val
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.Selector = nil
|
out.Selector = nil
|
||||||
|
@ -67,8 +67,8 @@ func addDefaultingFuncs(scheme *runtime.Scheme) {
|
|||||||
labels := obj.Spec.Template.Labels
|
labels := obj.Spec.Template.Labels
|
||||||
|
|
||||||
if labels != nil {
|
if labels != nil {
|
||||||
if len(obj.Spec.Selector) == 0 {
|
if obj.Spec.Selector == nil {
|
||||||
obj.Spec.Selector = labels
|
obj.Spec.Selector = &LabelSelector{MatchLabels: labels}
|
||||||
}
|
}
|
||||||
if len(obj.Labels) == 0 {
|
if len(obj.Labels) == 0 {
|
||||||
obj.Labels = labels
|
obj.Labels = labels
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -199,7 +199,7 @@ type ThirdPartyResourceData struct {
|
|||||||
Data []byte `json:"data,omitempty"`
|
Data []byte `json:"data,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deployment enables declarative updates for Pods and ReplicationControllers.
|
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||||
type Deployment struct {
|
type Deployment struct {
|
||||||
unversioned.TypeMeta `json:",inline"`
|
unversioned.TypeMeta `json:",inline"`
|
||||||
// Standard object metadata.
|
// Standard object metadata.
|
||||||
@ -218,9 +218,9 @@ type DeploymentSpec struct {
|
|||||||
// zero and not specified. Defaults to 1.
|
// zero and not specified. Defaults to 1.
|
||||||
Replicas *int32 `json:"replicas,omitempty"`
|
Replicas *int32 `json:"replicas,omitempty"`
|
||||||
|
|
||||||
// Label selector for pods. Existing ReplicationControllers whose pods are
|
// Label selector for pods. Existing ReplicaSets whose pods are
|
||||||
// selected by this will be the ones affected by this deployment.
|
// selected by this will be the ones affected by this deployment.
|
||||||
Selector map[string]string `json:"selector,omitempty"`
|
Selector *LabelSelector `json:"selector,omitempty"`
|
||||||
|
|
||||||
// Template describes the pods that will be created.
|
// Template describes the pods that will be created.
|
||||||
Template v1.PodTemplateSpec `json:"template"`
|
Template v1.PodTemplateSpec `json:"template"`
|
||||||
@ -233,7 +233,7 @@ type DeploymentSpec struct {
|
|||||||
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||||
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
|
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
|
||||||
|
|
||||||
// The number of old ReplicationControllers to retain to allow rollback.
|
// The number of old ReplicaSets to retain to allow rollback.
|
||||||
// This is a pointer to distinguish between explicit zero and not specified.
|
// This is a pointer to distinguish between explicit zero and not specified.
|
||||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
|
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ func (DaemonSetUpdateStrategy) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_Deployment = map[string]string{
|
var map_Deployment = map[string]string{
|
||||||
"": "Deployment enables declarative updates for Pods and ReplicationControllers.",
|
"": "Deployment enables declarative updates for Pods and ReplicaSets.",
|
||||||
"metadata": "Standard object metadata.",
|
"metadata": "Standard object metadata.",
|
||||||
"spec": "Specification of the desired behavior of the Deployment.",
|
"spec": "Specification of the desired behavior of the Deployment.",
|
||||||
"status": "Most recently observed status of the Deployment.",
|
"status": "Most recently observed status of the Deployment.",
|
||||||
@ -181,11 +181,11 @@ func (DeploymentRollback) SwaggerDoc() map[string]string {
|
|||||||
var map_DeploymentSpec = map[string]string{
|
var map_DeploymentSpec = map[string]string{
|
||||||
"": "DeploymentSpec is the specification of the desired behavior of the Deployment.",
|
"": "DeploymentSpec is the specification of the desired behavior of the Deployment.",
|
||||||
"replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.",
|
"replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.",
|
||||||
"selector": "Label selector for pods. Existing ReplicationControllers whose pods are selected by this will be the ones affected by this deployment.",
|
"selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment.",
|
||||||
"template": "Template describes the pods that will be created.",
|
"template": "Template describes the pods that will be created.",
|
||||||
"strategy": "The deployment strategy to use to replace existing pods with new ones.",
|
"strategy": "The deployment strategy to use to replace existing pods with new ones.",
|
||||||
"minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)",
|
"minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)",
|
||||||
"revisionHistoryLimit": "The number of old ReplicationControllers to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.",
|
"revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified.",
|
||||||
"paused": "Indicates that the deployment is paused and will not be processed by the deployment controller.",
|
"paused": "Indicates that the deployment is paused and will not be processed by the deployment controller.",
|
||||||
"rollbackTo": "The config this deployment is rolling back to. Will be cleared after rollback is done.",
|
"rollbackTo": "The config this deployment is rolling back to. Will be cleared after rollback is done.",
|
||||||
}
|
}
|
||||||
|
@ -346,9 +346,24 @@ func ValidateRollback(rollback *extensions.RollbackConfig, fldPath *field.Path)
|
|||||||
// Validates given deployment spec.
|
// Validates given deployment spec.
|
||||||
func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path) field.ErrorList {
|
func ValidateDeploymentSpec(spec *extensions.DeploymentSpec, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
allErrs = append(allErrs, apivalidation.ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...)
|
|
||||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
||||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(&spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"))...)
|
|
||||||
|
if spec.Selector == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("selector"), ""))
|
||||||
|
} else {
|
||||||
|
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
|
||||||
|
if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is not valid for deployment."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selector, err := unversioned.LabelSelectorAsSelector(spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "failed to convert LabelSelector to Selector."))
|
||||||
|
} else {
|
||||||
|
allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"))...)
|
||||||
|
}
|
||||||
|
|
||||||
allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...)
|
allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...)
|
||||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
|
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
|
||||||
if spec.RevisionHistoryLimit != nil {
|
if spec.RevisionHistoryLimit != nil {
|
||||||
|
@ -952,8 +952,10 @@ func validDeployment() *extensions.Deployment {
|
|||||||
Namespace: api.NamespaceDefault,
|
Namespace: api.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Selector: map[string]string{
|
Selector: &unversioned.LabelSelector{
|
||||||
"name": "abc",
|
MatchLabels: map[string]string{
|
||||||
|
"name": "abc",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
@ -1000,8 +1002,10 @@ func TestValidateDeployment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// selector should match the labels in pod template.
|
// selector should match the labels in pod template.
|
||||||
invalidSelectorDeployment := validDeployment()
|
invalidSelectorDeployment := validDeployment()
|
||||||
invalidSelectorDeployment.Spec.Selector = map[string]string{
|
invalidSelectorDeployment.Spec.Selector = &unversioned.LabelSelector{
|
||||||
"name": "def",
|
MatchLabels: map[string]string{
|
||||||
|
"name": "def",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
errorCases["`selector` does not match template `labels`"] = invalidSelectorDeployment
|
errorCases["`selector` does not match template `labels`"] = invalidSelectorDeployment
|
||||||
|
|
||||||
|
42
pkg/client/cache/listers.go
vendored
42
pkg/client/cache/listers.go
vendored
@ -236,33 +236,34 @@ func (s *StoreToDeploymentLister) List() (deployments []extensions.Deployment, e
|
|||||||
return deployments, nil
|
return deployments, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDeploymentsForRC returns a list of deployments managing a replication controller. Returns an error only if no matching deployments are found.
|
// GetDeploymentsForReplicaSet returns a list of deployments managing a replica set. Returns an error only if no matching deployments are found.
|
||||||
func (s *StoreToDeploymentLister) GetDeploymentsForRC(rc *api.ReplicationController) (deployments []extensions.Deployment, err error) {
|
func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) (deployments []extensions.Deployment, err error) {
|
||||||
var selector labels.Selector
|
|
||||||
var d extensions.Deployment
|
var d extensions.Deployment
|
||||||
|
|
||||||
if len(rc.Labels) == 0 {
|
if len(rs.Labels) == 0 {
|
||||||
err = fmt.Errorf("no deployments found for replication controller %v because it has no labels", rc.Name)
|
err = fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
||||||
for _, m := range s.Store.List() {
|
for _, m := range s.Store.List() {
|
||||||
d = *m.(*extensions.Deployment)
|
d = *m.(*extensions.Deployment)
|
||||||
if d.Namespace != rc.Namespace {
|
if d.Namespace != rs.Namespace {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
labelSet := labels.Set(d.Spec.Selector)
|
|
||||||
selector = labels.Set(d.Spec.Selector).AsSelector()
|
|
||||||
|
|
||||||
|
selector, err := unversioned.LabelSelectorAsSelector(rs.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert LabelSelector to Selector: %v", err)
|
||||||
|
}
|
||||||
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||||
if labelSet.AsSelector().Empty() || !selector.Matches(labels.Set(rc.Labels)) {
|
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
deployments = append(deployments, d)
|
deployments = append(deployments, d)
|
||||||
}
|
}
|
||||||
if len(deployments) == 0 {
|
if len(deployments) == 0 {
|
||||||
err = fmt.Errorf("could not find deployments set for replication controller %s in namespace %s with labels: %v", rc.Name, rc.Namespace, rc.Labels)
|
err = fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -290,6 +291,27 @@ func (s *StoreToReplicaSetLister) List() (rss []extensions.ReplicaSet, err error
|
|||||||
return rss, nil
|
return rss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type storeReplicaSetsNamespacer struct {
|
||||||
|
store Store
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s storeReplicaSetsNamespacer) List(selector labels.Selector) (rss []extensions.ReplicaSet, err error) {
|
||||||
|
for _, c := range s.store.List() {
|
||||||
|
rs := *(c.(*extensions.ReplicaSet))
|
||||||
|
if s.namespace == api.NamespaceAll || s.namespace == rs.Namespace {
|
||||||
|
if selector.Matches(labels.Set(rs.Labels)) {
|
||||||
|
rss = append(rss, rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreToReplicaSetLister) ReplicaSets(namespace string) storeReplicaSetsNamespacer {
|
||||||
|
return storeReplicaSetsNamespacer{s.Store, namespace}
|
||||||
|
}
|
||||||
|
|
||||||
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found.
|
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found.
|
||||||
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *api.Pod) (rss []extensions.ReplicaSet, err error) {
|
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *api.Pod) (rss []extensions.ReplicaSet, err error) {
|
||||||
var selector labels.Selector
|
var selector labels.Selector
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
"k8s.io/kubernetes/pkg/client/cache"
|
"k8s.io/kubernetes/pkg/client/cache"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/client/record"
|
"k8s.io/kubernetes/pkg/client/record"
|
||||||
@ -477,3 +478,16 @@ func (o ControllersByCreationTimestamp) Less(i, j int) bool {
|
|||||||
}
|
}
|
||||||
return o[i].CreationTimestamp.Before(o[j].CreationTimestamp)
|
return o[i].CreationTimestamp.Before(o[j].CreationTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReplicaSetsByCreationTimestamp sorts a list of ReplicationSets by creation timestamp, using their names as a tie breaker.
|
||||||
|
type ReplicaSetsByCreationTimestamp []*extensions.ReplicaSet
|
||||||
|
|
||||||
|
func (o ReplicaSetsByCreationTimestamp) Len() int { return len(o) }
|
||||||
|
func (o ReplicaSetsByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||||
|
|
||||||
|
func (o ReplicaSetsByCreationTimestamp) Less(i, j int) bool {
|
||||||
|
if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) {
|
||||||
|
return o[i].Name < o[j].Name
|
||||||
|
}
|
||||||
|
return o[i].CreationTimestamp.Before(o[j].CreationTimestamp)
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDeploymentController_reconcileNewRC(t *testing.T) {
|
func TestDeploymentController_reconcileNewReplicaSet(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
deploymentReplicas int
|
deploymentReplicas int
|
||||||
maxSurge intstr.IntOrString
|
maxSurge intstr.IntOrString
|
||||||
@ -87,16 +87,16 @@ func TestDeploymentController_reconcileNewRC(t *testing.T) {
|
|||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Logf("executing scenario %d", i)
|
t.Logf("executing scenario %d", i)
|
||||||
newRc := rc("foo-v2", test.newReplicas, nil)
|
newRS := rs("foo-v2", test.newReplicas, nil)
|
||||||
oldRc := rc("foo-v2", test.oldReplicas, nil)
|
oldRS := rs("foo-v2", test.oldReplicas, nil)
|
||||||
allRcs := []*api.ReplicationController{newRc, oldRc}
|
allRSs := []*exp.ReplicaSet{newRS, oldRS}
|
||||||
deployment := deployment("foo", test.deploymentReplicas, test.maxSurge, intstr.FromInt(0))
|
deployment := deployment("foo", test.deploymentReplicas, test.maxSurge, intstr.FromInt(0))
|
||||||
fake := fake.Clientset{}
|
fake := fake.Clientset{}
|
||||||
controller := &DeploymentController{
|
controller := &DeploymentController{
|
||||||
client: &fake,
|
client: &fake,
|
||||||
eventRecorder: &record.FakeRecorder{},
|
eventRecorder: &record.FakeRecorder{},
|
||||||
}
|
}
|
||||||
scaled, err := controller.reconcileNewRC(allRcs, newRc, deployment)
|
scaled, err := controller.reconcileNewReplicaSet(allRSs, newRS, deployment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -115,21 +115,21 @@ func TestDeploymentController_reconcileNewRC(t *testing.T) {
|
|||||||
t.Errorf("expected 1 action during scale, got: %v", fake.Actions())
|
t.Errorf("expected 1 action during scale, got: %v", fake.Actions())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
updated := fake.Actions()[0].(testclient.UpdateAction).GetObject().(*api.ReplicationController)
|
updated := fake.Actions()[0].(testclient.UpdateAction).GetObject().(*exp.ReplicaSet)
|
||||||
if e, a := test.expectedNewReplicas, updated.Spec.Replicas; e != a {
|
if e, a := test.expectedNewReplicas, updated.Spec.Replicas; e != a {
|
||||||
t.Errorf("expected update to %d replicas, got %d", e, a)
|
t.Errorf("expected update to %d replicas, got %d", e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
func TestDeploymentController_reconcileOldReplicaSets(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
deploymentReplicas int
|
deploymentReplicas int
|
||||||
maxUnavailable intstr.IntOrString
|
maxUnavailable intstr.IntOrString
|
||||||
oldReplicas int
|
oldReplicas int
|
||||||
newReplicas int
|
newReplicas int
|
||||||
readyPodsFromOldRC int
|
readyPodsFromOldRS int
|
||||||
readyPodsFromNewRC int
|
readyPodsFromNewRS int
|
||||||
scaleExpected bool
|
scaleExpected bool
|
||||||
expectedOldReplicas int
|
expectedOldReplicas int
|
||||||
}{
|
}{
|
||||||
@ -138,8 +138,8 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
maxUnavailable: intstr.FromInt(0),
|
maxUnavailable: intstr.FromInt(0),
|
||||||
oldReplicas: 10,
|
oldReplicas: 10,
|
||||||
newReplicas: 0,
|
newReplicas: 0,
|
||||||
readyPodsFromOldRC: 10,
|
readyPodsFromOldRS: 10,
|
||||||
readyPodsFromNewRC: 0,
|
readyPodsFromNewRS: 0,
|
||||||
scaleExpected: false,
|
scaleExpected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -147,38 +147,38 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
maxUnavailable: intstr.FromInt(2),
|
maxUnavailable: intstr.FromInt(2),
|
||||||
oldReplicas: 10,
|
oldReplicas: 10,
|
||||||
newReplicas: 0,
|
newReplicas: 0,
|
||||||
readyPodsFromOldRC: 10,
|
readyPodsFromOldRS: 10,
|
||||||
readyPodsFromNewRC: 0,
|
readyPodsFromNewRS: 0,
|
||||||
scaleExpected: true,
|
scaleExpected: true,
|
||||||
expectedOldReplicas: 8,
|
expectedOldReplicas: 8,
|
||||||
},
|
},
|
||||||
{ // expect unhealthy replicas from old rcs been cleaned up
|
{ // expect unhealthy replicas from old replica sets been cleaned up
|
||||||
deploymentReplicas: 10,
|
deploymentReplicas: 10,
|
||||||
maxUnavailable: intstr.FromInt(2),
|
maxUnavailable: intstr.FromInt(2),
|
||||||
oldReplicas: 10,
|
oldReplicas: 10,
|
||||||
newReplicas: 0,
|
newReplicas: 0,
|
||||||
readyPodsFromOldRC: 8,
|
readyPodsFromOldRS: 8,
|
||||||
readyPodsFromNewRC: 0,
|
readyPodsFromNewRS: 0,
|
||||||
scaleExpected: true,
|
scaleExpected: true,
|
||||||
expectedOldReplicas: 8,
|
expectedOldReplicas: 8,
|
||||||
},
|
},
|
||||||
{ // expect 1 unhealthy replica from old rcs been cleaned up, and 1 ready pod been scaled down
|
{ // expect 1 unhealthy replica from old replica sets been cleaned up, and 1 ready pod been scaled down
|
||||||
deploymentReplicas: 10,
|
deploymentReplicas: 10,
|
||||||
maxUnavailable: intstr.FromInt(2),
|
maxUnavailable: intstr.FromInt(2),
|
||||||
oldReplicas: 10,
|
oldReplicas: 10,
|
||||||
newReplicas: 0,
|
newReplicas: 0,
|
||||||
readyPodsFromOldRC: 9,
|
readyPodsFromOldRS: 9,
|
||||||
readyPodsFromNewRC: 0,
|
readyPodsFromNewRS: 0,
|
||||||
scaleExpected: true,
|
scaleExpected: true,
|
||||||
expectedOldReplicas: 8,
|
expectedOldReplicas: 8,
|
||||||
},
|
},
|
||||||
{ // the unavailable pods from the newRC would not make us scale down old RCs in a further step
|
{ // the unavailable pods from the newRS would not make us scale down old RSs in a further step
|
||||||
deploymentReplicas: 10,
|
deploymentReplicas: 10,
|
||||||
maxUnavailable: intstr.FromInt(2),
|
maxUnavailable: intstr.FromInt(2),
|
||||||
oldReplicas: 8,
|
oldReplicas: 8,
|
||||||
newReplicas: 2,
|
newReplicas: 2,
|
||||||
readyPodsFromOldRC: 8,
|
readyPodsFromOldRS: 8,
|
||||||
readyPodsFromNewRC: 0,
|
readyPodsFromNewRS: 0,
|
||||||
scaleExpected: false,
|
scaleExpected: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -187,10 +187,10 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
|
|
||||||
newSelector := map[string]string{"foo": "new"}
|
newSelector := map[string]string{"foo": "new"}
|
||||||
oldSelector := map[string]string{"foo": "old"}
|
oldSelector := map[string]string{"foo": "old"}
|
||||||
newRc := rc("foo-new", test.newReplicas, newSelector)
|
newRS := rs("foo-new", test.newReplicas, newSelector)
|
||||||
oldRc := rc("foo-old", test.oldReplicas, oldSelector)
|
oldRS := rs("foo-old", test.oldReplicas, oldSelector)
|
||||||
oldRCs := []*api.ReplicationController{oldRc}
|
oldRSs := []*exp.ReplicaSet{oldRS}
|
||||||
allRCs := []*api.ReplicationController{oldRc, newRc}
|
allRSs := []*exp.ReplicaSet{oldRS, newRS}
|
||||||
|
|
||||||
deployment := deployment("foo", test.deploymentReplicas, intstr.FromInt(0), test.maxUnavailable)
|
deployment := deployment("foo", test.deploymentReplicas, intstr.FromInt(0), test.maxUnavailable)
|
||||||
fakeClientset := fake.Clientset{}
|
fakeClientset := fake.Clientset{}
|
||||||
@ -198,10 +198,10 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
switch action.(type) {
|
switch action.(type) {
|
||||||
case core.ListAction:
|
case core.ListAction:
|
||||||
podList := &api.PodList{}
|
podList := &api.PodList{}
|
||||||
for podIndex := 0; podIndex < test.readyPodsFromOldRC; podIndex++ {
|
for podIndex := 0; podIndex < test.readyPodsFromOldRS; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-oldReadyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-oldReadyPod-%d", oldRS.Name, podIndex),
|
||||||
Labels: oldSelector,
|
Labels: oldSelector,
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
@ -214,10 +214,10 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for podIndex := 0; podIndex < test.oldReplicas-test.readyPodsFromOldRC; podIndex++ {
|
for podIndex := 0; podIndex < test.oldReplicas-test.readyPodsFromOldRS; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-oldUnhealthyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-oldUnhealthyPod-%d", oldRS.Name, podIndex),
|
||||||
Labels: oldSelector,
|
Labels: oldSelector,
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
@ -230,10 +230,10 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for podIndex := 0; podIndex < test.readyPodsFromNewRC; podIndex++ {
|
for podIndex := 0; podIndex < test.readyPodsFromNewRS; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-newReadyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-newReadyPod-%d", oldRS.Name, podIndex),
|
||||||
Labels: newSelector,
|
Labels: newSelector,
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
@ -246,10 +246,10 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for podIndex := 0; podIndex < test.oldReplicas-test.readyPodsFromOldRC; podIndex++ {
|
for podIndex := 0; podIndex < test.oldReplicas-test.readyPodsFromOldRS; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-newUnhealthyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-newUnhealthyPod-%d", oldRS.Name, podIndex),
|
||||||
Labels: newSelector,
|
Labels: newSelector,
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
@ -271,7 +271,7 @@ func TestDeploymentController_reconcileOldRCs(t *testing.T) {
|
|||||||
eventRecorder: &record.FakeRecorder{},
|
eventRecorder: &record.FakeRecorder{},
|
||||||
}
|
}
|
||||||
|
|
||||||
scaled, err := controller.reconcileOldRCs(allRCs, oldRCs, newRc, deployment, false)
|
scaled, err := controller.reconcileOldReplicaSets(allRSs, oldRSs, newRS, deployment, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -327,8 +327,8 @@ func TestDeploymentController_cleanupUnhealthyReplicas(t *testing.T) {
|
|||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Logf("executing scenario %d", i)
|
t.Logf("executing scenario %d", i)
|
||||||
oldRc := rc("foo-v2", test.oldReplicas, nil)
|
oldRS := rs("foo-v2", test.oldReplicas, nil)
|
||||||
oldRCs := []*api.ReplicationController{oldRc}
|
oldRSs := []*exp.ReplicaSet{oldRS}
|
||||||
deployment := deployment("foo", 10, intstr.FromInt(2), intstr.FromInt(2))
|
deployment := deployment("foo", 10, intstr.FromInt(2), intstr.FromInt(2))
|
||||||
fakeClientset := fake.Clientset{}
|
fakeClientset := fake.Clientset{}
|
||||||
fakeClientset.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
fakeClientset.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
||||||
@ -338,7 +338,7 @@ func TestDeploymentController_cleanupUnhealthyReplicas(t *testing.T) {
|
|||||||
for podIndex := 0; podIndex < test.readyPods; podIndex++ {
|
for podIndex := 0; podIndex < test.readyPods; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-readyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-readyPod-%d", oldRS.Name, podIndex),
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
Conditions: []api.PodCondition{
|
Conditions: []api.PodCondition{
|
||||||
@ -353,7 +353,7 @@ func TestDeploymentController_cleanupUnhealthyReplicas(t *testing.T) {
|
|||||||
for podIndex := 0; podIndex < test.unHealthyPods; podIndex++ {
|
for podIndex := 0; podIndex < test.unHealthyPods; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-unHealthyPod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-unHealthyPod-%d", oldRS.Name, podIndex),
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
Conditions: []api.PodCondition{
|
Conditions: []api.PodCondition{
|
||||||
@ -374,7 +374,7 @@ func TestDeploymentController_cleanupUnhealthyReplicas(t *testing.T) {
|
|||||||
client: &fakeClientset,
|
client: &fakeClientset,
|
||||||
eventRecorder: &record.FakeRecorder{},
|
eventRecorder: &record.FakeRecorder{},
|
||||||
}
|
}
|
||||||
cleanupCount, err := controller.cleanupUnhealthyReplicas(oldRCs, deployment, test.maxCleanupCount)
|
cleanupCount, err := controller.cleanupUnhealthyReplicas(oldRSs, deployment, test.maxCleanupCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -386,7 +386,7 @@ func TestDeploymentController_cleanupUnhealthyReplicas(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeploymentController_scaleDownOldRCsForRollingUpdate(t *testing.T) {
|
func TestDeploymentController_scaleDownOldReplicaSetsForRollingUpdate(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
deploymentReplicas int
|
deploymentReplicas int
|
||||||
maxUnavailable intstr.IntOrString
|
maxUnavailable intstr.IntOrString
|
||||||
@ -428,9 +428,9 @@ func TestDeploymentController_scaleDownOldRCsForRollingUpdate(t *testing.T) {
|
|||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Logf("executing scenario %d", i)
|
t.Logf("executing scenario %d", i)
|
||||||
oldRc := rc("foo-v2", test.oldReplicas, nil)
|
oldRS := rs("foo-v2", test.oldReplicas, nil)
|
||||||
allRcs := []*api.ReplicationController{oldRc}
|
allRSs := []*exp.ReplicaSet{oldRS}
|
||||||
oldRcs := []*api.ReplicationController{oldRc}
|
oldRSs := []*exp.ReplicaSet{oldRS}
|
||||||
deployment := deployment("foo", test.deploymentReplicas, intstr.FromInt(0), test.maxUnavailable)
|
deployment := deployment("foo", test.deploymentReplicas, intstr.FromInt(0), test.maxUnavailable)
|
||||||
fakeClientset := fake.Clientset{}
|
fakeClientset := fake.Clientset{}
|
||||||
fakeClientset.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
fakeClientset.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
||||||
@ -440,7 +440,8 @@ func TestDeploymentController_scaleDownOldRCsForRollingUpdate(t *testing.T) {
|
|||||||
for podIndex := 0; podIndex < test.readyPods; podIndex++ {
|
for podIndex := 0; podIndex < test.readyPods; podIndex++ {
|
||||||
podList.Items = append(podList.Items, api.Pod{
|
podList.Items = append(podList.Items, api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-pod-%d", oldRc.Name, podIndex),
|
Name: fmt.Sprintf("%s-pod-%d", oldRS.Name, podIndex),
|
||||||
|
Labels: map[string]string{"foo": "bar"},
|
||||||
},
|
},
|
||||||
Status: api.PodStatus{
|
Status: api.PodStatus{
|
||||||
Conditions: []api.PodCondition{
|
Conditions: []api.PodCondition{
|
||||||
@ -460,7 +461,7 @@ func TestDeploymentController_scaleDownOldRCsForRollingUpdate(t *testing.T) {
|
|||||||
client: &fakeClientset,
|
client: &fakeClientset,
|
||||||
eventRecorder: &record.FakeRecorder{},
|
eventRecorder: &record.FakeRecorder{},
|
||||||
}
|
}
|
||||||
scaled, err := controller.scaleDownOldRCsForRollingUpdate(allRcs, oldRcs, deployment)
|
scaled, err := controller.scaleDownOldReplicaSetsForRollingUpdate(allRSs, oldRSs, deployment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -492,42 +493,42 @@ func TestDeploymentController_scaleDownOldRCsForRollingUpdate(t *testing.T) {
|
|||||||
t.Errorf("expected an update action")
|
t.Errorf("expected an update action")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
updated := updateAction.GetObject().(*api.ReplicationController)
|
updated := updateAction.GetObject().(*exp.ReplicaSet)
|
||||||
if e, a := test.expectedOldReplicas, updated.Spec.Replicas; e != a {
|
if e, a := test.expectedOldReplicas, updated.Spec.Replicas; e != a {
|
||||||
t.Errorf("expected update to %d replicas, got %d", e, a)
|
t.Errorf("expected update to %d replicas, got %d", e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeploymentController_cleanupOldRCs(t *testing.T) {
|
func TestDeploymentController_cleanupOldReplicaSets(t *testing.T) {
|
||||||
selector := map[string]string{"foo": "bar"}
|
selector := map[string]string{"foo": "bar"}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
oldRCs []*api.ReplicationController
|
oldRSs []*exp.ReplicaSet
|
||||||
revisionHistoryLimit int
|
revisionHistoryLimit int
|
||||||
expectedDeletions int
|
expectedDeletions int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
oldRCs: []*api.ReplicationController{
|
oldRSs: []*exp.ReplicaSet{
|
||||||
rc("foo-1", 0, selector),
|
rs("foo-1", 0, selector),
|
||||||
rc("foo-2", 0, selector),
|
rs("foo-2", 0, selector),
|
||||||
rc("foo-3", 0, selector),
|
rs("foo-3", 0, selector),
|
||||||
},
|
},
|
||||||
revisionHistoryLimit: 1,
|
revisionHistoryLimit: 1,
|
||||||
expectedDeletions: 2,
|
expectedDeletions: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oldRCs: []*api.ReplicationController{
|
oldRSs: []*exp.ReplicaSet{
|
||||||
rc("foo-1", 0, selector),
|
rs("foo-1", 0, selector),
|
||||||
rc("foo-2", 0, selector),
|
rs("foo-2", 0, selector),
|
||||||
},
|
},
|
||||||
revisionHistoryLimit: 0,
|
revisionHistoryLimit: 0,
|
||||||
expectedDeletions: 2,
|
expectedDeletions: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oldRCs: []*api.ReplicationController{
|
oldRSs: []*exp.ReplicaSet{
|
||||||
rc("foo-1", 1, selector),
|
rs("foo-1", 1, selector),
|
||||||
rc("foo-2", 1, selector),
|
rs("foo-2", 1, selector),
|
||||||
},
|
},
|
||||||
revisionHistoryLimit: 0,
|
revisionHistoryLimit: 0,
|
||||||
expectedDeletions: 0,
|
expectedDeletions: 0,
|
||||||
@ -539,14 +540,14 @@ func TestDeploymentController_cleanupOldRCs(t *testing.T) {
|
|||||||
controller := NewDeploymentController(fake, controller.NoResyncPeriodFunc)
|
controller := NewDeploymentController(fake, controller.NoResyncPeriodFunc)
|
||||||
|
|
||||||
controller.eventRecorder = &record.FakeRecorder{}
|
controller.eventRecorder = &record.FakeRecorder{}
|
||||||
controller.rcStoreSynced = alwaysReady
|
controller.rsStoreSynced = alwaysReady
|
||||||
controller.podStoreSynced = alwaysReady
|
controller.podStoreSynced = alwaysReady
|
||||||
for _, rc := range test.oldRCs {
|
for _, rs := range test.oldRSs {
|
||||||
controller.rcStore.Add(rc)
|
controller.rsStore.Add(rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newDeployment(1, &tests[i].revisionHistoryLimit)
|
d := newDeployment(1, &tests[i].revisionHistoryLimit)
|
||||||
controller.cleanupOldRcs(test.oldRCs, *d)
|
controller.cleanupOldReplicaSets(test.oldRSs, *d)
|
||||||
|
|
||||||
gotDeletions := 0
|
gotDeletions := 0
|
||||||
for _, action := range fake.Actions() {
|
for _, action := range fake.Actions() {
|
||||||
@ -555,20 +556,20 @@ func TestDeploymentController_cleanupOldRCs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if gotDeletions != test.expectedDeletions {
|
if gotDeletions != test.expectedDeletions {
|
||||||
t.Errorf("expect %v old rcs been deleted, but got %v", test.expectedDeletions, gotDeletions)
|
t.Errorf("expect %v old replica sets been deleted, but got %v", test.expectedDeletions, gotDeletions)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rc(name string, replicas int, selector map[string]string) *api.ReplicationController {
|
func rs(name string, replicas int, selector map[string]string) *exp.ReplicaSet {
|
||||||
return &api.ReplicationController{
|
return &exp.ReplicaSet{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: exp.ReplicaSetSpec{
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
Selector: selector,
|
Selector: &unversioned.LabelSelector{MatchLabels: selector},
|
||||||
Template: &api.PodTemplateSpec{},
|
Template: &api.PodTemplateSpec{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -609,7 +610,7 @@ func newDeployment(replicas int, revisionHistoryLimit *int) *exp.Deployment {
|
|||||||
RollingUpdate: &exp.RollingUpdateDeployment{},
|
RollingUpdate: &exp.RollingUpdateDeployment{},
|
||||||
},
|
},
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
Selector: map[string]string{"foo": "bar"},
|
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
@ -640,13 +641,13 @@ func getKey(d *exp.Deployment, t *testing.T) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newReplicationController(d *exp.Deployment, name string, replicas int) *api.ReplicationController {
|
func newReplicaSet(d *exp.Deployment, name string, replicas int) *exp.ReplicaSet {
|
||||||
return &api.ReplicationController{
|
return &exp.ReplicaSet{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
Namespace: api.NamespaceDefault,
|
Namespace: api.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: exp.ReplicaSetSpec{
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
Template: &d.Spec.Template,
|
Template: &d.Spec.Template,
|
||||||
},
|
},
|
||||||
@ -664,7 +665,7 @@ type fixture struct {
|
|||||||
client *fake.Clientset
|
client *fake.Clientset
|
||||||
// Objects to put in the store.
|
// Objects to put in the store.
|
||||||
dStore []*exp.Deployment
|
dStore []*exp.Deployment
|
||||||
rcStore []*api.ReplicationController
|
rsStore []*exp.ReplicaSet
|
||||||
podStore []*api.Pod
|
podStore []*api.Pod
|
||||||
|
|
||||||
// Actions expected to happen on the client. Objects from here are also
|
// Actions expected to happen on the client. Objects from here are also
|
||||||
@ -678,14 +679,14 @@ func (f *fixture) expectUpdateDeploymentAction(d *exp.Deployment) {
|
|||||||
f.objects.Items = append(f.objects.Items, d)
|
f.objects.Items = append(f.objects.Items, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fixture) expectCreateRCAction(rc *api.ReplicationController) {
|
func (f *fixture) expectCreateRSAction(rs *exp.ReplicaSet) {
|
||||||
f.actions = append(f.actions, core.NewCreateAction("replicationcontrollers", rc.Namespace, rc))
|
f.actions = append(f.actions, core.NewCreateAction("replicasets", rs.Namespace, rs))
|
||||||
f.objects.Items = append(f.objects.Items, rc)
|
f.objects.Items = append(f.objects.Items, rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fixture) expectUpdateRCAction(rc *api.ReplicationController) {
|
func (f *fixture) expectUpdateRSAction(rs *exp.ReplicaSet) {
|
||||||
f.actions = append(f.actions, core.NewUpdateAction("replicationcontrollers", rc.Namespace, rc))
|
f.actions = append(f.actions, core.NewUpdateAction("replicasets", rs.Namespace, rs))
|
||||||
f.objects.Items = append(f.objects.Items, rc)
|
f.objects.Items = append(f.objects.Items, rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fixture) expectListPodAction(namespace string, opt api.ListOptions) {
|
func (f *fixture) expectListPodAction(namespace string, opt api.ListOptions) {
|
||||||
@ -703,13 +704,13 @@ func (f *fixture) run(deploymentName string) {
|
|||||||
f.client = fake.NewSimpleClientset(f.objects)
|
f.client = fake.NewSimpleClientset(f.objects)
|
||||||
c := NewDeploymentController(f.client, controller.NoResyncPeriodFunc)
|
c := NewDeploymentController(f.client, controller.NoResyncPeriodFunc)
|
||||||
c.eventRecorder = &record.FakeRecorder{}
|
c.eventRecorder = &record.FakeRecorder{}
|
||||||
c.rcStoreSynced = alwaysReady
|
c.rsStoreSynced = alwaysReady
|
||||||
c.podStoreSynced = alwaysReady
|
c.podStoreSynced = alwaysReady
|
||||||
for _, d := range f.dStore {
|
for _, d := range f.dStore {
|
||||||
c.dStore.Store.Add(d)
|
c.dStore.Store.Add(d)
|
||||||
}
|
}
|
||||||
for _, rc := range f.rcStore {
|
for _, rs := range f.rsStore {
|
||||||
c.rcStore.Store.Add(rc)
|
c.rsStore.Store.Add(rs)
|
||||||
}
|
}
|
||||||
for _, pod := range f.podStore {
|
for _, pod := range f.podStore {
|
||||||
c.podStore.Store.Add(pod)
|
c.podStore.Store.Add(pod)
|
||||||
@ -739,22 +740,22 @@ func (f *fixture) run(deploymentName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncDeploymentCreatesRC(t *testing.T) {
|
func TestSyncDeploymentCreatesReplicaSet(t *testing.T) {
|
||||||
f := newFixture(t)
|
f := newFixture(t)
|
||||||
|
|
||||||
d := newDeployment(1, nil)
|
d := newDeployment(1, nil)
|
||||||
f.dStore = append(f.dStore, d)
|
f.dStore = append(f.dStore, d)
|
||||||
|
|
||||||
// expect that one rc with zero replicas is created
|
// expect that one ReplicaSet with zero replicas is created
|
||||||
// then is updated to 1 replica
|
// then is updated to 1 replica
|
||||||
rc := newReplicationController(d, "deploymentrc-4186632231", 0)
|
rs := newReplicaSet(d, "deploymentrs-4186632231", 0)
|
||||||
updatedRC := newReplicationController(d, "deploymentrc-4186632231", 1)
|
updatedRS := newReplicaSet(d, "deploymentrs-4186632231", 1)
|
||||||
opt := newListOptions()
|
opt := newListOptions()
|
||||||
|
|
||||||
f.expectCreateRCAction(rc)
|
f.expectCreateRSAction(rs)
|
||||||
f.expectUpdateDeploymentAction(d)
|
f.expectUpdateDeploymentAction(d)
|
||||||
f.expectUpdateRCAction(updatedRC)
|
f.expectUpdateRSAction(updatedRS)
|
||||||
f.expectListPodAction(rc.Namespace, opt)
|
f.expectListPodAction(rs.Namespace, opt)
|
||||||
f.expectUpdateDeploymentAction(d)
|
f.expectUpdateDeploymentAction(d)
|
||||||
|
|
||||||
f.run(getKey(d, t))
|
f.run(getKey(d, t))
|
||||||
|
@ -125,6 +125,7 @@ __custom_func() {
|
|||||||
* persistentvolumeclaims (aka 'pvc')
|
* persistentvolumeclaims (aka 'pvc')
|
||||||
* quota
|
* quota
|
||||||
* resourcequotas (aka 'quota')
|
* resourcequotas (aka 'quota')
|
||||||
|
* replicasets (aka 'rs')
|
||||||
* replicationcontrollers (aka 'rc')
|
* replicationcontrollers (aka 'rc')
|
||||||
* secrets
|
* secrets
|
||||||
* serviceaccounts
|
* serviceaccounts
|
||||||
|
@ -290,6 +290,7 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
|||||||
}
|
}
|
||||||
rf := cmdutil.NewFactory(nil)
|
rf := cmdutil.NewFactory(nil)
|
||||||
f.PodSelectorForObject = rf.PodSelectorForObject
|
f.PodSelectorForObject = rf.PodSelectorForObject
|
||||||
|
f.MapBasedSelectorForObject = rf.MapBasedSelectorForObject
|
||||||
f.PortsForObject = rf.PortsForObject
|
f.PortsForObject = rf.PortsForObject
|
||||||
f.LabelsForObject = rf.LabelsForObject
|
f.LabelsForObject = rf.LabelsForObject
|
||||||
f.CanBeExposed = rf.CanBeExposed
|
f.CanBeExposed = rf.CanBeExposed
|
||||||
|
@ -149,9 +149,9 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
|||||||
// For objects that need a pod selector, derive it from the exposed object in case a user
|
// For objects that need a pod selector, derive it from the exposed object in case a user
|
||||||
// didn't explicitly specify one via --selector
|
// didn't explicitly specify one via --selector
|
||||||
if s, found := params["selector"]; found && kubectl.IsZero(s) {
|
if s, found := params["selector"]; found && kubectl.IsZero(s) {
|
||||||
s, err := f.PodSelectorForObject(inputObject)
|
s, err := f.MapBasedSelectorForObject(inputObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find selectors via --selector flag or introspection: %s", err))
|
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't retrieve selectors via --selector flag or introspection: %s", err))
|
||||||
}
|
}
|
||||||
params["selector"] = s
|
params["selector"] = s
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,10 @@ type Factory struct {
|
|||||||
Rollbacker func(mapping *meta.RESTMapping) (kubectl.Rollbacker, error)
|
Rollbacker func(mapping *meta.RESTMapping) (kubectl.Rollbacker, error)
|
||||||
// PodSelectorForObject returns the pod selector associated with the provided object
|
// PodSelectorForObject returns the pod selector associated with the provided object
|
||||||
PodSelectorForObject func(object runtime.Object) (string, error)
|
PodSelectorForObject func(object runtime.Object) (string, error)
|
||||||
|
// MapBasedSelectorForObject returns the map-based selector associated with the provided object. If a
|
||||||
|
// new set-based selector is provided, an error is returned if the selector cannot be converted to a
|
||||||
|
// map-based selector
|
||||||
|
MapBasedSelectorForObject func(object runtime.Object) (string, error)
|
||||||
// PortsForObject returns the ports associated with the provided object
|
// PortsForObject returns the ports associated with the provided object
|
||||||
PortsForObject func(object runtime.Object) ([]string, error)
|
PortsForObject func(object runtime.Object) ([]string, error)
|
||||||
// LabelsForObject returns the labels associated with the provided object
|
// LabelsForObject returns the labels associated with the provided object
|
||||||
@ -257,7 +261,41 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||||||
}
|
}
|
||||||
return kubectl.MakeLabels(t.Spec.Selector), nil
|
return kubectl.MakeLabels(t.Spec.Selector), nil
|
||||||
case *extensions.Deployment:
|
case *extensions.Deployment:
|
||||||
|
selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to convert label selector to selector: %v", err)
|
||||||
|
}
|
||||||
|
return selector.String(), nil
|
||||||
|
default:
|
||||||
|
gvk, err := api.Scheme.ObjectKind(object)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("cannot extract pod selector from %v", gvk)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MapBasedSelectorForObject: func(object runtime.Object) (string, error) {
|
||||||
|
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
|
||||||
|
switch t := object.(type) {
|
||||||
|
case *api.ReplicationController:
|
||||||
return kubectl.MakeLabels(t.Spec.Selector), nil
|
return kubectl.MakeLabels(t.Spec.Selector), nil
|
||||||
|
case *api.Pod:
|
||||||
|
if len(t.Labels) == 0 {
|
||||||
|
return "", fmt.Errorf("the pod has no labels and cannot be exposed")
|
||||||
|
}
|
||||||
|
return kubectl.MakeLabels(t.Labels), nil
|
||||||
|
case *api.Service:
|
||||||
|
if t.Spec.Selector == nil {
|
||||||
|
return "", fmt.Errorf("the service has no pod selector set")
|
||||||
|
}
|
||||||
|
return kubectl.MakeLabels(t.Spec.Selector), nil
|
||||||
|
case *extensions.Deployment:
|
||||||
|
// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
|
||||||
|
// operator, DoubleEquals operator and In operator with only one element in the set.
|
||||||
|
if len(t.Spec.Selector.MatchExpressions) > 0 {
|
||||||
|
return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format")
|
||||||
|
}
|
||||||
|
return kubectl.MakeLabels(t.Spec.Selector.MatchLabels), nil
|
||||||
default:
|
default:
|
||||||
gvk, err := api.Scheme.ObjectKind(object)
|
gvk, err := api.Scheme.ObjectKind(object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -447,11 +485,20 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||||||
}
|
}
|
||||||
switch t := object.(type) {
|
switch t := object.(type) {
|
||||||
case *api.ReplicationController:
|
case *api.ReplicationController:
|
||||||
return GetFirstPod(client, t.Namespace, t.Spec.Selector)
|
selector := labels.SelectorFromSet(t.Spec.Selector)
|
||||||
|
return GetFirstPod(client, t.Namespace, selector)
|
||||||
case *extensions.Deployment:
|
case *extensions.Deployment:
|
||||||
return GetFirstPod(client, t.Namespace, t.Spec.Selector)
|
selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert label selector to selector: %v", err)
|
||||||
|
}
|
||||||
|
return GetFirstPod(client, t.Namespace, selector)
|
||||||
case *extensions.Job:
|
case *extensions.Job:
|
||||||
return GetFirstPod(client, t.Namespace, t.Spec.Selector.MatchLabels)
|
selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert label selector to selector: %v", err)
|
||||||
|
}
|
||||||
|
return GetFirstPod(client, t.Namespace, selector)
|
||||||
case *api.Pod:
|
case *api.Pod:
|
||||||
return t, nil
|
return t, nil
|
||||||
default:
|
default:
|
||||||
@ -469,12 +516,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetFirstPod returns the first pod of an object from its namespace and selector
|
// GetFirstPod returns the first pod of an object from its namespace and selector
|
||||||
func GetFirstPod(client *client.Client, namespace string, selector map[string]string) (*api.Pod, error) {
|
func GetFirstPod(client *client.Client, namespace string, selector labels.Selector) (*api.Pod, error) {
|
||||||
var pods *api.PodList
|
var pods *api.PodList
|
||||||
for pods == nil || len(pods.Items) == 0 {
|
for pods == nil || len(pods.Items) == 0 {
|
||||||
var err error
|
var err error
|
||||||
labelSelector := labels.SelectorFromSet(selector)
|
options := api.ListOptions{LabelSelector: selector}
|
||||||
options := api.ListOptions{LabelSelector: labelSelector}
|
|
||||||
if pods, err = client.Pods(namespace).List(options); err != nil {
|
if pods, err = client.Pods(namespace).List(options); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1607,12 +1607,16 @@ func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
selector, err := unversioned.LabelSelectorAsSelector(d.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
return tabbedString(func(out io.Writer) error {
|
return tabbedString(func(out io.Writer) error {
|
||||||
fmt.Fprintf(out, "Name:\t%s\n", d.ObjectMeta.Name)
|
fmt.Fprintf(out, "Name:\t%s\n", d.ObjectMeta.Name)
|
||||||
fmt.Fprintf(out, "Namespace:\t%s\n", d.ObjectMeta.Namespace)
|
fmt.Fprintf(out, "Namespace:\t%s\n", d.ObjectMeta.Namespace)
|
||||||
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", d.CreationTimestamp.Time.Format(time.RFC1123Z))
|
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", d.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||||
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(d.Labels))
|
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(d.Labels))
|
||||||
fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(d.Spec.Selector))
|
fmt.Fprintf(out, "Selector:\t%s\n", selector)
|
||||||
fmt.Fprintf(out, "Replicas:\t%d updated | %d total | %d available | %d unavailable\n", d.Status.UpdatedReplicas, d.Spec.Replicas, d.Status.AvailableReplicas, d.Status.UnavailableReplicas)
|
fmt.Fprintf(out, "Replicas:\t%d updated | %d total | %d available | %d unavailable\n", d.Status.UpdatedReplicas, d.Spec.Replicas, d.Status.AvailableReplicas, d.Status.UnavailableReplicas)
|
||||||
fmt.Fprintf(out, "StrategyType:\t%s\n", d.Spec.Strategy.Type)
|
fmt.Fprintf(out, "StrategyType:\t%s\n", d.Spec.Strategy.Type)
|
||||||
fmt.Fprintf(out, "MinReadySeconds:\t%s\n", d.Spec.MinReadySeconds)
|
fmt.Fprintf(out, "MinReadySeconds:\t%s\n", d.Spec.MinReadySeconds)
|
||||||
@ -1620,17 +1624,17 @@ func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error)
|
|||||||
ru := d.Spec.Strategy.RollingUpdate
|
ru := d.Spec.Strategy.RollingUpdate
|
||||||
fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge\n", ru.MaxUnavailable.String(), ru.MaxSurge.String())
|
fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge\n", ru.MaxUnavailable.String(), ru.MaxSurge.String())
|
||||||
}
|
}
|
||||||
oldRCs, _, err := deploymentutil.GetOldRCs(*d, dd)
|
oldRSs, _, err := deploymentutil.GetOldReplicaSets(*d, dd)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Fprintf(out, "OldReplicationControllers:\t%s\n", printReplicationControllersByLabels(oldRCs))
|
fmt.Fprintf(out, "OldReplicaSets:\t%s\n", printReplicaSetsByLabels(oldRSs))
|
||||||
}
|
}
|
||||||
newRC, err := deploymentutil.GetNewRC(*d, dd)
|
newRS, err := deploymentutil.GetNewReplicaSet(*d, dd)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var newRCs []*api.ReplicationController
|
var newRSs []*extensions.ReplicaSet
|
||||||
if newRC != nil {
|
if newRS != nil {
|
||||||
newRCs = append(newRCs, newRC)
|
newRSs = append(newRSs, newRS)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "NewReplicationController:\t%s\n", printReplicationControllersByLabels(newRCs))
|
fmt.Fprintf(out, "NewReplicaSet:\t%s\n", printReplicaSetsByLabels(newRSs))
|
||||||
}
|
}
|
||||||
events, err := dd.Core().Events(namespace).Search(d)
|
events, err := dd.Core().Events(namespace).Search(d)
|
||||||
if err == nil && events != nil {
|
if err == nil && events != nil {
|
||||||
@ -1705,6 +1709,20 @@ func printReplicationControllersByLabels(matchingRCs []*api.ReplicationControlle
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printReplicaSetsByLabels(matchingRSs []*extensions.ReplicaSet) string {
|
||||||
|
// Format the matching ReplicaSets into strings.
|
||||||
|
var rsStrings []string
|
||||||
|
for _, rs := range matchingRSs {
|
||||||
|
rsStrings = append(rsStrings, fmt.Sprintf("%s (%d/%d replicas created)", rs.Name, rs.Status.Replicas, rs.Spec.Replicas))
|
||||||
|
}
|
||||||
|
|
||||||
|
list := strings.Join(rsStrings, ", ")
|
||||||
|
if list == "" {
|
||||||
|
return "<none>"
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
func getPodStatusForController(c client.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) {
|
func getPodStatusForController(c client.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) {
|
||||||
options := api.ListOptions{LabelSelector: selector}
|
options := api.ListOptions{LabelSelector: selector}
|
||||||
rcPods, err := c.List(options)
|
rcPods, err := c.List(options)
|
||||||
|
@ -58,7 +58,7 @@ type DeploymentHistoryViewer struct {
|
|||||||
c clientset.Interface
|
c clientset.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// History returns a revision-to-RC map as the revision history of a deployment
|
// History returns a revision-to-replicaset map as the revision history of a deployment
|
||||||
func (h *DeploymentHistoryViewer) History(namespace, name string) (HistoryInfo, error) {
|
func (h *DeploymentHistoryViewer) History(namespace, name string) (HistoryInfo, error) {
|
||||||
historyInfo := HistoryInfo{
|
historyInfo := HistoryInfo{
|
||||||
RevisionToTemplate: make(map[int64]*api.PodTemplateSpec),
|
RevisionToTemplate: make(map[int64]*api.PodTemplateSpec),
|
||||||
@ -67,22 +67,22 @@ func (h *DeploymentHistoryViewer) History(namespace, name string) (HistoryInfo,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return historyInfo, fmt.Errorf("failed to retrieve deployment %s: %v", name, err)
|
return historyInfo, fmt.Errorf("failed to retrieve deployment %s: %v", name, err)
|
||||||
}
|
}
|
||||||
_, allOldRCs, err := deploymentutil.GetOldRCs(*deployment, h.c)
|
_, allOldRSs, err := deploymentutil.GetOldReplicaSets(*deployment, h.c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return historyInfo, fmt.Errorf("failed to retrieve old RCs from deployment %s: %v", name, err)
|
return historyInfo, fmt.Errorf("failed to retrieve old replica sets from deployment %s: %v", name, err)
|
||||||
}
|
}
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, h.c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, h.c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return historyInfo, fmt.Errorf("failed to retrieve new RC from deployment %s: %v", name, err)
|
return historyInfo, fmt.Errorf("failed to retrieve new replica set from deployment %s: %v", name, err)
|
||||||
}
|
}
|
||||||
allRCs := append(allOldRCs, newRC)
|
allRSs := append(allOldRSs, newRS)
|
||||||
for _, rc := range allRCs {
|
for _, rs := range allRSs {
|
||||||
v, err := deploymentutil.Revision(rc)
|
v, err := deploymentutil.Revision(rs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
historyInfo.RevisionToTemplate[v] = rc.Spec.Template
|
historyInfo.RevisionToTemplate[v] = rs.Spec.Template
|
||||||
changeCause := getChangeCause(rc)
|
changeCause := getChangeCause(rs)
|
||||||
if historyInfo.RevisionToTemplate[v].Annotations == nil {
|
if historyInfo.RevisionToTemplate[v].Annotations == nil {
|
||||||
historyInfo.RevisionToTemplate[v].Annotations = make(map[string]string)
|
historyInfo.RevisionToTemplate[v].Annotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ func (DeploymentV1Beta1) Generate(genericParams map[string]interface{}) (runtime
|
|||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Replicas: count,
|
Replicas: count,
|
||||||
Selector: labels,
|
Selector: &unversioned.LabelSelector{MatchLabels: labels},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
|
@ -656,7 +656,7 @@ func TestGenerateDeployment(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Replicas: 3,
|
Replicas: 3,
|
||||||
Selector: map[string]string{"foo": "bar", "baz": "blah"},
|
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar", "baz": "blah"}},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: map[string]string{"foo": "bar", "baz": "blah"},
|
Labels: map[string]string{"foo": "bar", "baz": "blah"},
|
||||||
|
@ -48,8 +48,9 @@ func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
|
|||||||
return &ReplicaSetScaler{c.Extensions()}, nil
|
return &ReplicaSetScaler{c.Extensions()}, nil
|
||||||
case extensions.Kind("Job"):
|
case extensions.Kind("Job"):
|
||||||
return &JobScaler{c.Extensions()}, nil
|
return &JobScaler{c.Extensions()}, nil
|
||||||
case extensions.Kind("Deployment"):
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
return &DeploymentScaler{c.Extensions()}, nil
|
// case extensions.Kind("Deployment"):
|
||||||
|
// return &DeploymentScaler{c.Extensions()}, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no scaler has been implemented for %q", kind)
|
return nil, fmt.Errorf("no scaler has been implemented for %q", kind)
|
||||||
}
|
}
|
||||||
@ -327,53 +328,57 @@ func (precondition *ScalePrecondition) ValidateDeployment(deployment *extensions
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeploymentScaler struct {
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
c client.ExtensionsInterface
|
// type DeploymentScaler struct {
|
||||||
}
|
// c client.ExtensionsInterface
|
||||||
|
// }
|
||||||
|
|
||||||
// ScaleSimple is responsible for updating a deployment's desired replicas count.
|
// // ScaleSimple is responsible for updating a deployment's desired replicas count.
|
||||||
func (scaler *DeploymentScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
|
// func (scaler *DeploymentScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error {
|
||||||
deployment, err := scaler.c.Deployments(namespace).Get(name)
|
// deployment, err := scaler.c.Deployments(namespace).Get(name)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return ScaleError{ScaleGetFailure, "Unknown", err}
|
// return ScaleError{ScaleGetFailure, "Unknown", err}
|
||||||
}
|
// }
|
||||||
if preconditions != nil {
|
// if preconditions != nil {
|
||||||
if err := preconditions.ValidateDeployment(deployment); err != nil {
|
// if err := preconditions.ValidateDeployment(deployment); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
scale := extensions.ScaleFromDeployment(deployment)
|
// scale, err := extensions.ScaleFromDeployment(deployment)
|
||||||
scale.Spec.Replicas = int(newSize)
|
// if err != nil {
|
||||||
if _, err := scaler.c.Scales(namespace).Update("Deployment", scale); err != nil {
|
// return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
|
||||||
if errors.IsInvalid(err) {
|
// }
|
||||||
return ScaleError{ScaleUpdateInvalidFailure, deployment.ResourceVersion, err}
|
// scale.Spec.Replicas = int(newSize)
|
||||||
}
|
// if _, err := scaler.c.Scales(namespace).Update("Deployment", scale); err != nil {
|
||||||
return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
|
// if errors.IsInvalid(err) {
|
||||||
}
|
// return ScaleError{ScaleUpdateInvalidFailure, deployment.ResourceVersion, err}
|
||||||
return nil
|
// }
|
||||||
}
|
// return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
// Scale updates a deployment to a new size, with optional precondition check (if preconditions is not nil),
|
// // Scale updates a deployment to a new size, with optional precondition check (if preconditions is not nil),
|
||||||
// optional retries (if retry is not nil), and then optionally waits for the status to reach desired count.
|
// // optional retries (if retry is not nil), and then optionally waits for the status to reach desired count.
|
||||||
func (scaler *DeploymentScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
|
// func (scaler *DeploymentScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
|
||||||
if preconditions == nil {
|
// if preconditions == nil {
|
||||||
preconditions = &ScalePrecondition{-1, ""}
|
// preconditions = &ScalePrecondition{-1, ""}
|
||||||
}
|
// }
|
||||||
if retry == nil {
|
// if retry == nil {
|
||||||
// Make it try only once, immediately
|
// // Make it try only once, immediately
|
||||||
retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
|
// retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
|
||||||
}
|
// }
|
||||||
cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
|
// cond := ScaleCondition(scaler, preconditions, namespace, name, newSize)
|
||||||
if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
|
// if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if waitForReplicas != nil {
|
// if waitForReplicas != nil {
|
||||||
deployment, err := scaler.c.Deployments(namespace).Get(name)
|
// deployment, err := scaler.c.Deployments(namespace).Get(name)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
|
// return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
|
||||||
client.DeploymentHasDesiredReplicas(scaler.c, deployment))
|
// client.DeploymentHasDesiredReplicas(scaler.c, deployment))
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
@ -488,143 +488,145 @@ func TestValidateJob(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrorScales struct {
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
testclient.FakeScales
|
|
||||||
invalid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ErrorScales) Update(kind string, scale *extensions.Scale) (*extensions.Scale, error) {
|
// type ErrorScales struct {
|
||||||
if c.invalid {
|
// testclient.FakeScales
|
||||||
return nil, kerrors.NewInvalid(extensions.Kind(scale.Kind), scale.Name, nil)
|
// invalid bool
|
||||||
}
|
// }
|
||||||
return nil, errors.New("scale update failure")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ErrorScales) Get(kind, name string) (*extensions.Scale, error) {
|
// func (c *ErrorScales) Update(kind string, scale *extensions.Scale) (*extensions.Scale, error) {
|
||||||
return &extensions.Scale{
|
// if c.invalid {
|
||||||
Spec: extensions.ScaleSpec{
|
// return nil, kerrors.NewInvalid(extensions.Kind(scale.Kind), scale.Name, nil)
|
||||||
Replicas: 0,
|
// }
|
||||||
},
|
// return nil, errors.New("scale update failure")
|
||||||
}, nil
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorDeployments struct {
|
// func (c *ErrorScales) Get(kind, name string) (*extensions.Scale, error) {
|
||||||
testclient.FakeDeployments
|
// return &extensions.Scale{
|
||||||
invalid bool
|
// Spec: extensions.ScaleSpec{
|
||||||
}
|
// Replicas: 0,
|
||||||
|
// },
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (c *ErrorDeployments) Update(deployment *extensions.Deployment) (*extensions.Deployment, error) {
|
// type ErrorDeployments struct {
|
||||||
if c.invalid {
|
// testclient.FakeDeployments
|
||||||
return nil, kerrors.NewInvalid(extensions.Kind(deployment.Kind), deployment.Name, nil)
|
// invalid bool
|
||||||
}
|
// }
|
||||||
return nil, errors.New("deployment update failure")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ErrorDeployments) Get(name string) (*extensions.Deployment, error) {
|
// func (c *ErrorDeployments) Update(deployment *extensions.Deployment) (*extensions.Deployment, error) {
|
||||||
return &extensions.Deployment{
|
// if c.invalid {
|
||||||
Spec: extensions.DeploymentSpec{
|
// return nil, kerrors.NewInvalid(extensions.Kind(deployment.Kind), deployment.Name, nil)
|
||||||
Replicas: 0,
|
// }
|
||||||
},
|
// return nil, errors.New("deployment update failure")
|
||||||
}, nil
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorDeploymentClient struct {
|
// func (c *ErrorDeployments) Get(name string) (*extensions.Deployment, error) {
|
||||||
testclient.FakeExperimental
|
// return &extensions.Deployment{
|
||||||
invalid bool
|
// Spec: extensions.DeploymentSpec{
|
||||||
}
|
// Replicas: 0,
|
||||||
|
// },
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (c *ErrorDeploymentClient) Deployments(namespace string) client.DeploymentInterface {
|
// type ErrorDeploymentClient struct {
|
||||||
return &ErrorDeployments{testclient.FakeDeployments{Fake: &c.FakeExperimental, Namespace: namespace}, c.invalid}
|
// testclient.FakeExperimental
|
||||||
}
|
// invalid bool
|
||||||
|
// }
|
||||||
|
|
||||||
func (c *ErrorDeploymentClient) Scales(namespace string) client.ScaleInterface {
|
// func (c *ErrorDeploymentClient) Deployments(namespace string) client.DeploymentInterface {
|
||||||
return &ErrorScales{testclient.FakeScales{Fake: &c.FakeExperimental, Namespace: namespace}, c.invalid}
|
// return &ErrorDeployments{testclient.FakeDeployments{Fake: &c.FakeExperimental, Namespace: namespace}, c.invalid}
|
||||||
}
|
// }
|
||||||
|
|
||||||
func TestDeploymentScaleRetry(t *testing.T) {
|
// func (c *ErrorDeploymentClient) Scales(namespace string) client.ScaleInterface {
|
||||||
fake := &ErrorDeploymentClient{FakeExperimental: testclient.FakeExperimental{Fake: &testclient.Fake{}}, invalid: false}
|
// return &ErrorScales{testclient.FakeScales{Fake: &c.FakeExperimental, Namespace: namespace}, c.invalid}
|
||||||
scaler := &DeploymentScaler{fake}
|
// }
|
||||||
preconditions := &ScalePrecondition{-1, ""}
|
|
||||||
count := uint(3)
|
|
||||||
name := "foo"
|
|
||||||
namespace := "default"
|
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, preconditions, namespace, name, count)
|
// func TestDeploymentScaleRetry(t *testing.T) {
|
||||||
pass, err := scaleFunc()
|
// fake := &ErrorDeploymentClient{FakeExperimental: testclient.FakeExperimental{Fake: &testclient.Fake{}}, invalid: false}
|
||||||
if pass != false {
|
// scaler := &DeploymentScaler{fake}
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
// preconditions := &ScalePrecondition{-1, ""}
|
||||||
}
|
// count := uint(3)
|
||||||
if err != nil {
|
// name := "foo"
|
||||||
t.Errorf("Did not expect an error on update failure, got %v", err)
|
// namespace := "default"
|
||||||
}
|
|
||||||
preconditions = &ScalePrecondition{3, ""}
|
|
||||||
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count)
|
|
||||||
pass, err = scaleFunc()
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("Expected error on precondition failure")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeploymentScale(t *testing.T) {
|
// scaleFunc := ScaleCondition(scaler, preconditions, namespace, name, count)
|
||||||
fake := &testclient.FakeExperimental{Fake: &testclient.Fake{}}
|
// pass, err := scaleFunc()
|
||||||
scaler := DeploymentScaler{fake}
|
// if pass != false {
|
||||||
preconditions := ScalePrecondition{-1, ""}
|
// t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
count := uint(3)
|
// }
|
||||||
name := "foo"
|
// if err != nil {
|
||||||
scaler.Scale("default", name, count, &preconditions, nil, nil)
|
// t.Errorf("Did not expect an error on update failure, got %v", err)
|
||||||
|
// }
|
||||||
|
// preconditions = &ScalePrecondition{3, ""}
|
||||||
|
// scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count)
|
||||||
|
// pass, err = scaleFunc()
|
||||||
|
// if err == nil {
|
||||||
|
// t.Errorf("Expected error on precondition failure")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
actions := fake.Actions()
|
// func TestDeploymentScale(t *testing.T) {
|
||||||
if len(actions) != 2 {
|
// fake := &testclient.FakeExperimental{Fake: &testclient.Fake{}}
|
||||||
t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions)
|
// scaler := DeploymentScaler{fake}
|
||||||
}
|
// preconditions := ScalePrecondition{-1, ""}
|
||||||
if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "deployments" || action.GetName() != name {
|
// count := uint(3)
|
||||||
t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name)
|
// name := "foo"
|
||||||
}
|
// scaler.Scale("default", name, count, &preconditions, nil, nil)
|
||||||
// TODO: The testclient needs to support subresources
|
|
||||||
if action, ok := actions[1].(testclient.UpdateAction); !ok || action.GetResource() != "Deployment" || action.GetObject().(*extensions.Scale).Spec.Replicas != int(count) {
|
|
||||||
t.Errorf("unexpected action %v, expected update-deployment-scale with replicas = %d", actions[1], count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeploymentScaleInvalid(t *testing.T) {
|
// actions := fake.Actions()
|
||||||
fake := &ErrorDeploymentClient{FakeExperimental: testclient.FakeExperimental{Fake: &testclient.Fake{}}, invalid: true}
|
// if len(actions) != 2 {
|
||||||
scaler := DeploymentScaler{fake}
|
// t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions)
|
||||||
preconditions := ScalePrecondition{-1, ""}
|
// }
|
||||||
count := uint(3)
|
// if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "deployments" || action.GetName() != name {
|
||||||
name := "foo"
|
// t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name)
|
||||||
namespace := "default"
|
// }
|
||||||
|
// // TODO: The testclient needs to support subresources
|
||||||
|
// if action, ok := actions[1].(testclient.UpdateAction); !ok || action.GetResource() != "Deployment" || action.GetObject().(*extensions.Scale).Spec.Replicas != int(count) {
|
||||||
|
// t.Errorf("unexpected action %v, expected update-deployment-scale with replicas = %d", actions[1], count)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count)
|
// func TestDeploymentScaleInvalid(t *testing.T) {
|
||||||
pass, err := scaleFunc()
|
// fake := &ErrorDeploymentClient{FakeExperimental: testclient.FakeExperimental{Fake: &testclient.Fake{}}, invalid: true}
|
||||||
if pass {
|
// scaler := DeploymentScaler{fake}
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
// preconditions := ScalePrecondition{-1, ""}
|
||||||
}
|
// count := uint(3)
|
||||||
e, ok := err.(ScaleError)
|
// name := "foo"
|
||||||
if err == nil || !ok || e.FailureType != ScaleUpdateInvalidFailure {
|
// namespace := "default"
|
||||||
t.Errorf("Expected error on invalid update failure, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeploymentScaleFailsPreconditions(t *testing.T) {
|
// scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count)
|
||||||
fake := testclient.NewSimpleFake(&extensions.Deployment{
|
// pass, err := scaleFunc()
|
||||||
Spec: extensions.DeploymentSpec{
|
// if pass {
|
||||||
Replicas: 10,
|
// t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
},
|
// }
|
||||||
})
|
// e, ok := err.(ScaleError)
|
||||||
scaler := DeploymentScaler{&testclient.FakeExperimental{fake}}
|
// if err == nil || !ok || e.FailureType != ScaleUpdateInvalidFailure {
|
||||||
preconditions := ScalePrecondition{2, ""}
|
// t.Errorf("Expected error on invalid update failure, got %v", err)
|
||||||
count := uint(3)
|
// }
|
||||||
name := "foo"
|
// }
|
||||||
scaler.Scale("default", name, count, &preconditions, nil, nil)
|
|
||||||
|
|
||||||
actions := fake.Actions()
|
// func TestDeploymentScaleFailsPreconditions(t *testing.T) {
|
||||||
if len(actions) != 1 {
|
// fake := testclient.NewSimpleFake(&extensions.Deployment{
|
||||||
t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions)
|
// Spec: extensions.DeploymentSpec{
|
||||||
}
|
// Replicas: 10,
|
||||||
if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "deployments" || action.GetName() != name {
|
// },
|
||||||
t.Errorf("unexpected action: %v, expected get-deployment %s", actions[0], name)
|
// })
|
||||||
}
|
// scaler := DeploymentScaler{&testclient.FakeExperimental{fake}}
|
||||||
}
|
// preconditions := ScalePrecondition{2, ""}
|
||||||
|
// count := uint(3)
|
||||||
|
// name := "foo"
|
||||||
|
// scaler.Scale("default", name, count, &preconditions, nil, nil)
|
||||||
|
|
||||||
|
// actions := fake.Actions()
|
||||||
|
// if len(actions) != 1 {
|
||||||
|
// t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions)
|
||||||
|
// }
|
||||||
|
// if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "deployments" || action.GetName() != name {
|
||||||
|
// t.Errorf("unexpected action: %v, expected get-deployment %s", actions[0], name)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
func TestValidateDeployment(t *testing.T) {
|
func TestValidateDeployment(t *testing.T) {
|
||||||
zero, ten, twenty := 0, 10, 20
|
zero, ten, twenty := 0, 10, 20
|
||||||
|
@ -624,7 +624,8 @@ func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage {
|
|||||||
deploymentStorage := deploymentetcd.NewStorage(dbClient("deployments"), storageDecorator)
|
deploymentStorage := deploymentetcd.NewStorage(dbClient("deployments"), storageDecorator)
|
||||||
storage["deployments"] = deploymentStorage.Deployment
|
storage["deployments"] = deploymentStorage.Deployment
|
||||||
storage["deployments/status"] = deploymentStorage.Status
|
storage["deployments/status"] = deploymentStorage.Status
|
||||||
storage["deployments/scale"] = deploymentStorage.Scale
|
// TODO(madhusudancs): Install scale when Scale group issues are fixed (see issue #18528).
|
||||||
|
// storage["deployments/scale"] = deploymentStorage.Scale
|
||||||
storage["deployments/rollback"] = deploymentStorage.Rollback
|
storage["deployments/rollback"] = deploymentStorage.Rollback
|
||||||
}
|
}
|
||||||
if isEnabled("jobs") {
|
if isEnabled("jobs") {
|
||||||
|
@ -183,43 +183,53 @@ type ScaleREST struct {
|
|||||||
registry *deployment.Registry
|
registry *deployment.Registry
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScaleREST implements Patcher
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
var _ = rest.Patcher(&ScaleREST{})
|
|
||||||
|
|
||||||
// New creates a new Scale object
|
// // ScaleREST implements Patcher
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
// var _ = rest.Patcher(&ScaleREST{})
|
||||||
return &extensions.Scale{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ScaleREST) Get(ctx api.Context, name string) (runtime.Object, error) {
|
// // New creates a new Scale object
|
||||||
deployment, err := (*r.registry).GetDeployment(ctx, name)
|
// func (r *ScaleREST) New() runtime.Object {
|
||||||
if err != nil {
|
// return &extensions.Scale{}
|
||||||
return nil, errors.NewNotFound(extensions.Resource("deployments/scale"), name)
|
// }
|
||||||
}
|
|
||||||
return extensions.ScaleFromDeployment(deployment), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
|
// func (r *ScaleREST) Get(ctx api.Context, name string) (runtime.Object, error) {
|
||||||
if obj == nil {
|
// deployment, err := (*r.registry).GetDeployment(ctx, name)
|
||||||
return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale"))
|
// if err != nil {
|
||||||
}
|
// return nil, errors.NewNotFound(extensions.Resource("deployments/scale"), name)
|
||||||
scale, ok := obj.(*extensions.Scale)
|
// }
|
||||||
if !ok {
|
// scale, err := extensions.ScaleFromDeployment(deployment)
|
||||||
return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj))
|
// if err != nil {
|
||||||
}
|
// return nil, errors.NewBadRequest(fmt.Sprintf("%v", err))
|
||||||
|
// }
|
||||||
|
// return scale, nil
|
||||||
|
// }
|
||||||
|
|
||||||
if errs := extvalidation.ValidateScale(scale); len(errs) > 0 {
|
// func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
|
||||||
return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs)
|
// if obj == nil {
|
||||||
}
|
// return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale"))
|
||||||
|
// }
|
||||||
|
// scale, ok := obj.(*extensions.Scale)
|
||||||
|
// if !ok {
|
||||||
|
// return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj))
|
||||||
|
// }
|
||||||
|
|
||||||
deployment, err := (*r.registry).GetDeployment(ctx, scale.Name)
|
// if errs := extvalidation.ValidateScale(scale); len(errs) > 0 {
|
||||||
if err != nil {
|
// return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs)
|
||||||
return nil, false, errors.NewNotFound(extensions.Resource("deployments/scale"), scale.Name)
|
// }
|
||||||
}
|
|
||||||
deployment.Spec.Replicas = scale.Spec.Replicas
|
// deployment, err := (*r.registry).GetDeployment(ctx, scale.Name)
|
||||||
deployment, err = (*r.registry).UpdateDeployment(ctx, deployment)
|
// if err != nil {
|
||||||
if err != nil {
|
// return nil, false, errors.NewNotFound(extensions.Resource("deployments/scale"), scale.Name)
|
||||||
return nil, false, errors.NewConflict(extensions.Resource("deployments/scale"), scale.Name, err)
|
// }
|
||||||
}
|
// deployment.Spec.Replicas = scale.Spec.Replicas
|
||||||
return extensions.ScaleFromDeployment(deployment), false, nil
|
// deployment, err = (*r.registry).UpdateDeployment(ctx, deployment)
|
||||||
}
|
// if err != nil {
|
||||||
|
// return nil, false, errors.NewConflict(extensions.Resource("deployments/scale"), scale.Name, err)
|
||||||
|
// }
|
||||||
|
// newScale, err := extensions.ScaleFromDeployment(deployment)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, false, errors.NewBadRequest(fmt.Sprintf("%v", err))
|
||||||
|
// }
|
||||||
|
// return newScale, false, nil
|
||||||
|
// }
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
etcderrors "k8s.io/kubernetes/pkg/api/errors/etcd"
|
etcderrors "k8s.io/kubernetes/pkg/api/errors/etcd"
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
@ -31,7 +32,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
|
"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
|
||||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newStorage(t *testing.T) (*DeploymentStorage, *etcdtesting.EtcdTestServer) {
|
func newStorage(t *testing.T) (*DeploymentStorage, *etcdtesting.EtcdTestServer) {
|
||||||
@ -50,7 +50,7 @@ func validNewDeployment() *extensions.Deployment {
|
|||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Selector: map[string]string{"a": "b"},
|
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: map[string]string{"a": "b"},
|
Labels: map[string]string{"a": "b"},
|
||||||
@ -89,7 +89,7 @@ func TestCreate(t *testing.T) {
|
|||||||
// invalid (invalid selector)
|
// invalid (invalid selector)
|
||||||
&extensions.Deployment{
|
&extensions.Deployment{
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Selector: map[string]string{},
|
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{}},
|
||||||
Template: validDeployment.Spec.Template,
|
Template: validDeployment.Spec.Template,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -127,7 +127,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
func(obj runtime.Object) runtime.Object {
|
func(obj runtime.Object) runtime.Object {
|
||||||
object := obj.(*extensions.Deployment)
|
object := obj.(*extensions.Deployment)
|
||||||
object.Spec.Selector = map[string]string{}
|
object.Spec.Selector = &unversioned.LabelSelector{MatchLabels: map[string]string{}}
|
||||||
return object
|
return object
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -179,71 +179,73 @@ func TestWatch(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validNewScale() *extensions.Scale {
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
return &extensions.Scale{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace},
|
|
||||||
Spec: extensions.ScaleSpec{
|
|
||||||
Replicas: validDeployment.Spec.Replicas,
|
|
||||||
},
|
|
||||||
Status: extensions.ScaleStatus{
|
|
||||||
Replicas: validDeployment.Status.Replicas,
|
|
||||||
Selector: validDeployment.Spec.Template.Labels,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var validScale = *validNewScale()
|
// func validNewScale() *extensions.Scale {
|
||||||
|
// return &extensions.Scale{
|
||||||
|
// ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace},
|
||||||
|
// Spec: extensions.ScaleSpec{
|
||||||
|
// Replicas: validDeployment.Spec.Replicas,
|
||||||
|
// },
|
||||||
|
// Status: extensions.ScaleStatus{
|
||||||
|
// Replicas: validDeployment.Status.Replicas,
|
||||||
|
// Selector: validDeployment.Spec.Template.Labels,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
func TestScaleGet(t *testing.T) {
|
// var validScale = *validNewScale()
|
||||||
storage, server := newStorage(t)
|
|
||||||
defer server.Terminate(t)
|
|
||||||
|
|
||||||
ctx := api.WithNamespace(api.NewContext(), namespace)
|
// func TestScaleGet(t *testing.T) {
|
||||||
key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name)
|
// storage, server := newStorage(t)
|
||||||
if err := storage.Deployment.Storage.Set(ctx, key, &validDeployment, nil, 0); err != nil {
|
// defer server.Terminate(t)
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expect := &validScale
|
// ctx := api.WithNamespace(api.NewContext(), namespace)
|
||||||
obj, err := storage.Scale.Get(ctx, name)
|
// key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name)
|
||||||
if err != nil {
|
// if err := storage.Deployment.Storage.Set(ctx, key, &validDeployment, nil, 0); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
// t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
// }
|
||||||
scale := obj.(*extensions.Scale)
|
|
||||||
if e, a := expect, scale; !api.Semantic.DeepDerivative(e, a) {
|
|
||||||
t.Errorf("unexpected scale: %s", util.ObjectDiff(e, a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestScaleUpdate(t *testing.T) {
|
// expect := &validScale
|
||||||
storage, server := newStorage(t)
|
// obj, err := storage.Scale.Get(ctx, name)
|
||||||
defer server.Terminate(t)
|
// if err != nil {
|
||||||
|
// t.Fatalf("unexpected error: %v", err)
|
||||||
|
// }
|
||||||
|
// scale := obj.(*extensions.Scale)
|
||||||
|
// if e, a := expect, scale; !api.Semantic.DeepDerivative(e, a) {
|
||||||
|
// t.Errorf("unexpected scale: %s", util.ObjectDiff(e, a))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
ctx := api.WithNamespace(api.NewContext(), namespace)
|
// func TestScaleUpdate(t *testing.T) {
|
||||||
key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name)
|
// storage, server := newStorage(t)
|
||||||
if err := storage.Deployment.Storage.Set(ctx, key, &validDeployment, nil, 0); err != nil {
|
// defer server.Terminate(t)
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
replicas := 12
|
|
||||||
update := extensions.Scale{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace},
|
|
||||||
Spec: extensions.ScaleSpec{
|
|
||||||
Replicas: replicas,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err := storage.Scale.Update(ctx, &update); err != nil {
|
// ctx := api.WithNamespace(api.NewContext(), namespace)
|
||||||
t.Fatalf("unexpected error: %v", err)
|
// key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name)
|
||||||
}
|
// if err := storage.Deployment.Storage.Set(ctx, key, &validDeployment, nil, 0); err != nil {
|
||||||
obj, err := storage.Deployment.Get(ctx, name)
|
// t.Fatalf("unexpected error: %v", err)
|
||||||
if err != nil {
|
// }
|
||||||
t.Fatalf("unexpected error: %v", err)
|
// replicas := 12
|
||||||
}
|
// update := extensions.Scale{
|
||||||
deployment := obj.(*extensions.Deployment)
|
// ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace},
|
||||||
if deployment.Spec.Replicas != replicas {
|
// Spec: extensions.ScaleSpec{
|
||||||
t.Errorf("wrong replicas count expected: %d got: %d", replicas, deployment.Spec.Replicas)
|
// Replicas: replicas,
|
||||||
}
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// if _, _, err := storage.Scale.Update(ctx, &update); err != nil {
|
||||||
|
// t.Fatalf("unexpected error: %v", err)
|
||||||
|
// }
|
||||||
|
// obj, err := storage.Deployment.Get(ctx, name)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatalf("unexpected error: %v", err)
|
||||||
|
// }
|
||||||
|
// deployment := obj.(*extensions.Deployment)
|
||||||
|
// if deployment.Spec.Replicas != replicas {
|
||||||
|
// t.Errorf("wrong replicas count expected: %d got: %d", replicas, deployment.Spec.Replicas)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
func TestStatusUpdate(t *testing.T) {
|
func TestStatusUpdate(t *testing.T) {
|
||||||
storage, server := newStorage(t)
|
storage, server := newStorage(t)
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
@ -30,7 +31,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// The revision annotation of a deployment's replication controllers which records its rollout sequence
|
// The revision annotation of a deployment's replica sets which records its rollout sequence
|
||||||
RevisionAnnotation = "deployment.kubernetes.io/revision"
|
RevisionAnnotation = "deployment.kubernetes.io/revision"
|
||||||
|
|
||||||
// Here are the possible rollback event reasons
|
// Here are the possible rollback event reasons
|
||||||
@ -39,112 +40,124 @@ const (
|
|||||||
RollbackDone = "DeploymentRollback"
|
RollbackDone = "DeploymentRollback"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetOldRCs returns the old RCs targeted by the given Deployment; get PodList and RCList from client interface.
|
// GetOldReplicaSets returns the old replica sets targeted by the given Deployment; get PodList and ReplicaSetList from client interface.
|
||||||
// Note that the first set of old RCs doesn't include the ones with no pods, and the second set of old RCs include all old RCs.
|
// Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets.
|
||||||
func GetOldRCs(deployment extensions.Deployment, c clientset.Interface) ([]*api.ReplicationController, []*api.ReplicationController, error) {
|
func GetOldReplicaSets(deployment extensions.Deployment, c clientset.Interface) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) {
|
||||||
return GetOldRCsFromLists(deployment, c,
|
return GetOldReplicaSetsFromLists(deployment, c,
|
||||||
func(namespace string, options api.ListOptions) (*api.PodList, error) {
|
func(namespace string, options api.ListOptions) (*api.PodList, error) {
|
||||||
return c.Core().Pods(namespace).List(options)
|
return c.Core().Pods(namespace).List(options)
|
||||||
},
|
},
|
||||||
func(namespace string, options api.ListOptions) ([]api.ReplicationController, error) {
|
func(namespace string, options api.ListOptions) ([]extensions.ReplicaSet, error) {
|
||||||
rcList, err := c.Core().ReplicationControllers(namespace).List(options)
|
rsList, err := c.Extensions().ReplicaSets(namespace).List(options)
|
||||||
return rcList.Items, err
|
return rsList.Items, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOldRCsFromLists returns two sets of old RCs targeted by the given Deployment; get PodList and RCList with input functions.
|
// GetOldReplicaSetsFromLists returns two sets of old replica sets targeted by the given Deployment; get PodList and ReplicaSetList with input functions.
|
||||||
// Note that the first set of old RCs doesn't include the ones with no pods, and the second set of old RCs include all old RCs.
|
// Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets.
|
||||||
func GetOldRCsFromLists(deployment extensions.Deployment, c clientset.Interface, getPodList func(string, api.ListOptions) (*api.PodList, error), getRcList func(string, api.ListOptions) ([]api.ReplicationController, error)) ([]*api.ReplicationController, []*api.ReplicationController, error) {
|
func GetOldReplicaSetsFromLists(deployment extensions.Deployment, c clientset.Interface, getPodList func(string, api.ListOptions) (*api.PodList, error), getRSList func(string, api.ListOptions) ([]extensions.ReplicaSet, error)) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) {
|
||||||
namespace := deployment.ObjectMeta.Namespace
|
namespace := deployment.ObjectMeta.Namespace
|
||||||
|
selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to convert LabelSelector to Selector: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Find all pods whose labels match deployment.Spec.Selector
|
// 1. Find all pods whose labels match deployment.Spec.Selector
|
||||||
selector := labels.SelectorFromSet(deployment.Spec.Selector)
|
|
||||||
options := api.ListOptions{LabelSelector: selector}
|
options := api.ListOptions{LabelSelector: selector}
|
||||||
podList, err := getPodList(namespace, options)
|
podList, err := getPodList(namespace, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error listing pods: %v", err)
|
return nil, nil, fmt.Errorf("error listing pods: %v", err)
|
||||||
}
|
}
|
||||||
// 2. Find the corresponding RCs for pods in podList.
|
// 2. Find the corresponding replica sets for pods in podList.
|
||||||
// TODO: Right now we list all RCs and then filter. We should add an API for this.
|
// TODO: Right now we list all replica sets and then filter. We should add an API for this.
|
||||||
oldRCs := map[string]api.ReplicationController{}
|
oldRSs := map[string]extensions.ReplicaSet{}
|
||||||
allOldRCs := map[string]api.ReplicationController{}
|
allOldRSs := map[string]extensions.ReplicaSet{}
|
||||||
rcList, err := getRcList(namespace, options)
|
rsList, err := getRSList(namespace, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error listing replication controllers: %v", err)
|
return nil, nil, fmt.Errorf("error listing replica sets: %v", err)
|
||||||
}
|
}
|
||||||
newRCTemplate := GetNewRCTemplate(deployment)
|
newRSTemplate := GetNewReplicaSetTemplate(deployment)
|
||||||
for _, pod := range podList.Items {
|
for _, pod := range podList.Items {
|
||||||
podLabelsSelector := labels.Set(pod.ObjectMeta.Labels)
|
podLabelsSelector := labels.Set(pod.ObjectMeta.Labels)
|
||||||
for _, rc := range rcList {
|
for _, rs := range rsList {
|
||||||
rcLabelsSelector := labels.SelectorFromSet(rc.Spec.Selector)
|
rsLabelsSelector, err := unversioned.LabelSelectorAsSelector(rs.Spec.Selector)
|
||||||
// Filter out RC that has the same pod template spec as the deployment - that is the new RC.
|
if err != nil {
|
||||||
if api.Semantic.DeepEqual(rc.Spec.Template, &newRCTemplate) {
|
return nil, nil, fmt.Errorf("failed to convert LabelSelector to Selector: %v", err)
|
||||||
|
}
|
||||||
|
// Filter out replica set that has the same pod template spec as the deployment - that is the new replica set.
|
||||||
|
if api.Semantic.DeepEqual(rs.Spec.Template, &newRSTemplate) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
allOldRCs[rc.ObjectMeta.Name] = rc
|
allOldRSs[rs.ObjectMeta.Name] = rs
|
||||||
if rcLabelsSelector.Matches(podLabelsSelector) {
|
if rsLabelsSelector.Matches(podLabelsSelector) {
|
||||||
oldRCs[rc.ObjectMeta.Name] = rc
|
oldRSs[rs.ObjectMeta.Name] = rs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requiredRCs := []*api.ReplicationController{}
|
requiredRSs := []*extensions.ReplicaSet{}
|
||||||
for key := range oldRCs {
|
for key := range oldRSs {
|
||||||
value := oldRCs[key]
|
value := oldRSs[key]
|
||||||
requiredRCs = append(requiredRCs, &value)
|
requiredRSs = append(requiredRSs, &value)
|
||||||
}
|
}
|
||||||
allRCs := []*api.ReplicationController{}
|
allRSs := []*extensions.ReplicaSet{}
|
||||||
for key := range allOldRCs {
|
for key := range allOldRSs {
|
||||||
value := allOldRCs[key]
|
value := allOldRSs[key]
|
||||||
allRCs = append(allRCs, &value)
|
allRSs = append(allRSs, &value)
|
||||||
}
|
}
|
||||||
return requiredRCs, allRCs, nil
|
return requiredRSs, allRSs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNewRC returns an RC that matches the intent of the given deployment; get RCList from client interface.
|
// GetNewReplicaSet returns a replica set that matches the intent of the given deployment; get ReplicaSetList from client interface.
|
||||||
// Returns nil if the new RC doesnt exist yet.
|
// Returns nil if the new replica set doesnt exist yet.
|
||||||
func GetNewRC(deployment extensions.Deployment, c clientset.Interface) (*api.ReplicationController, error) {
|
func GetNewReplicaSet(deployment extensions.Deployment, c clientset.Interface) (*extensions.ReplicaSet, error) {
|
||||||
return GetNewRCFromList(deployment, c,
|
return GetNewReplicaSetFromList(deployment, c,
|
||||||
func(namespace string, options api.ListOptions) ([]api.ReplicationController, error) {
|
func(namespace string, options api.ListOptions) ([]extensions.ReplicaSet, error) {
|
||||||
rcList, err := c.Core().ReplicationControllers(namespace).List(options)
|
rsList, err := c.Extensions().ReplicaSets(namespace).List(options)
|
||||||
return rcList.Items, err
|
return rsList.Items, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNewRCFromList returns an RC that matches the intent of the given deployment; get RCList with the input function.
|
// GetNewReplicaSetFromList returns a replica set that matches the intent of the given deployment; get ReplicaSetList with the input function.
|
||||||
// Returns nil if the new RC doesnt exist yet.
|
// Returns nil if the new replica set doesnt exist yet.
|
||||||
func GetNewRCFromList(deployment extensions.Deployment, c clientset.Interface, getRcList func(string, api.ListOptions) ([]api.ReplicationController, error)) (*api.ReplicationController, error) {
|
func GetNewReplicaSetFromList(deployment extensions.Deployment, c clientset.Interface, getRSList func(string, api.ListOptions) ([]extensions.ReplicaSet, error)) (*extensions.ReplicaSet, error) {
|
||||||
namespace := deployment.ObjectMeta.Namespace
|
namespace := deployment.ObjectMeta.Namespace
|
||||||
rcList, err := getRcList(namespace, api.ListOptions{LabelSelector: labels.SelectorFromSet(deployment.Spec.Selector)})
|
selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error listing replication controllers: %v", err)
|
return nil, fmt.Errorf("failed to convert LabelSelector to Selector: %v", err)
|
||||||
}
|
}
|
||||||
newRCTemplate := GetNewRCTemplate(deployment)
|
|
||||||
|
|
||||||
for i := range rcList {
|
rsList, err := getRSList(namespace, api.ListOptions{LabelSelector: selector})
|
||||||
if api.Semantic.DeepEqual(rcList[i].Spec.Template, &newRCTemplate) {
|
if err != nil {
|
||||||
// This is the new RC.
|
return nil, fmt.Errorf("error listing ReplicaSets: %v", err)
|
||||||
return &rcList[i], nil
|
}
|
||||||
|
newRSTemplate := GetNewReplicaSetTemplate(deployment)
|
||||||
|
|
||||||
|
for i := range rsList {
|
||||||
|
if api.Semantic.DeepEqual(rsList[i].Spec.Template, &newRSTemplate) {
|
||||||
|
// This is the new ReplicaSet.
|
||||||
|
return &rsList[i], nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// new RC does not exist.
|
// new ReplicaSet does not exist.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the desired PodTemplateSpec for the new RC corresponding to the given RC.
|
// Returns the desired PodTemplateSpec for the new ReplicaSet corresponding to the given ReplicaSet.
|
||||||
func GetNewRCTemplate(deployment extensions.Deployment) api.PodTemplateSpec {
|
func GetNewReplicaSetTemplate(deployment extensions.Deployment) api.PodTemplateSpec {
|
||||||
// newRC will have the same template as in deployment spec, plus a unique label in some cases.
|
// newRS will have the same template as in deployment spec, plus a unique label in some cases.
|
||||||
newRCTemplate := api.PodTemplateSpec{
|
newRSTemplate := api.PodTemplateSpec{
|
||||||
ObjectMeta: deployment.Spec.Template.ObjectMeta,
|
ObjectMeta: deployment.Spec.Template.ObjectMeta,
|
||||||
Spec: deployment.Spec.Template.Spec,
|
Spec: deployment.Spec.Template.Spec,
|
||||||
}
|
}
|
||||||
newRCTemplate.ObjectMeta.Labels = labelsutil.CloneAndAddLabel(
|
newRSTemplate.ObjectMeta.Labels = labelsutil.CloneAndAddLabel(
|
||||||
deployment.Spec.Template.ObjectMeta.Labels,
|
deployment.Spec.Template.ObjectMeta.Labels,
|
||||||
extensions.DefaultDeploymentUniqueLabelKey,
|
extensions.DefaultDeploymentUniqueLabelKey,
|
||||||
podutil.GetPodTemplateSpecHash(newRCTemplate))
|
podutil.GetPodTemplateSpecHash(newRSTemplate))
|
||||||
return newRCTemplate
|
return newRSTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTemplate sets the desired PodTemplateSpec from an RC template to the given deployment.
|
// SetFromReplicaSetTemplate sets the desired PodTemplateSpec from a replica set template to the given deployment.
|
||||||
func SetFromRCTemplate(deployment *extensions.Deployment, template api.PodTemplateSpec) *extensions.Deployment {
|
func SetFromReplicaSetTemplate(deployment *extensions.Deployment, template api.PodTemplateSpec) *extensions.Deployment {
|
||||||
deployment.Spec.Template.ObjectMeta = template.ObjectMeta
|
deployment.Spec.Template.ObjectMeta = template.ObjectMeta
|
||||||
deployment.Spec.Template.Spec = template.Spec
|
deployment.Spec.Template.Spec = template.Spec
|
||||||
deployment.Spec.Template.ObjectMeta.Labels = labelsutil.CloneAndRemoveLabel(
|
deployment.Spec.Template.ObjectMeta.Labels = labelsutil.CloneAndRemoveLabel(
|
||||||
@ -153,18 +166,18 @@ func SetFromRCTemplate(deployment *extensions.Deployment, template api.PodTempla
|
|||||||
return deployment
|
return deployment
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the sum of Replicas of the given replication controllers.
|
// Returns the sum of Replicas of the given replica sets.
|
||||||
func GetReplicaCountForRCs(replicationControllers []*api.ReplicationController) int {
|
func GetReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int {
|
||||||
totalReplicaCount := 0
|
totalReplicaCount := 0
|
||||||
for _, rc := range replicationControllers {
|
for _, rs := range replicaSets {
|
||||||
totalReplicaCount += rc.Spec.Replicas
|
totalReplicaCount += rs.Spec.Replicas
|
||||||
}
|
}
|
||||||
return totalReplicaCount
|
return totalReplicaCount
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of available pods corresponding to the given RCs.
|
// Returns the number of available pods corresponding to the given replica sets.
|
||||||
func GetAvailablePodsForRCs(c clientset.Interface, rcs []*api.ReplicationController, minReadySeconds int) (int, error) {
|
func GetAvailablePodsForReplicaSets(c clientset.Interface, rss []*extensions.ReplicaSet, minReadySeconds int) (int, error) {
|
||||||
allPods, err := getPodsForRCs(c, rcs)
|
allPods, err := getPodsForReplicaSets(c, rss)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -195,12 +208,15 @@ func getReadyPodsCount(pods []api.Pod, minReadySeconds int) int {
|
|||||||
return readyPodCount
|
return readyPodCount
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPodsForRCs(c clientset.Interface, replicationControllers []*api.ReplicationController) ([]api.Pod, error) {
|
func getPodsForReplicaSets(c clientset.Interface, replicaSets []*extensions.ReplicaSet) ([]api.Pod, error) {
|
||||||
allPods := []api.Pod{}
|
allPods := []api.Pod{}
|
||||||
for _, rc := range replicationControllers {
|
for _, rs := range replicaSets {
|
||||||
selector := labels.SelectorFromSet(rc.Spec.Selector)
|
selector, err := unversioned.LabelSelectorAsSelector(rs.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert LabelSelector to Selector: %v", err)
|
||||||
|
}
|
||||||
options := api.ListOptions{LabelSelector: selector}
|
options := api.ListOptions{LabelSelector: selector}
|
||||||
podList, err := c.Core().Pods(rc.ObjectMeta.Namespace).List(options)
|
podList, err := c.Core().Pods(rs.ObjectMeta.Namespace).List(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return allPods, fmt.Errorf("error listing pods: %v", err)
|
return allPods, fmt.Errorf("error listing pods: %v", err)
|
||||||
}
|
}
|
||||||
@ -209,9 +225,9 @@ func getPodsForRCs(c clientset.Interface, replicationControllers []*api.Replicat
|
|||||||
return allPods, nil
|
return allPods, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revision returns the revision number of the input RC
|
// Revision returns the revision number of the input replica set
|
||||||
func Revision(rc *api.ReplicationController) (int64, error) {
|
func Revision(rs *extensions.ReplicaSet) (int64, error) {
|
||||||
v, ok := rc.Annotations[RevisionAnnotation]
|
v, ok := rs.Annotations[RevisionAnnotation]
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ func TestGetReadyPodsCount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generatePodFromRC creates a pod, with the input rc's selector and its template
|
// generatePodFromRS creates a pod, with the input ReplicaSet's selector and its template
|
||||||
func generatePodFromRC(rc api.ReplicationController) api.Pod {
|
func generatePodFromRS(rs extensions.ReplicaSet) api.Pod {
|
||||||
return api.Pod{
|
return api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: rc.Spec.Selector,
|
Labels: rs.Labels,
|
||||||
},
|
},
|
||||||
Spec: rc.Spec.Template.Spec,
|
Spec: rs.Spec.Template.Spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,15 +110,15 @@ func generatePod(labels map[string]string, image string) api.Pod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateRCWithLabel(labels map[string]string, image string) api.ReplicationController {
|
func generateRSWithLabel(labels map[string]string, image string) extensions.ReplicaSet {
|
||||||
return api.ReplicationController{
|
return extensions.ReplicaSet{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: api.SimpleNameGenerator.GenerateName("rc"),
|
Name: api.SimpleNameGenerator.GenerateName("replicaset"),
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: extensions.ReplicaSetSpec{
|
||||||
Replicas: 1,
|
Replicas: 1,
|
||||||
Selector: labels,
|
Selector: &unversioned.LabelSelector{MatchLabels: labels},
|
||||||
Template: &api.PodTemplateSpec{
|
Template: &api.PodTemplateSpec{
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
@ -135,17 +135,17 @@ func generateRCWithLabel(labels map[string]string, image string) api.Replication
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateRC creates a replication controller, with the input deployment's template as its template
|
// generateRS creates a replica set, with the input deployment's template as its template
|
||||||
func generateRC(deployment extensions.Deployment) api.ReplicationController {
|
func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
|
||||||
template := GetNewRCTemplate(deployment)
|
template := GetNewReplicaSetTemplate(deployment)
|
||||||
return api.ReplicationController{
|
return extensions.ReplicaSet{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: api.SimpleNameGenerator.GenerateName("rc"),
|
Name: api.SimpleNameGenerator.GenerateName("replicaset"),
|
||||||
Labels: template.Labels,
|
Labels: template.Labels,
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: extensions.ReplicaSetSpec{
|
||||||
Template: &template,
|
Template: &template,
|
||||||
Selector: template.Labels,
|
Selector: &unversioned.LabelSelector{MatchLabels: template.Labels},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ func generateDeployment(image string) extensions.Deployment {
|
|||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Replicas: 1,
|
Replicas: 1,
|
||||||
Selector: podLabels,
|
Selector: &unversioned.LabelSelector{MatchLabels: podLabels},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: podLabels,
|
Labels: podLabels,
|
||||||
@ -186,32 +186,32 @@ func generateDeployment(image string) extensions.Deployment {
|
|||||||
|
|
||||||
func TestGetNewRC(t *testing.T) {
|
func TestGetNewRC(t *testing.T) {
|
||||||
newDeployment := generateDeployment("nginx")
|
newDeployment := generateDeployment("nginx")
|
||||||
newRC := generateRC(newDeployment)
|
newRC := generateRS(newDeployment)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
test string
|
test string
|
||||||
rcList api.ReplicationControllerList
|
rsList extensions.ReplicaSetList
|
||||||
expected *api.ReplicationController
|
expected *extensions.ReplicaSet
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"No new RC",
|
"No new ReplicaSet",
|
||||||
api.ReplicationControllerList{
|
extensions.ReplicaSetList{
|
||||||
Items: []api.ReplicationController{
|
Items: []extensions.ReplicaSet{
|
||||||
generateRC(generateDeployment("foo")),
|
generateRS(generateDeployment("foo")),
|
||||||
generateRC(generateDeployment("bar")),
|
generateRS(generateDeployment("bar")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Has new RC",
|
"Has new ReplicaSet",
|
||||||
api.ReplicationControllerList{
|
extensions.ReplicaSetList{
|
||||||
Items: []api.ReplicationController{
|
Items: []extensions.ReplicaSet{
|
||||||
generateRC(generateDeployment("foo")),
|
generateRS(generateDeployment("foo")),
|
||||||
generateRC(generateDeployment("bar")),
|
generateRS(generateDeployment("bar")),
|
||||||
generateRC(generateDeployment("abc")),
|
generateRS(generateDeployment("abc")),
|
||||||
newRC,
|
newRC,
|
||||||
generateRC(generateDeployment("xyz")),
|
generateRS(generateDeployment("xyz")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&newRC,
|
&newRC,
|
||||||
@ -223,69 +223,69 @@ func TestGetNewRC(t *testing.T) {
|
|||||||
c := &simple.Client{
|
c := &simple.Client{
|
||||||
Request: simple.Request{
|
Request: simple.Request{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Path: testapi.Default.ResourcePath("replicationControllers", ns, ""),
|
Path: testapi.Default.ResourcePath("replicaSets", ns, ""),
|
||||||
},
|
},
|
||||||
Response: simple.Response{
|
Response: simple.Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: &test.rcList,
|
Body: &test.rsList,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
rc, err := GetNewRC(newDeployment, c.Setup(t).Clientset)
|
rs, err := GetNewReplicaSet(newDeployment, c.Setup(t).Clientset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("In test case %s, got unexpected error %v", test.test, err)
|
t.Errorf("In test case %s, got unexpected error %v", test.test, err)
|
||||||
}
|
}
|
||||||
if !api.Semantic.DeepEqual(rc, test.expected) {
|
if !api.Semantic.DeepEqual(rs, test.expected) {
|
||||||
t.Errorf("In test case %s, expected %+v, got %+v", test.test, test.expected, rc)
|
t.Errorf("In test case %s, expected %+v, got %+v", test.test, test.expected, rs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetOldRCs(t *testing.T) {
|
func TestGetOldRCs(t *testing.T) {
|
||||||
newDeployment := generateDeployment("nginx")
|
newDeployment := generateDeployment("nginx")
|
||||||
newRC := generateRC(newDeployment)
|
newRS := generateRS(newDeployment)
|
||||||
newPod := generatePodFromRC(newRC)
|
newPod := generatePodFromRS(newRS)
|
||||||
|
|
||||||
// create 2 old deployments and related rcs/pods, with the same labels but different template
|
// create 2 old deployments and related replica sets/pods, with the same labels but different template
|
||||||
oldDeployment := generateDeployment("nginx")
|
oldDeployment := generateDeployment("nginx")
|
||||||
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
||||||
oldRC := generateRC(oldDeployment)
|
oldRS := generateRS(oldDeployment)
|
||||||
oldPod := generatePodFromRC(oldRC)
|
oldPod := generatePodFromRS(oldRS)
|
||||||
oldDeployment2 := generateDeployment("nginx")
|
oldDeployment2 := generateDeployment("nginx")
|
||||||
oldDeployment2.Spec.Template.Spec.Containers[0].Name = "nginx-old-2"
|
oldDeployment2.Spec.Template.Spec.Containers[0].Name = "nginx-old-2"
|
||||||
oldRC2 := generateRC(oldDeployment2)
|
oldRS2 := generateRS(oldDeployment2)
|
||||||
oldPod2 := generatePodFromRC(oldRC2)
|
oldPod2 := generatePodFromRS(oldRS2)
|
||||||
|
|
||||||
// create 1 rc that existed before the deployment, with the same labels as the deployment
|
// create 1 ReplicaSet that existed before the deployment, with the same labels as the deployment
|
||||||
existedPod := generatePod(newDeployment.Spec.Selector, "foo")
|
existedPod := generatePod(newDeployment.Spec.Template.Labels, "foo")
|
||||||
existedRC := generateRCWithLabel(newDeployment.Spec.Selector, "foo")
|
existedRS := generateRSWithLabel(newDeployment.Spec.Template.Labels, "foo")
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
test string
|
test string
|
||||||
objs []runtime.Object
|
objs []runtime.Object
|
||||||
expected []*api.ReplicationController
|
expected []*extensions.ReplicaSet
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"No old RCs",
|
"No old ReplicaSets",
|
||||||
[]runtime.Object{
|
[]runtime.Object{
|
||||||
&api.PodList{
|
&api.PodList{
|
||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
generatePod(newDeployment.Spec.Selector, "foo"),
|
generatePod(newDeployment.Spec.Template.Labels, "foo"),
|
||||||
generatePod(newDeployment.Spec.Selector, "bar"),
|
generatePod(newDeployment.Spec.Template.Labels, "bar"),
|
||||||
newPod,
|
newPod,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&api.ReplicationControllerList{
|
&extensions.ReplicaSetList{
|
||||||
Items: []api.ReplicationController{
|
Items: []extensions.ReplicaSet{
|
||||||
generateRC(generateDeployment("foo")),
|
generateRS(generateDeployment("foo")),
|
||||||
newRC,
|
newRS,
|
||||||
generateRC(generateDeployment("bar")),
|
generateRS(generateDeployment("bar")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[]*api.ReplicationController{},
|
[]*extensions.ReplicaSet{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Has old RC",
|
"Has old ReplicaSet",
|
||||||
[]runtime.Object{
|
[]runtime.Object{
|
||||||
&api.PodList{
|
&api.PodList{
|
||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
@ -294,51 +294,51 @@ func TestGetOldRCs(t *testing.T) {
|
|||||||
generatePod(map[string]string{"name": "bar"}, "bar"),
|
generatePod(map[string]string{"name": "bar"}, "bar"),
|
||||||
generatePod(map[string]string{"name": "xyz"}, "xyz"),
|
generatePod(map[string]string{"name": "xyz"}, "xyz"),
|
||||||
existedPod,
|
existedPod,
|
||||||
generatePod(newDeployment.Spec.Selector, "abc"),
|
generatePod(newDeployment.Spec.Template.Labels, "abc"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&api.ReplicationControllerList{
|
&extensions.ReplicaSetList{
|
||||||
Items: []api.ReplicationController{
|
Items: []extensions.ReplicaSet{
|
||||||
oldRC2,
|
oldRS2,
|
||||||
oldRC,
|
oldRS,
|
||||||
existedRC,
|
existedRS,
|
||||||
newRC,
|
newRS,
|
||||||
generateRCWithLabel(map[string]string{"name": "xyz"}, "xyz"),
|
generateRSWithLabel(map[string]string{"name": "xyz"}, "xyz"),
|
||||||
generateRCWithLabel(map[string]string{"name": "bar"}, "bar"),
|
generateRSWithLabel(map[string]string{"name": "bar"}, "bar"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[]*api.ReplicationController{&oldRC, &oldRC2, &existedRC},
|
[]*extensions.ReplicaSet{&oldRS, &oldRS2, &existedRS},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
rcs, _, err := GetOldRCs(newDeployment, fake.NewSimpleClientset(test.objs...))
|
rss, _, err := GetOldReplicaSets(newDeployment, fake.NewSimpleClientset(test.objs...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("In test case %s, got unexpected error %v", test.test, err)
|
t.Errorf("In test case %s, got unexpected error %v", test.test, err)
|
||||||
}
|
}
|
||||||
if !equal(rcs, test.expected) {
|
if !equal(rss, test.expected) {
|
||||||
t.Errorf("In test case %q, expected %v, got %v", test.test, test.expected, rcs)
|
t.Errorf("In test case %q, expected %v, got %v", test.test, test.expected, rss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// equal compares the equality of two rc slices regardless of their ordering
|
// equal compares the equality of two ReplicaSet slices regardless of their ordering
|
||||||
func equal(rcs1, rcs2 []*api.ReplicationController) bool {
|
func equal(rss1, rss2 []*extensions.ReplicaSet) bool {
|
||||||
if reflect.DeepEqual(rcs1, rcs2) {
|
if reflect.DeepEqual(rss1, rss2) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if rcs1 == nil || rcs2 == nil || len(rcs1) != len(rcs2) {
|
if rss1 == nil || rss2 == nil || len(rss1) != len(rss2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
count := 0
|
count := 0
|
||||||
for _, rc1 := range rcs1 {
|
for _, rs1 := range rss1 {
|
||||||
for _, rc2 := range rcs2 {
|
for _, rs2 := range rss2 {
|
||||||
if reflect.DeepEqual(rc1, rc2) {
|
if reflect.DeepEqual(rs1, rs2) {
|
||||||
count++
|
count++
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count == len(rcs1)
|
return count == len(rss1)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ package labels
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Clones the given map and returns a new map with the given key and value added.
|
// Clones the given map and returns a new map with the given key and value added.
|
||||||
@ -51,3 +53,43 @@ func CloneAndRemoveLabel(labels map[string]string, labelKey string) map[string]s
|
|||||||
delete(newLabels, labelKey)
|
delete(newLabels, labelKey)
|
||||||
return newLabels
|
return newLabels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clones the given selector and returns a new selector with the given key and value added.
|
||||||
|
// Returns the given selector, if labelKey is empty.
|
||||||
|
func CloneSelectorAndAddLabel(selector *unversioned.LabelSelector, labelKey string, labelValue uint32) *unversioned.LabelSelector {
|
||||||
|
if labelKey == "" {
|
||||||
|
// Dont need to add a label.
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone.
|
||||||
|
newSelector := new(unversioned.LabelSelector)
|
||||||
|
|
||||||
|
// TODO(madhusudancs): Check if you can use deepCopy_extensions_LabelSelector here.
|
||||||
|
newSelector.MatchLabels = make(map[string]string)
|
||||||
|
if selector.MatchLabels != nil {
|
||||||
|
for key, val := range selector.MatchLabels {
|
||||||
|
newSelector.MatchLabels[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newSelector.MatchLabels[labelKey] = fmt.Sprintf("%d", labelValue)
|
||||||
|
|
||||||
|
if selector.MatchExpressions != nil {
|
||||||
|
newMExps := make([]unversioned.LabelSelectorRequirement, len(selector.MatchExpressions))
|
||||||
|
for i, me := range selector.MatchExpressions {
|
||||||
|
newMExps[i].Key = me.Key
|
||||||
|
newMExps[i].Operator = me.Operator
|
||||||
|
if me.Values != nil {
|
||||||
|
newMExps[i].Values = make([]string, len(me.Values))
|
||||||
|
copy(newMExps[i].Values, me.Values)
|
||||||
|
} else {
|
||||||
|
newMExps[i].Values = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newSelector.MatchExpressions = newMExps
|
||||||
|
} else {
|
||||||
|
newSelector.MatchExpressions = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSelector
|
||||||
|
}
|
||||||
|
@ -21,10 +21,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
|
||||||
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
|
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ var _ = Describe("Deployment [Feature:Deployment]", func() {
|
|||||||
It("RecreateDeployment should delete old pods and create new ones", func() {
|
It("RecreateDeployment should delete old pods and create new ones", func() {
|
||||||
testRecreateDeployment(f)
|
testRecreateDeployment(f)
|
||||||
})
|
})
|
||||||
It("deployment should delete old rcs", func() {
|
It("deployment should delete old replica sets", func() {
|
||||||
testDeploymentCleanUpPolicy(f)
|
testDeploymentCleanUpPolicy(f)
|
||||||
})
|
})
|
||||||
It("deployment should support rollover", func() {
|
It("deployment should support rollover", func() {
|
||||||
@ -59,22 +59,22 @@ var _ = Describe("Deployment [Feature:Deployment]", func() {
|
|||||||
It("deployment should support rollback", func() {
|
It("deployment should support rollback", func() {
|
||||||
testRollbackDeployment(f)
|
testRollbackDeployment(f)
|
||||||
})
|
})
|
||||||
It("deployment should support rollback when there's RC with no revision", func() {
|
It("deployment should support rollback when there's replica set with no revision", func() {
|
||||||
testRollbackDeploymentRCNoRevision(f)
|
testRollbackDeploymentRSNoRevision(f)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func newRC(rcName string, replicas int, rcPodLabels map[string]string, imageName string, image string) *api.ReplicationController {
|
func newRS(rsName string, replicas int, rsPodLabels map[string]string, imageName string, image string) *extensions.ReplicaSet {
|
||||||
return &api.ReplicationController{
|
return &extensions.ReplicaSet{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: rcName,
|
Name: rsName,
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: extensions.ReplicaSetSpec{
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
Selector: rcPodLabels,
|
Selector: &unversioned.LabelSelector{MatchLabels: rsPodLabels},
|
||||||
Template: &api.PodTemplateSpec{
|
Template: &api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Labels: rcPodLabels,
|
Labels: rsPodLabels,
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
@ -96,7 +96,7 @@ func newDeployment(deploymentName string, replicas int, podLabels map[string]str
|
|||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
Selector: podLabels,
|
Selector: &unversioned.LabelSelector{MatchLabels: podLabels},
|
||||||
Strategy: extensions.DeploymentStrategy{
|
Strategy: extensions.DeploymentStrategy{
|
||||||
Type: strategyType,
|
Type: strategyType,
|
||||||
},
|
},
|
||||||
@ -126,27 +126,27 @@ func newDeploymentRollback(name string, annotations map[string]string, revision
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkDeploymentRevision checks if the input deployment's and its new RC's revision and images are as expected.
|
// checkDeploymentRevision checks if the input deployment's and its new replica set's revision and images are as expected.
|
||||||
func checkDeploymentRevision(c *clientset.Clientset, ns, deploymentName, revision, imageName, image string) (*extensions.Deployment, *api.ReplicationController) {
|
func checkDeploymentRevision(c *clientset.Clientset, ns, deploymentName, revision, imageName, image string) (*extensions.Deployment, *extensions.ReplicaSet) {
|
||||||
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
// Check revision of the new RC of this deployment
|
// Check revision of the new replica set of this deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(newRC.Annotations).NotTo(Equal(nil))
|
Expect(newRS.Annotations).NotTo(Equal(nil))
|
||||||
Expect(newRC.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(revision))
|
Expect(newRS.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(revision))
|
||||||
// Check revision of This deployment
|
// Check revision of This deployment
|
||||||
Expect(deployment.Annotations).NotTo(Equal(nil))
|
Expect(deployment.Annotations).NotTo(Equal(nil))
|
||||||
Expect(deployment.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(revision))
|
Expect(deployment.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(revision))
|
||||||
if len(imageName) > 0 {
|
if len(imageName) > 0 {
|
||||||
// Check the image the new RC creates
|
// Check the image the new replica set creates
|
||||||
Expect(newRC.Spec.Template.Spec.Containers[0].Name).Should(Equal(imageName))
|
Expect(newRS.Spec.Template.Spec.Containers[0].Name).Should(Equal(imageName))
|
||||||
Expect(newRC.Spec.Template.Spec.Containers[0].Image).Should(Equal(image))
|
Expect(newRS.Spec.Template.Spec.Containers[0].Image).Should(Equal(image))
|
||||||
// Check the image the deployment creates
|
// Check the image the deployment creates
|
||||||
Expect(deployment.Spec.Template.Spec.Containers[0].Name).Should(Equal(imageName))
|
Expect(deployment.Spec.Template.Spec.Containers[0].Name).Should(Equal(imageName))
|
||||||
Expect(deployment.Spec.Template.Spec.Containers[0].Image).Should(Equal(image))
|
Expect(deployment.Spec.Template.Spec.Containers[0].Image).Should(Equal(image))
|
||||||
}
|
}
|
||||||
return deployment, newRC
|
return deployment, newRS
|
||||||
}
|
}
|
||||||
|
|
||||||
func testNewDeployment(f *Framework) {
|
func testNewDeployment(f *Framework) {
|
||||||
@ -161,7 +161,7 @@ func testNewDeployment(f *Framework) {
|
|||||||
replicas := 1
|
replicas := 1
|
||||||
Logf("Creating simple deployment %s", deploymentName)
|
Logf("Creating simple deployment %s", deploymentName)
|
||||||
d := newDeployment(deploymentName, replicas, podLabels, "nginx", "nginx", extensions.RollingUpdateDeploymentStrategyType, nil)
|
d := newDeployment(deploymentName, replicas, podLabels, "nginx", "nginx", extensions.RollingUpdateDeploymentStrategyType, nil)
|
||||||
d.Annotations = map[string]string{"test": "should-copy-to-RC", kubectl.LastAppliedConfigAnnotation: "should-not-copy-to-RC"}
|
d.Annotations = map[string]string{"test": "should-copy-to-replica-set", kubectl.LastAppliedConfigAnnotation: "should-not-copy-to-replica-set"}
|
||||||
_, err := c.Extensions().Deployments(ns).Create(d)
|
_, err := c.Extensions().Deployments(ns).Create(d)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -169,10 +169,10 @@ func testNewDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Check that deployment is created fine.
|
// Check that deployment is created fine.
|
||||||
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
||||||
@ -191,12 +191,12 @@ func testNewDeployment(f *Framework) {
|
|||||||
Expect(deployment.Status.UpdatedReplicas).Should(Equal(replicas))
|
Expect(deployment.Status.UpdatedReplicas).Should(Equal(replicas))
|
||||||
|
|
||||||
// Check if it's updated to revision 1 correctly
|
// Check if it's updated to revision 1 correctly
|
||||||
_, newRC := checkDeploymentRevision(c, ns, deploymentName, "1", "nginx", "nginx")
|
_, newRS := checkDeploymentRevision(c, ns, deploymentName, "1", "nginx", "nginx")
|
||||||
// Check other annotations
|
// Check other annotations
|
||||||
Expect(newRC.Annotations["test"]).Should(Equal("should-copy-to-RC"))
|
Expect(newRS.Annotations["test"]).Should(Equal("should-copy-to-replica-set"))
|
||||||
Expect(newRC.Annotations[kubectl.LastAppliedConfigAnnotation]).Should(Equal(""))
|
Expect(newRS.Annotations[kubectl.LastAppliedConfigAnnotation]).Should(Equal(""))
|
||||||
Expect(deployment.Annotations["test"]).Should(Equal("should-copy-to-RC"))
|
Expect(deployment.Annotations["test"]).Should(Equal("should-copy-to-replica-set"))
|
||||||
Expect(deployment.Annotations[kubectl.LastAppliedConfigAnnotation]).Should(Equal("should-not-copy-to-RC"))
|
Expect(deployment.Annotations[kubectl.LastAppliedConfigAnnotation]).Should(Equal("should-not-copy-to-replica-set"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRollingUpdateDeployment(f *Framework) {
|
func testRollingUpdateDeployment(f *Framework) {
|
||||||
@ -207,18 +207,18 @@ func testRollingUpdateDeployment(f *Framework) {
|
|||||||
c := clientset.FromUnversionedClient(unversionedClient)
|
c := clientset.FromUnversionedClient(unversionedClient)
|
||||||
// Create nginx pods.
|
// Create nginx pods.
|
||||||
deploymentPodLabels := map[string]string{"name": "sample-pod"}
|
deploymentPodLabels := map[string]string{"name": "sample-pod"}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": "sample-pod",
|
"name": "sample-pod",
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
|
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
replicas := 3
|
replicas := 3
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(newRC(rcName, replicas, rcPodLabels, "nginx", "nginx"))
|
_, err := c.Extensions().ReplicaSets(ns).Create(newRS(rsName, replicas, rsPodLabels, "nginx", "nginx"))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
Logf("deleting replication controller %s", rcName)
|
Logf("deleting replica set %s", rsName)
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(rcName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(rsName, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Verify that the required pods have come up.
|
// Verify that the required pods have come up.
|
||||||
err = verifyPods(unversionedClient, ns, "sample-pod", false, 3)
|
err = verifyPods(unversionedClient, ns, "sample-pod", false, 3)
|
||||||
@ -237,10 +237,10 @@ func testRollingUpdateDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, replicas-1, replicas+1, 0)
|
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, replicas-1, replicas+1, 0)
|
||||||
@ -258,24 +258,24 @@ func testRollingUpdateDeploymentEvents(f *Framework) {
|
|||||||
c := clientset.FromUnversionedClient(unversionedClient)
|
c := clientset.FromUnversionedClient(unversionedClient)
|
||||||
// Create nginx pods.
|
// Create nginx pods.
|
||||||
deploymentPodLabels := map[string]string{"name": "sample-pod-2"}
|
deploymentPodLabels := map[string]string{"name": "sample-pod-2"}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": "sample-pod-2",
|
"name": "sample-pod-2",
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
replicas := 1
|
replicas := 1
|
||||||
|
|
||||||
rcRevision := "3546343826724305832"
|
rsRevision := "3546343826724305832"
|
||||||
annotations := make(map[string]string)
|
annotations := make(map[string]string)
|
||||||
annotations[deploymentutil.RevisionAnnotation] = rcRevision
|
annotations[deploymentutil.RevisionAnnotation] = rsRevision
|
||||||
rc := newRC(rcName, replicas, rcPodLabels, "nginx", "nginx")
|
rs := newRS(rsName, replicas, rsPodLabels, "nginx", "nginx")
|
||||||
rc.Annotations = annotations
|
rs.Annotations = annotations
|
||||||
|
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(rc)
|
_, err := c.Extensions().ReplicaSets(ns).Create(rs)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
Logf("deleting replication controller %s", rcName)
|
Logf("deleting replica set %s", rsName)
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(rcName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(rsName, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Verify that the required pods have come up.
|
// Verify that the required pods have come up.
|
||||||
err = verifyPods(unversionedClient, ns, "sample-pod-2", false, 1)
|
err = verifyPods(unversionedClient, ns, "sample-pod-2", false, 1)
|
||||||
@ -294,10 +294,10 @@ func testRollingUpdateDeploymentEvents(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, replicas-1, replicas+1, 0)
|
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, replicas-1, replicas+1, 0)
|
||||||
@ -311,13 +311,14 @@ func testRollingUpdateDeploymentEvents(f *Framework) {
|
|||||||
Logf("error in listing events: %s", err)
|
Logf("error in listing events: %s", err)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
// There should be 2 events, one to scale up the new RC and then to scale down the old RC.
|
// There should be 2 events, one to scale up the new ReplicaSet and then to scale down
|
||||||
|
// the old ReplicaSet.
|
||||||
Expect(len(events.Items)).Should(Equal(2))
|
Expect(len(events.Items)).Should(Equal(2))
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(newRC).NotTo(Equal(nil))
|
Expect(newRS).NotTo(Equal(nil))
|
||||||
Expect(events.Items[0].Message).Should(Equal(fmt.Sprintf("Scaled up rc %s to 1", newRC.Name)))
|
Expect(events.Items[0].Message).Should(Equal(fmt.Sprintf("Scaled up replica set %s to 1", newRS.Name)))
|
||||||
Expect(events.Items[1].Message).Should(Equal(fmt.Sprintf("Scaled down rc %s to 0", rcName)))
|
Expect(events.Items[1].Message).Should(Equal(fmt.Sprintf("Scaled down replica set %s to 0", rsName)))
|
||||||
|
|
||||||
// Check if it's updated to revision 3546343826724305833 correctly
|
// Check if it's updated to revision 3546343826724305833 correctly
|
||||||
checkDeploymentRevision(c, ns, deploymentName, "3546343826724305833", "redis", "redis")
|
checkDeploymentRevision(c, ns, deploymentName, "3546343826724305833", "redis", "redis")
|
||||||
@ -331,18 +332,18 @@ func testRecreateDeployment(f *Framework) {
|
|||||||
c := clientset.FromUnversionedClient(unversionedClient)
|
c := clientset.FromUnversionedClient(unversionedClient)
|
||||||
// Create nginx pods.
|
// Create nginx pods.
|
||||||
deploymentPodLabels := map[string]string{"name": "sample-pod-3"}
|
deploymentPodLabels := map[string]string{"name": "sample-pod-3"}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": "sample-pod-3",
|
"name": "sample-pod-3",
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
|
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
replicas := 3
|
replicas := 3
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(newRC(rcName, replicas, rcPodLabels, "nginx", "nginx"))
|
_, err := c.Extensions().ReplicaSets(ns).Create(newRS(rsName, replicas, rsPodLabels, "nginx", "nginx"))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
Logf("deleting replication controller %s", rcName)
|
Logf("deleting replica set %s", rsName)
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(rcName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(rsName, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Verify that the required pods have come up.
|
// Verify that the required pods have come up.
|
||||||
err = verifyPods(unversionedClient, ns, "sample-pod-3", false, 3)
|
err = verifyPods(unversionedClient, ns, "sample-pod-3", false, 3)
|
||||||
@ -361,10 +362,10 @@ func testRecreateDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, 0, replicas, 0)
|
err = waitForDeploymentStatus(c, ns, deploymentName, replicas, 0, replicas, 0)
|
||||||
@ -383,13 +384,13 @@ func testRecreateDeployment(f *Framework) {
|
|||||||
Logf("error in listing events: %s", err)
|
Logf("error in listing events: %s", err)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
// There should be 2 events, one to scale up the new RC and then to scale down the old RC.
|
// There should be 2 events, one to scale up the new ReplicaSet and then to scale down the old ReplicaSet.
|
||||||
Expect(len(events.Items)).Should(Equal(2))
|
Expect(len(events.Items)).Should(Equal(2))
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(newRC).NotTo(Equal(nil))
|
Expect(newRS).NotTo(Equal(nil))
|
||||||
Expect(events.Items[0].Message).Should(Equal(fmt.Sprintf("Scaled down rc %s to 0", rcName)))
|
Expect(events.Items[0].Message).Should(Equal(fmt.Sprintf("Scaled down replica set %s to 0", rsName)))
|
||||||
Expect(events.Items[1].Message).Should(Equal(fmt.Sprintf("Scaled up rc %s to 3", newRC.Name)))
|
Expect(events.Items[1].Message).Should(Equal(fmt.Sprintf("Scaled up replica set %s to 3", newRS.Name)))
|
||||||
|
|
||||||
// Check if it's updated to revision 1 correctly
|
// Check if it's updated to revision 1 correctly
|
||||||
checkDeploymentRevision(c, ns, deploymentName, "1", "redis", "redis")
|
checkDeploymentRevision(c, ns, deploymentName, "1", "redis", "redis")
|
||||||
@ -402,15 +403,15 @@ func testDeploymentCleanUpPolicy(f *Framework) {
|
|||||||
c := clientset.FromUnversionedClient(unversionedClient)
|
c := clientset.FromUnversionedClient(unversionedClient)
|
||||||
// Create nginx pods.
|
// Create nginx pods.
|
||||||
deploymentPodLabels := map[string]string{"name": "cleanup-pod"}
|
deploymentPodLabels := map[string]string{"name": "cleanup-pod"}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": "cleanup-pod",
|
"name": "cleanup-pod",
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
replicas := 1
|
replicas := 1
|
||||||
revisionHistoryLimit := new(int)
|
revisionHistoryLimit := new(int)
|
||||||
*revisionHistoryLimit = 0
|
*revisionHistoryLimit = 0
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(newRC(rcName, replicas, rcPodLabels, "nginx", "nginx"))
|
_, err := c.Extensions().ReplicaSets(ns).Create(newRS(rsName, replicas, rsPodLabels, "nginx", "nginx"))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Verify that the required pods have come up.
|
// Verify that the required pods have come up.
|
||||||
@ -430,13 +431,13 @@ func testDeploymentCleanUpPolicy(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = waitForDeploymentOldRCsNum(c, ns, deploymentName, *revisionHistoryLimit)
|
err = waitForDeploymentOldRSsNum(c, ns, deploymentName, *revisionHistoryLimit)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,21 +451,21 @@ func testRolloverDeployment(f *Framework) {
|
|||||||
c := clientset.FromUnversionedClient(unversionedClient)
|
c := clientset.FromUnversionedClient(unversionedClient)
|
||||||
podName := "rollover-pod"
|
podName := "rollover-pod"
|
||||||
deploymentPodLabels := map[string]string{"name": podName}
|
deploymentPodLabels := map[string]string{"name": podName}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": podName,
|
"name": podName,
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
|
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
rcReplicas := 4
|
rsReplicas := 4
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(newRC(rcName, rcReplicas, rcPodLabels, "nginx", "nginx"))
|
_, err := c.Extensions().ReplicaSets(ns).Create(newRS(rsName, rsReplicas, rsPodLabels, "nginx", "nginx"))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
Logf("deleting replication controller %s", rcName)
|
Logf("deleting replica set %s", rsName)
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(rcName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(rsName, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Verify that the required pods have come up.
|
// Verify that the required pods have come up.
|
||||||
err = verifyPods(unversionedClient, ns, podName, false, rcReplicas)
|
err = verifyPods(unversionedClient, ns, podName, false, rsReplicas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logf("error in waiting for pods to come up: %s", err)
|
Logf("error in waiting for pods to come up: %s", err)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
@ -490,22 +491,22 @@ func testRolloverDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
// Verify that the pods were scaled up and down as expected. We use events to verify that.
|
// Verify that the pods were scaled up and down as expected. We use events to verify that.
|
||||||
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
// Make sure the deployment starts to scale up and down RCs
|
// Make sure the deployment starts to scale up and down replica sets
|
||||||
waitForPartialEvents(unversionedClient, ns, deployment, 2)
|
waitForPartialEvents(unversionedClient, ns, deployment, 2)
|
||||||
// Check if it's updated to revision 1 correctly
|
// Check if it's updated to revision 1 correctly
|
||||||
_, newRC := checkDeploymentRevision(c, ns, deploymentName, "1", deploymentImageName, deploymentImage)
|
_, newRS := checkDeploymentRevision(c, ns, deploymentName, "1", deploymentImageName, deploymentImage)
|
||||||
|
|
||||||
// Before the deployment finishes, update the deployment to rollover the above 2 rcs and bring up redis pods.
|
// Before the deployment finishes, update the deployment to rollover the above 2 ReplicaSets and bring up redis pods.
|
||||||
// If the deployment already finished here, the test would fail. When this happens, increase its minReadySeconds or replicas to prevent it.
|
// If the deployment already finished here, the test would fail. When this happens, increase its minReadySeconds or replicas to prevent it.
|
||||||
Expect(newRC.Spec.Replicas).Should(BeNumerically("<", deploymentReplicas))
|
Expect(newRS.Spec.Replicas).Should(BeNumerically("<", deploymentReplicas))
|
||||||
updatedDeploymentImage := "redis"
|
updatedDeploymentImage := "redis"
|
||||||
newDeployment.Spec.Template.Spec.Containers[0].Name = updatedDeploymentImage
|
newDeployment.Spec.Template.Spec.Containers[0].Name = updatedDeploymentImage
|
||||||
newDeployment.Spec.Template.Spec.Containers[0].Image = updatedDeploymentImage
|
newDeployment.Spec.Template.Spec.Containers[0].Image = updatedDeploymentImage
|
||||||
@ -544,10 +545,10 @@ func testPausedDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Verify that there is no latest state realized for the new deployment.
|
// Verify that there is no latest state realized for the new deployment.
|
||||||
rc, err := deploymentutil.GetNewRC(*deployment, c)
|
rs, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
if rc != nil {
|
if rs != nil {
|
||||||
err = fmt.Errorf("unexpected new rc/%s for deployment/%s", rc.Name, deployment.Name)
|
err = fmt.Errorf("unexpected new rs/%s for deployment/%s", rs.Name, deployment.Name)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,28 +557,32 @@ func testPausedDeployment(f *Framework) {
|
|||||||
deployment, err = c.Extensions().Deployments(ns).Update(deployment)
|
deployment, err = c.Extensions().Deployments(ns).Update(deployment)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
opts := api.ListOptions{LabelSelector: labels.Set(deployment.Spec.Selector).AsSelector()}
|
selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
w, err := c.Core().ReplicationControllers(ns).Watch(opts)
|
if err != nil {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
opts := api.ListOptions{LabelSelector: selector}
|
||||||
|
w, err := c.Extensions().ReplicaSets(ns).Watch(opts)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-w.ResultChan():
|
case <-w.ResultChan():
|
||||||
// this is it
|
// this is it
|
||||||
case <-time.After(time.Minute):
|
case <-time.After(time.Minute):
|
||||||
err = fmt.Errorf("expected a new rc to be created")
|
err = fmt.Errorf("expected a new replica set to be created")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause the deployment and delete the replication controller.
|
// Pause the deployment and delete the replica set.
|
||||||
// The paused deployment shouldn't recreate a new one.
|
// The paused deployment shouldn't recreate a new one.
|
||||||
deployment.Spec.Paused = true
|
deployment.Spec.Paused = true
|
||||||
deployment.ResourceVersion = ""
|
deployment.ResourceVersion = ""
|
||||||
deployment, err = c.Extensions().Deployments(ns).Update(deployment)
|
deployment, err = c.Extensions().Deployments(ns).Update(deployment)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
|
|
||||||
deployment, err = c.Extensions().Deployments(ns).Get(deploymentName)
|
deployment, err = c.Extensions().Deployments(ns).Get(deploymentName)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
@ -586,10 +591,10 @@ func testPausedDeployment(f *Framework) {
|
|||||||
err = fmt.Errorf("deployment %q should be paused", deployment.Name)
|
err = fmt.Errorf("deployment %q should be paused", deployment.Name)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
shouldBeNil, err := deploymentutil.GetNewRC(*deployment, c)
|
shouldBeNil, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
if shouldBeNil != nil {
|
if shouldBeNil != nil {
|
||||||
err = fmt.Errorf("deployment %q shouldn't have a rc but there is %q", deployment.Name, shouldBeNil.Name)
|
err = fmt.Errorf("deployment %q shouldn't have a replica set but there is %q", deployment.Name, shouldBeNil.Name)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,14 +623,14 @@ func testRollbackDeployment(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
oldRCs, _, err := deploymentutil.GetOldRCs(*deployment, c)
|
oldRSs, _, err := deploymentutil.GetOldReplicaSets(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
for _, oldRC := range oldRCs {
|
for _, oldRS := range oldRSs {
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(oldRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(oldRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Check that deployment is created fine.
|
// Check that deployment is created fine.
|
||||||
@ -689,36 +694,36 @@ func testRollbackDeployment(f *Framework) {
|
|||||||
checkDeploymentRevision(c, ns, deploymentName, "4", updatedDeploymentImageName, updatedDeploymentImage)
|
checkDeploymentRevision(c, ns, deploymentName, "4", updatedDeploymentImageName, updatedDeploymentImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// testRollbackDeploymentRCNoRevision tests that deployment supports rollback even when there's old RC without revision.
|
// testRollbackDeploymentRSNoRevision tests that deployment supports rollback even when there's old replica set without revision.
|
||||||
// An old RC without revision is created, and then a deployment is created (v1). The deployment shouldn't add revision
|
// An old replica set without revision is created, and then a deployment is created (v1). The deployment shouldn't add revision
|
||||||
// annotation to the old RC. Then rollback the deployment to last revision, and it should fail and emit related event.
|
// annotation to the old replica set. Then rollback the deployment to last revision, and it should fail and emit related event.
|
||||||
// Then update the deployment to v2 and rollback it to v1 should succeed and emit related event, now the deployment
|
// Then update the deployment to v2 and rollback it to v1 should succeed and emit related event, now the deployment
|
||||||
// becomes v3. Then rollback the deployment to v10 (doesn't exist in history) should fail and emit related event.
|
// becomes v3. Then rollback the deployment to v10 (doesn't exist in history) should fail and emit related event.
|
||||||
// Finally, rollback the deployment (v3) to v3 should be no-op and emit related event.
|
// Finally, rollback the deployment (v3) to v3 should be no-op and emit related event.
|
||||||
func testRollbackDeploymentRCNoRevision(f *Framework) {
|
func testRollbackDeploymentRSNoRevision(f *Framework) {
|
||||||
ns := f.Namespace.Name
|
ns := f.Namespace.Name
|
||||||
unversionedClient := f.Client
|
unversionedClient := f.Client
|
||||||
c := clientset.FromUnversionedClient(f.Client)
|
c := clientset.FromUnversionedClient(f.Client)
|
||||||
podName := "nginx"
|
podName := "nginx"
|
||||||
deploymentPodLabels := map[string]string{"name": podName}
|
deploymentPodLabels := map[string]string{"name": podName}
|
||||||
rcPodLabels := map[string]string{
|
rsPodLabels := map[string]string{
|
||||||
"name": podName,
|
"name": podName,
|
||||||
"pod": "nginx",
|
"pod": "nginx",
|
||||||
}
|
}
|
||||||
|
|
||||||
rcName := "nginx-controller"
|
rsName := "nginx-controller"
|
||||||
rcReplicas := 0
|
rsReplicas := 0
|
||||||
rc := newRC(rcName, rcReplicas, rcPodLabels, "nginx", "nginx")
|
rs := newRS(rsName, rsReplicas, rsPodLabels, "nginx", "nginx")
|
||||||
rc.Annotations = make(map[string]string)
|
rs.Annotations = make(map[string]string)
|
||||||
rc.Annotations["make"] = "difference"
|
rs.Annotations["make"] = "difference"
|
||||||
_, err := c.Core().ReplicationControllers(ns).Create(rc)
|
_, err := c.Extensions().ReplicaSets(ns).Create(rs)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() {
|
defer func() {
|
||||||
Logf("deleting replication controller %s", rcName)
|
Logf("deleting replica set %s", rsName)
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(rcName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(rsName, nil)).NotTo(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Create a deployment to create nginx pods, which have different template than the rc created above.
|
// Create a deployment to create nginx pods, which have different template than the replica set created above.
|
||||||
deploymentName, deploymentImageName := "nginx-deployment", "nginx"
|
deploymentName, deploymentImageName := "nginx-deployment", "nginx"
|
||||||
deploymentReplicas := 1
|
deploymentReplicas := 1
|
||||||
deploymentImage := "nginx"
|
deploymentImage := "nginx"
|
||||||
@ -732,14 +737,14 @@ func testRollbackDeploymentRCNoRevision(f *Framework) {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Logf("deleting deployment %s", deploymentName)
|
Logf("deleting deployment %s", deploymentName)
|
||||||
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred())
|
||||||
// TODO: remove this once we can delete rcs with deployment
|
// TODO: remove this once we can delete replica sets with deployment
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(newRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(newRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
oldRCs, _, err := deploymentutil.GetOldRCs(*deployment, c)
|
oldRSs, _, err := deploymentutil.GetOldReplicaSets(*deployment, c)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
for _, oldRC := range oldRCs {
|
for _, oldRS := range oldRSs {
|
||||||
Expect(c.Core().ReplicationControllers(ns).Delete(oldRC.Name, nil)).NotTo(HaveOccurred())
|
Expect(c.Extensions().ReplicaSets(ns).Delete(oldRS.Name, nil)).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Check that deployment is created fine.
|
// Check that deployment is created fine.
|
||||||
@ -761,9 +766,9 @@ func testRollbackDeploymentRCNoRevision(f *Framework) {
|
|||||||
// Check if it's updated to revision 1 correctly
|
// Check if it's updated to revision 1 correctly
|
||||||
checkDeploymentRevision(c, ns, deploymentName, "1", deploymentImageName, deploymentImage)
|
checkDeploymentRevision(c, ns, deploymentName, "1", deploymentImageName, deploymentImage)
|
||||||
|
|
||||||
// Check that the rc we created still doesn't contain revision information
|
// Check that the replica set we created still doesn't contain revision information
|
||||||
rc, err = c.Core().ReplicationControllers(ns).Get(rcName)
|
rs, err = c.Extensions().ReplicaSets(ns).Get(rsName)
|
||||||
Expect(rc.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(""))
|
Expect(rs.Annotations[deploymentutil.RevisionAnnotation]).Should(Equal(""))
|
||||||
|
|
||||||
// Update the deploymentRollback to rollback to last revision
|
// Update the deploymentRollback to rollback to last revision
|
||||||
// Since there's only 1 revision in history, it should stay as revision 1
|
// Since there's only 1 revision in history, it should stay as revision 1
|
||||||
|
@ -41,15 +41,16 @@ var _ = Describe("Horizontal pod autoscaling (scale resource: CPU) [Serial] [Slo
|
|||||||
titleUp := "Should scale from 1 pod to 3 pods and from 3 to 5"
|
titleUp := "Should scale from 1 pod to 3 pods and from 3 to 5"
|
||||||
titleDown := "Should scale from 5 pods to 3 pods and from 3 to 1"
|
titleDown := "Should scale from 5 pods to 3 pods and from 3 to 1"
|
||||||
|
|
||||||
Describe("Deployment [Feature:Deployment]", func() {
|
// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528).
|
||||||
// CPU tests via deployments
|
// Describe("Deployment [Feature:Deployment]", func() {
|
||||||
It(titleUp, func() {
|
// // CPU tests via deployments
|
||||||
scaleUp("deployment", kindDeployment, rc, f)
|
// It(titleUp, func() {
|
||||||
})
|
// scaleUp("deployment", kindDeployment, rc, f)
|
||||||
It(titleDown, func() {
|
// })
|
||||||
scaleDown("deployment", kindDeployment, rc, f)
|
// It(titleDown, func() {
|
||||||
})
|
// scaleDown("deployment", kindDeployment, rc, f)
|
||||||
})
|
// })
|
||||||
|
// })
|
||||||
|
|
||||||
Describe("ReplicationController", func() {
|
Describe("ReplicationController", func() {
|
||||||
// CPU tests via replication controllers
|
// CPU tests via replication controllers
|
||||||
|
@ -457,7 +457,7 @@ var _ = Describe("Kubectl client", func() {
|
|||||||
withStdinData("abcd1234\n").
|
withStdinData("abcd1234\n").
|
||||||
execOrDie()
|
execOrDie()
|
||||||
Expect(runOutput).ToNot(ContainSubstring("stdin closed"))
|
Expect(runOutput).ToNot(ContainSubstring("stdin closed"))
|
||||||
runTestPod, err := util.GetFirstPod(c, ns, map[string]string{"run": "run-test-3"})
|
runTestPod, err := util.GetFirstPod(c, ns, labels.SelectorFromSet(map[string]string{"run": "run-test-3"}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -1529,8 +1529,10 @@ func (config *DeploymentConfig) create() error {
|
|||||||
},
|
},
|
||||||
Spec: extensions.DeploymentSpec{
|
Spec: extensions.DeploymentSpec{
|
||||||
Replicas: config.Replicas,
|
Replicas: config.Replicas,
|
||||||
Selector: map[string]string{
|
Selector: &unversioned.LabelSelector{
|
||||||
"name": config.Name,
|
MatchLabels: map[string]string{
|
||||||
|
"name": config.Name,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Template: api.PodTemplateSpec{
|
Template: api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
@ -2064,43 +2066,43 @@ func waitForDeploymentStatus(c clientset.Interface, ns, deploymentName string, d
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
oldRCs, _, err := deploymentutil.GetOldRCs(*deployment, c)
|
oldRSs, _, err := deploymentutil.GetOldReplicaSets(*deployment, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
newRC, err := deploymentutil.GetNewRC(*deployment, c)
|
newRS, err := deploymentutil.GetNewReplicaSet(*deployment, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if newRC == nil {
|
if newRS == nil {
|
||||||
// New RC hasnt been created yet.
|
// New RC hasnt been created yet.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
allRCs := append(oldRCs, newRC)
|
allRSs := append(oldRSs, newRS)
|
||||||
totalCreated := deploymentutil.GetReplicaCountForRCs(allRCs)
|
totalCreated := deploymentutil.GetReplicaCountForReplicaSets(allRSs)
|
||||||
totalAvailable, err := deploymentutil.GetAvailablePodsForRCs(c, allRCs, minReadySeconds)
|
totalAvailable, err := deploymentutil.GetAvailablePodsForReplicaSets(c, allRSs, minReadySeconds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if totalCreated > maxCreated {
|
if totalCreated > maxCreated {
|
||||||
logRCsOfDeployment(deploymentName, oldRCs, newRC)
|
logReplicaSetsOfDeployment(deploymentName, oldRSs, newRS)
|
||||||
return false, fmt.Errorf("total pods created: %d, more than the max allowed: %d", totalCreated, maxCreated)
|
return false, fmt.Errorf("total pods created: %d, more than the max allowed: %d", totalCreated, maxCreated)
|
||||||
}
|
}
|
||||||
if totalAvailable < minAvailable {
|
if totalAvailable < minAvailable {
|
||||||
logRCsOfDeployment(deploymentName, oldRCs, newRC)
|
logReplicaSetsOfDeployment(deploymentName, oldRSs, newRS)
|
||||||
return false, fmt.Errorf("total pods available: %d, less than the min required: %d", totalAvailable, minAvailable)
|
return false, fmt.Errorf("total pods available: %d, less than the min required: %d", totalAvailable, minAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
if deployment.Status.Replicas == desiredUpdatedReplicas &&
|
if deployment.Status.Replicas == desiredUpdatedReplicas &&
|
||||||
deployment.Status.UpdatedReplicas == desiredUpdatedReplicas {
|
deployment.Status.UpdatedReplicas == desiredUpdatedReplicas {
|
||||||
// Verify RCs.
|
// Verify replica sets.
|
||||||
if deploymentutil.GetReplicaCountForRCs(oldRCs) != 0 {
|
if deploymentutil.GetReplicaCountForReplicaSets(oldRSs) != 0 {
|
||||||
logRCsOfDeployment(deploymentName, oldRCs, newRC)
|
logReplicaSetsOfDeployment(deploymentName, oldRSs, newRS)
|
||||||
return false, fmt.Errorf("old RCs are not fully scaled down")
|
return false, fmt.Errorf("old replica sets are not fully scaled down")
|
||||||
}
|
}
|
||||||
if deploymentutil.GetReplicaCountForRCs([]*api.ReplicationController{newRC}) != desiredUpdatedReplicas {
|
if deploymentutil.GetReplicaCountForReplicaSets([]*extensions.ReplicaSet{newRS}) != desiredUpdatedReplicas {
|
||||||
logRCsOfDeployment(deploymentName, oldRCs, newRC)
|
logReplicaSetsOfDeployment(deploymentName, oldRSs, newRS)
|
||||||
return false, fmt.Errorf("new RC is not fully scaled up")
|
return false, fmt.Errorf("new replica sets is not fully scaled up")
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@ -2109,26 +2111,25 @@ func waitForDeploymentStatus(c clientset.Interface, ns, deploymentName string, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Waits for the deployment to clean up old rcs.
|
// Waits for the deployment to clean up old rcs.
|
||||||
func waitForDeploymentOldRCsNum(c *clientset.Clientset, ns, deploymentName string, desiredRCNum int) error {
|
func waitForDeploymentOldRSsNum(c *clientset.Clientset, ns, deploymentName string, desiredRSNum int) error {
|
||||||
return wait.Poll(poll, 5*time.Minute, func() (bool, error) {
|
return wait.Poll(poll, 5*time.Minute, func() (bool, error) {
|
||||||
|
|
||||||
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
deployment, err := c.Extensions().Deployments(ns).Get(deploymentName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
oldRCs, _, err := deploymentutil.GetOldRCs(*deployment, c)
|
oldRSs, _, err := deploymentutil.GetOldReplicaSets(*deployment, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return len(oldRCs) == desiredRCNum, nil
|
return len(oldRSs) == desiredRSNum, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func logRCsOfDeployment(deploymentName string, oldRCs []*api.ReplicationController, newRC *api.ReplicationController) {
|
func logReplicaSetsOfDeployment(deploymentName string, oldRSs []*extensions.ReplicaSet, newRS *extensions.ReplicaSet) {
|
||||||
for i := range oldRCs {
|
for i := range oldRSs {
|
||||||
Logf("Old RCs (%d/%d) of deployment %s: %+v", i+1, len(oldRCs), deploymentName, oldRCs[i])
|
Logf("Old ReplicaSets (%d/%d) of deployment %s: %+v", i+1, len(oldRSs), deploymentName, oldRSs[i])
|
||||||
}
|
}
|
||||||
Logf("New RC of deployment %s: %+v", deploymentName, newRC)
|
Logf("New ReplicaSet of deployment %s: %+v", deploymentName, newRS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Waits for the number of events on the given object to reach a desired count.
|
// Waits for the number of events on the given object to reach a desired count.
|
||||||
|
Loading…
Reference in New Issue
Block a user