Skip to content

Commit 206c606

Browse files
committed
Adjust syncPayload handling to explicit switch on various changes
1 parent 903e16e commit 206c606

1 file changed

Lines changed: 132 additions & 125 deletions

File tree

pkg/cvo/sync_worker.go

Lines changed: 132 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,19 @@ func (w *SyncWorker) syncPayload(ctx context.Context, work *SyncWork) ([]configv
296296
// cache the payload until the release image changes
297297
validPayload := w.payload
298298

299-
previousEnabledFeatureGates := w.status.EnabledFeatureGates
300-
if !work.EnabledFeatureGates.Equal(previousEnabledFeatureGates) {
299+
switch {
300+
case validPayload == nil:
301+
klog.V(2).Info("Loading initial payload")
302+
case !equalUpdate(configv1.Update{Image: validPayload.Release.Image}, configv1.Update{Image: desired.Image}):
303+
klog.V(2).Info("Loading payload due to desired image not being equal to the current one.")
304+
case !work.EnabledFeatureGates.Equal(w.status.EnabledFeatureGates):
301305
// When the feature gates change, we must reload the payload.
302306
// Loading the payload filters out files that didn't match the previous set of feature gates,
303307
// this means now, additional files may match the new set of feature gates and need to be included.
304308
// Some files in the current payload may no longer match the new set of feature gates and need to be excluded,
305309
// though these ones are already excluded when apply calls Include on the manifests.
306-
klog.V(2).Infof("Enabled feature gates changed from %v to %v, forcing a payload refresh", previousEnabledFeatureGates, work.EnabledFeatureGates)
307-
w.payload = nil
308-
}
309-
310-
if validPayload != nil && validPayload.Release.Image == desired.Image {
311-
310+
klog.V(2).Infof("Enabled feature gates changed from %v to %v, forcing a payload refresh", w.status.EnabledFeatureGates, work.EnabledFeatureGates)
311+
case validPayload.Release.Image == desired.Image:
312312
// reset payload status to currently loaded payload if it no longer applies to desired target
313313
if !reporter.ValidPayloadStatus(desired) {
314314
klog.V(2).Info("Resetting payload status to currently loaded payload.")
@@ -321,144 +321,151 @@ func (w *SyncWorker) syncPayload(ctx context.Context, work *SyncWork) ([]configv
321321
LastTransitionTime: time.Now(),
322322
})
323323
}
324+
324325
// possibly complain here if Version, etc. diverges from the payload content
325326
return implicitlyEnabledCaps, nil
326-
} else if validPayload == nil || !equalUpdate(configv1.Update{Image: validPayload.Release.Image}, configv1.Update{Image: desired.Image}) {
327-
cvoObjectRef := &corev1.ObjectReference{APIVersion: "config.openshift.io/v1", Kind: "ClusterVersion", Name: "version", Namespace: "openshift-cluster-version"}
328-
msg := fmt.Sprintf("Retrieving and verifying payload version=%q image=%q", desired.Version, desired.Image)
329-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "RetrievePayload", msg)
327+
}
328+
329+
// The remainder of this logic is for loading a new payload.
330+
// Any filtering as to not needing to reload the payload should be done in the switch before this point.
331+
332+
cvoObjectRef := &corev1.ObjectReference{APIVersion: "config.openshift.io/v1", Kind: "ClusterVersion", Name: "version", Namespace: "openshift-cluster-version"}
333+
msg := fmt.Sprintf("Retrieving and verifying payload version=%q image=%q", desired.Version, desired.Image)
334+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "RetrievePayload", msg)
335+
reporter.ReportPayload(LoadPayloadStatus{
336+
Step: "RetrievePayload",
337+
Message: msg,
338+
Update: desired,
339+
LastTransitionTime: time.Now(),
340+
})
341+
342+
// syncPayload executes while locked, but RetrievePayload is a potentially long-running operation
343+
// which does not need the lock, so holding it may block other loops (mainly the apply loop) from
344+
// execution
345+
w.lock.Unlock()
346+
info, err := w.retriever.RetrievePayload(ctx, work.Desired)
347+
w.lock.Lock()
348+
if err != nil {
349+
msg := fmt.Sprintf("Retrieving payload failed version=%q image=%q failure=%s", desired.Version, desired.Image, strings.ReplaceAll(unwrappedErrorAggregate(err), "\n", " // "))
350+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "RetrievePayloadFailed", msg)
351+
msg = fmt.Sprintf("Retrieving payload failed version=%q image=%q failure=%s", desired.Version, desired.Image, err)
330352
reporter.ReportPayload(LoadPayloadStatus{
353+
Failure: err,
331354
Step: "RetrievePayload",
332355
Message: msg,
333356
Update: desired,
357+
Local: info.Local,
334358
LastTransitionTime: time.Now(),
335359
})
360+
return nil, err
361+
}
336362

