Skip to content

Commit 61fd505

Browse files
authored
Merge pull request #529 from weaveworks/fix-daemonset-ready-cond
pkg/canary/daemonset: fix ready condition according to kubectl
2 parents 7821bc6 + 4242bf0 commit 61fd505

File tree

3 files changed

+67
-37
lines changed

3 files changed

+67
-37
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/aws/aws-sdk-go v1.29.29
88
github.com/davecgh/go-spew v1.1.1
99
github.com/google/go-cmp v0.4.0
10+
github.com/pkg/errors v0.9.1
1011
github.com/prometheus/client_golang v1.5.1
1112
github.com/stretchr/testify v1.5.1
1213
go.uber.org/zap v1.14.1

pkg/canary/daemonset_ready.go

+21-11
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,31 @@ func (c *DaemonSetController) IsCanaryReady(cd *flaggerv1.Canary) (bool, error)
4444
}
4545

4646
// isDaemonSetReady determines if a daemonset is ready by checking the number of old version daemons
47+
// reference: https://github.com/kubernetes/kubernetes/blob/5232ad4a00ec93942d0b2c6359ee6cd1201b46bc/pkg/kubectl/rollout_status.go#L110
4748
func (c *DaemonSetController) isDaemonSetReady(cd *flaggerv1.Canary, daemonSet *appsv1.DaemonSet) (bool, error) {
48-
if diff := daemonSet.Status.DesiredNumberScheduled - daemonSet.Status.UpdatedNumberScheduled; diff > 0 || daemonSet.Status.NumberUnavailable > 0 {
49+
if daemonSet.Generation <= daemonSet.Status.ObservedGeneration {
50+
// calculate conditions
51+
newCond := daemonSet.Status.UpdatedNumberScheduled < daemonSet.Status.DesiredNumberScheduled
52+
availableCond := daemonSet.Status.NumberAvailable < daemonSet.Status.DesiredNumberScheduled
53+
if !newCond && !availableCond {
54+
return true, nil
55+
}
56+
57+
// check if deadline exceeded
4958
from := cd.Status.LastTransitionTime
5059
delta := time.Duration(cd.GetProgressDeadlineSeconds()) * time.Second
51-
dl := from.Add(delta)
52-
if dl.Before(time.Now()) {
60+
if from.Add(delta).Before(time.Now()) {
5361
return false, fmt.Errorf("exceeded its progressDeadlineSeconds: %d", cd.GetProgressDeadlineSeconds())
54-
} else {
55-
return true, fmt.Errorf(
56-
"waiting for rollout to finish: desiredNumberScheduled=%d, updatedNumberScheduled=%d, numberUnavailable=%d",
57-
daemonSet.Status.DesiredNumberScheduled,
58-
daemonSet.Status.UpdatedNumberScheduled,
59-
daemonSet.Status.NumberUnavailable,
60-
)
62+
}
63+
64+
// retryable
65+
if newCond {
66+
return true, fmt.Errorf("waiting for rollout to finish: %d out of %d new pods have been updated",
67+
daemonSet.Status.UpdatedNumberScheduled, daemonSet.Status.DesiredNumberScheduled)
68+
} else if availableCond {
69+
return true, fmt.Errorf("waiting for rollout to finish: %d of %d updated pods are available",
70+
daemonSet.Status.NumberAvailable, daemonSet.Status.DesiredNumberScheduled)
6171
}
6272
}
63-
return true, nil
73+
return true, fmt.Errorf("waiting for rollout to finish: observed daemonset generation less then desired generation")
6474
}

pkg/canary/daemonset_ready_test.go

+45-26
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package canary
22

33
import (
4+
"strings"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -24,39 +25,57 @@ func TestDaemonSetController_IsReady(t *testing.T) {
2425
}
2526

2627
func TestDaemonSetController_isDaemonSetReady(t *testing.T) {
27-
ds := &appsv1.DaemonSet{
28-
Status: appsv1.DaemonSetStatus{
29-
DesiredNumberScheduled: 1,
30-
UpdatedNumberScheduled: 1,
31-
},
32-
}
33-
28+
mocks := newDaemonSetFixture()
3429
cd := &flaggerv1.Canary{}
35-
cd.Spec.ProgressDeadlineSeconds = int32p(1e5)
36-
cd.Status.LastTransitionTime = metav1.Now()
3730

38-
// ready
39-
mocks := newDaemonSetFixture()
40-
_, err := mocks.controller.isDaemonSetReady(cd, ds)
31+
// observed generation is less than desired generation
32+
ds := &appsv1.DaemonSet{Status: appsv1.DaemonSetStatus{}}
33+
ds.Status.ObservedGeneration--
34+
retyable, err := mocks.controller.isDaemonSetReady(cd, ds)
35+
require.Error(t, err)
36+
require.True(t, retyable)
37+
38+
// succeeded
39+
ds = &appsv1.DaemonSet{Status: appsv1.DaemonSetStatus{
40+
UpdatedNumberScheduled: 1,
41+
DesiredNumberScheduled: 1,
42+
NumberAvailable: 1,
43+
}}
44+
retyable, err = mocks.controller.isDaemonSetReady(cd, ds)
4145
require.NoError(t, err)
46+
require.True(t, retyable)
4247

43-
// not ready but retriable
44-
ds.Status.NumberUnavailable++
45-
retrieable, err := mocks.controller.isDaemonSetReady(cd, ds)
48+
// deadline exceeded
49+
ds = &appsv1.DaemonSet{Status: appsv1.DaemonSetStatus{
50+
UpdatedNumberScheduled: 0,
51+
DesiredNumberScheduled: 1,
52+
}}
53+
cd.Status.LastTransitionTime = metav1.Now()
54+
cd.Spec.ProgressDeadlineSeconds = int32p(-1e6)
55+
retyable, err = mocks.controller.isDaemonSetReady(cd, ds)
4656
require.Error(t, err)
47-
require.True(t, retrieable)
48-
ds.Status.NumberUnavailable--
57+
require.False(t, retyable)
4958

50-
ds.Status.DesiredNumberScheduled++
51-
retrieable, err = mocks.controller.isDaemonSetReady(cd, ds)
59+
// only newCond not satisfied
60+
ds = &appsv1.DaemonSet{Status: appsv1.DaemonSetStatus{
61+
UpdatedNumberScheduled: 0,
62+
DesiredNumberScheduled: 1,
63+
NumberAvailable: 1,
64+
}}
65+
cd.Spec.ProgressDeadlineSeconds = int32p(1e6)
66+
retyable, err = mocks.controller.isDaemonSetReady(cd, ds)
5267
require.Error(t, err)
53-
require.True(t, retrieable)
68+
require.True(t, retyable)
69+
require.True(t, strings.Contains(err.Error(), "new pods"))
5470

55-
// not ready and not retriable
56-
cd.Status.LastTransitionTime = metav1.Now()
57-
cd.Spec.ProgressDeadlineSeconds = int32p(-1e5)
58-
retrieable, err = mocks.controller.isDaemonSetReady(cd, ds)
71+
// only availableCond not satisfied
72+
ds = &appsv1.DaemonSet{Status: appsv1.DaemonSetStatus{
73+
UpdatedNumberScheduled: 1,
74+
DesiredNumberScheduled: 1,
75+
NumberAvailable: 0,
76+
}}
77+
retyable, err = mocks.controller.isDaemonSetReady(cd, ds)
5978
require.Error(t, err)
60-
require.False(t, retrieable)
61-
79+
require.True(t, retyable)
80+
require.True(t, strings.Contains(err.Error(), "available"))
6281
}

0 commit comments

Comments
 (0)