@@ -25,6 +25,7 @@ import (
2525 corev1 "k8s.io/api/core/v1"
2626 "k8s.io/apimachinery/pkg/api/errors"
2727 "k8s.io/apimachinery/pkg/runtime"
28+ "k8s.io/client-go/tools/record"
2829 "k8s.io/klog/v2"
2930 ctrl "sigs.k8s.io/controller-runtime"
3031 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -39,13 +40,15 @@ import (
3940// CachedImageReconciler reconciles a CachedImage object
4041type CachedImageReconciler struct {
4142 client.Client
42- Scheme * runtime.Scheme
43+ Scheme * runtime.Scheme
44+ Recorder record.EventRecorder
4345}
4446
4547//+kubebuilder:rbac:groups=dcr.enix.io,resources=cachedimages,verbs=get;list;watch;create;update;patch;delete
4648//+kubebuilder:rbac:groups=dcr.enix.io,resources=cachedimages/status,verbs=get;update;patch
4749//+kubebuilder:rbac:groups=dcr.enix.io,resources=cachedimages/finalizers,verbs=update
4850//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list
51+ //+kubebuilder:rbac:groups="",resources=events,verbs=create;patch
4952
5053// Reconcile is part of the main kubernetes reconciliation loop which aims to
5154// move the current state of the cluster closer to the desired state.
@@ -72,10 +75,13 @@ func (r *CachedImageReconciler) Reconcile(ctx context.Context, req ctrl.Request)
7275 // Remove image from registry when CachedImage is beeing deleted, finalizer is removed after it
7376 if ! cachedImage .ObjectMeta .DeletionTimestamp .IsZero () {
7477 if containsString (cachedImage .GetFinalizers (), finalizerName ) {
75- log .Info ("deleting image cache" )
78+ log .Info ("deleting image from cache" )
79+ r .Recorder .Eventf (& cachedImage , "Normal" , "CleaningUp" , "Removing image %s from cache" , cachedImage .Spec .SourceImage )
7680 if err := registry .DeleteImage (cachedImage .Spec .SourceImage ); err != nil {
81+ r .Recorder .Eventf (& cachedImage , "Warning" , "CleanupFailed" , "Image %s could not be removed from cache: %s" , cachedImage .Spec .SourceImage , err )
7782 return ctrl.Result {}, err
7883 }
84+ r .Recorder .Eventf (& cachedImage , "Normal" , "CleanedUp" , "Image %s successfully removed from cache" , cachedImage .Spec .SourceImage )
7985
8086 log .Info ("removing finalizer" )
8187 controllerutil .RemoveFinalizer (& cachedImage , finalizerName )
@@ -127,10 +133,13 @@ func (r *CachedImageReconciler) Reconcile(ctx context.Context, req ctrl.Request)
127133 if ! expiresAt .IsZero () {
128134 if time .Now ().After (expiresAt .Time ) {
129135 log .Info ("cachedimage expired, deleting it" , "now" , time .Now (), "expiresAt" , expiresAt )
136+ r .Recorder .Eventf (& cachedImage , "Normal" , "Expiring" , "Image %s has expired, deleting it" , cachedImage .Spec .SourceImage )
130137 err := r .Delete (ctx , & cachedImage )
131138 if err != nil {
139+ r .Recorder .Eventf (& cachedImage , "Warning" , "ExpiringFailed" , "Image %s could not expire: %s" , cachedImage .Spec .SourceImage , err )
132140 return ctrl.Result {}, err
133141 }
142+ r .Recorder .Eventf (& cachedImage , "Normal" , "Expired" , "Image %s successfully expired" , cachedImage .Spec .SourceImage )
134143 return ctrl.Result {}, nil
135144 } else {
136145 return ctrl.Result {RequeueAfter : expiresAt .Sub (time .Now ())}, nil
@@ -139,17 +148,28 @@ func (r *CachedImageReconciler) Reconcile(ctx context.Context, req ctrl.Request)
139148
140149 // Adding image to registry
141150 log .Info ("caching image" )
142- keychain := registry .NewKubernetesKeychain ( r . Client , cachedImage .Spec .PullSecretsNamespace , cachedImage . Spec . PullSecretNames )
143- if cacheUpdated , err := registry . CacheImage ( cachedImage . Spec . SourceImage , keychain ); err != nil {
144- log .Error (err , "failed to cache image" )
151+ isCached , err := registry .ImageIsCached ( cachedImage .Spec .SourceImage )
152+ if err != nil {
153+ log .Error (err , "could not determine if the image present in cache " )
145154 return ctrl.Result {}, err
146- } else if cacheUpdated {
147- log .Info ("image cached" )
148- if err := r .Get (ctx , req .NamespacedName , & cachedImage ); err != nil {
149- return ctrl.Result {}, client .IgnoreNotFound (err )
155+ }
156+
157+ if ! isCached {
158+ r .Recorder .Eventf (& cachedImage , "Normal" , "Caching" , "Start caching image %s" , cachedImage .Spec .SourceImage )
159+ keychain := registry .NewKubernetesKeychain (r .Client , cachedImage .Spec .PullSecretsNamespace , cachedImage .Spec .PullSecretNames )
160+ if err := registry .CacheImage (cachedImage .Spec .SourceImage , keychain ); err != nil {
161+ log .Error (err , "failed to cache image" )
162+ r .Recorder .Eventf (& cachedImage , "Warning" , "CacheFailed" , "Failed to cache image %s, reason: %s" , cachedImage .Spec .SourceImage , err )
163+ return ctrl.Result {}, err
164+ } else {
165+ log .Info ("image cached" )
166+ r .Recorder .Eventf (& cachedImage , "Normal" , "Cached" , "Successfully cached image %s" , cachedImage .Spec .SourceImage )
167+ if err := r .Get (ctx , req .NamespacedName , & cachedImage ); err != nil {
168+ return ctrl.Result {}, client .IgnoreNotFound (err )
169+ }
150170 }
151171 } else {
152- log .Info ("image already cached, cache not updated " )
172+ log .Info ("image already present in cache, ignoring " )
153173 }
154174
155175 // Update CachedImage IsCached status
0 commit comments