Skip to content

Commit a99ad7c

Browse files
mrunalpagnisl-technicore
authored andcommitted
Support xfs file system type in block volumes
Support xfs file system type in block volumes. added e2es Support xfs file system type in block volumes. added unit test Support xfs file system type in block volumes. added e2es
1 parent f3c9d7b commit a99ad7c

File tree

9 files changed

+143
-15
lines changed

9 files changed

+143
-15
lines changed

pkg/csi-util/utils.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const (
4343
ociVolumeBackupID = "volume.beta.kubernetes.io/oci-volume-source"
4444

4545
// Block Volume Performance Units
46-
VpusPerGB = "vpusPerGB"
46+
VpusPerGB = "vpusPerGB"
4747
LowCostPerformanceOption = 0
4848
BalancedPerformanceOption = 10
4949
HigherPerformanceOption = 20
@@ -249,11 +249,11 @@ func FormatBytes(inputBytes int64) string {
249249

250250
func ValidateFsType(logger *zap.SugaredLogger, fsType string) string {
251251
defaultFsType := "ext4"
252-
if fsType == "ext4" || fsType == "ext3" {
252+
if fsType == "ext4" || fsType == "ext3" || fsType == "xfs" {
253253
return fsType
254254
} else if fsType != "" {
255255
//TODO: Remove this code when we support other than ext4 || ext3.
256-
logger.With("fsType", fsType).Warn("Supporting only 'ext4' as fsType.")
256+
logger.With("fsType", fsType).Warn("Supporting only 'ext4/ext3/xfs' as fsType.")
257257
return defaultFsType
258258
} else {
259259
//No fsType provided returning ext4

pkg/csi-util/utils_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ func Test_validateFsType(t *testing.T) {
7474
},
7575
want: "ext3",
7676
},
77+
{
78+
name: "Return xfs",
79+
args: args{
80+
logger: zap.S(),
81+
fsType: "xfs",
82+
},
83+
want: "xfs",
84+
},
7785
{
7886
name: "Return default ext4 for empty string",
7987
args: args{

pkg/csi/driver/controller.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ import (
2626

2727
const (
2828
// Prefix to apply to the name of a created volume. This should be the same as the option '--volume-name-prefix' of csi-provisioner.
29-
pvcPrefix = "csi"
30-
csiDriver = "csi"
31-
29+
pvcPrefix = "csi"
30+
csiDriver = "csi"
31+
fsTypeKey = "csi.storage.k8s.io/fstype"
32+
fsTypeKeyDeprecated = "fstype"
3233
timeout = time.Minute * 3
3334
kmsKey = "kms-key-id"
3435
attachmentType = "attachment-type"
@@ -70,14 +71,16 @@ type VolumeAttachmentOption struct {
7071
enableInTransitEncryption bool
7172
}
7273

73-
func extractVolumeParameters(parameters map[string]string) (VolumeParameters, error) {
74+
func extractVolumeParameters(log *zap.SugaredLogger, parameters map[string]string) (VolumeParameters, error) {
7475
p := VolumeParameters{
7576
diskEncryptionKey: "",
7677
attachmentParameter: make(map[string]string),
7778
vpusPerGB: 10, // default value is 10 -> Balanced
7879
}
7980
for k, v := range parameters {
8081
switch k {
82+
case fsTypeKeyDeprecated:
83+
log.Warnf("%s is deprecated, please use %s instead", fsTypeKeyDeprecated, fsTypeKey)
8184
case kmsKey:
8285
if v != "" {
8386
p.diskEncryptionKey = v
@@ -206,7 +209,7 @@ func (d *ControllerDriver) CreateVolume(ctx context.Context, req *csi.CreateVolu
206209
return nil, fmt.Errorf("duplicate volume %q exists", volumeName)
207210
}
208211

209-
volumeParams, err := extractVolumeParameters(req.GetParameters())
212+
volumeParams, err := extractVolumeParameters(log, req.GetParameters())
210213
if err != nil {
211214
log.Error("Failed to parse storageclass parameters %s", err)
212215
csiMetricDimension = util.GetMetricDimensionForComponent(util.ErrValidation, util.CSIStorageType)
@@ -296,6 +299,7 @@ func (d *ControllerDriver) CreateVolume(ctx context.Context, req *csi.CreateVolu
296299
},
297300
},
298301
},
302+
299303
VolumeContext: map[string]string{
300304
attachmentType: volumeParams.attachmentParameter[attachmentType],
301305
csi_util.VpusPerGB: strconv.FormatInt(volumeParams.vpusPerGB, 10),

pkg/csi/driver/controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ func TestExtractVolumeParameters(t *testing.T) {
10001000

10011001
for name, tt := range tests {
10021002
t.Run(name, func(t *testing.T) {
1003-
volumeParameters, err := extractVolumeParameters(tt.storageParameters)
1003+
volumeParameters, err := extractVolumeParameters(zap.S(), tt.storageParameters)
10041004
if (err != nil) != tt.wantErr {
10051005
t.Errorf("extractVolumeParameters() error = %v, wantErr %v", err, tt.wantErr)
10061006
return

test/e2e/cloud-provider-oci/block_volume_creation.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var _ = Describe("Block Volume Creation", func() {
3838
scName := f.CreateStorageClassOrFail(framework.ClassOCIExt3, core.ProvisionerNameDefault, map[string]string{block.FSType: "ext3"}, pvcJig.Labels, "", false)
3939
pvc := pvcJig.CreateAndAwaitPVCOrFail(f.Namespace.Name, framework.MinVolumeBlock, scName, setupF.AdLabel, nil)
4040
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
41+
_ = f.DeleteStorageClass(framework.ClassOCIExt3)
4142
})
4243

4344
It("Should be possible to create a persistent volume claim (PVC) for a block storage with no AD specified ", func() {

test/e2e/cloud-provider-oci/csi_volume_creation.go

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,106 @@ var _ = Describe("CSI Volume Creation", func() {
8484
})
8585
})
8686

87+
var _ = Describe("CSI Volume Creation with different fstypes", func() {
88+
f := framework.NewDefaultFramework("csi-fstypes")
89+
Context("[cloudprovider][storage][csi][fstypes][iSCSI]", func() {
90+
It("Create PVC with fstype as XFS", func() {
91+
pvcJig := framework.NewPVCTestJig(f.ClientSet, "csi-provisioner-e2e-tests-fstype-xfs")
92+
93+
scName := f.CreateStorageClassOrFail(framework.ClassOCIXfs, "blockvolume.csi.oraclecloud.com", map[string]string{framework.FstypeKey: "xfs"}, pvcJig.Labels, "WaitForFirstConsumer", true)
94+
pvc := pvcJig.CreateAndAwaitPVCOrFailCSI(f.Namespace.Name, framework.MaxVolumeBlock, scName, nil)
95+
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
96+
podName := pvcJig.NewPodForCSI("app-xfs", f.Namespace.Name, pvc.Name, setupF.AdLabel)
97+
98+
time.Sleep(60 * time.Second) //waiting for pod to up and running
99+
100+
pvcJig.CheckFilesystemTypeOfVolumeInsidePod(f.Namespace.Name, podName, "xfs")
101+
_ = f.DeleteStorageClass(framework.ClassOCIXfs)
102+
})
103+
It("Create PVC with fstype as EXT3", func() {
104+
pvcJig := framework.NewPVCTestJig(f.ClientSet, "csi-provisioner-e2e-tests-fstype-ext3")
105+
106+
scName := f.CreateStorageClassOrFail(framework.ClassOCIExt3, "blockvolume.csi.oraclecloud.com", map[string]string{framework.FstypeKey: "ext3"}, pvcJig.Labels, "WaitForFirstConsumer", true)
107+
pvc := pvcJig.CreateAndAwaitPVCOrFailCSI(f.Namespace.Name, framework.MaxVolumeBlock, scName, nil)
108+
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
109+
podName := pvcJig.NewPodForCSI("app-ext3", f.Namespace.Name, pvc.Name, setupF.AdLabel)
110+
111+
time.Sleep(60 * time.Second) //waiting for pod to up and running
112+
113+
pvcJig.CheckFilesystemTypeOfVolumeInsidePod(f.Namespace.Name, podName, "ext3")
114+
_ = f.DeleteStorageClass(framework.ClassOCIExt3)
115+
})
116+
})
117+
Context("[cloudprovider][storage][csi][fstypes][paravirtualized]", func() {
118+
It("Create PVC with fstype as XFS with paravirtualized attachment type", func() {
119+
pvcJig := framework.NewPVCTestJig(f.ClientSet, "csi-provisioner-e2e-tests-fstype-xfs")
120+
121+
scName := f.CreateStorageClassOrFail(framework.ClassOCIXfs, "blockvolume.csi.oraclecloud.com", map[string]string{framework.FstypeKey: "xfs", framework.KmsKey: setupF.CMEKKMSKey, framework.AttachmentType: framework.AttachmentTypeParavirtualized}, pvcJig.Labels, "WaitForFirstConsumer", true)
122+
pvc := pvcJig.CreateAndAwaitPVCOrFailCSI(f.Namespace.Name, framework.MaxVolumeBlock, scName, nil)
123+
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
124+
podName := pvcJig.NewPodForCSI("app-xfs", f.Namespace.Name, pvc.Name, setupF.AdLabel)
125+
pvcJig.CheckCMEKKey(f.Client.BlockStorage(), pvc.Name, f.Namespace.Name, setupF.CMEKKMSKey)
126+
pvcJig.CheckAttachmentTypeAndEncryptionType(f.Client.Compute(), pvc.Name, f.Namespace.Name, podName, framework.AttachmentTypeParavirtualized)
127+
time.Sleep(60 * time.Second) //waiting for pod to up and running
128+
129+
pvcJig.CheckFilesystemTypeOfVolumeInsidePod(f.Namespace.Name, podName, "xfs")
130+
_ = f.DeleteStorageClass(framework.ClassOCIXfs)
131+
})
132+
})
133+
Context("[cloudprovider][storage][csi][expand][fstypes][iSCSI]", func() {
134+
It("Expand PVC VolumeSize from 50Gi to 100Gi and asserts size, file existence and file corruptions for iSCSI volumes with xfs filesystem type", func() {
135+
var size = "100Gi"
136+
pvcJig := framework.NewPVCTestJig(f.ClientSet, "csi-pvc-expand-to-100gi-iscsi-xfs")
137+
138+
scName := f.CreateStorageClassOrFail(framework.ClassOCIXfs, "blockvolume.csi.oraclecloud.com",
139+
map[string]string{framework.AttachmentType: framework.AttachmentTypeISCSI, framework.FstypeKey: "xfs"},
140+
pvcJig.Labels, "WaitForFirstConsumer", true)
141+
pvc := pvcJig.CreateAndAwaitPVCOrFailCSI(f.Namespace.Name, framework.MinVolumeBlock, scName, nil)
142+
podName := pvcJig.NewPodForCSI("expanded-pvc-app", f.Namespace.Name, pvc.Name, setupF.AdLabel)
143+
144+
time.Sleep(60 * time.Second) //waiting for pod to up and running
145+
146+
expandedPvc := pvcJig.UpdateAndAwaitPVCOrFailCSI(pvc, pvc.Namespace, size, nil)
147+
148+
time.Sleep(120 * time.Second) //waiting for expanded pvc to be functional
149+
150+
pvcJig.CheckFilesystemTypeOfVolumeInsidePod(f.Namespace.Name, podName, "xfs")
151+
pvcJig.CheckVolumeCapacity("100Gi", expandedPvc.Name, f.Namespace.Name)
152+
pvcJig.CheckFileExists(f.Namespace.Name, podName, "/data", "testdata.txt")
153+
pvcJig.CheckFileCorruption(f.Namespace.Name, podName, "/data", "testdata.txt")
154+
pvcJig.CheckExpandedVolumeReadWrite(f.Namespace.Name, podName)
155+
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName, "100G")
156+
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
157+
_ = f.DeleteStorageClass(framework.ClassOCIXfs)
158+
})
159+
It("Expand PVC VolumeSize from 50Gi to 100Gi and asserts size, file existence and file corruptions for iSCSI volumes with ext3 filesystem type", func() {
160+
var size = "100Gi"
161+
pvcJig := framework.NewPVCTestJig(f.ClientSet, "csi-pvc-expand-to-100gi-iscsi-ext3")
162+
163+
scName := f.CreateStorageClassOrFail(framework.ClassOCIExt3, "blockvolume.csi.oraclecloud.com",
164+
map[string]string{framework.AttachmentType: framework.AttachmentTypeISCSI, framework.FstypeKey: "ext3"},
165+
pvcJig.Labels, "WaitForFirstConsumer", true)
166+
pvc := pvcJig.CreateAndAwaitPVCOrFailCSI(f.Namespace.Name, framework.MinVolumeBlock, scName, nil)
167+
podName := pvcJig.NewPodForCSI("expanded-pvc-app", f.Namespace.Name, pvc.Name, setupF.AdLabel)
168+
169+
time.Sleep(60 * time.Second) //waiting for pod to up and running
170+
171+
expandedPvc := pvcJig.UpdateAndAwaitPVCOrFailCSI(pvc, pvc.Namespace, size, nil)
172+
173+
time.Sleep(120 * time.Second) //waiting for expanded pvc to be functional
174+
175+
pvcJig.CheckFilesystemTypeOfVolumeInsidePod(f.Namespace.Name, podName, "ext3")
176+
pvcJig.CheckVolumeCapacity("100Gi", expandedPvc.Name, f.Namespace.Name)
177+
pvcJig.CheckFileExists(f.Namespace.Name, podName, "/data", "testdata.txt")
178+
pvcJig.CheckFileCorruption(f.Namespace.Name, podName, "/data", "testdata.txt")
179+
pvcJig.CheckExpandedVolumeReadWrite(f.Namespace.Name, podName)
180+
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName, "99G")
181+
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
182+
_ = f.DeleteStorageClass(framework.ClassOCIExt3)
183+
})
184+
})
185+
})
186+
87187
var _ = Describe("CSI Volume Expansion iSCSI", func() {
88188
f := framework.NewDefaultFramework("csi-expansion")
89189
Context("[cloudprovider][storage][csi][expand][iSCSI]", func() {
@@ -107,9 +207,8 @@ var _ = Describe("CSI Volume Expansion iSCSI", func() {
107207
pvcJig.CheckFileExists(f.Namespace.Name, podName, "/data", "testdata.txt")
108208
pvcJig.CheckFileCorruption(f.Namespace.Name, podName, "/data", "testdata.txt")
109209
pvcJig.CheckExpandedVolumeReadWrite(f.Namespace.Name, podName)
110-
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName)
210+
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName, "99G")
111211
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
112-
_ = f.DeleteStorageClass(framework.ClassOCICSIExpand)
113212
})
114213
})
115214
})
@@ -137,7 +236,7 @@ var _ = Describe("CSI Volume Expansion iSCSI", func() {
137236
pvcJig.CheckFileExists(f.Namespace.Name, podName, "/data", "testdata.txt")
138237
pvcJig.CheckFileCorruption(f.Namespace.Name, podName, "/data", "testdata.txt")
139238
pvcJig.CheckExpandedVolumeReadWrite(f.Namespace.Name, podName)
140-
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName)
239+
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName, "99G")
141240
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
142241
_ = f.DeleteStorageClass(framework.ClassOCICSIExpand)
143242
})
@@ -297,7 +396,7 @@ var _ = Describe("CSI Volume Expansion Paravirtualized", func() {
297396
pvcJig.CheckFileExists(f.Namespace.Name, podName, "/data", "testdata.txt")
298397
pvcJig.CheckFileCorruption(f.Namespace.Name, podName, "/data", "testdata.txt")
299398
pvcJig.CheckExpandedVolumeReadWrite(f.Namespace.Name, podName)
300-
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName)
399+
pvcJig.CheckUsableVolumeSizeInsidePod(f.Namespace.Name, podName, "99G")
301400
f.VolumeIds = append(f.VolumeIds, pvc.Spec.VolumeName)
302401
_ = f.DeleteStorageClass(framework.ClassOCICSIExpand)
303402
})

test/e2e/framework/framework.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const (
3434
ClassOCIHigh = "oci-bv-high"
3535
ClassOCIKMS = "oci-kms"
3636
ClassOCIExt3 = "oci-ext3"
37+
ClassOCIXfs = "oci-xfs"
3738
MinVolumeBlock = "50Gi"
3839
MaxVolumeBlock = "100Gi"
3940
VolumeFss = "1Gi"

test/e2e/framework/pod_util.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (j *PVCTestJig) CheckExpandedVolumeReadWrite(namespace string, podName stri
177177
}
178178

179179
//CheckUsableVolumeSizeInsidePod checks a pvc expanded pod with a dymincally provisioned volume
180-
func (j *PVCTestJig) CheckUsableVolumeSizeInsidePod(namespace string, podName string) {
180+
func (j *PVCTestJig) CheckUsableVolumeSizeInsidePod(namespace string, podName string, capacity string) {
181181

182182
command := fmt.Sprintf("df -BG | grep '/data'")
183183

@@ -187,7 +187,7 @@ func (j *PVCTestJig) CheckUsableVolumeSizeInsidePod(namespace string, podName st
187187
Logf("got err: %v, retry until timeout", err)
188188
return false, nil
189189
}
190-
if strings.Fields(strings.TrimSpace(stdout))[1] != "99G" {
190+
if strings.Fields(strings.TrimSpace(stdout))[1] != capacity {
191191
return false, nil
192192
} else {
193193
return true, nil
@@ -198,6 +198,20 @@ func (j *PVCTestJig) CheckUsableVolumeSizeInsidePod(namespace string, podName st
198198

199199
}
200200

201+
//CheckFilesystemTypeOfVolumeInsidePod Checks the volume is provisioned with FsType as requested
202+
func (j *PVCTestJig) CheckFilesystemTypeOfVolumeInsidePod(namespace string, podName string, expectedFsType string) {
203+
command := fmt.Sprintf("df -Th | grep '/data'")
204+
stdout, err := RunHostCmd(namespace, podName, command)
205+
if err != nil {
206+
Logf("got err: %v, retry until timeout", err)
207+
}
208+
actualFsType := strings.Fields(strings.TrimSpace(stdout))[1]
209+
if actualFsType != expectedFsType {
210+
Failf("Filesystem type: %s does not match expected: %s", actualFsType, expectedFsType)
211+
}
212+
Logf("Filesystem type: %s is as expected", actualFsType)
213+
}
214+
201215
// CreateAndAwaitNginxPodOrFail returns a pod definition based on the namespace using nginx image
202216
func (j *PVCTestJig) CreateAndAwaitNginxPodOrFail(ns string, pvc *v1.PersistentVolumeClaim, command string) string {
203217
By("Creating a pod with the dynamically provisioned volume")

test/e2e/framework/pvc_util.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const (
4747
AttachmentTypeISCSI = "iscsi"
4848
AttachmentTypeParavirtualized = "paravirtualized"
4949
AttachmentType = "attachment-type"
50+
FstypeKey = "csi.storage.k8s.io/fstype"
5051
)
5152

5253
// PVCTestJig is a jig to help create PVC tests.

0 commit comments

Comments
 (0)