@@ -19,7 +19,6 @@ package pvcprotection
19
19
import (
20
20
"context"
21
21
"fmt"
22
- "sync"
23
22
"time"
24
23
25
24
v1 "k8s.io/api/core/v1"
@@ -42,65 +41,6 @@ import (
42
41
43
42
// Controller is controller that removes PVCProtectionFinalizer
44
43
// from PVCs that are used by no pods.
45
-
46
- type LazyLivePodList struct {
47
- cache []v1.Pod
48
- controller * Controller
49
- }
50
-
51
- func (ll * LazyLivePodList ) getCache () []v1.Pod {
52
- return ll .cache
53
- }
54
-
55
- func (ll * LazyLivePodList ) setCache (pods []v1.Pod ) {
56
- ll .cache = pods
57
- }
58
-
59
- type pvcData struct {
60
- pvcKey string
61
- pvcName string
62
- }
63
-
64
- type pvcProcessingStore struct {
65
- namespaceToPVCsMap map [string ][]pvcData
66
- namespaceQueue workqueue.TypedInterface [string ]
67
- mu sync.Mutex
68
- }
69
-
70
- func NewPVCProcessingStore () * pvcProcessingStore {
71
- return & pvcProcessingStore {
72
- namespaceToPVCsMap : make (map [string ][]pvcData ),
73
- namespaceQueue : workqueue .NewTyped [string ](),
74
- }
75
- }
76
-
77
- func (m * pvcProcessingStore ) addOrUpdate (namespace string , pvcKey , pvcName string ) {
78
- m .mu .Lock ()
79
- defer m .mu .Unlock ()
80
- if _ , exists := m .namespaceToPVCsMap [namespace ]; ! exists {
81
- m .namespaceToPVCsMap [namespace ] = make ([]pvcData , 0 )
82
- m .namespaceQueue .Add (namespace )
83
- }
84
- m .namespaceToPVCsMap [namespace ] = append (m .namespaceToPVCsMap [namespace ], pvcData {pvcKey : pvcKey , pvcName : pvcName })
85
- }
86
-
87
- // Returns a list of pvcs and the associated namespace to be processed downstream
88
- func (m * pvcProcessingStore ) flushNextPVCsByNamespace () ([]pvcData , string ) {
89
-
90
- nextNamespace , quit := m .namespaceQueue .Get ()
91
- if quit {
92
- return nil , nextNamespace
93
- }
94
-
95
- m .mu .Lock ()
96
- defer m .mu .Unlock ()
97
- pvcs := m .namespaceToPVCsMap [nextNamespace ]
98
-
99
- delete (m .namespaceToPVCsMap , nextNamespace )
100
- m .namespaceQueue .Done (nextNamespace )
101
- return pvcs , nextNamespace
102
- }
103
-
104
44
type Controller struct {
105
45
client clientset.Interface
106
46
@@ -111,8 +51,7 @@ type Controller struct {
111
51
podListerSynced cache.InformerSynced
112
52
podIndexer cache.Indexer
113
53
114
- queue workqueue.TypedRateLimitingInterface [string ]
115
- pvcProcessingStore * pvcProcessingStore
54
+ queue workqueue.TypedRateLimitingInterface [string ]
116
55
}
117
56
118
57
// NewPVCProtectionController returns a new instance of PVCProtectionController.
@@ -123,7 +62,6 @@ func NewPVCProtectionController(logger klog.Logger, pvcInformer coreinformers.Pe
123
62
workqueue .DefaultTypedControllerRateLimiter [string ](),
124
63
workqueue.TypedRateLimitingQueueConfig [string ]{Name : "pvcprotection" },
125
64
),
126
- pvcProcessingStore : NewPVCProcessingStore (),
127
65
}
128
66
129
67
e .pvcLister = pvcInformer .Lister ()
@@ -162,7 +100,6 @@ func NewPVCProtectionController(logger klog.Logger, pvcInformer coreinformers.Pe
162
100
func (c * Controller ) Run (ctx context.Context , workers int ) {
163
101
defer utilruntime .HandleCrash ()
164
102
defer c .queue .ShutDown ()
165
- defer c .pvcProcessingStore .namespaceQueue .ShutDown ()
166
103
167
104
logger := klog .FromContext (ctx )
168
105
logger .Info ("Starting PVC protection controller" )
@@ -172,64 +109,45 @@ func (c *Controller) Run(ctx context.Context, workers int) {
172
109
return
173
110
}
174
111
175
- go wait .UntilWithContext (ctx , c .runMainWorker , time .Second )
176
112
for i := 0 ; i < workers ; i ++ {
177
- go wait .UntilWithContext (ctx , c .runProcessNamespaceWorker , time .Second )
113
+ go wait .UntilWithContext (ctx , c .runWorker , time .Second )
178
114
}
179
115
180
116
<- ctx .Done ()
181
117
}
182
118
183
- // Main worker batch-pulls PVC items off informer's work queue and populates namespace queue and namespace-PVCs map
184
- func (c * Controller ) runMainWorker (ctx context.Context ) {
185
- for c .processNextWorkItem () {
119
+ func (c * Controller ) runWorker (ctx context.Context ) {
120
+ for c .processNextWorkItem (ctx ) {
186
121
}
187
122
}
188
123
189
- // Consumer worker pulls items off namespace queue and processes associated PVCs
190
- func (c * Controller ) runProcessNamespaceWorker (ctx context.Context ) {
191
- for c .processPVCsByNamespace (ctx ) {
124
+ // processNextWorkItem deals with one pvcKey off the queue. It returns false when it's time to quit.
125
+ func (c * Controller ) processNextWorkItem (ctx context.Context ) bool {
126
+ pvcKey , quit := c .queue .Get ()
127
+ if quit {
128
+ return false
192
129
}
193
- }
130
+ defer c . queue . Done ( pvcKey )
194
131
195
- func (c * Controller ) processNextWorkItem () bool {
196
- queueLength := c .queue .Len ()
197
- for i := 0 ; i < queueLength ; i ++ {
198
- pvcKey , quit := c .queue .Get ()
199
- if quit {
200
- return false
201
- }
202
- pvcNamespace , pvcName , err := cache .SplitMetaNamespaceKey (pvcKey )
203
- if err != nil {
204
- utilruntime .HandleError (fmt .Errorf ("error parsing PVC key %q: %w" , pvcKey , err ))
205
- }
206
- c .pvcProcessingStore .addOrUpdate (pvcNamespace , pvcKey , pvcName )
132
+ pvcNamespace , pvcName , err := cache .SplitMetaNamespaceKey (pvcKey )
133
+ if err != nil {
134
+ utilruntime .HandleError (fmt .Errorf ("error parsing PVC key %q: %w" , pvcKey , err ))
135
+ return true
207
136
}
208
- return ! c .queue .ShuttingDown ()
209
- }
210
137
211
- func ( c * Controller ) processPVCsByNamespace (ctx context. Context ) bool {
212
- pvcList , namespace := c . pvcProcessingStore . flushNextPVCsByNamespace ()
213
- if pvcList == nil {
214
- return false
138
+ err = c . processPVC (ctx , pvcNamespace , pvcName )
139
+ if err == nil {
140
+ c . queue . Forget ( pvcKey )
141
+ return true
215
142
}
216
143
217
- lazyLivePodList := & LazyLivePodList {controller : c }
218
- for _ , item := range pvcList {
219
- pvcKey , pvcName := item .pvcKey , item .pvcName
220
- err := c .processPVC (ctx , namespace , pvcName , lazyLivePodList )
221
- if err == nil {
222
- c .queue .Forget (pvcKey )
223
- } else {
224
- c .queue .AddRateLimited (pvcKey )
225
- utilruntime .HandleError (fmt .Errorf ("PVC %v in namespace %v failed with: %w" , pvcName , namespace , err ))
226
- }
227
- c .queue .Done (pvcKey )
228
- }
144
+ utilruntime .HandleError (fmt .Errorf ("PVC %v failed with : %w" , pvcKey , err ))
145
+ c .queue .AddRateLimited (pvcKey )
146
+
229
147
return true
230
148
}
231
149
232
- func (c * Controller ) processPVC (ctx context.Context , pvcNamespace , pvcName string , lazyLivePodList * LazyLivePodList ) error {
150
+ func (c * Controller ) processPVC (ctx context.Context , pvcNamespace , pvcName string ) error {
233
151
logger := klog .FromContext (ctx )
234
152
logger .V (4 ).Info ("Processing PVC" , "PVC" , klog .KRef (pvcNamespace , pvcName ))
235
153
startTime := time .Now ()
@@ -249,7 +167,7 @@ func (c *Controller) processPVC(ctx context.Context, pvcNamespace, pvcName strin
249
167
if protectionutil .IsDeletionCandidate (pvc , volumeutil .PVCProtectionFinalizer ) {
250
168
// PVC should be deleted. Check if it's used and remove finalizer if
251
169
// it's not.
252
- isUsed , err := c .isBeingUsed (ctx , pvc , lazyLivePodList )
170
+ isUsed , err := c .isBeingUsed (ctx , pvc )
253
171
if err != nil {
254
172
return err
255
173
}
@@ -291,11 +209,11 @@ func (c *Controller) removeFinalizer(ctx context.Context, pvc *v1.PersistentVolu
291
209
logger .Error (err , "Error removing protection finalizer from PVC" , "PVC" , klog .KObj (pvc ))
292
210
return err
293
211
}
294
- logger .Info ("Removed protection finalizer from PVC" , "PVC" , klog .KObj (pvc ))
212
+ logger .V ( 3 ). Info ("Removed protection finalizer from PVC" , "PVC" , klog .KObj (pvc ))
295
213
return nil
296
214
}
297
215
298
- func (c * Controller ) isBeingUsed (ctx context.Context , pvc * v1.PersistentVolumeClaim , lazyLivePodList * LazyLivePodList ) (bool , error ) {
216
+ func (c * Controller ) isBeingUsed (ctx context.Context , pvc * v1.PersistentVolumeClaim ) (bool , error ) {
299
217
// Look for a Pod using pvc in the Informer's cache. If one is found the
300
218
// correct decision to keep pvc is taken without doing an expensive live
301
219
// list.
@@ -311,9 +229,7 @@ func (c *Controller) isBeingUsed(ctx context.Context, pvc *v1.PersistentVolumeCl
311
229
// mean such a Pod doesn't exist: it might just not be in the cache yet. To
312
230
// be 100% confident that it is safe to delete pvc make sure no Pod is using
313
231
// it among those returned by a live list.
314
-
315
- // Use lazy live pod list instead of directly calling API server
316
- return c .askAPIServer (ctx , pvc , lazyLivePodList )
232
+ return c .askAPIServer (ctx , pvc )
317
233
}
318
234
319
235
func (c * Controller ) askInformer (logger klog.Logger , pvc * v1.PersistentVolumeClaim ) (bool , error ) {
@@ -342,24 +258,16 @@ func (c *Controller) askInformer(logger klog.Logger, pvc *v1.PersistentVolumeCla
342
258
return false , nil
343
259
}
344
260
345
- func (c * Controller ) askAPIServer (ctx context.Context , pvc * v1.PersistentVolumeClaim , lazyLivePodList * LazyLivePodList ) (bool , error ) {
261
+ func (c * Controller ) askAPIServer (ctx context.Context , pvc * v1.PersistentVolumeClaim ) (bool , error ) {
346
262
logger := klog .FromContext (ctx )
347
263
logger .V (4 ).Info ("Looking for Pods using PVC with a live list" , "PVC" , klog .KObj (pvc ))
348
- if lazyLivePodList .getCache () == nil {
349
- podsList , err := c .client .CoreV1 ().Pods (pvc .Namespace ).List (ctx , metav1.ListOptions {})
350
264
351
- if err != nil {
352
- return false , fmt .Errorf ("live list of pods failed: %s" , err .Error ())
353
- }
354
-
355
- if podsList .Items == nil {
356
- lazyLivePodList .setCache (make ([]v1.Pod , 0 ))
357
- } else {
358
- lazyLivePodList .setCache (podsList .Items )
359
- }
265
+ podsList , err := c .client .CoreV1 ().Pods (pvc .Namespace ).List (ctx , metav1.ListOptions {})
266
+ if err != nil {
267
+ return false , fmt .Errorf ("live list of pods failed: %s" , err .Error ())
360
268
}
361
269
362
- for _ , pod := range lazyLivePodList . getCache () {
270
+ for _ , pod := range podsList . Items {
363
271
if c .podUsesPVC (logger , & pod , pvc ) {
364
272
return true , nil
365
273
}
0 commit comments