Skip to content

Commit

Permalink
Merge pull request kubernetes#22 from tossmilestone/deploy-progress
Browse files Browse the repository at this point in the history
Deploy progress
  • Loading branch information
tossmilestone authored Aug 18, 2018
2 parents bb8b3c9 + 09cc3df commit 440b7aa
Show file tree
Hide file tree
Showing 14 changed files with 63 additions and 28 deletions.
2 changes: 1 addition & 1 deletion api/openapi-spec/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/swagger-spec/extensions_v1beta1.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/api-reference/extensions/v1beta1/definitions.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/apis/extensions/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ type DeploymentSpec struct {
// is considered to be failed. The deployment controller will continue to
// process failed deployments and a condition with a ProgressDeadlineExceeded
// reason will be surfaced in the deployment status. Note that progress will
// not be estimated during the time a deployment is paused. This is not set
// by default.
// not be estimated during the time a deployment is paused. This is set to
// the max value of int32 (i.e. 2147483647) by default, which means "no deadline".
// +optional
ProgressDeadlineSeconds *int32
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/extensions/v1beta1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1beta1

import (
"math"

"k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -110,6 +112,12 @@ func SetDefaults_Deployment(obj *extensionsv1beta1.Deployment) {
strategy.RollingUpdate.MaxSurge = &maxSurge
}
}
// Set extensionsv1beta1.DeploymentSpec.ProgressDeadlineSeconds to MaxInt,
// which has the same meaning as unset.
if obj.Spec.ProgressDeadlineSeconds == nil {
obj.Spec.ProgressDeadlineSeconds = new(int32)
*obj.Spec.ProgressDeadlineSeconds = math.MaxInt32
}
}

