Add mount option for Cephfs

The storage class already takes MountOptions(MountFlags), these are the
bind mount options. Some of these options may not be recognised by the
cephfs mount. Hence added a new parameterin Storage Class for
- cephfs kernel mount options,
- ceph-fuse mount options

Ceph kernel mount options are different from ceph-fuse options, hence
added two different parameters.

Signed-off-by: Poornima G <pgurusid@redhat.com>
This commit is contained in:
Poornima G 2019-08-28 09:47:12 +00:00 committed by Madhu Rajanna
parent b38496793e
commit 82b85d536f
4 changed files with 45 additions and 11 deletions

View File

@ -78,6 +78,8 @@ 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 | | `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". | | `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". |
| `pool` | no | Ceph pool into which volume data shall be stored | | `pool` | no | Ceph pool into which volume data shall be stored |
| `kernelMountOptions` | no | Comma separated string of mount options accepted by cephfs kernel mounter, by default no options are passed. Check man mount.ceph for options. |
| `fuseMountOptions` | no | Comma separated string of mount options accepted by ceph-fuse mounter, by default no options are passed. |
| `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-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 | | `csi.storage.k8s.io/provisioner-secret-namespace`, `csi.storage.k8s.io/node-stage-secret-namespace` | for Kubernetes | Namespaces of the above Secret objects |

View File

@ -20,6 +20,14 @@ parameters:
# (optional) Ceph pool into which volume data shall be stored # (optional) Ceph pool into which volume data shall be stored
# pool: cephfs_data # pool: cephfs_data
# (optional) Comma separated string of Ceph-fuse mount options.
# For eg:
# fuseMountOptions: debug
# (optional) Comma separated string of Cephfs kernel mount options.
# Check man mount.ceph for mount options. For eg:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# The secrets have to contain user and/or Ceph admin credentials. # 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-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default csi.storage.k8s.io/provisioner-secret-namespace: default

View File

@ -141,6 +141,9 @@ func mountFuse(ctx context.Context, mountPoint string, cr *util.Credentials, vol
"-o", "nonempty", "-o", "nonempty",
} }
if volOptions.FuseMountOptions != "" {
args = append(args, ","+volOptions.FuseMountOptions)
}
if volOptions.FsName != "" { if volOptions.FsName != "" {
args = append(args, "--client_mds_namespace="+volOptions.FsName) args = append(args, "--client_mds_namespace="+volOptions.FsName)
} }
@ -197,6 +200,9 @@ func mountKernel(ctx context.Context, mountPoint string, cr *util.Credentials, v
if volOptions.FsName != "" { if volOptions.FsName != "" {
optionsStr += fmt.Sprintf(",mds_namespace=%s", volOptions.FsName) optionsStr += fmt.Sprintf(",mds_namespace=%s", volOptions.FsName)
} }
if volOptions.KernelMountOptions != "" {
optionsStr += fmt.Sprintf(",%s", volOptions.KernelMountOptions)
}
args = append(args, "-o", optionsStr) args = append(args, "-o", optionsStr)
return execCommandErr(ctx, "mount", args[:]...) return execCommandErr(ctx, "mount", args[:]...)

View File

@ -27,17 +27,19 @@ import (
) )
type volumeOptions struct { type volumeOptions struct {
RequestName string RequestName string
Size int64 Size int64
ClusterID string ClusterID string
FsName string FsName string
FscID int64 FscID int64
MetadataPool string MetadataPool string
Monitors string `json:"monitors"` Monitors string `json:"monitors"`
Pool string `json:"pool"` Pool string `json:"pool"`
RootPath string `json:"rootPath"` RootPath string `json:"rootPath"`
Mounter string `json:"mounter"` Mounter string `json:"mounter"`
ProvisionVolume bool `json:"provisionVolume"` ProvisionVolume bool `json:"provisionVolume"`
KernelMountOptions string `json:"kernelMountOptions"`
FuseMountOptions string `json:"fuseMountOptions"`
} }
func validateNonEmptyField(field, fieldName string) error { func validateNonEmptyField(field, fieldName string) error {
@ -147,6 +149,14 @@ func newVolumeOptions(ctx context.Context, requestName string, size int64, volOp
return nil, err return nil, err
} }
if err = extractOptionalOption(&opts.KernelMountOptions, "kernelMountOptions", volOptions); err != nil {
return nil, err
}
if err = extractOptionalOption(&opts.FuseMountOptions, "fuseMountOptions", volOptions); err != nil {
return nil, err
}
opts.RequestName = requestName opts.RequestName = requestName
opts.Size = size opts.Size = size
@ -223,6 +233,14 @@ func newVolumeOptionsFromVolID(ctx context.Context, volID string, volOpt, secret
return nil, nil, err return nil, nil, err
} }
if err = extractOptionalOption(&volOptions.KernelMountOptions, "kernelMountOptions", volOpt); err != nil {
return nil, nil, err
}
if err = extractOptionalOption(&volOptions.FuseMountOptions, "fuseMountOptions", volOpt); err != nil {
return nil, nil, err
}
if err = extractMounter(&volOptions.Mounter, volOpt); err != nil { if err = extractMounter(&volOptions.Mounter, volOpt); err != nil {
return nil, nil, err return nil, nil, err
} }