Skip to content

Commit a941b5d

Browse files
committed
Make Pod informer registration optional
1 parent 0df1aa7 commit a941b5d

File tree

3 files changed

+100
-29
lines changed

3 files changed

+100
-29
lines changed

cmd/csi-resizer/main.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ import (
2020
"context"
2121
"flag"
2222
"fmt"
23-
"k8s.io/client-go/util/workqueue"
2423
"os"
2524
"time"
2625

26+
"k8s.io/client-go/util/workqueue"
27+
2728
"github.com/kubernetes-csi/csi-lib-utils/leaderelection"
2829
"github.com/kubernetes-csi/external-resizer/pkg/controller"
2930
"github.com/kubernetes-csi/external-resizer/pkg/resizer"
@@ -53,6 +54,8 @@ var (
5354
metricsAddress = flag.String("metrics-address", "", "The TCP network address where the prometheus metrics endpoint will listen (example: `:8080`). The default is empty string, which means metrics endpoint is disabled.")
5455
metricsPath = flag.String("metrics-path", "/metrics", "The HTTP path where prometheus metrics will be exposed. Default is `/metrics`.")
5556

57+
handleVolumeInUseError = flag.Bool("handle-volume-inuse-error", true, "Flag to turn on/off capability to handle volume in use error in resizer controller")
58+
5659
version = "unknown"
5760
)
5861

@@ -88,7 +91,7 @@ func main() {
8891
resizerName := csiResizer.Name()
8992
rc := controller.NewResizeController(resizerName, csiResizer, kubeClient, *resyncPeriod, informerFactory,
9093
workqueue.NewItemExponentialFailureRateLimiter(*retryIntervalStart, *retryIntervalMax),
91-
)
94+
*handleVolumeInUseError)
9295
run := func(ctx context.Context) {
9396
informerFactory.Start(wait.NeverStop)
9497
rc.Run(*workers, ctx)

pkg/controller/controller.go

+33-25
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ type resizeController struct {
6262

6363
usedPVCs *inUsePVCStore
6464

65-
podLister corelisters.PodLister
66-
podListerSynced cache.InformerSynced
65+
podLister corelisters.PodLister
66+
podListerSynced cache.InformerSynced
67+
handleVolumeInUseError bool
6768
}
6869

6970
// NewResizeController returns a ResizeController.
@@ -73,13 +74,10 @@ func NewResizeController(
7374
kubeClient kubernetes.Interface,
7475
resyncPeriod time.Duration,
7576
informerFactory informers.SharedInformerFactory,
76-
pvcRateLimiter workqueue.RateLimiter) ResizeController {
77+
pvcRateLimiter workqueue.RateLimiter,
78+
handleVolumeInUseError bool) ResizeController {
7779
pvInformer := informerFactory.Core().V1().PersistentVolumes()
7880
pvcInformer := informerFactory.Core().V1().PersistentVolumeClaims()
79-
80-
// list pods so as we can identify PVC that are in-use
81-
podInformer := informerFactory.Core().V1().Pods()
82-
8381
eventBroadcaster := record.NewBroadcaster()
8482
eventBroadcaster.StartLogging(klog.Infof)
8583
eventBroadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events(v1.NamespaceAll)})
@@ -90,18 +88,17 @@ func NewResizeController(
9088
pvcRateLimiter, fmt.Sprintf("%s-pvc", name))
9189

9290
ctrl := &resizeController{
93-
name: name,
94-
resizer: resizer,
95-
kubeClient: kubeClient,
96-
pvLister: pvInformer.Lister(),
97-
pvSynced: pvInformer.Informer().HasSynced,
98-
pvcLister: pvcInformer.Lister(),
99-
pvcSynced: pvcInformer.Informer().HasSynced,
100-
podLister: podInformer.Lister(),
101-
podListerSynced: podInformer.Informer().HasSynced,
102-
claimQueue: claimQueue,
103-
eventRecorder: eventRecorder,
104-
usedPVCs: newUsedPVCStore(),
91+
name: name,
92+
resizer: resizer,
93+
kubeClient: kubeClient,
94+
pvLister: pvInformer.Lister(),
95+
pvSynced: pvInformer.Informer().HasSynced,
96+
pvcLister: pvcInformer.Lister(),
97+
pvcSynced: pvcInformer.Informer().HasSynced,
98+
claimQueue: claimQueue,
99+
eventRecorder: eventRecorder,
100+
usedPVCs: newUsedPVCStore(),
101+
handleVolumeInUseError: handleVolumeInUseError,
105102
}
106103

107104
// Add a resync period as the PVC's request size can be resized again when we handling
@@ -112,11 +109,18 @@ func NewResizeController(
112109
DeleteFunc: ctrl.deletePVC,
113110
}, resyncPeriod)
114111

115-
podInformer.Informer().AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{
116-
AddFunc: ctrl.addPod,
117-
DeleteFunc: ctrl.deletePod,
118-
UpdateFunc: ctrl.updatePod,
119-
}, resyncPeriod)
112+
if handleVolumeInUseError {
113+
// list pods so as we can identify PVC that are in-use
114+
klog.Infof("Register Pod informer for resizer %s", ctrl.name)
115+
podInformer := informerFactory.Core().V1().Pods()
116+
ctrl.podLister = podInformer.Lister()
117+
ctrl.podListerSynced = podInformer.Informer().HasSynced
118+
podInformer.Informer().AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{
119+
AddFunc: ctrl.addPod,
120+
DeleteFunc: ctrl.deletePod,
121+
UpdateFunc: ctrl.updatePod,
122+
}, resyncPeriod)
123+
}
120124

