Skip to content

Commit 3812e5f

Browse files
committed
pkg/cvo/availableupdates: Split 'At' into LastAttempt and LastSyncOrConfigChange
The previous At had been tracking the most recent attempt, regardless of success. With this commit, we rename it to the more explicit LastAttempt and add godocs explaining the intended semantics. Also grow a LastSyncOrConfigChange sibling, tracking the time since the last success (or since the configured upstream had been changed). This will make it more convenient to alert when the slice of available updates is stale, although that alert itself and the metric that feeds it will come from follow-up work [1]. Setting u.LastSyncOrConfigChange from optr.availableUpdates in the else branch preserves any existing timestamp if the new status did not trigger a reset. [1]: #357
1 parent e318b86 commit 3812e5f

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

pkg/cvo/availableupdates.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,27 @@ type availableUpdates struct {
6565
Upstream string
6666
Channel string
6767

68-
At time.Time
68+
// LastAttempt records the time of the most recent attempt at update
69+
// retrieval, regardless of whether it was successful.
70+
LastAttempt time.Time
71+
72+
// LastSyncOrConfigChange records the most recent time when any of
73+
// the following events occurred:
74+
//
75+
// * Upstream changed, reflecting a new authority, and obsoleting
76+
// any information retrieved from (or failures // retrieving from) the
77+
// previous authority.
78+
// * Channel changes. Same reasoning as for Upstream.
79+
// * A slice of Updates was successfully retrieved, even if that
80+
// slice was empty.
81+
LastSyncOrConfigChange time.Time
6982

7083
Updates []configv1.Update
7184
Condition configv1.ClusterOperatorStatusCondition
7285
}
7386

7487
func (u *availableUpdates) RecentlyChanged(interval time.Duration) bool {
75-
return u.At.After(time.Now().Add(-interval))
88+
return u.LastAttempt.After(time.Now().Add(-interval))
7689
}
7790

7891
func (u *availableUpdates) NeedsUpdate(original *configv1.ClusterVersion) *configv1.ClusterVersion {
@@ -95,12 +108,26 @@ func (u *availableUpdates) NeedsUpdate(original *configv1.ClusterVersion) *confi
95108

96109
// setAvailableUpdates updates the currently calculated version of updates.
97110
func (optr *Operator) setAvailableUpdates(u *availableUpdates) {
111+
success := false
98112
if u != nil {
99-
u.At = time.Now()
113+
u.LastAttempt = time.Now()
114+
if u.Condition.Type == configv1.RetrievedUpdates {
115+
success = u.Condition.Status == configv1.ConditionTrue
116+
} else {
117+
klog.Warningf("Unrecognized condition %s=%s (%s: %s): cannot judge update retrieval success", u.Condition.Type, u.Condition.Status, u.Condition.Reason, u.Condition.Message)
118+
}
100119
}
101120

102121
optr.statusLock.Lock()
103122
defer optr.statusLock.Unlock()
123+
if u != nil && (optr.availableUpdates == nil ||
124+
optr.availableUpdates.Upstream != u.Upstream ||
125+
optr.availableUpdates.Channel != u.Channel ||
126+
success) {
127+
u.LastSyncOrConfigChange = u.LastAttempt
128+
} else if optr.availableUpdates != nil {
129+
u.LastSyncOrConfigChange = optr.availableUpdates.LastSyncOrConfigChange
130+
}
104131
optr.availableUpdates = u
105132
}
106133

pkg/cvo/cvo_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,10 +2581,10 @@ func TestOperator_availableUpdatesSync(t *testing.T) {
25812581
optr: Operator{
25822582
defaultUpstreamServer: "http://localhost:8080/graph",
25832583
minimumUpdateCheckInterval: 1 * time.Minute,
2584-
availableUpdates: &availableUpdates{
2585-
Upstream: "http://localhost:8080/graph",
2586-
Channel: "fast",
2587-
At: time.Now(),
2584+
availableUpdates: &availableUpdates{
2585+
Upstream: "http://localhost:8080/graph",
2586+
Channel: "fast",
2587+
LastAttempt: time.Now(),
25882588
},
25892589

25902590
releaseVersion: "4.0.1",
@@ -2658,7 +2658,8 @@ func TestOperator_availableUpdatesSync(t *testing.T) {
26582658
optr.availableUpdates.Upstream = "<default>"
26592659
}
26602660
optr.availableUpdates.Condition.LastTransitionTime = metav1.Time{}
2661-
optr.availableUpdates.At = time.Time{}
2661+
optr.availableUpdates.LastAttempt = time.Time{}
2662+
optr.availableUpdates.LastSyncOrConfigChange = time.Time{}
26622663
}
26632664
if !reflect.DeepEqual(optr.availableUpdates, tt.wantUpdates) {
26642665
t.Fatalf("unexpected: %s", diff.ObjectReflectDiff(tt.wantUpdates, optr.availableUpdates))

0 commit comments

Comments
 (0)