337-
// syncPayload executes while locked, but RetrievePayload is a potentially long-running operation
338-
// which does not need the lock, so holding it may block other loops (mainly the apply loop) from
339-
// execution
340-
w.lock.Unlock()
341-
info, err := w.retriever.RetrievePayload(ctx, work.Desired)
342-
w.lock.Lock()
343-
if err != nil {
344-
msg := fmt.Sprintf("Retrieving payload failed version=%q image=%q failure=%s", desired.Version, desired.Image, strings.ReplaceAll(unwrappedErrorAggregate(err), "\n", " // "))
345-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "RetrievePayloadFailed", msg)
346-
msg = fmt.Sprintf("Retrieving payload failed version=%q image=%q failure=%s", desired.Version, desired.Image, err)
347-
reporter.ReportPayload(LoadPayloadStatus{
348-
Failure: err,
349-
Step: "RetrievePayload",
350-
Message: msg,
351-
Update: desired,
352-
Local: info.Local,
353-
LastTransitionTime: time.Now(),
354-
})
355-
return nil, err
356-
}
357-
acceptedRisksMsg := ""
358-
if info.VerificationError != nil {
359-
acceptedRisksMsg = unwrappedErrorAggregate(info.VerificationError)
360-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "RetrievePayload", acceptedRisksMsg)
361-
}
362-
363-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "LoadPayload", "Loading payload version=%q image=%q", desired.Version, desired.Image)
364-
365-
// Capability filtering is not done here since unknown capabilities are allowed
366-
// during updated payload load and enablement checking only occurs during apply.
367-
payloadUpdate, err := payload.LoadUpdate(info.Directory, desired.Image, w.exclude, string(w.requiredFeatureSet), w.clusterProfile, nil, work.EnabledFeatureGates)
368-
369-
if err != nil {
370-
msg := fmt.Sprintf("Loading payload failed version=%q image=%q failure=%v", desired.Version, desired.Image, err)
371-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "LoadPayloadFailed", msg)
372-
reporter.ReportPayload(LoadPayloadStatus{
373-
Failure: err,
374-
Step: "LoadPayload",
375-
Message: msg,
376-
Verified: info.Verified,
377-
Local: info.Local,
378-
Update: desired,
379-
LastTransitionTime: time.Now(),
380-
})
381-
return nil, err
382-
}
363+
acceptedRisksMsg := ""
364+
if info.VerificationError != nil {
365+
acceptedRisksMsg = unwrappedErrorAggregate(info.VerificationError)
366+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "RetrievePayload", acceptedRisksMsg)
367+
}
383368

384-
payloadUpdate.VerifiedImage = info.Verified
385-
payloadUpdate.LoadedAt = time.Now()
369+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "LoadPayload", "Loading payload version=%q image=%q", desired.Version, desired.Image)
386370