121125
return ctrl
122126
}
@@ -235,8 +239,12 @@ func (ctrl *resizeController) Run(
235239
defer klog.Infof("Shutting down external resizer %s", ctrl.name)
236240

237241
stopCh := ctx.Done()
242+
informersSyncd := []cache.InformerSynced{ctrl.pvSynced, ctrl.pvcSynced}
243+
if ctrl.handleVolumeInUseError {
244+
informersSyncd = append(informersSyncd, ctrl.podListerSynced)
245+
}
238246

239-
if !cache.WaitForCacheSync(stopCh, ctrl.pvSynced, ctrl.pvcSynced, ctrl.podListerSynced) {
247+
if !cache.WaitForCacheSync(stopCh, informersSyncd...) {
240248
klog.Errorf("Cannot sync pod, pv or pvc caches")
241249
return
242250
}

pkg/controller/controller_test.go

+62-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
func TestController(t *testing.T) {
2525
blockVolumeMode := v1.PersistentVolumeBlock
2626
fsVolumeMode := v1.PersistentVolumeFilesystem
27+
2728
for _, test := range []struct {
2829
Name string
2930
PVC *v1.PersistentVolumeClaim
@@ -37,7 +38,8 @@ func TestController(t *testing.T) {
3738
// is PVC being expanded in-use
3839
pvcInUse bool
3940
// does PVC being expanded has Failed Precondition errors
40-
pvcHasInUseErrors bool
41+
pvcHasInUseErrors bool
42+
disableVolumeInUseErrorHandler bool
4143
}{
4244
{
4345
Name: "Invalid key",
@@ -130,6 +132,64 @@ func TestController(t *testing.T) {
130132
pvcHasInUseErrors: true,
131133
pvcInUse: false,
132134
},
135+
// test cases with volume in use error handling disabled.
136+
{
137+
Name: "Feat disabled, Resize PVC, no FS resize, pvc-inuse with failedprecondition",
138+
PVC: createPVC(2, 1),
139+
PV: createPV(1, "testPVC", defaultNS, "foobar", &fsVolumeMode),
140+
CreateObjects: true,
141+
CallCSIExpand: true,
142+
pvcHasInUseErrors: true,
143+
pvcInUse: true,
144+
disableVolumeInUseErrorHandler: true,
145+
},
146+
{
147+
Name: "Feat disabled, Resize PVC, no FS resize, pvc-inuse but no failedprecondition error",
148+
PVC: createPVC(2, 1),
149+
PV: createPV(1, "testPVC", defaultNS, "foobar", &fsVolumeMode),
150+
CreateObjects: true,
151+
CallCSIExpand: true,
152+
pvcHasInUseErrors: false,
153+
pvcInUse: true,
154+
disableVolumeInUseErrorHandler: true,
155+
},
156+
{
157+
Name: "Feat disabled, Resize PVC, no FS resize, pvc not in-use but has failedprecondition error",
158+
PVC: createPVC(2, 1),
159+
PV: createPV(1, "testPVC", defaultNS, "foobar", &fsVolumeMode),
160+
CreateObjects: true,
161+
CallCSIExpand: true,
162+
pvcHasInUseErrors: true,
163+
pvcInUse: false,
164+
disableVolumeInUseErrorHandler: true,
165+
},
166+
{
167+
Name: "Feat disabled, Block Resize PVC with FS resize",
168+
PVC: createPVC(2, 1),
169+
PV: createPV(1, "testPVC", defaultNS, "foobar", &blockVolumeMode),
170+
CreateObjects: true,
171+
NodeResize: true,
172+
CallCSIExpand: true,
173+
expectBlockVolume: true,
174+
disableVolumeInUseErrorHandler: true,
175+
},
176+
{
177+
Name: "Feat disabled, Resize PVC with FS resize",
178+
PVC: createPVC(2, 1),
179+
PV: createPV(1, "testPVC", defaultNS, "foobar", &fsVolumeMode),
180+
CreateObjects: true,
181+
NodeResize: true,
182+
CallCSIExpand: true,
183+
disableVolumeInUseErrorHandler: true,
184+
},
185+
{
186+
Name: "Feat disabled, Resize PVC, no FS resize",
187+
PVC: createPVC(2, 1),
188+
PV: createPV(1, "testPVC", defaultNS, "foobar", &fsVolumeMode),
189+
CreateObjects: true,
190+
CallCSIExpand: true,
191+
disableVolumeInUseErrorHandler: true,
192+
},
133193
} {
134194
client := csi.NewMockClient("mock", test.NodeResize, true, true)
135195
driverName, _ := client.GetDriverName(context.TODO())
@@ -163,7 +223,7 @@ func TestController(t *testing.T) {
163223
t.Fatalf("Test %s: Unable to create resizer: %v", test.Name, err)
164224
}
165225

166-
controller := NewResizeController(driverName, csiResizer, kubeClient, time.Second, informerFactory, workqueue.DefaultControllerRateLimiter())
226+
controller := NewResizeController(driverName, csiResizer, kubeClient, time.Second, informerFactory, workqueue.DefaultControllerRateLimiter(), !test.disableVolumeInUseErrorHandler)
167227

168228
ctrlInstance, _ := controller.(*resizeController)
169229

0 commit comments

Comments
 (0)