@@ -33,12 +33,7 @@ import (
33
33
"k8s.io/kubernetes/pkg/volume/util"
34
34
)
35
35
36
- // CreateVolumeSpec creates and returns a mutatable volume.Spec object for the
37
- // specified volume. It dereference any PVC to get PV objects, if needed.
38
- // A volume.Spec that refers to an in-tree plugin spec is translated to refer
39
- // to a migrated CSI plugin spec if all conditions for CSI migration on a node
40
- // for the in-tree plugin is satisfied.
41
- func CreateVolumeSpec (logger klog.Logger , podVolume v1.Volume , pod * v1.Pod , nodeName types.NodeName , vpm * volume.VolumePluginMgr , pvcLister corelisters.PersistentVolumeClaimLister , pvLister corelisters.PersistentVolumeLister , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator ) (* volume.Spec , error ) {
36
+ func createInTreeVolumeSpec (logger klog.Logger , podVolume * v1.Volume , pod * v1.Pod , vpm * volume.VolumePluginMgr , pvcLister corelisters.PersistentVolumeClaimLister , pvLister corelisters.PersistentVolumeLister , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator ) (* volume.Spec , string , error ) {
42
37
claimName := ""
43
38
readOnly := false
44
39
if pvcSource := podVolume .VolumeSource .PersistentVolumeClaim ; pvcSource != nil {
@@ -47,67 +42,83 @@ func CreateVolumeSpec(logger klog.Logger, podVolume v1.Volume, pod *v1.Pod, node
47
42
}
48
43
isEphemeral := podVolume .VolumeSource .Ephemeral != nil
49
44
if isEphemeral {
50
- claimName = ephemeral .VolumeClaimName (pod , & podVolume )
45
+ claimName = ephemeral .VolumeClaimName (pod , podVolume )
46
+ }
47
+ if claimName == "" {
48
+ // In-line volume
49
+ return volume .NewSpecFromVolume (podVolume ), "" , nil
51
50
}
52
- if claimName != "" {
53
- logger .V (10 ).Info ("Found PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ))
51
+ // The volume is a PVC, dereference the PVC + PV
52
+ logger .V (10 ).Info ("Found PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ))
54
53
55
- // If podVolume is a PVC, fetch the real PV behind the claim
56
- pvc , err := getPVCFromCache (pod .Namespace , claimName , pvcLister )
57
- if err != nil {
58
- return nil , fmt .Errorf (
59
- "error processing PVC %q/%q: %v" ,
60
- pod .Namespace ,
61
- claimName ,
62
- err )
63
- }
64
- if isEphemeral {
65
- if err := ephemeral .VolumeIsForPod (pod , pvc ); err != nil {
66
- return nil , err
67
- }
54
+ // If podVolume is a PVC, fetch the real PV behind the claim
55
+ pvc , err := getPVCFromCache (pod .Namespace , claimName , pvcLister )
56
+ if err != nil {
57
+ return nil , claimName , fmt .Errorf (
58
+ "error processing PVC %q/%q: %w" ,
59
+ pod .Namespace ,
60
+ claimName ,
61
+ err )
62
+ }
63
+ if isEphemeral {
64
+ if err := ephemeral .VolumeIsForPod (pod , pvc ); err != nil {
65
+ return nil , claimName , err
68
66
}
67
+ }
69
68
70
- pvName , pvcUID := pvc .Spec .VolumeName , pvc .UID
71
- logger .V (10 ).Info ("Found bound PV for PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ), "pvcUID" , pvcUID , "PV" , klog .KRef ("" , pvName ))
72
-
73
- // Fetch actual PV object
74
- volumeSpec , err := getPVSpecFromCache (
75
- pvName , readOnly , pvcUID , pvLister )
76
- if err != nil {
77
- return nil , fmt .Errorf (
78
- "error processing PVC %q/%q: %v" ,
79
- pod .Namespace ,
80
- claimName ,
81
- err )
82
- }
69
+ pvName , pvcUID := pvc .Spec .VolumeName , pvc .UID
70
+ logger .V (10 ).Info ("Found bound PV for PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ), "pvcUID" , pvcUID , "PV" , klog .KRef ("" , pvName ))
83
71
84
- volumeSpec , err = translateInTreeSpecToCSIIfNeeded (logger , volumeSpec , nodeName , vpm , csiMigratedPluginManager , csiTranslator , pod .Namespace )
85
- if err != nil {
86
- return nil , fmt .Errorf (
87
- "error performing CSI migration checks and translation for PVC %q/%q: %v" ,
88
- pod .Namespace ,
89
- claimName ,
90
- err )
91
- }
72
+ // Fetch actual PV object
73
+ volumeSpec , err := getPVSpecFromCache (
74
+ pvName , readOnly , pvcUID , pvLister )
75
+ if err != nil {
76
+ return nil , claimName , fmt .Errorf (
77
+ "error processing PVC %q/%q: %w" ,
78
+ pod .Namespace ,
79
+ claimName ,
80
+ err )
81
+ }
92
82
93
- logger .V (10 ).Info ("Extracted volumeSpec from bound PV and PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ), "pvcUID" , pvcUID , "PV" , klog .KRef ("" , pvName ), "volumeSpecName" , volumeSpec .Name ())
83
+ logger .V (10 ).Info ("Extracted volumeSpec from bound PV and PVC" , "PVC" , klog .KRef (pod .Namespace , claimName ), "pvcUID" , pvcUID , "PV" , klog .KRef ("" , pvName ), "volumeSpecName" , volumeSpec .Name ())
84
+ return volumeSpec , claimName , nil
85
+ }
94
86
95
- return volumeSpec , nil
87
+ func CreateVolumeSpec (logger klog.Logger , podVolume v1.Volume , pod * v1.Pod , vpm * volume.VolumePluginMgr , pvcLister corelisters.PersistentVolumeClaimLister , pvLister corelisters.PersistentVolumeLister , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator ) (* volume.Spec , error ) {
88
+ volumeSpec , claimName , err := createInTreeVolumeSpec (logger , & podVolume , pod , vpm , pvcLister , pvLister , csiMigratedPluginManager , csiTranslator )
89
+ if err != nil {
90
+ return nil , err
96
91
}
92
+ volumeSpec , err = translateInTreeSpecToCSIIfNeeded (logger , volumeSpec , vpm , csiMigratedPluginManager , csiTranslator , pod .Namespace )
93
+ if err != nil {
94
+ return nil , fmt .Errorf (
95
+ "error performing CSI migration checks and translation for PVC %q/%q: %w" ,
96
+ pod .Namespace ,
97
+ claimName ,
98
+ err )
99
+ }
100
+ return volumeSpec , nil
101
+ }
97
102
98
- // Do not return the original volume object, since it's from the shared
99
- // informer it may be mutated by another consumer.
100
- clonedPodVolume := podVolume .DeepCopy ()
101
-
102
- origspec := volume .NewSpecFromVolume (clonedPodVolume )
103
- spec , err := translateInTreeSpecToCSIIfNeeded (logger , origspec , nodeName , vpm , csiMigratedPluginManager , csiTranslator , pod .Namespace )
103
+ // CreateVolumeSpec creates and returns a mutatable volume.Spec object for the
104
+ // specified volume. It dereference any PVC to get PV objects, if needed.
105
+ // A volume.Spec that refers to an in-tree plugin spec is translated to refer
106
+ // to a migrated CSI plugin spec if all conditions for CSI migration on a node
107
+ // for the in-tree plugin is satisfied.
108
+ func CreateVolumeSpecWithNodeMigration (logger klog.Logger , podVolume v1.Volume , pod * v1.Pod , nodeName types.NodeName , vpm * volume.VolumePluginMgr , pvcLister corelisters.PersistentVolumeClaimLister , pvLister corelisters.PersistentVolumeLister , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator ) (* volume.Spec , error ) {
109
+ volumeSpec , claimName , err := createInTreeVolumeSpec (logger , & podVolume , pod , vpm , pvcLister , pvLister , csiMigratedPluginManager , csiTranslator )
110
+ if err != nil {
111
+ return nil , err
112
+ }
113
+ volumeSpec , err = translateInTreeSpecToCSIOnNodeIfNeeded (logger , volumeSpec , nodeName , vpm , csiMigratedPluginManager , csiTranslator , pod .Namespace )
104
114
if err != nil {
105
115
return nil , fmt .Errorf (
106
- "error performing CSI migration checks and translation for inline volume %q: %v" ,
107
- podVolume .Name ,
116
+ "error performing CSI migration checks and translation for PVC %q/%q: %w" ,
117
+ pod .Namespace ,
118
+ claimName ,
108
119
err )
109
120
}
110
- return spec , nil
121
+ return volumeSpec , nil
111
122
}
112
123
113
124
// getPVCFromCache fetches the PVC object with the given namespace and
@@ -144,7 +155,6 @@ func getPVSpecFromCache(name string, pvcReadOnly bool, expectedClaimUID types.UI
144
155
if err != nil {
145
156
return nil , fmt .Errorf ("failed to find PV %q in PVInformer cache: %v" , name , err )
146
157
}
147
-
148
158
if pv .Spec .ClaimRef == nil {
149
159
return nil , fmt .Errorf (
150
160
"found PV object %q but it has a nil pv.Spec.ClaimRef indicating it is not yet bound to the claim" ,
@@ -204,7 +214,7 @@ func ProcessPodVolumes(logger klog.Logger, pod *v1.Pod, addVolumes bool, desired
204
214
205
215
// Process volume spec for each volume defined in pod
206
216
for _ , podVolume := range pod .Spec .Volumes {
207
- volumeSpec , err := CreateVolumeSpec (logger , podVolume , pod , nodeName , volumePluginMgr , pvcLister , pvLister , csiMigratedPluginManager , csiTranslator )
217
+ volumeSpec , err := CreateVolumeSpecWithNodeMigration (logger , podVolume , pod , nodeName , volumePluginMgr , pvcLister , pvLister , csiMigratedPluginManager , csiTranslator )
208
218
if err != nil {
209
219
logger .V (10 ).Info ("Error processing volume for pod" , "pod" , klog .KObj (pod ), "volumeName" , podVolume .Name , "err" , err )
210
220
continue
@@ -240,7 +250,7 @@ func ProcessPodVolumes(logger klog.Logger, pod *v1.Pod, addVolumes bool, desired
240
250
}
241
251
}
242
252
243
- func translateInTreeSpecToCSIIfNeeded (logger klog.Logger , spec * volume.Spec , nodeName types.NodeName , vpm * volume.VolumePluginMgr , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator , podNamespace string ) (* volume.Spec , error ) {
253
+ func translateInTreeSpecToCSIOnNodeIfNeeded (logger klog.Logger , spec * volume.Spec , nodeName types.NodeName , vpm * volume.VolumePluginMgr , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator , podNamespace string ) (* volume.Spec , error ) {
244
254
translatedSpec := spec
245
255
migratable , err := csiMigratedPluginManager .IsMigratable (spec )
246
256
if err != nil {
@@ -263,6 +273,22 @@ func translateInTreeSpecToCSIIfNeeded(logger klog.Logger, spec *volume.Spec, nod
263
273
return translatedSpec , nil
264
274
}
265
275
276
+ func translateInTreeSpecToCSIIfNeeded (logger klog.Logger , spec * volume.Spec , vpm * volume.VolumePluginMgr , csiMigratedPluginManager csimigration.PluginManager , csiTranslator csimigration.InTreeToCSITranslator , podNamespace string ) (* volume.Spec , error ) {
277
+ migratable , err := csiMigratedPluginManager .IsMigratable (spec )
278
+ if err != nil {
279
+ return nil , err
280
+ }
281
+ if ! migratable {
282
+ // Jump out of translation fast so we don't check the node if the spec itself is not migratable
283
+ return spec , nil
284
+ }
285
+ translatedSpec , err := csimigration .TranslateInTreeSpecToCSI (logger , spec , podNamespace , csiTranslator )
286
+ if err != nil {
287
+ return nil , err
288
+ }
289
+ return translatedSpec , nil
290
+ }
291
+
266
292
func isCSIMigrationSupportedOnNode (nodeName types.NodeName , spec * volume.Spec , vpm * volume.VolumePluginMgr , csiMigratedPluginManager csimigration.PluginManager ) (bool , error ) {
267
293
pluginName , err := csiMigratedPluginManager .GetInTreePluginNameFromSpec (spec .PersistentVolume , spec .Volume )
268
294
if err != nil {
0 commit comments