387-
if work.Desired.Version == "" {
388-
work.Desired.Version = payloadUpdate.Release.Version
389-
desired.Version = payloadUpdate.Release.Version
390-
} else if payloadUpdate.Release.Version != work.Desired.Version {
391-
err = fmt.Errorf("release image version %s does not match the expected upstream version %s", payloadUpdate.Release.Version, work.Desired.Version)
392-
msg := fmt.Sprintf("Verifying payload failed version=%q image=%q failure=%v", work.Desired.Version, work.Desired.Image, err)
393-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "VerifyPayloadVersionFailed", msg)
394-
reporter.ReportPayload(LoadPayloadStatus{
395-
Failure: err,
396-
Step: "VerifyPayloadVersion",
397-
Message: msg,
398-
Verified: info.Verified,
399-
Local: info.Local,
400-
Update: desired,
401-
LastTransitionTime: time.Now(),
402-
})
403-
return nil, err
404-
}
371+
// Capability filtering is not done here since unknown capabilities are allowed
372+
// during updated payload load and enablement checking only occurs during apply.
373+
payloadUpdate, err := payload.LoadUpdate(info.Directory, desired.Image, w.exclude, string(w.requiredFeatureSet), w.clusterProfile, nil, work.EnabledFeatureGates)
374+
if err != nil {
375+
msg := fmt.Sprintf("Loading payload failed version=%q image=%q failure=%v", desired.Version, desired.Image, err)
376+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "LoadPayloadFailed", msg)
377+
reporter.ReportPayload(LoadPayloadStatus{
378+
Failure: err,
379+
Step: "LoadPayload",
380+
Message: msg,
381+
Verified: info.Verified,
382+
Local: info.Local,
383+
Update: desired,
384+
LastTransitionTime: time.Now(),
385+
})
386+
return nil, err
387+
}
405388

