@@ -38,14 +38,12 @@ import (
38
38
"helm.sh/helm/v3/pkg/storage/driver"
39
39
corev1 "k8s.io/api/core/v1"
40
40
"k8s.io/apimachinery/pkg/api/equality"
41
- apierrors "k8s.io/apimachinery/pkg/api/errors"
42
41
apimeta "k8s.io/apimachinery/pkg/api/meta"
43
42
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
44
43
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
45
44
"k8s.io/apimachinery/pkg/runtime"
46
45
"k8s.io/apimachinery/pkg/runtime/schema"
47
46
"k8s.io/apimachinery/pkg/types"
48
- utilerrors "k8s.io/apimachinery/pkg/util/errors"
49
47
"k8s.io/apimachinery/pkg/util/sets"
50
48
apimachyaml "k8s.io/apimachinery/pkg/util/yaml"
51
49
ctrl "sigs.k8s.io/controller-runtime"
@@ -120,40 +118,35 @@ func (r *ClusterExtensionReconciler) Reconcile(ctx context.Context, req ctrl.Req
120
118
121
119
var existingExt = & ocv1alpha1.ClusterExtension {}
122
120
if err := r .Client .Get (ctx , req .NamespacedName , existingExt ); err != nil {
123
- return ctrl.Result {}, utilerrors . NewAggregate ([] error { client .IgnoreNotFound (err ), nil } )
121
+ return ctrl.Result {}, client .IgnoreNotFound (err )
124
122
}
125
123
126
- reconciledExt := existingExt .DeepCopy ()
127
- res , reconcileErr := r .reconcile (ctx , reconciledExt )
124
+ var updateError error
128
125
129
- var updateErrors []error
126
+ reconciledExt := existingExt .DeepCopy ()
127
+ res , err := r .reconcile (ctx , reconciledExt )
128
+ updateError = errors .Join (updateError , err )
130
129
131
130
// Do checks before any Update()s, as Update() may modify the resource structure!
132
131
updateStatus := ! equality .Semantic .DeepEqual (existingExt .Status , reconciledExt .Status )
133
132
updateFinalizers := ! equality .Semantic .DeepEqual (existingExt .Finalizers , reconciledExt .Finalizers )
134
133
unexpectedFieldsChanged := checkForUnexpectedFieldChange (* existingExt , * reconciledExt )
135
134
136
135
if updateStatus {
137
- if updateErr := r .Client .Status ().Update (ctx , reconciledExt ); updateErr != nil {
138
- updateErrors = append (updateErrors , updateErr )
139
- }
136
+ err = r .Client .Status ().Update (ctx , reconciledExt )
137
+ updateError = errors .Join (updateError , err )
140
138
}
141
139
142
140
if unexpectedFieldsChanged {
143
141
panic ("spec or metadata changed by reconciler" )
144
142
}
145
143
146
144
if updateFinalizers {
147
- if updateErr := r .Client .Update (ctx , reconciledExt ); updateErr != nil {
148
- updateErrors = append (updateErrors , updateErr )
149
- }
150
- }
151
-
152
- if reconcileErr != nil {
153
- updateErrors = append (updateErrors , reconcileErr )
145
+ err = r .Client .Update (ctx , reconciledExt )
146
+ updateError = errors .Join (updateError , err )
154
147
}
155
148
156
- return res , utilerrors . NewAggregate ( updateErrors )
149
+ return res , updateError
157
150
}
158
151
159
152
// ensureAllConditionsWithReason checks that all defined condition types exist in the given ClusterExtension,
@@ -183,35 +176,6 @@ func checkForUnexpectedFieldChange(a, b ocv1alpha1.ClusterExtension) bool {
183
176
return ! equality .Semantic .DeepEqual (a , b )
184
177
}
185
178
186
- func (r * ClusterExtensionReconciler ) handleResolutionErrors (ext * ocv1alpha1.ClusterExtension , err error ) (ctrl.Result , error ) {
187
- var aggErrs utilerrors.Aggregate
188
- if errors .As (err , & aggErrs ) {
189
- for _ , err := range aggErrs .Errors () {
190
- errorMessage := err .Error ()
191
- if strings .Contains (errorMessage , "no package" ) {
192
- // Handle no package found errors, potentially setting status conditions
193
- setResolvedStatusConditionFailed (& ext .Status .Conditions , errorMessage , ext .Generation )
194
- ensureAllConditionsWithReason (ext , "ResolutionFailed" , errorMessage )
195
- } else if strings .Contains (errorMessage , "invalid version range" ) {
196
- // Handle invalid version range errors, potentially setting status conditions
197
- setResolvedStatusConditionFailed (& ext .Status .Conditions , errorMessage , ext .Generation )
198
- ensureAllConditionsWithReason (ext , "ResolutionFailed" , errorMessage )
199
- } else {
200
- // General error handling
201
- setResolvedStatusConditionFailed (& ext .Status .Conditions , errorMessage , ext .Generation )
202
- ensureAllConditionsWithReason (ext , "InstallationStatusUnknown" , "" )
203
- }
204
- }
205
- } else {
206
- // If the error is not an aggregate, handle it as a general error
207
- errorMessage := err .Error ()
208
- setResolvedStatusConditionFailed (& ext .Status .Conditions , errorMessage , ext .Generation )
209
- ensureAllConditionsWithReason (ext , "InstallationStatusUnknown" , "" )
210
- }
211
- ext .Status .ResolvedBundle = nil
212
- return ctrl.Result {}, err
213
- }
214
-
215
179
// Helper function to do the actual reconcile
216
180
//
217
181
// Today we always return ctrl.Result{} and an error.
@@ -232,10 +196,18 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
232
196
// run resolution
233
197
bundle , err := r .resolve (ctx , * ext )
234
198
if err != nil {
235
- return r .handleResolutionErrors (ext , err )
199
+ // Note: We don't distinguish between resolution-specific errors and generic errors
200
+ ext .Status .ResolvedBundle = nil
201
+ ext .Status .InstalledBundle = nil
202
+ setResolvedStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
203
+ ensureAllConditionsWithReason (ext , ocv1alpha1 .ReasonResolutionFailed , err .Error ())
204
+ return ctrl.Result {}, err
236
205
}
237
206
238
207
if err := r .validateBundle (bundle ); err != nil {
208
+ ext .Status .ResolvedBundle = nil
209
+ ext .Status .InstalledBundle = nil
210
+ setResolvedStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
239
211
setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
240
212
setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
241
213
return ctrl.Result {}, err
@@ -291,23 +263,13 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
291
263
292
264
bundleFS , err := r .Storage .Load (ctx , ext )
293
265
if err != nil {
294
- apimeta .SetStatusCondition (& ext .Status .Conditions , metav1.Condition {
295
- Type : ocv1alpha1 .TypeHasValidBundle ,
296
- Status : metav1 .ConditionFalse ,
297
- Reason : ocv1alpha1 .ReasonBundleLoadFailed ,
298
- Message : err .Error (),
299
- })
266
+ setHasValidBundleFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
300
267
return ctrl.Result {}, err
301
268
}
302
269
303
270
chrt , values , err := r .Handler .Handle (ctx , bundleFS , ext )
304
271
if err != nil {
305
- apimeta .SetStatusCondition (& ext .Status .Conditions , metav1.Condition {
306
- Type : ocv1alpha1 .TypeInstalled ,
307
- Status : metav1 .ConditionFalse ,
308
- Reason : ocv1alpha1 .ReasonInstallationFailed ,
309
- Message : err .Error (),
310
- })
272
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
311
273
return ctrl.Result {}, err
312
274
}
313
275
@@ -342,26 +304,17 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
342
304
return nil
343
305
}, helmclient .AppendInstallPostRenderer (post ))
344
306
if err != nil {
345
- if isResourceNotFoundErr (err ) {
346
- err = errRequiredResourceNotFound {err }
347
- }
348
307
setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("%s:%v" , ocv1alpha1 .ReasonInstallationFailed , err ), ext .Generation )
349
308
return ctrl.Result {}, err
350
309
}
351
310
case stateNeedsUpgrade :
352
311
rel , err = ac .Upgrade (ext .GetName (), r .ReleaseNamespace , chrt , values , helmclient .AppendUpgradePostRenderer (post ))
353
312
if err != nil {
354
- if isResourceNotFoundErr (err ) {
355
- err = errRequiredResourceNotFound {err }
356
- }
357
313
setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("%s:%v" , ocv1alpha1 .ReasonUpgradeFailed , err ), ext .Generation )
358
314
return ctrl.Result {}, err
359
315
}
360
316
case stateUnchanged :
361
317
if err := ac .Reconcile (rel ); err != nil {
362
- if isResourceNotFoundErr (err ) {
363
- err = errRequiredResourceNotFound {err }
364
- }
365
318
setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("%s:%v" , ocv1alpha1 .ReasonResolutionFailed , err ), ext .Generation )
366
319
return ctrl.Result {}, err
367
320
}
@@ -414,7 +367,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
414
367
func (r * ClusterExtensionReconciler ) resolve (ctx context.Context , ext ocv1alpha1.ClusterExtension ) (* catalogmetadata.Bundle , error ) {
415
368
allBundles , err := r .BundleProvider .Bundles (ctx )
416
369
if err != nil {
417
- return nil , utilerrors . NewAggregate ([] error { fmt .Errorf ("error fetching bundles: %w" , err )} )
370
+ return nil , fmt .Errorf ("error fetching bundles: %w" , err )
418
371
}
419
372
420
373
packageName := ext .Spec .PackageName
@@ -437,7 +390,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1
437
390
if versionRange != "" {
438
391
vr , err := mmsemver .NewConstraint (versionRange )
439
392
if err != nil {
440
- return nil , utilerrors . NewAggregate ([] error { fmt .Errorf ("invalid version range '%s' : %w" , versionRange , err )} )
393
+ return nil , fmt .Errorf ("invalid version range %q : %w" , versionRange , err )
441
394
}
442
395
predicates = append (predicates , catalogfilter .InMastermindsSemverRange (vr ))
443
396
}
@@ -753,37 +706,6 @@ func (d *DefaultInstalledBundleGetter) GetInstalledBundle(ctx context.Context, a
753
706
return resultSet [0 ], nil
754
707
}
755
708
756
- type errRequiredResourceNotFound struct {
757
- error
758
- }
759
-
760
- func (err errRequiredResourceNotFound ) Error () string {
761
- return fmt .Sprintf ("required resource not found: %v" , err .error )
762
- }
763
-
764
- func isResourceNotFoundErr (err error ) bool {
765
- var agg utilerrors.Aggregate
766
- if errors .As (err , & agg ) {
767
- for _ , err := range agg .Errors () {
768
- return isResourceNotFoundErr (err )
769
- }
770
- }
771
-
772
- nkme := & apimeta.NoKindMatchError {}
773
- if errors .As (err , & nkme ) {
774
- return true
775
- }
776
- if apierrors .IsNotFound (err ) {
777
- return true
778
- }
779
-
780
- // TODO: improve NoKindMatchError matching
781
- // An error that is bubbled up from the k8s.io/cli-runtime library
782
- // does not wrap meta.NoKindMatchError, so we need to fallback to
783
- // the use of string comparisons for now.
784
- return strings .Contains (err .Error (), "no matches for kind" )
785
- }
786
-
787
709
type postrenderer struct {
788
710
labels map [string ]string
789
711
cascade postrender.PostRenderer
0 commit comments