Skip to content

Commit 365b457

Browse files
authored
Merge pull request kubernetes#128455 from jsafrane/refactor-kcm-plugins
Refactor KCM volume plugin probe
2 parents 7a43ede + 9e29f95 commit 365b457

File tree

4 files changed

+132
-41
lines changed

4 files changed

+132
-41
lines changed

cmd/kube-controller-manager/app/core.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ func newPersistentVolumeBinderControllerDescriptor() *ControllerDescriptor {
270270

271271
func startPersistentVolumeBinderController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
272272
logger := klog.FromContext(ctx)
273-
plugins, err := ProbeControllerVolumePlugins(logger, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
273+
plugins, err := ProbeProvisionableRecyclableVolumePlugins(logger, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
274274
if err != nil {
275275
return nil, true, fmt.Errorf("failed to probe volume plugins when starting persistentvolume controller: %v", err)
276276
}
@@ -307,7 +307,7 @@ func startPersistentVolumeAttachDetachController(ctx context.Context, controller
307307
csiNodeInformer := controllerContext.InformerFactory.Storage().V1().CSINodes()
308308
csiDriverInformer := controllerContext.InformerFactory.Storage().V1().CSIDrivers()
309309

310-
plugins, err := ProbeAttachableVolumePlugins(logger)
310+
plugins, err := ProbeAttachableVolumePlugins(logger, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
311311
if err != nil {
312312
return nil, true, fmt.Errorf("failed to probe volume plugins when starting attach/detach controller: %v", err)
313313
}

cmd/kube-controller-manager/app/plugins.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ import (
2424
"fmt"
2525

2626
"k8s.io/klog/v2"
27+
"k8s.io/kubernetes/pkg/volume/csi"
28+
"k8s.io/kubernetes/pkg/volume/iscsi"
2729

2830
// Volume plugins
2931
"k8s.io/kubernetes/pkg/volume"
30-
"k8s.io/kubernetes/pkg/volume/csi"
3132
"k8s.io/kubernetes/pkg/volume/fc"
3233
"k8s.io/kubernetes/pkg/volume/flexvolume"
3334
"k8s.io/kubernetes/pkg/volume/hostpath"
34-
"k8s.io/kubernetes/pkg/volume/iscsi"
3535
"k8s.io/kubernetes/pkg/volume/nfs"
3636
volumeutil "k8s.io/kubernetes/pkg/volume/util"
3737

@@ -42,19 +42,11 @@ import (
4242

4343
// ProbeAttachableVolumePlugins collects all volume plugins for the attach/
4444
// detach controller.
45-
// The list of plugins is manually compiled. This code and the plugin
46-
// initialization code for kubelet really, really need a through refactor.
47-
func ProbeAttachableVolumePlugins(logger klog.Logger) ([]volume.VolumePlugin, error) {
48-
var err error
49-
allPlugins := []volume.VolumePlugin{}
50-
allPlugins, err = appendAttachableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
51-
if err != nil {
52-
return allPlugins, err
53-
}
54-
allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
55-
allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...)
56-
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
57-
return allPlugins, nil
45+
func ProbeAttachableVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
46+
return probeControllerVolumePlugins(logger, config, func(plugin volume.VolumePlugin) bool {
47+
_, ok := plugin.(volume.AttachableVolumePlugin)
48+
return ok
49+
})
5850
}
5951

6052
// GetDynamicPluginProber gets the probers of dynamically discoverable plugins
@@ -66,21 +58,31 @@ func GetDynamicPluginProber(config persistentvolumeconfig.VolumeConfiguration) v
6658

6759
// ProbeExpandableVolumePlugins returns volume plugins which are expandable
6860
func ProbeExpandableVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
69-
var err error
70-
allPlugins := []volume.VolumePlugin{}
71-
allPlugins, err = appendExpandableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
72-
if err != nil {
73-
return allPlugins, err
74-
}
75-
allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
76-
return allPlugins, nil
61+
return probeControllerVolumePlugins(logger, config, func(plugin volume.VolumePlugin) bool {
62+
_, ok := plugin.(volume.ExpandableVolumePlugin)
63+
return ok
64+
})
65+
}
66+
67+
func ProbeProvisionableRecyclableVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
68+
return probeControllerVolumePlugins(logger, config, func(plugin volume.VolumePlugin) bool {
69+
if _, ok := plugin.(volume.ProvisionableVolumePlugin); ok {
70+
return true
71+
}
72+
if _, ok := plugin.(volume.DeletableVolumePlugin); ok {
73+
return true
74+
}
75+
if _, ok := plugin.(volume.RecyclableVolumePlugin); ok {
76+
return true
77+
}
78+
return false
79+
})
7780
}
7881

79-
// ProbeControllerVolumePlugins collects all persistent volume plugins into an
80-
// easy to use list. Only volume plugins that implement any of
81-
// provisioner/recycler/deleter interface should be returned.
82-
func ProbeControllerVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
83-
allPlugins := []volume.VolumePlugin{}
82+
// probeControllerVolumePlugins collects all persistent volume plugins
83+
// used by KCM controllers into an easy to use list.
84+
func probeControllerVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration, filter func(plugin volume.VolumePlugin) bool) ([]volume.VolumePlugin, error) {
85+
var allPlugins []volume.VolumePlugin
8486

8587
// The list of plugins to probe is decided by this binary, not
8688
// by dynamic linking or other "magic". Plugins will be analyzed and
@@ -113,14 +115,28 @@ func ProbeControllerVolumePlugins(logger klog.Logger, config persistentvolumecon
113115
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
114116
}
115117
allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...)
118+
allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
119+
allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...)
120+
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
116121

117122
var err error
118-
allPlugins, err = appendExpandableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
123+
allPlugins, err = appendLegacyControllerProviders(logger, allPlugins, utilfeature.DefaultFeatureGate)
119124
if err != nil {
120125
return allPlugins, err
121126
}
122127

123-
return allPlugins, nil
128+
var filteredPlugins []volume.VolumePlugin
129+
if filter == nil {
130+
filteredPlugins = allPlugins
131+
} else {
132+
for _, plugin := range allPlugins {
133+
if filter(plugin) {
134+
filteredPlugins = append(filteredPlugins, plugin)
135+
}
136+
}
137+
}
138+
139+
return filteredPlugins, nil
124140
}
125141

126142
// AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume.

cmd/kube-controller-manager/app/plugins_providers.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ type pluginInfo struct {
5353
pluginProbeFunction probeFn
5454
}
5555

56-
func appendAttachableLegacyProviderVolumes(logger klog.Logger, allPlugins []volume.VolumePlugin, featureGate featuregate.FeatureGate) ([]volume.VolumePlugin, error) {
56+
func appendLegacyControllerProviders(logger klog.Logger, allPlugins []volume.VolumePlugin, featureGate featuregate.FeatureGate) ([]volume.VolumePlugin, error) {
5757
pluginMigrationStatus := make(map[string]pluginInfo)
5858
pluginMigrationStatus[plugins.PortworxVolumePluginName] = pluginInfo{pluginMigrationFeature: features.CSIMigrationPortworx, pluginUnregisterFeature: features.InTreePluginPortworxUnregister, pluginProbeFunction: portworx.ProbeVolumePlugins}
5959
var err error
@@ -65,11 +65,3 @@ func appendAttachableLegacyProviderVolumes(logger klog.Logger, allPlugins []volu
6565
}
6666
return allPlugins, nil
6767
}
68-
69-
func appendExpandableLegacyProviderVolumes(logger klog.Logger, allPlugins []volume.VolumePlugin, featureGate featuregate.FeatureGate) ([]volume.VolumePlugin, error) {
70-
return appendLegacyProviderVolumes(logger, allPlugins, featureGate)
71-
}
72-
73-
func appendLegacyProviderVolumes(logger klog.Logger, allPlugins []volume.VolumePlugin, featureGate featuregate.FeatureGate) ([]volume.VolumePlugin, error) {
74-
return appendAttachableLegacyProviderVolumes(logger, allPlugins, featureGate)
75-
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package app
18+
19+
import (
20+
"reflect"
21+
"sort"
22+
"testing"
23+
24+
"k8s.io/klog/v2/ktesting"
25+
persistentvolumeconfig "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/config"
26+
"k8s.io/kubernetes/pkg/volume"
27+
)
28+
29+
func checkPlugins(t *testing.T, got []volume.VolumePlugin, expected []string) {
30+
pluginNames := make([]string, len(got))
31+
for i, p := range got {
32+
pluginNames[i] = p.GetPluginName()
33+
}
34+
sort.Strings(pluginNames)
35+
sort.Strings(expected)
36+
if !reflect.DeepEqual(pluginNames, expected) {
37+
t.Errorf("Expected %+v, got %+v", expected, pluginNames)
38+
}
39+
}
40+
41+
func TestProbeAttachableVolumePlugins(t *testing.T) {
42+
logger, _ := ktesting.NewTestContext(t)
43+
plugins, err := ProbeAttachableVolumePlugins(logger, getConfig())
44+
if err != nil {
45+
t.Fatalf("ProbeAttachableVolumePlugins failed: %s", err)
46+
}
47+
checkPlugins(t, plugins, []string{"kubernetes.io/csi", "kubernetes.io/fc", "kubernetes.io/iscsi"})
48+
}
49+
50+
func TestProbeExpandableVolumePlugins(t *testing.T) {
51+
logger, _ := ktesting.NewTestContext(t)
52+
plugins, err := ProbeExpandableVolumePlugins(logger, getConfig())
53+
if err != nil {
54+
t.Fatalf("TestProbeExpandableVolumePlugins failed: %s", err)
55+
}
56+
checkPlugins(t, plugins, []string{"kubernetes.io/portworx-volume"})
57+
}
58+
59+
func TestProbeControllerVolumePlugins(t *testing.T) {
60+
logger, _ := ktesting.NewTestContext(t)
61+
plugins, err := ProbeProvisionableRecyclableVolumePlugins(logger, getConfig())
62+
if err != nil {
63+
t.Fatalf("ProbeControllerVolumePlugins failed: %s", err)
64+
}
65+
checkPlugins(t, plugins, []string{"kubernetes.io/host-path", "kubernetes.io/nfs", "kubernetes.io/portworx-volume"})
66+
}
67+
68+
func getConfig() persistentvolumeconfig.VolumeConfiguration {
69+
return persistentvolumeconfig.VolumeConfiguration{
70+
EnableHostPathProvisioning: true,
71+
EnableDynamicProvisioning: true,
72+
PersistentVolumeRecyclerConfiguration: persistentvolumeconfig.PersistentVolumeRecyclerConfiguration{
73+
MaximumRetry: 5,
74+
MinimumTimeoutNFS: 30,
75+
PodTemplateFilePathNFS: "",
76+
IncrementTimeoutNFS: 10,
77+
PodTemplateFilePathHostPath: "",
78+
MinimumTimeoutHostPath: 30,
79+
IncrementTimeoutHostPath: 10,
80+
},
81+
FlexVolumePluginDir: "",
82+
}
83+
}

0 commit comments

Comments
 (0)