@@ -26,10 +26,10 @@ import (
26
26
"google.golang.org/grpc/codes"
27
27
"google.golang.org/grpc/status"
28
28
v1 "k8s.io/api/core/v1"
29
- storagev1beta1 "k8s.io/api/storage/v1beta1"
30
29
apierrors "k8s.io/apimachinery/pkg/api/errors"
31
30
"k8s.io/client-go/tools/cache"
32
31
"k8s.io/klog/v2"
32
+ "k8s.io/utils/ptr"
33
33
)
34
34
35
35
const (
@@ -40,8 +40,6 @@ const (
40
40
41
41
// The return value bool is only used as a sentinel value when function returns without actually performing modification
42
42
func (ctrl * modifyController ) modify (pvc * v1.PersistentVolumeClaim , pv * v1.PersistentVolume ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error , bool ) {
43
- pvcSpecVacName := pvc .Spec .VolumeAttributesClassName
44
- curVacName := pvc .Status .CurrentVolumeAttributesClassName
45
43
pvcKey , err := cache .MetaNamespaceKeyFunc (pvc )
46
44
if err != nil {
47
45
return pvc , pv , err , false
@@ -53,74 +51,89 @@ func (ctrl *modifyController) modify(pvc *v1.PersistentVolumeClaim, pv *v1.Persi
53
51
return pvc , pv , delayModificationErr , false
54
52
}
55
53
56
- if pvcSpecVacName != nil && curVacName == nil {
57
- // First time adding VAC to a PVC
58
- return ctrl . validateVACAndModifyVolumeWithTarget ( pvc , pv )
59
- } else if pvcSpecVacName != nil && curVacName != nil && * pvcSpecVacName != * curVacName {
60
- // Check if PVC in uncertain state
61
- _ , inUncertainState := ctrl . uncertainPVCs . Load ( pvcKey )
62
- if ! inUncertainState {
63
- klog . V ( 3 ). InfoS ( "previous operation on the PVC failed with a final error, retrying" )
64
- return ctrl . validateVACAndModifyVolumeWithTarget ( pvc , pv )
65
- } else {
66
- vac , err := ctrl . vacLister . Get ( * pvcSpecVacName )
67
- if err != nil {
68
- if apierrors . IsNotFound ( err ) {
69
- ctrl . eventRecorder . Eventf ( pvc , v1 . EventTypeWarning , util . VolumeModifyFailed , "VAC " + * pvcSpecVacName + " does not exist." )
70
- }
71
- return pvc , pv , err , false
72
- }
73
- return ctrl . controllerModifyVolumeWithTarget ( pvc , pv , vac , pvcSpecVacName )
54
+ pvcSpecVacName := ptr . Deref ( pvc . Spec . VolumeAttributesClassName , "" )
55
+ curVacName := ptr . Deref ( pvc . Status . CurrentVolumeAttributesClassName , "" )
56
+ if pvc . Status . ModifyVolumeStatus == nil && pvcSpecVacName == curVacName {
57
+ // No modification required
58
+ return pvc , pv , nil , false
59
+ }
60
+
61
+ if pvcSpecVacName == "" && curVacName != "" {
62
+ klog . V ( 4 ). InfoS ( "Can only set VAC to empty for rollback" , "PV" , klog . KObj ( pv ) )
63
+ return pvc , pv , nil , false
64
+ }
65
+
66
+ // Check if PVC in uncertain state
67
+ _ , inUncertainState := ctrl . uncertainPVCs . Load ( pvcKey )
68
+ if inUncertainState {
69
+ pvcSpecVacName , parameters , err := ctrl . getTargetParameters ( pvc )
70
+ if err != nil {
71
+ return pvc , pv , err , false
74
72
}
73
+ return ctrl .controllerModifyVolumeWithTarget (pvc , pv , parameters , pvcSpecVacName )
75
74
}
76
75
77
- // No modification required
78
- return pvc , pv , nil , false
76
+ return ctrl .validateVACAndModifyVolumeWithTarget (pvc , pv )
77
+ }
78
+
79
+ func (ctrl * modifyController ) getTargetParameters (pvc * v1.PersistentVolumeClaim ) (pvcSpecVacName string , parameters map [string ]string , err error ) {
80
+ if pvc .Spec .VolumeAttributesClassName == nil || * pvc .Spec .VolumeAttributesClassName == "" {
81
+ pvcSpecVacName = "[nil]"
82
+ } else {
83
+ pvcSpecVacName = * pvc .Spec .VolumeAttributesClassName
84
+ vac , err := ctrl .vacLister .Get (pvcSpecVacName )
85
+ // Check if pvcSpecVac is valid and exist
86
+ if err != nil {
87
+ if apierrors .IsNotFound (err ) {
88
+ ctrl .eventRecorder .Eventf (pvc , v1 .EventTypeWarning , util .VolumeModifyFailed , "VAC " + pvcSpecVacName + " does not exist." )
89
+ }
90
+ klog .Errorf ("Get VAC with vac name %s in VACInformer cache failed: %v" , pvcSpecVacName , err )
91
+ return "" , nil , err
92
+ }
93
+ parameters = vac .Parameters
94
+ }
95
+ return pvcSpecVacName , parameters , nil
79
96
}
80
97
81
98
// func validateVACAndModifyVolumeWithTarget validate the VAC. The function sets pvc.Status.ModifyVolumeStatus
82
99
// to Pending if VAC does not exist and proceeds to trigger ModifyVolume if VAC exists
83
100
func (ctrl * modifyController ) validateVACAndModifyVolumeWithTarget (
84
101
pvc * v1.PersistentVolumeClaim ,
85
102
pv * v1.PersistentVolume ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error , bool ) {
86
- // The controller only triggers ModifyVolume if pvcSpecVacName is not nil nor empty
87
- pvcSpecVacName := pvc .Spec .VolumeAttributesClassName
88
- // Check if pvcSpecVac is valid and exist
89
- vac , err := ctrl .vacLister .Get (* pvcSpecVacName )
90
- if err == nil {
91
- // Mark pvc.Status.ModifyVolumeStatus as in progress
92
- pvc , err = ctrl .markControllerModifyVolumeStatus (pvc , v1 .PersistentVolumeClaimModifyVolumeInProgress , nil )
93
- if err != nil {
94
- return pvc , pv , err , false
95
- }
96
- // Record an event to indicate that external resizer is modifying this volume.
97
- ctrl .eventRecorder .Event (pvc , v1 .EventTypeNormal , util .VolumeModify ,
98
- fmt .Sprintf ("external resizer is modifying volume %s with vac %s" , pvc .Name , * pvcSpecVacName ))
99
- return ctrl .controllerModifyVolumeWithTarget (pvc , pv , vac , pvcSpecVacName )
100
- } else {
103
+
104
+ pvcSpecVacName , parameters , err := ctrl .getTargetParameters (pvc )
105
+ if err != nil {
101
106
if apierrors .IsNotFound (err ) {
102
- ctrl .eventRecorder .Eventf (pvc , v1 .EventTypeWarning , util .VolumeModifyFailed , "VAC " + * pvcSpecVacName + " does not exist." )
107
+ // Mark pvc.Status.ModifyVolumeStatus as pending
108
+ pvc , err = ctrl .markControllerModifyVolumeStatus (pvc , v1 .PersistentVolumeClaimModifyVolumePending , nil )
103
109
}
104
- klog .Errorf ("Get VAC with vac name %s in VACInformer cache failed: %v" , * pvcSpecVacName , err )
105
- // Mark pvc.Status.ModifyVolumeStatus as pending
106
- pvc , err = ctrl .markControllerModifyVolumeStatus (pvc , v1 .PersistentVolumeClaimModifyVolumePending , nil )
107
110
return pvc , pv , err , false
108
111
}
112
+
113
+ // Mark pvc.Status.ModifyVolumeStatus as in progress
114
+ pvc , err = ctrl .markControllerModifyVolumeStatus (pvc , v1 .PersistentVolumeClaimModifyVolumeInProgress , nil )
115
+ if err != nil {
116
+ return pvc , pv , err , false
117
+ }
118
+ // Record an event to indicate that external resizer is modifying this volume.
119
+ ctrl .eventRecorder .Event (pvc , v1 .EventTypeNormal , util .VolumeModify ,
120
+ fmt .Sprintf ("external resizer is modifying volume %s with vac %s" , pvc .Name , pvcSpecVacName ))
121
+ return ctrl .controllerModifyVolumeWithTarget (pvc , pv , parameters , pvcSpecVacName )
109
122
}
110
123
111
124
// func controllerModifyVolumeWithTarget trigger the CSI ControllerModifyVolume API call
112
125
// and handle both success and error scenarios
113
126
func (ctrl * modifyController ) controllerModifyVolumeWithTarget (
114
127
pvc * v1.PersistentVolumeClaim ,
115
128
pv * v1.PersistentVolume ,
116
- vacObj * storagev1beta1. VolumeAttributesClass ,
117
- pvcSpecVacName * string ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error , bool ) {
129
+ parameters map [ string ] string ,
130
+ pvcSpecVacName string ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error , bool ) {
118
131
var err error
119
- pvc , pv , err = ctrl .callModifyVolumeOnPlugin (pvc , pv , vacObj )
132
+ pvc , pv , err = ctrl .callModifyVolumeOnPlugin (pvc , pv , parameters )
120
133
if err == nil {
121
- klog .V (4 ).Infof ("Update volumeAttributesClass of PV %q to %s succeeded" , pv .Name , * pvcSpecVacName )
134
+ klog .V (4 ).Infof ("Update volumeAttributesClass of PV %q to %s succeeded" , pv .Name , pvcSpecVacName )
122
135
// Record an event to indicate that modify operation is successful.
123
- ctrl .eventRecorder .Eventf (pvc , v1 .EventTypeNormal , util .VolumeModifySuccess , fmt .Sprintf ("external resizer modified volume %s with vac %s successfully" , pvc .Name , vacObj . Name ))
136
+ ctrl .eventRecorder .Eventf (pvc , v1 .EventTypeNormal , util .VolumeModifySuccess , fmt .Sprintf ("external resizer modified volume %s with vac %s successfully" , pvc .Name , pvcSpecVacName ))
124
137
return pvc , pv , nil , true
125
138
} else {
126
139
errStatus , ok := status .FromError (err )
@@ -161,8 +174,7 @@ func (ctrl *modifyController) controllerModifyVolumeWithTarget(
161
174
func (ctrl * modifyController ) callModifyVolumeOnPlugin (
162
175
pvc * v1.PersistentVolumeClaim ,
163
176
pv * v1.PersistentVolume ,
164
- vac * storagev1beta1.VolumeAttributesClass ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error ) {
165
- parameters := vac .Parameters
177
+ parameters map [string ]string ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume , error ) {
166
178
if ctrl .extraModifyMetadata {
167
179
if len (parameters ) == 0 {
168
180
parameters = make (map [string ]string , 3 )
0 commit comments