func SetDefaults_ReplicaSet(obj *extensionsv1beta1.ReplicaSet) {
Expand Down
13 changes: 9 additions & 4 deletions pkg/apis/extensions/v1beta1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1_test

import (
"math"
"reflect"
"testing"

Expand Down Expand Up @@ -187,7 +188,8 @@ func TestSetDefaultDeployment(t *testing.T) {
MaxUnavailable: &defaultIntOrString,
},
},
Template: defaultTemplate,
Template: defaultTemplate,
ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32),
},
},
},
Expand All @@ -212,7 +214,8 @@ func TestSetDefaultDeployment(t *testing.T) {
MaxUnavailable: &defaultIntOrString,
},
},
Template: defaultTemplate,
Template: defaultTemplate,
ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32),
},
},
},
Expand All @@ -236,7 +239,8 @@ func TestSetDefaultDeployment(t *testing.T) {
MaxUnavailable: &defaultIntOrString,
},
},
Template: defaultTemplate,
Template: defaultTemplate,
ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32),
},
},
},
Expand All @@ -255,7 +259,8 @@ func TestSetDefaultDeployment(t *testing.T) {
Strategy: extensionsv1beta1.DeploymentStrategy{
Type: extensionsv1beta1.RecreateDeploymentStrategyType,
},
Template: defaultTemplate,
Template: defaultTemplate,
ProgressDeadlineSeconds: utilpointer.Int32Ptr(math.MaxInt32),
},
},
},
Expand Down
6 changes: 3 additions & 3 deletions pkg/controller/deployment/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (dc *DeploymentController) syncRolloutStatus(allRSs []*extensions.ReplicaSe
newStatus := calculateStatus(allRSs, newRS, d)

// If there is no progressDeadlineSeconds set, remove any Progressing condition.
if d.Spec.ProgressDeadlineSeconds == nil {
if !util.HasProgressDeadline(d) {
util.RemoveDeploymentCondition(&newStatus, extensions.DeploymentProgressing)
}

Expand All @@ -47,7 +47,7 @@ func (dc *DeploymentController) syncRolloutStatus(allRSs []*extensions.ReplicaSe
isCompleteDeployment := newStatus.Replicas == newStatus.UpdatedReplicas && currentCond != nil && currentCond.Reason == util.NewRSAvailableReason
// Check for progress only if there is a progress deadline set and the latest rollout
// hasn't completed yet.
if d.Spec.ProgressDeadlineSeconds != nil && !isCompleteDeployment {
if util.HasProgressDeadline(d) && !isCompleteDeployment {
switch {
case util.DeploymentComplete(d, &newStatus):
// Update the deployment conditions with a message for the new replica set that
Expand Down Expand Up @@ -159,7 +159,7 @@ var nowFn = func() time.Time { return time.Now() }
func (dc *DeploymentController) requeueStuckDeployment(d *extensions.Deployment, newStatus extensions.DeploymentStatus) time.Duration {
currentCond := util.GetDeploymentCondition(d.Status, extensions.DeploymentProgressing)
// Can't estimate progress if there is no deadline in the spec or progressing condition in the current status.
if d.Spec.ProgressDeadlineSeconds == nil || currentCond == nil {
if !util.HasProgressDeadline(d) || currentCond == nil {
return time.Duration(-1)
}
// No need to estimate progress if the rollout is complete or already timed out.
Expand Down
14 changes: 11 additions & 3 deletions pkg/controller/deployment/progress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package deployment

import (
"math"
"testing"
"time"

Expand Down Expand Up @@ -67,7 +68,8 @@ func newRSWithAvailable(name string, specReplicas, statusReplicas, availableRepl

func TestRequeueStuckDeployment(t *testing.T) {
pds := int32(60)
failed := []extensions.DeploymentCondition{
infinite := int32(math.MaxInt32)
failed := []apps.DeploymentCondition{
{
Type: extensions.DeploymentProgressing,
Status: v1.ConditionFalse,
Expand All @@ -90,11 +92,17 @@ func TestRequeueStuckDeployment(t *testing.T) {
expected time.Duration
}{
{
name: "no progressDeadlineSeconds specified",
name: "nil progressDeadlineSeconds specified",
d: currentDeployment(nil, 4, 3, 3, 2, nil),
status: newDeploymentStatus(3, 3, 2),
expected: time.Duration(-1),
},
{
name: "infinite progressDeadlineSeconds specified",
d: currentDeployment(&infinite, 4, 3, 3, 2, nil),
status: newDeploymentStatus(3, 3, 2),
expected: time.Duration(-1),
},
{
name: "no progressing condition found",
d: currentDeployment(&pds, 4, 3, 3, 2, nil),
Expand Down Expand Up @@ -327,7 +335,7 @@ func TestSyncRolloutStatus(t *testing.T) {
newCond := util.GetDeploymentCondition(test.d.Status, test.conditionType)
switch {
case newCond == nil:
if test.d.Spec.ProgressDeadlineSeconds != nil {
if test.d.Spec.ProgressDeadlineSeconds != nil && *test.d.Spec.ProgressDeadlineSeconds != math.MaxInt32 {
t.Errorf("%s: expected deployment condition: %s", test.name, test.conditionType)
}
case newCond.Status != test.conditionStatus || newCond.Reason != test.conditionReason:
Expand Down
8 changes: 4 additions & 4 deletions pkg/controller/deployment/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (dc *DeploymentController) sync(d *extensions.Deployment, rsList []*extensi
// These conditions are needed so that we won't accidentally report lack of progress for resumed deployments
// that were paused for longer than progressDeadlineSeconds.
func (dc *DeploymentController) checkPausedConditions(d *extensions.Deployment) error {
if d.Spec.ProgressDeadlineSeconds == nil {
if !deploymentutil.HasProgressDeadline(d) {
return nil
}
cond := deploymentutil.GetDeploymentCondition(d.Status, extensions.DeploymentProgressing)
Expand Down Expand Up @@ -260,7 +260,7 @@ func (dc *DeploymentController) getNewReplicaSet(d *extensions.Deployment, rsLis
// of this deployment then it is likely that old users started caring about progress. In that
// case we need to take into account the first time we noticed their new replica set.
cond := deploymentutil.GetDeploymentCondition(d.Status, extensions.DeploymentProgressing)
if d.Spec.ProgressDeadlineSeconds != nil && cond == nil {
if deploymentutil.HasProgressDeadline(d) && cond == nil {
msg := fmt.Sprintf("Found new replica set %q", rsCopy.Name)
condition := deploymentutil.NewDeploymentCondition(extensions.DeploymentProgressing, v1.ConditionTrue, deploymentutil.FoundNewRSReason, msg)
deploymentutil.SetDeploymentCondition(&d.Status, *condition)
Expand Down Expand Up @@ -349,7 +349,7 @@ func (dc *DeploymentController) getNewReplicaSet(d *extensions.Deployment, rsLis
err = nil
case err != nil:
msg := fmt.Sprintf("Failed to create new replica set %q: %v", newRS.Name, err)
if d.Spec.ProgressDeadlineSeconds != nil {
if deploymentutil.HasProgressDeadline(d) {
cond := deploymentutil.NewDeploymentCondition(extensions.DeploymentProgressing, v1.ConditionFalse, deploymentutil.FailedRSCreateReason, msg)
deploymentutil.SetDeploymentCondition(&d.Status, *cond)
// We don't really care about this error at this point, since we have a bigger issue to report.
Expand All @@ -365,7 +365,7 @@ func (dc *DeploymentController) getNewReplicaSet(d *extensions.Deployment, rsLis
}

needsUpdate := deploymentutil.SetDeploymentRevision(d, newRevision)
if !alreadyExists && d.Spec.ProgressDeadlineSeconds != nil {
if !alreadyExists && deploymentutil.HasProgressDeadline(d) {
msg := fmt.Sprintf("Created new replica set %q", createdRS.Name)
condition := deploymentutil.NewDeploymentCondition(extensions.DeploymentProgressing, v1.ConditionTrue, deploymentutil.NewReplicaSetReason, msg)
deploymentutil.SetDeploymentCondition(&d.Status, *condition)
Expand Down
7 changes: 6 additions & 1 deletion pkg/controller/deployment/util/deployment_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package util

import (
"fmt"
"math"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -831,7 +832,7 @@ var nowFn = func() time.Time { return time.Now() }
// is older than progressDeadlineSeconds or a Progressing condition with a TimedOutReason reason already
// exists.
func DeploymentTimedOut(deployment *extensions.Deployment, newStatus *extensions.DeploymentStatus) bool {
if deployment.Spec.ProgressDeadlineSeconds == nil {
if !HasProgressDeadline(deployment) {
return false
}

Expand Down Expand Up @@ -976,3 +977,7 @@ func ResolveFenceposts(maxSurge, maxUnavailable *intstrutil.IntOrString, desired

return int32(surge), int32(unavailable), nil
}

func HasProgressDeadline(d *apps.Deployment) bool {
return d.Spec.ProgressDeadlineSeconds != nil && *d.Spec.ProgressDeadlineSeconds != math.MaxInt32
}
15 changes: 12 additions & 3 deletions pkg/controller/deployment/util/deployment_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package util

import (
"fmt"
"math"
"math/rand"
"reflect"
"sort"
Expand Down Expand Up @@ -1056,8 +1057,9 @@ func TestDeploymentProgressing(t *testing.T) {

func TestDeploymentTimedOut(t *testing.T) {
var (
null *int32
ten = int32(10)
null *int32
ten = int32(10)
infinite = int32(math.MaxInt32)
)

timeFn := func(min, sec int) time.Time {
Expand Down Expand Up @@ -1090,12 +1092,19 @@ func TestDeploymentTimedOut(t *testing.T) {
expected bool
}{
{
name: "no progressDeadlineSeconds specified - no timeout",
name: "nil progressDeadlineSeconds specified - no timeout",

d: deployment(extensions.DeploymentProgressing, v1.ConditionTrue, "", null, timeFn(1, 9)),
nowFn: func() time.Time { return timeFn(1, 20) },
expected: false,
},
{
name: "infinite progressDeadlineSeconds specified - no timeout",

d: deployment(apps.DeploymentProgressing, v1.ConditionTrue, "", &infinite, timeFn(1, 9)),
nowFn: func() time.Time { return timeFn(1, 20) },
expected: false,
},
{
name: "progressDeadlineSeconds: 10s, now - started => 00:01:20 - 00:01:09 => 11s",

Expand Down
4 changes: 2 additions & 2 deletions staging/src/k8s.io/api/extensions/v1beta1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions staging/src/k8s.io/api/extensions/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ type DeploymentSpec struct {
// is considered to be failed. The deployment controller will continue to
// process failed deployments and a condition with a ProgressDeadlineExceeded
// reason will be surfaced in the deployment status. Note that progress will
// not be estimated during the time a deployment is paused. This is not set
// by default.
// not be estimated during the time a deployment is paused. This is set to
// the max value of int32 (i.e. 2147483647) by default, which means "no deadline".
// +optional
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,9,opt,name=progressDeadlineSeconds"`
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 440b7aa

Please sign in to comment.