Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proportionally scale paused and rolling deployments #20273

Merged
merged 3 commits into from
Jun 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1772,35 +1772,35 @@ __EOF__
# Command
# Create a deployment (revision 1)
kubectl create -f hack/testdata/deployment-revision1.yaml "${kube_flags[@]}"
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" 'nginx-deployment:'
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" 'nginx:'
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
# Rollback to revision 1 - should be no-op
kubectl rollout undo deployment nginx-deployment --to-revision=1 "${kube_flags[@]}"
kubectl rollout undo deployment nginx --to-revision=1 "${kube_flags[@]}"
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
# Update the deployment (revision 2)
kubectl apply -f hack/testdata/deployment-revision2.yaml "${kube_flags[@]}"
kube::test::get_object_assert deployment.extensions "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
# Rollback to revision 1
kubectl rollout undo deployment nginx-deployment --to-revision=1 "${kube_flags[@]}"
kubectl rollout undo deployment nginx --to-revision=1 "${kube_flags[@]}"
sleep 1
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
# Rollback to revision 1000000 - should be no-op
kubectl rollout undo deployment nginx-deployment --to-revision=1000000 "${kube_flags[@]}"
kubectl rollout undo deployment nginx --to-revision=1000000 "${kube_flags[@]}"
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
# Rollback to last revision
kubectl rollout undo deployment nginx-deployment "${kube_flags[@]}"
kubectl rollout undo deployment nginx "${kube_flags[@]}"
sleep 1
kube::test::get_object_assert deployment "{{range.items}}{{$deployment_image_field}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
# Pause the deployment
kubectl-with-retry rollout pause deployment nginx-deployment "${kube_flags[@]}"
kubectl-with-retry rollout pause deployment nginx "${kube_flags[@]}"
# A paused deployment cannot be rolled back
! kubectl rollout undo deployment nginx-deployment "${kube_flags[@]}"
! kubectl rollout undo deployment nginx "${kube_flags[@]}"
# Resume the deployment
kubectl-with-retry rollout resume deployment nginx-deployment "${kube_flags[@]}"
kubectl-with-retry rollout resume deployment nginx "${kube_flags[@]}"
# The resumed deployment can now be rolled back
kubectl rollout undo deployment nginx-deployment "${kube_flags[@]}"
kubectl rollout undo deployment nginx "${kube_flags[@]}"
# Clean up
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
kubectl delete deployment nginx "${kube_flags[@]}"

### Set image of a deployment
# Pre-condition: no deployment exists
Expand Down
8 changes: 4 additions & 4 deletions hack/testdata/deployment-revision1.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
name: nginx
labels:
name: nginx-deployment
name: nginx-undo
spec:
replicas: 3
selector:
matchLabels:
name: nginx
name: nginx-undo
template:
metadata:
labels:
name: nginx
name: nginx-undo
spec:
containers:
- name: nginx
Expand Down
8 changes: 4 additions & 4 deletions hack/testdata/deployment-revision2.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
name: nginx
labels:
name: nginx-deployment
name: nginx-undo
spec:
replicas: 3
selector:
matchLabels:
name: nginx
name: nginx-undo
template:
metadata:
labels:
name: nginx
name: nginx-undo
spec:
containers:
- name: nginx
Expand Down
9 changes: 6 additions & 3 deletions pkg/apis/extensions/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,15 @@ var ValidateDeploymentName = apivalidation.NameIsDNSSubdomain

func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if intOrPercent.Type == intstr.String {
switch intOrPercent.Type {
case intstr.String:
if !validation.IsValidPercent(intOrPercent.StrVal) {
allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, "must be an integer or percentage (e.g '5%')"))
allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, "must be an integer or percentage (e.g '5%%')"))
}
} else if intOrPercent.Type == intstr.Int {
case intstr.Int:
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(intOrPercent.IntValue()), fldPath)...)
default:
allErrs = append(allErrs, field.Invalid(fldPath, intOrPercent, "must be an integer or percentage (e.g '5%%')"))
}
return allErrs
}
Expand Down
34 changes: 30 additions & 4 deletions pkg/controller/controller_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,9 @@ func IsPodActive(p api.Pod) bool {
func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions.ReplicaSet {
active := []*extensions.ReplicaSet{}
for i := range replicaSets {
if replicaSets[i].Spec.Replicas > 0 {
rs := replicaSets[i]

if rs != nil && rs.Spec.Replicas > 0 {
active = append(active, replicaSets[i])
}
}
Expand All @@ -639,23 +641,47 @@ type ControllersByCreationTimestamp []*api.ReplicationController

func (o ControllersByCreationTimestamp) Len() int { return len(o) }
func (o ControllersByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }

func (o ControllersByCreationTimestamp) 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)
}

// ReplicaSetsByCreationTimestamp sorts a list of ReplicationSets by creation timestamp, using their names as a tie breaker.
// ReplicaSetsByCreationTimestamp sorts a list of ReplicaSet 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)
}

// ReplicaSetsBySizeOlder sorts a list of ReplicaSet by size in descending order, using their creation timestamp or name as a tie breaker.
// By using the creation timestamp, this sorts from old to new replica sets.
type ReplicaSetsBySizeOlder []*extensions.ReplicaSet

func (o ReplicaSetsBySizeOlder) Len() int { return len(o) }
func (o ReplicaSetsBySizeOlder) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ReplicaSetsBySizeOlder) Less(i, j int) bool {
if o[i].Spec.Replicas == o[j].Spec.Replicas {
return ReplicaSetsByCreationTimestamp(o).Less(i, j)
}
return o[i].Spec.Replicas > o[j].Spec.Replicas
}

// ReplicaSetsBySizeNewer sorts a list of ReplicaSet by size in descending order, using their creation timestamp or name as a tie breaker.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems correct. The only difference with ReplicaSetsBySizeOlder is in the second line of the comment.

// By using the creation timestamp, this sorts from new to old replica sets.
type ReplicaSetsBySizeNewer []*extensions.ReplicaSet

func (o ReplicaSetsBySizeNewer) Len() int { return len(o) }
func (o ReplicaSetsBySizeNewer) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ReplicaSetsBySizeNewer) Less(i, j int) bool {
if o[i].Spec.Replicas == o[j].Spec.Replicas {
return ReplicaSetsByCreationTimestamp(o).Less(j, i)
}
return o[i].Spec.Replicas > o[j].Spec.Replicas
}
Loading