@@ -77,44 +77,55 @@ func (p *podVolModifier) getVolumePhase(vol *ActualVolume) VolumePhase {
77
77
return VolumePhaseModified
78
78
}
79
79
80
- if p .waitForNextTime (vol .PVC , vol .Desired .StorageClass ) {
80
+ if p .waitForNextTime (vol .PVC , vol .StorageClass , vol . Desired .StorageClass ) {
81
81
return VolumePhasePending
82
82
}
83
83
84
84
return VolumePhasePreparing
85
85
}
86
86
87
- func isVolumeExpansionSupported (sc * storagev1.StorageClass ) bool {
87
+ func isVolumeExpansionSupported (sc * storagev1.StorageClass ) (bool , error ) {
88
+ if sc == nil {
89
+ // always assume expansion is supported
90
+ return true , fmt .Errorf ("expansion cap of volume is unknown" )
91
+ }
88
92
if sc .AllowVolumeExpansion == nil {
89
- return false
93
+ return false , nil
90
94
}
91
- return * sc .AllowVolumeExpansion
95
+ return * sc .AllowVolumeExpansion , nil
92
96
}
93
97
94
98
func (p * podVolModifier ) validate (vol * ActualVolume ) error {
95
99
if vol .Desired == nil {
96
100
return fmt .Errorf ("can't match desired volume" )
97
101
}
98
- if vol .Desired .StorageClass == nil {
99
- // TODO: support default storage class
100
- return fmt .Errorf ("can't change storage class to the default one" )
101
- }
102
- desired := vol .Desired .Size
103
- actual := getStorageSize (vol .PVC .Spec .Resources .Requests )
102
+ desired := vol .Desired .GetStorageSize ()
103
+ actual := vol .GetStorageSize ()
104
104
result := desired .Cmp (actual )
105
105
switch {
106
106
case result == 0 :
107
107
case result < 0 :
108
108
return fmt .Errorf ("can't shrunk size from %s to %s" , & actual , & desired )
109
109
case result > 0 :
110
- if ! isVolumeExpansionSupported (vol .StorageClass ) {
110
+ supported , err := isVolumeExpansionSupported (vol .StorageClass )
111
+ if err != nil {
112
+ klog .Warningf ("volume expansion of storage class %s may be not supported, but it will be tried" , vol .GetStorageClassName ())
113
+ }
114
+ if ! supported {
111
115
return fmt .Errorf ("volume expansion is not supported by storageclass %s" , vol .StorageClass .Name )
112
116
}
113
117
}
114
- m := p .getVolumeModifier (vol .Desired .StorageClass )
118
+
119
+ m := p .getVolumeModifier (vol .StorageClass , vol .Desired .StorageClass )
115
120
if m == nil {
116
121
return nil
117
122
}
123
+
124
+ // if no pv permission but have sc permission: cannot change sc
125
+ if isStorageClassChanged (vol .GetStorageClassName (), vol .Desired .GetStorageClassName ()) && vol .PV == nil {
126
+ return fmt .Errorf ("cannot change storage class (%s to %s), because there is no permission to get persistent volume" , vol .GetStorageClassName (), vol .Desired .GetStorageClassName ())
127
+ }
128
+
118
129
desiredPVC := vol .PVC .DeepCopy ()
119
130
desiredPVC .Spec .Resources .Requests [corev1 .ResourceStorage ] = desired
120
131
@@ -128,7 +139,7 @@ func isPVCRevisionChanged(pvc *corev1.PersistentVolumeClaim) bool {
128
139
return specRevision != statusRevision
129
140
}
130
141
131
- func (p * podVolModifier ) waitForNextTime (pvc * corev1.PersistentVolumeClaim , sc * storagev1.StorageClass ) bool {
142
+ func (p * podVolModifier ) waitForNextTime (pvc * corev1.PersistentVolumeClaim , actualSc , desciredSc * storagev1.StorageClass ) bool {
132
143
str , ok := pvc .Annotations [annoKeyPVCLastTransitionTimestamp ]
133
144
if ! ok {
134
145
return false
@@ -139,7 +150,7 @@ func (p *podVolModifier) waitForNextTime(pvc *corev1.PersistentVolumeClaim, sc *
139
150
}
140
151
d := time .Since (timestamp )
141
152
142
- m := p .getVolumeModifier (sc )
153
+ m := p .getVolumeModifier (actualSc , desciredSc )
143
154
144
155
waitDur := defaultModifyWaitingDuration
145
156
if m != nil {
@@ -156,23 +167,14 @@ func (p *podVolModifier) waitForNextTime(pvc *corev1.PersistentVolumeClaim, sc *
156
167
157
168
func needModify (pvc * corev1.PersistentVolumeClaim , desired * DesiredVolume ) bool {
158
169
size := desired .Size
159
- scName := ""
160
- if desired .StorageClass != nil {
161
- scName = desired .StorageClass .Name
162
- }
170
+ scName := desired .GetStorageClassName ()
163
171
164
172
return isPVCStatusMatched (pvc , scName , size )
165
173
}
166
174
167
175
func isPVCStatusMatched (pvc * corev1.PersistentVolumeClaim , scName string , size resource.Quantity ) bool {
168
- isChanged := false
169
- oldSc , ok := pvc .Annotations [annoKeyPVCStatusStorageClass ]
170
- if ! ok {
171
- oldSc = ignoreNil (pvc .Spec .StorageClassName )
172
- }
173
- if oldSc != scName {
174
- isChanged = true
175
- }
176
+ oldSc := getStorageClassNameFromPVC (pvc )
177
+ isChanged := isStorageClassChanged (oldSc , scName )
176
178
177
179
oldSize , ok := pvc .Annotations [annoKeyPVCStatusStorageSize ]
178
180
if ! ok {
@@ -188,3 +190,10 @@ func isPVCStatusMatched(pvc *corev1.PersistentVolumeClaim, scName string, size r
188
190
189
191
return isChanged
190
192
}
193
+
194
+ func isStorageClassChanged (pre , cur string ) bool {
195
+ if cur != "" && pre != cur {
196
+ return true
197
+ }
198
+ return false
199
+ }
0 commit comments