406-
// need to make sure the payload is only set when the preconditions have been successful
407-
if len(w.preconditions) == 0 {
408-
klog.V(2).Info("No preconditions configured.")
409-
} else if info.Local {
410-
klog.V(2).Info("Skipping preconditions for a local operator image payload.")
411-
} else {
412-
if block, err := precondition.Summarize(w.preconditions.RunAll(ctx, precondition.ReleaseContext{
413-
DesiredVersion: payloadUpdate.Release.Version,
414-
}), work.Desired.Force); err != nil {
415-
klog.V(2).Infof("Precondition error (force %t, block %t): %v", work.Desired.Force, block, err)
416-
if block {
417-
msg := fmt.Sprintf("Preconditions failed for payload loaded version=%q image=%q: %v", desired.Version, desired.Image, err)
418-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "PreconditionBlock", msg)
419-
reporter.ReportPayload(LoadPayloadStatus{
420-
Failure: err,
421-
Step: "PreconditionChecks",
422-
Message: msg,
423-
Verified: info.Verified,
424-
Local: info.Local,
425-
Update: desired,
426-
LastTransitionTime: time.Now(),
427-
})
428-
return nil, err
429-
} else {
430-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "PreconditionWarn", "precondition warning for payload loaded version=%q image=%q: %v", desired.Version, desired.Image, err)
389+
payloadUpdate.VerifiedImage = info.Verified
390+
payloadUpdate.LoadedAt = time.Now()
431391

432-
if acceptedRisksMsg == "" {
433-
acceptedRisksMsg = err.Error()
434-
} else {
435-
acceptedRisksMsg = fmt.Sprintf("%s\n%s", acceptedRisksMsg, err.Error())
436-
}
437-
}
438-
}
439-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "PreconditionsPassed", "preconditions passed for payload loaded version=%q image=%q", desired.Version, desired.Image)
440-
}
441-
if w.payload != nil {
442-
implicitlyEnabledCaps = capability.SortedList(payload.GetImplicitlyEnabledCapabilities(payloadUpdate.Manifests, w.payload.Manifests,
443-
work.Capabilities, work.EnabledFeatureGates))
444-
}
445-
w.payload = payloadUpdate
446-
msg = fmt.Sprintf("Payload loaded version=%q image=%q architecture=%q", desired.Version, desired.Image,
447-
payloadUpdate.Architecture)
448-
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "PayloadLoaded", msg)
392+
if work.Desired.Version == "" {
393+
work.Desired.Version = payloadUpdate.Release.Version
394+
desired.Version = payloadUpdate.Release.Version
395+
} else if payloadUpdate.Release.Version != work.Desired.Version {
396+
err = fmt.Errorf("release image version %s does not match the expected upstream version %s", payloadUpdate.Release.Version, work.Desired.Version)
397+
msg := fmt.Sprintf("Verifying payload failed version=%q image=%q failure=%v", work.Desired.Version, work.Desired.Image, err)
398+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "VerifyPayloadVersionFailed", msg)
449399
reporter.ReportPayload(LoadPayloadStatus{
450-
Failure: nil,
451-
Step: "PayloadLoaded",
400+
Failure: err,
401+
Step: "VerifyPayloadVersion",
452402
Message: msg,
453-
AcceptedRisks: acceptedRisksMsg,
454403
Verified: info.Verified,
455404
Local: info.Local,
456405
Update: desired,
457406
LastTransitionTime: time.Now(),
458407
})
459-
klog.V(2).Infof("Payload loaded from %s with hash %s, architecture %s", desired.Image, payloadUpdate.ManifestHash,
460-
payloadUpdate.Architecture)
408+
return nil, err
409+
}
410+
411+
// need to make sure the payload is only set when the preconditions have been successful
412+
if len(w.preconditions) == 0 {
413+
klog.V(2).Info("No preconditions configured.")
414+
} else if info.Local {
415+
klog.V(2).Info("Skipping preconditions for a local operator image payload.")
416+
} else {
417+
if block, err := precondition.Summarize(w.preconditions.RunAll(ctx, precondition.ReleaseContext{
418+
DesiredVersion: payloadUpdate.Release.Version,
419+
}), work.Desired.Force); err != nil {
420+
klog.V(2).Infof("Precondition error (force %t, block %t): %v", work.Desired.Force, block, err)
421+
if block {
422+
msg := fmt.Sprintf("Preconditions failed for payload loaded version=%q image=%q: %v", desired.Version, desired.Image, err)
423+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "PreconditionBlock", msg)
424+
reporter.ReportPayload(LoadPayloadStatus{
425+
Failure: err,
426+
Step: "PreconditionChecks",
427+
Message: msg,
428+
Verified: info.Verified,
429+
Local: info.Local,
430+
Update: desired,
431+
LastTransitionTime: time.Now(),
432+
})
433+
return nil, err
434+
} else {
435+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "PreconditionWarn", "precondition warning for payload loaded version=%q image=%q: %v", desired.Version, desired.Image, err)
436+
437+
if acceptedRisksMsg == "" {
438+
acceptedRisksMsg = err.Error()
439+
} else {
440+
acceptedRisksMsg = fmt.Sprintf("%s\n%s", acceptedRisksMsg, err.Error())
441+
}
442+
}
443+
}
444+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "PreconditionsPassed", "preconditions passed for payload loaded version=%q image=%q", desired.Version, desired.Image)
445+
}
446+
447+
if w.payload != nil {
448+
implicitlyEnabledCaps = capability.SortedList(payload.GetImplicitlyEnabledCapabilities(payloadUpdate.Manifests, w.payload.Manifests,
449+
work.Capabilities, work.EnabledFeatureGates))
461450
}
451+
452+
w.payload = payloadUpdate
453+
msg = fmt.Sprintf("Payload loaded version=%q image=%q architecture=%q", desired.Version, desired.Image,
454+
payloadUpdate.Architecture)
455+
w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "PayloadLoaded", msg)
456+
reporter.ReportPayload(LoadPayloadStatus{
457+
Failure: nil,
458+
Step: "PayloadLoaded",
459+
Message: msg,
460+
AcceptedRisks: acceptedRisksMsg,
461+
Verified: info.Verified,
462+
Local: info.Local,
463+
Update: desired,
464+
LastTransitionTime: time.Now(),
465+
})
466+
klog.V(2).Infof("Payload loaded from %s with hash %s, architecture %s", desired.Image, payloadUpdate.ManifestHash,
467+
payloadUpdate.Architecture)
468+
462469
return implicitlyEnabledCaps, nil
463470
}
464471

0 commit comments

Comments
 (0)