@@ -24,6 +24,7 @@ import (
24
24
"sync"
25
25
"time"
26
26
27
+ "github.com/containers/image/v5/docker/reference"
27
28
"k8s.io/apimachinery/pkg/api/equality"
28
29
"k8s.io/apimachinery/pkg/api/meta"
29
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -38,8 +39,8 @@ import (
38
39
"sigs.k8s.io/controller-runtime/pkg/reconcile"
39
40
40
41
catalogdv1 "github.com/operator-framework/operator-controller/catalogd/api/v1"
41
- "github.com/operator-framework/operator-controller/internal/catalogd/source"
42
42
"github.com/operator-framework/operator-controller/internal/catalogd/storage"
43
+ imageutil "github.com/operator-framework/operator-controller/internal/shared/util/image"
43
44
)
44
45
45
46
const (
@@ -52,8 +53,11 @@ const (
52
53
// ClusterCatalogReconciler reconciles a Catalog object
53
54
type ClusterCatalogReconciler struct {
54
55
client.Client
55
- Unpacker source.Unpacker
56
- Storage storage.Instance
56
+
57
+ ImageCache imageutil.Cache
58
+ ImagePuller imageutil.Puller
59
+
60
+ Storage storage.Instance
57
61
58
62
finalizers crfinalizer.Finalizers
59
63
@@ -66,8 +70,10 @@ type ClusterCatalogReconciler struct {
66
70
}
67
71
68
72
type storedCatalogData struct {
73
+ ref reference.Canonical
74
+ lastUnpack time.Time
75
+ lastSuccessfulPoll time.Time
69
76
observedGeneration int64
70
- unpackResult source.Result
71
77
}
72
78
73
79
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs,verbs=get;list;watch;create;update;patch;delete
@@ -216,50 +222,58 @@ func (r *ClusterCatalogReconciler) reconcile(ctx context.Context, catalog *catal
216
222
case catalog .Generation != storedCatalog .observedGeneration :
217
223
l .Info ("unpack required: catalog generation differs from observed generation" )
218
224
needsUnpack = true
219
- case r .needsPoll (storedCatalog .unpackResult . LastSuccessfulPollAttempt . Time , catalog ):
225
+ case r .needsPoll (storedCatalog .lastSuccessfulPoll , catalog ):
220
226
l .Info ("unpack required: poll duration has elapsed" )
221
227
needsUnpack = true
222
228
}
223
229
224
230
if ! needsUnpack {
225
231
// No need to update the status because we've already checked
226
232
// that it is set correctly. Otherwise, we'd be unpacking again.
227
- return nextPollResult (storedCatalog .unpackResult .LastSuccessfulPollAttempt .Time , catalog ), nil
233
+ return nextPollResult (storedCatalog .lastSuccessfulPoll , catalog ), nil
234
+ }
235
+
236
+ if catalog .Spec .Source .Type != catalogdv1 .SourceTypeImage {
237
+ err := reconcile .TerminalError (fmt .Errorf ("unknown source type %q" , catalog .Spec .Source .Type ))
238
+ updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), err )
239
+ return ctrl.Result {}, err
240
+ }
241
+ if catalog .Spec .Source .Image == nil {
242
+ err := reconcile .TerminalError (fmt .Errorf ("error parsing ClusterCatalog %q, image source is nil" , catalog .Name ))
243
+ updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), err )
244
+ return ctrl.Result {}, err
228
245
}
229
246
230
- unpackResult , err := r .Unpacker . Unpack (ctx , catalog )
247
+ fsys , canonicalRef , unpackTime , err := r .ImagePuller . Pull (ctx , catalog . Name , catalog . Spec . Source . Image . Ref , r . ImageCache )
231
248
if err != nil {
232
249
unpackErr := fmt .Errorf ("source catalog content: %w" , err )
233
250
updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), unpackErr )
234
251
return ctrl.Result {}, unpackErr
235
252
}
236
253
237
- switch unpackResult .State {
238
- case source .StateUnpacked :
239
- // TODO: We should check to see if the unpacked result has the same content
240
- // as the already unpacked content. If it does, we should skip this rest
241
- // of the unpacking steps.
242
- err := r .Storage .Store (ctx , catalog .Name , unpackResult .FS )
243
- if err != nil {
244
- storageErr := fmt .Errorf ("error storing fbc: %v" , err )
245
- updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), storageErr )
246
- return ctrl.Result {}, storageErr
247
- }
248
- baseURL := r .Storage .BaseURL (catalog .Name )
249
-
250
- updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), nil )
251
- updateStatusServing (& catalog .Status , * unpackResult , baseURL , catalog .GetGeneration ())
252
- default :
253
- panic (fmt .Sprintf ("unknown unpack state %q" , unpackResult .State ))
254
+ // TODO: We should check to see if the unpacked result has the same content
255
+ // as the already unpacked content. If it does, we should skip this rest
256
+ // of the unpacking steps.
257
+ if err := r .Storage .Store (ctx , catalog .Name , fsys ); err != nil {
258
+ storageErr := fmt .Errorf ("error storing fbc: %v" , err )
259
+ updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), storageErr )
260
+ return ctrl.Result {}, storageErr
254
261
}
262
+ baseURL := r .Storage .BaseURL (catalog .Name )
263
+
264
+ updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), nil )
265
+ updateStatusServing (& catalog .Status , canonicalRef , unpackTime , baseURL , catalog .GetGeneration ())
255
266
267
+ lastSuccessfulPoll := time .Now ()
256
268
r .storedCatalogsMu .Lock ()
257
269
r .storedCatalogs [catalog .Name ] = storedCatalogData {
258
- unpackResult : * unpackResult ,
270
+ ref : canonicalRef ,
271
+ lastUnpack : unpackTime ,
272
+ lastSuccessfulPoll : lastSuccessfulPoll ,
259
273
observedGeneration : catalog .GetGeneration (),
260
274
}
261
275
r .storedCatalogsMu .Unlock ()
262
- return nextPollResult (unpackResult . LastSuccessfulPollAttempt . Time , catalog ), nil
276
+ return nextPollResult (lastSuccessfulPoll , catalog ), nil
263
277
}
264
278
265
279
func (r * ClusterCatalogReconciler ) getCurrentState (catalog * catalogdv1.ClusterCatalog ) (* catalogdv1.ClusterCatalogStatus , storedCatalogData , bool ) {
@@ -272,7 +286,7 @@ func (r *ClusterCatalogReconciler) getCurrentState(catalog *catalogdv1.ClusterCa
272
286
// Set expected status based on what we see in the stored catalog
273
287
clearUnknownConditions (expectedStatus )
274
288
if hasStoredCatalog && r .Storage .ContentExists (catalog .Name ) {
275
- updateStatusServing (expectedStatus , storedCatalog .unpackResult , r .Storage .BaseURL (catalog .Name ), storedCatalog .observedGeneration )
289
+ updateStatusServing (expectedStatus , storedCatalog .ref , storedCatalog . lastUnpack , r .Storage .BaseURL (catalog .Name ), storedCatalog .observedGeneration )
276
290
updateStatusProgressing (expectedStatus , storedCatalog .observedGeneration , nil )
277
291
}
278
292
@@ -325,13 +339,17 @@ func updateStatusProgressing(status *catalogdv1.ClusterCatalogStatus, generation
325
339
meta .SetStatusCondition (& status .Conditions , progressingCond )
326
340
}
327
341
328
- func updateStatusServing (status * catalogdv1.ClusterCatalogStatus , result source.Result , baseURL string , generation int64 ) {
329
- status .ResolvedSource = result .ResolvedSource
330
- if status .URLs == nil {
331
- status .URLs = & catalogdv1.ClusterCatalogURLs {}
342
+ func updateStatusServing (status * catalogdv1.ClusterCatalogStatus , ref reference.Canonical , modTime time.Time , baseURL string , generation int64 ) {
343
+ status .ResolvedSource = & catalogdv1.ResolvedCatalogSource {
344
+ Type : catalogdv1 .SourceTypeImage ,
345
+ Image : & catalogdv1.ResolvedImageSource {
346
+ Ref : ref .String (),
347
+ },
348
+ }
349
+ status .URLs = & catalogdv1.ClusterCatalogURLs {
350
+ Base : baseURL ,
332
351
}
333
- status .URLs .Base = baseURL
334
- status .LastUnpacked = ptr .To (metav1 .NewTime (result .UnpackTime ))
352
+ status .LastUnpacked = ptr .To (metav1 .NewTime (modTime .Truncate (time .Second )))
335
353
meta .SetStatusCondition (& status .Conditions , metav1.Condition {
336
354
Type : catalogdv1 .TypeServing ,
337
355
Status : metav1 .ConditionTrue ,
@@ -434,7 +452,7 @@ func (r *ClusterCatalogReconciler) deleteCatalogCache(ctx context.Context, catal
434
452
return err
435
453
}
436
454
updateStatusNotServing (& catalog .Status , catalog .GetGeneration ())
437
- if err := r .Unpacker . Cleanup (ctx , catalog ); err != nil {
455
+ if err := r .ImageCache . Delete (ctx , catalog . Name ); err != nil {
438
456
updateStatusProgressing (& catalog .Status , catalog .GetGeneration (), err )
439
457
return err
440
458
}
0 commit comments