Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a3f3695

Browse files
committed
Fix VolumeAttachment garbage collection for migrated PVs
1 parent 5f6b1fa commit a3f3695

File tree

3 files changed

+66
-44
lines changed

3 files changed

+66
-44
lines changed

pkg/controller/volume/attachdetach/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ go_test(
6464
"//pkg/features:go_default_library",
6565
"//pkg/volume:go_default_library",
6666
"//pkg/volume/csi:go_default_library",
67-
"//pkg/volume/gcepd:go_default_library",
6867
"//pkg/volume/util:go_default_library",
6968
"//staging/src/k8s.io/api/core/v1:go_default_library",
7069
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

pkg/controller/volume/attachdetach/attach_detach_controller.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -716,33 +716,45 @@ func (adc *attachDetachController) processVolumeAttachments() error {
716716
klog.Errorf("Unable to lookup pv object for: %q, err: %v", *pvName, err)
717717
continue
718718
}
719+
720+
var plugin volume.AttachableVolumePlugin
719721
volumeSpec := volume.NewSpecFromPersistentVolume(pv, false)
720-
plugin, err := adc.volumePluginMgr.FindAttachablePluginBySpec(volumeSpec)
721-
if err != nil || plugin == nil {
722-
// Currently VA objects are created for CSI volumes only. nil plugin is unexpected, generate a warning
723-
klog.Warningf(
724-
"Skipping processing the volume %q on nodeName: %q, no attacher interface found. err=%v",
725-
*pvName,
726-
nodeName,
727-
err)
728-
continue
722+
723+
// Consult csiMigratedPluginManager first before querying the plugins registered during runtime in volumePluginMgr.
724+
// In-tree plugins that provisioned PVs will not be registered anymore after migration to CSI, once the respective
725+
// feature gate is enabled.
726+
if inTreePluginName, err := adc.csiMigratedPluginManager.GetInTreePluginNameFromSpec(pv, nil); err == nil {
727+
if adc.csiMigratedPluginManager.IsMigrationEnabledForPlugin(inTreePluginName) {
728+
// PV is migrated and should be handled by the CSI plugin instead of the in-tree one
729+
plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
730+
// podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace
731+
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator)
732+
if err != nil {
733+
klog.Errorf(
734+
"Failed to translate intree volumeSpec to CSI volumeSpec for volume:%q, va.Name:%q, nodeName:%q: %s. Error: %v",
735+
*pvName,
736+
va.Name,
737+
nodeName,
738+
inTreePluginName,
739+
err)
740+
continue
741+
}
742+
}
729743
}
730-
pluginName := plugin.GetPluginName()
731-
if adc.csiMigratedPluginManager.IsMigrationEnabledForPlugin(pluginName) {
732-
plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
733-
// podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace
734-
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator)
735-
if err != nil {
736-
klog.Errorf(
737-
"Failed to translate intree volumeSpec to CSI volumeSpec for volume:%q, va.Name:%q, nodeName:%q: %v",
744+
745+
if plugin == nil {
746+
plugin, err = adc.volumePluginMgr.FindAttachablePluginBySpec(volumeSpec)
747+
if err != nil || plugin == nil {
748+
// Currently VA objects are created for CSI volumes only. nil plugin is unexpected, generate a warning
749+
klog.Warningf(
750+
"Skipping processing the volume %q on nodeName: %q, no attacher interface found. err=%v",
738751
*pvName,
739-
va.Name,
740752
nodeName,
741-
pluginName,
742753
err)
743754
continue
744755
}
745756
}
757+
746758
volumeName, err := volumeutil.GetUniqueVolumeNameFromSpec(plugin, volumeSpec)
747759
if err != nil {
748760
klog.Errorf(

pkg/controller/volume/attachdetach/attach_detach_controller_test.go

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import (
3636
"k8s.io/kubernetes/pkg/features"
3737
"k8s.io/kubernetes/pkg/volume"
3838
"k8s.io/kubernetes/pkg/volume/csi"
39-
"k8s.io/kubernetes/pkg/volume/gcepd"
4039
"k8s.io/kubernetes/pkg/volume/util"
4140
)
4241

@@ -351,17 +350,18 @@ func attachDetachRecoveryTestCase(t *testing.T, extraPods1 []*v1.Pod, extraPods2
351350
}
352351

353352
type vaTest struct {
354-
testName string
355-
volName string
356-
podName string
357-
podNodeName string
358-
pvName string
359-
vaName string
360-
vaNodeName string
361-
vaAttachStatus bool
362-
csiMigration bool
363-
expected_attaches map[string][]string
364-
expected_detaches map[string][]string
353+
testName string
354+
volName string
355+
podName string
356+
podNodeName string
357+
pvName string
358+
vaName string
359+
vaNodeName string
360+
vaAttachStatus bool
361+
csiMigration bool
362+
expected_attaches map[string][]string
363+
expected_detaches map[string][]string
364+
expectedASWAttachState cache.AttachState
365365
}
366366

367367
func Test_ADC_VolumeAttachmentRecovery(t *testing.T) {
@@ -398,15 +398,26 @@ func Test_ADC_VolumeAttachmentRecovery(t *testing.T) {
398398
expected_attaches: map[string][]string{},
399399
expected_detaches: map[string][]string{"mynode-1": {"vol1"}},
400400
},
401-
{
402-
testName: "CSI Migration",
403-
volName: "vol1",
404-
podNodeName: "mynode-1",
405-
pvName: "pv1",
406-
vaName: "va1",
407-
vaNodeName: "mynode-1",
408-
vaAttachStatus: false,
409-
csiMigration: true,
401+
{ // pod is scheduled, volume is migrated, attach status:false, verify volume is marked as attached
402+
testName: "Scheduled Pod with migrated PV",
403+
volName: "vol1",
404+
podNodeName: "mynode-1",
405+
pvName: "pv1",
406+
vaName: "va1",
407+
vaNodeName: "mynode-1",
408+
vaAttachStatus: false,
409+
csiMigration: true,
410+
expectedASWAttachState: cache.AttachStateAttached,
411+
},
412+
{ // pod is deleted, volume is migrated, attach status:false, verify volume is marked as uncertain
413+
testName: "Deleted Pod with migrated PV",
414+
volName: "vol1",
415+
pvName: "pv1",
416+
vaName: "va1",
417+
vaNodeName: "mynode-1",
418+
vaAttachStatus: false,
419+
csiMigration: true,
420+
expectedASWAttachState: cache.AttachStateUncertain,
410421
},
411422
} {
412423
t.Run(tc.testName, func(t *testing.T) {
@@ -424,7 +435,7 @@ func volumeAttachmentRecoveryTestCase(t *testing.T, tc vaTest) {
424435
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIMigrationGCE, tc.csiMigration)()
425436
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIMigrationGCEComplete, tc.csiMigration)()
426437

427-
plugins = gcepd.ProbeVolumePlugins()
438+
// if InTreePluginGCEUnregister is enabled, only the CSI plugin is registered but not the in-tree one
428439
plugins = append(plugins, csi.ProbeVolumePlugins()...)
429440
} else {
430441
plugins = controllervolumetesting.CreateTestPlugin()
@@ -569,8 +580,8 @@ func verifyExpectedVolumeState(t *testing.T, adc *attachDetachController, tc vaT
569580
// Since csi migration is turned on, the attach state for the PV should be in CSI format.
570581
attachedState := adc.actualStateOfWorld.GetAttachState(
571582
v1.UniqueVolumeName(csiPDUniqueNamePrefix+tc.volName), types.NodeName(tc.vaNodeName))
572-
if attachedState != cache.AttachStateAttached {
573-
t.Fatalf("Expected attachedState %v, but it is %v", cache.AttachStateAttached, attachedState)
583+
if attachedState != tc.expectedASWAttachState {
584+
t.Fatalf("Expected attachedState %v, but it is %v", tc.expectedASWAttachState, attachedState)
574585
}
575586

576587
// kubernetes.io/gce-pd/<volName> should not be marked when CSI Migration is on

0 commit comments

Comments
 (0)