@@ -84,6 +84,7 @@ type Controller struct {
84
84
helmRequestSynced cache.InformerSynced
85
85
86
86
chartRepoSynced cache.InformerSynced
87
+ chartRepoLister listers.ChartRepoLister
87
88
88
89
// ClusterCache is used to store Cluster resource
89
90
ClusterCache * commoncache.Cache
@@ -93,7 +94,8 @@ type Controller struct {
93
94
// means we can ensure we only process a fixed amount of resources at a
94
95
// time, and makes it easy to ensure we are never processing the same item
95
96
// simultaneously in two different workers.
96
- workQueue workqueue.RateLimitingInterface
97
+ workQueue workqueue.RateLimitingInterface
98
+ chartRepoWorkQueue workqueue.RateLimitingInterface
97
99
// recorder is an event recorder for recording Event resources to the
98
100
// Kubernetes API.
99
101
recorder record.EventRecorder
@@ -132,12 +134,14 @@ func NewController(mgr manager.Manager, opt *config.Options, stopCh <-chan struc
132
134
clusterClient : clusterClient ,
133
135
globalClusterName : opt .GlobalClusterName ,
134
136
},
135
- restConfig : cfg ,
136
- recorder : mgr .GetEventRecorderFor (util .ComponentName ),
137
- helmRequestLister : informer .Lister (),
138
- helmRequestSynced : informer .Informer ().HasSynced ,
139
- chartRepoSynced : repoInformer .Informer ().HasSynced ,
140
- workQueue : workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "HelmRequests" ),
137
+ restConfig : cfg ,
138
+ recorder : mgr .GetEventRecorderFor (util .ComponentName ),
139
+ helmRequestLister : informer .Lister (),
140
+ chartRepoLister : repoInformer .Lister (),
141
+ helmRequestSynced : informer .Informer ().HasSynced ,
142
+ chartRepoSynced : repoInformer .Informer ().HasSynced ,
143
+ workQueue : workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "HelmRequests" ),
144
+ chartRepoWorkQueue : workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "ChartRepos" ),
141
145
// refresh frequently
142
146
ClusterCache : commoncache .New (1 * time .Minute , 5 * time .Minute ),
143
147
}
@@ -173,6 +177,7 @@ func (c *Controller) GetClusterClient() clusterclientset.Interface {
173
177
func (c * Controller ) Start (stopCh <- chan struct {}) error {
174
178
defer utilruntime .HandleCrash ()
175
179
defer c .workQueue .ShutDown ()
180
+ defer c .chartRepoWorkQueue .ShutDown ()
176
181
177
182
// Start the informer factories to begin populating the informer caches
178
183
klog .Info ("Starting HelmRequest controller" )
@@ -187,6 +192,7 @@ func (c *Controller) Start(stopCh <-chan struct{}) error {
187
192
// Launch two workers to process HelmRequest resources
188
193
for i := 0 ; i < 2 ; i ++ {
189
194
go wait .Until (c .runWorker , time .Second , stopCh )
195
+ go wait .Until (c .runChartRepoWorker , time .Second , stopCh )
190
196
}
191
197
192
198
klog .Info ("Started workers" )
@@ -204,6 +210,114 @@ func (c *Controller) runWorker() {
204
210
}
205
211
}
206
212
213
+ func (c * Controller ) runChartRepoWorker () {
214
+ for c .processNextChartRepo () {
215
+ }
216
+ }
217
+
218
+ // processNextWorkItem will read a single work item off the chartRepoWorkQueue and
219
+ // attempt to process it, by calling the syncHandler.
220
+ func (c * Controller ) processNextChartRepo () bool {
221
+ obj , shutdown := c .chartRepoWorkQueue .Get ()
222
+
223
+ if shutdown {
224
+ return false
225
+ }
226
+
227
+ // We wrap this block in a func so we can defer c.chartRepoWorkQueue.Done.
228
+ err := func (obj interface {}) error {
229
+ // We call Done here so the chartRepoWorkQueue knows we have finished
230
+ // processing this item. We also must remember to call Forget if we
231
+ // do not want this work item being re-queued. For example, we do
232
+ // not call Forget if a transient error occurs, instead the item is
233
+ // put back on the chartRepoWorkQueue and attempted again after a back-off
234
+ // period.
235
+ defer c .chartRepoWorkQueue .Done (obj )
236
+ var key string
237
+ var ok bool
238
+ // We expect strings to come off the chartRepoWorkQueue. These are of the
239
+ // form namespace/name. We do this as the delayed nature of the
240
+ // chartRepoWorkQueue means the items in the informer cache may actually be
241
+ // more up to date that when the item was initially put onto the
242
+ // chartRepoWorkQueue.
243
+ if key , ok = obj .(string ); ! ok {
244
+ // As the item in the chartRepoWorkQueue is actually invalid, we call
245
+ // Forget here else we'd go into a loop of attempting to
246
+ // process a work item that is invalid.
247
+ c .chartRepoWorkQueue .Forget (obj )
248
+ utilruntime .HandleError (fmt .Errorf ("expected string in chartRepoWorkQueue but got %#v" , obj ))
249
+ return nil
250
+ }
251
+ // Start the syncHandler, passing it the namespace/name string of the
252
+ // HelmRequest resource to be synced.
253
+ if err := c .syncChartRepoHandler (key ); err != nil {
254
+ // Put the item back on the chartRepoWorkQueue to handle any transient errors.
255
+ c .chartRepoWorkQueue .AddRateLimited (key )
256
+ return fmt .Errorf ("error syncing chartrepo '%s': %s, requeuing" , key , err .Error ())
257
+ }
258
+ // Finally, if no error occurs we Forget this item so it does not
259
+ // get queued again until another change happens.
260
+ c .chartRepoWorkQueue .Forget (obj )
261
+ klog .Infof ("Successfully synced '%s'" , key )
262
+ return nil
263
+ }(obj )
264
+
265
+ if err != nil {
266
+ utilruntime .HandleError (err )
267
+ return true
268
+ }
269
+
270
+ return true
271
+ }
272
+
273
+ // syncHandler compares the actual state with the desired, and attempts to
274
+ // converge the two. It then updates the Status block of the HelmRequest resource
275
+ // with the current status of the resource.
276
+ func (c * Controller ) syncChartRepoHandler (key string ) error {
277
+ // Convert the namespace/name string into a distinct namespace and name
278
+ namespace , name , err := cache .SplitMetaNamespaceKey (key )
279
+ if err != nil {
280
+ utilruntime .HandleError (fmt .Errorf ("invalid resource key: %s" , key ))
281
+ return nil
282
+ }
283
+ klog .V (9 ).Infof ("" )
284
+
285
+ // Get the HelmRequest resource with this namespace/name
286
+ chartRepo , err := c .chartRepoLister .ChartRepos (namespace ).Get (name )
287
+ if err != nil {
288
+ // The HelmRequest resource may no longer exist, in which case we stop
289
+ // processing.
290
+ if errors .IsNotFound (err ) {
291
+ utilruntime .HandleError (fmt .Errorf ("repo '%s' in work queue no longer exists" , key ))
292
+ return nil
293
+ }
294
+
295
+ return err
296
+ }
297
+
298
+ if ! chartRepo .DeletionTimestamp .IsZero () {
299
+ klog .Infof ("ChartRepo has not nil DeletionTimestamp, starting to delete it: %s" , chartRepo .Name )
300
+ return nil
301
+ }
302
+
303
+ c .syncChartRepo (chartRepo )
304
+
305
+ return nil
306
+ }
307
+
308
+ // enqueueHelmRequest takes a HelmRequest resource and converts it into a namespace/name
309
+ // string which is then put onto the work queue. This method should *not* be
310
+ // passed resources of any type other than HelmRequest.
311
+ func (c * Controller ) enqueueChartRepo (obj interface {}) {
312
+ var key string
313
+ var err error
314
+ if key , err = cache .MetaNamespaceKeyFunc (obj ); err != nil {
315
+ utilruntime .HandleError (err )
316
+ return
317
+ }
318
+ c .chartRepoWorkQueue .Add (key )
319
+ }
320
+
207
321
// processNextWorkItem will read a single work item off the workQueue and
208
322
// attempt to process it, by calling the syncHandler.
209
323
func (c * Controller ) processNextWorkItem () bool {
0 commit comments