Skip to content

Commit

Permalink
Add mount option for Cephfs
Browse files Browse the repository at this point in the history
Signed-off-by: Poornima G <[email protected]>
  • Loading branch information
Poornima G committed Sep 4, 2019
1 parent d03a352 commit e5c0538
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/deploy-cephfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ is used to define in which namespace you want the configmaps to be stored
| `fsName` | yes | CephFS filesystem name into which the volume shall be created |
| `mounter` | no | Mount method to be used for this volume. Available options are `kernel` for Ceph kernel client and `fuse` for Ceph FUSE driver. Defaults to "default mounter", see command line arguments. |
| `pool` | no | Ceph pool into which volume data shall be stored |
| `mountOptions` | no | Comma seperated string of mount options accepted by cephfs kernel and/or fuse mount. by default no options are passed. Check man mount.ceph for options. |
| `csi.storage.k8s.io/provisioner-secret-name`, `csi.storage.k8s.io/node-stage-secret-name` | for Kubernetes | Name of the Kubernetes Secret object containing Ceph client credentials. Both parameters should have the same value |
| `csi.storage.k8s.io/provisioner-secret-namespace`, `csi.storage.k8s.io/node-stage-secret-namespace` | for Kubernetes | Namespaces of the above Secret objects |

Expand Down
2 changes: 1 addition & 1 deletion e2e/cephfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ var _ = Describe("cephfs", func() {
})

By("check data persist after recreating pod with same pvc", func() {
err := checkDataPersist(pvcPath, appPath, f)
err := checkDataPersist(pvcPath, appPath, f, true)
if err != nil {
Fail(err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/rbd.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ var _ = Describe("RBD", func() {
})

By("check data persist after recreating pod with same pvc", func() {
err := checkDataPersist(pvcPath, appPath, f)
err := checkDataPersist(pvcPath, appPath, f, false)
if err != nil {
Fail(err.Error())
}
Expand Down
16 changes: 14 additions & 2 deletions e2e/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ func createCephfsStorageClass(c kubernetes.Interface, f *framework.Framework, en
sc.Parameters["clusterID"] = fsID
_, err := c.StorageV1().StorageClasses().Create(&sc)
Expect(err).Should(BeNil())

sc.Parameters["mountOptions"] = "dirstat"
}

func createRBDStorageClass(c kubernetes.Interface, f *framework.Framework) {
Expand Down Expand Up @@ -781,7 +783,7 @@ func listRBDImages(f *framework.Framework) []string {
// return snapInfos, err
// }

func checkDataPersist(pvcPath, appPath string, f *framework.Framework) error {
func checkDataPersist(pvcPath, appPath string, f *framework.Framework, mountOpts bool) error {
data := "checking data persist"
pvc, err := loadPVC(pvcPath)
if pvc == nil {
Expand All @@ -806,8 +808,10 @@ func checkDataPersist(pvcPath, appPath string, f *framework.Framework) error {
LabelSelector: "app=validate-data",
}
// write data to PVC
filePath := app.Spec.Containers[0].VolumeMounts[0].MountPath + "/test"
dirPath := app.Spec.Containers[0].VolumeMounts[0].MountPath + "/testdir/"
filePath := dirPath + "test"

execCommandInPod(f, fmt.Sprintf("mkdir -p %s", dirPath), app.Namespace, &opt)
execCommandInPod(f, fmt.Sprintf("echo %s > %s", data, filePath), app.Namespace, &opt)

// delete app
Expand All @@ -826,6 +830,14 @@ func checkDataPersist(pvcPath, appPath string, f *framework.Framework) error {
return fmt.Errorf("data not persistent expected data %s received data %s ", data, persistData)
}

if mountOpts {
dirstat, stdErr := execCommandInPod(f, fmt.Sprintf("cat %s", dirPath), app.Namespace, &opt)
Expect(stdErr).Should(BeEmpty())
if !strings.Contains(dirstat, "entries") {
return fmt.Errorf("mount options for cephfs mount not working, received data %s ", dirstat)
}
}

err = deletePVCAndApp("", f, pvc, app)
return err
}
4 changes: 4 additions & 0 deletions examples/cephfs/storageclass.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ parameters:
# (optional) Ceph pool into which volume data shall be stored
# pool: cephfs_data

# (optional) Comma seperated string of Cephfs kernel or ceph fuse
# mount options. Check man mount.ceph for mount options. For eg:
# mountOptions: readdir_max_bytes=1048576,norbytes

# The secrets have to contain user and/or Ceph admin credentials.
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
Expand Down
11 changes: 11 additions & 0 deletions pkg/cephfs/volumemounter.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,15 @@ func mountFuse(ctx context.Context, mountPoint string, cr *util.Credentials, vol
args = append(args, "--client_mds_namespace="+volOptions.FsName)
}

if volOptions.MountOptions != "" {
args = append(args, volOptions.MountOptions)
}

_, stderr, err := execCommand(ctx, "ceph-fuse", args[:]...)
if err != nil {
return err
}
klog.Infof("Fuse Mounted, command: %v err: %s", args, stderr)

// Parse the output:
// We need "starting fuse" meaning the mount is ok
Expand Down Expand Up @@ -183,6 +188,12 @@ func mountKernel(ctx context.Context, mountPoint string, cr *util.Credentials, v
}
args = append(args, "-o", optionsStr)

if volOptions.MountOptions != "" {
args = append(args, volOptions.MountOptions)
}

klog.Infof("Kernel Mounted, command: %v", args)

return execCommandErr(ctx, "mount", args[:]...)
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/cephfs/volumeoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type volumeOptions struct {
RootPath string `json:"rootPath"`
Mounter string `json:"mounter"`
ProvisionVolume bool `json:"provisionVolume"`
MountOptions string `json:"mountOptions"`
}

func validateNonEmptyField(field, fieldName string) error {
Expand Down Expand Up @@ -147,6 +148,10 @@ func newVolumeOptions(ctx context.Context, requestName string, size int64, volOp
return nil, err
}

if err = extractOptionalOption(&opts.MountOptions, "mountOptions", volOptions); err != nil {
return nil, err
}

opts.RequestName = requestName
opts.Size = size

Expand Down

0 comments on commit e5c0538

Please sign in to comment.