Skip to content

Commit 012ea43

Browse files
committed
Merge pull request oracle#348 in OKE/oci-cloud-controller-manager from OKE-21804-1.24 to release-1.24
* commit 'de5786ae44d42403258567525e4890d2ad434292': JIRA: OKE-21804 Support xfs file system type in block volumes
2 parents 3843f92 + de5786a commit 012ea43

File tree

9 files changed

+143
-15
lines changed

9 files changed

+143
-15
lines changed

pkg/csi-util/utils.go

+3-3
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

+8
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

+9-5
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ func TestExtractVolumeParameters(t *testing.T) {
10201020

10211021
for name, tt := range tests {
10221022
t.Run(name, func(t *testing.T) {
1023-
volumeParameters, err := extractVolumeParameters(tt.storageParameters)
1023+
volumeParameters, err := extractVolumeParameters(zap.S(), tt.storageParameters)
10241024
if (err != nil) != tt.wantErr {
10251025
t.Errorf("extractVolumeParameters() error = %v, wantErr %v", err, tt.wantErr)
10261026
return

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

+1
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

+103-4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,106 @@ var _ = Describe("CSI Volume Creation", func() {
8181
})
8282
})
8383

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

test/e2e/framework/framework.go

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const (
4646
ClassOCIHigh = "oci-bv-high"
4747
ClassOCIKMS = "oci-kms"
4848
ClassOCIExt3 = "oci-ext3"
49+
ClassOCIXfs = "oci-xfs"
4950
MinVolumeBlock = "50Gi"
5051
MaxVolumeBlock = "100Gi"
5152
VolumeFss = "1Gi"

test/e2e/framework/pod_util.go

+16-2
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

+1
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)