diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index b08013dd36..ac27183f18 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -540,7 +540,12 @@ func (p *csiProvisioner) ProvisionExt(options controller.ProvisionOptions) (*v1. volumeAttributes[k] = v } respCap := rep.GetVolume().GetCapacityBytes() - if respCap < volSizeBytes { + + //According to CSI spec CreateVolume should be able to return capacity = 0, which means it is unknown. for example NFS/FTP + if respCap == 0 { + respCap = volSizeBytes + klog.V(3).Infof("csiClient response volume with size 0, which is not supported by apiServer, will use claim size:%d", respCap) + } else if respCap < volSizeBytes { capErr := fmt.Errorf("created volume capacity %v less than requested capacity %v", respCap, volSizeBytes) delReq := &csi.DeleteVolumeRequest{ VolumeId: rep.GetVolume().GetVolumeId(), diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 5ad80a2a2c..60b5764fc5 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -767,6 +767,7 @@ type provisioningTestcase struct { getSecretRefErr bool getCredentialsErr bool volWithLessCap bool + volWithZeroCap bool expectedPVSpec *pvSpec withSecretRefs bool createVolumeError error @@ -1341,6 +1342,34 @@ func TestProvision(t *testing.T) { expectErr: true, expectState: controller.ProvisioningInBackground, }, + "provision with size 0": { + volOpts: controller.ProvisionOptions{ + StorageClass: &storagev1.StorageClass{ + Parameters: map[string]string{ + "fstype": "ext3", + }, + ReclaimPolicy: &deletePolicy, + }, + PVName: "test-name", + PVC: createFakePVC(requestedBytes), + }, + volWithZeroCap: true, + expectedPVSpec: &pvSpec{ + Name: "test-testi", + ReclaimPolicy: v1.PersistentVolumeReclaimDelete, + Capacity: v1.ResourceList{ + v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes), + }, + CSIPVS: &v1.CSIPersistentVolumeSource{ + Driver: "test-driver", + VolumeHandle: "test-volume-id", + FSType: "ext3", + VolumeAttributes: map[string]string{ + "storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner", + }, + }, + }, + }, } for k, tc := range testcases { @@ -1451,6 +1480,9 @@ func runProvisionTest(t *testing.T, k string, tc provisioningTestcase, requested out.Volume.CapacityBytes = int64(80) controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Return(out, tc.createVolumeError).Times(1) controllerServer.EXPECT().DeleteVolume(gomock.Any(), gomock.Any()).Return(&csi.DeleteVolumeResponse{}, tc.createVolumeError).Times(1) + } else if tc.volWithZeroCap { + out.Volume.CapacityBytes = int64(0) + controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Return(out, nil).Times(1) } else if tc.expectCreateVolDo != nil { controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Do(tc.expectCreateVolDo).Return(out, tc.createVolumeError).Times(1) } else {