cephfs: add netNamespaceFilePath for CephFS

as same host directory is not shared between
the cephfs and the rbd plugin pod. we need
to keep the netNamespaceFilePath separately
for both cephfs and rbd. CephFS plugin will
use this path to execute mount -t commands.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna 2022-04-18 12:02:31 +05:30 committed by mergify[bot]
parent eb4bfb7326
commit d2bc9743f7
5 changed files with 100 additions and 1 deletions

View File

@ -27,7 +27,7 @@ serviceAccounts:
# - "<MONValue2>" # - "<MONValue2>"
# cephFS: # cephFS:
# subvolumeGroup: "csi" # subvolumeGroup: "csi"
# netNamespaceFilePath: "{{ .kubeletDir }}/plugins/{{ .driverName }}/net" # netNamespaceFilePath: "{{ .kubeletDir }}/plugins/{{ .driverName }}/net"
csiConfig: [] csiConfig: []
# Set logging level for csi containers. # Set logging level for csi containers.

View File

@ -20,6 +20,10 @@ kind: ConfigMap
# NOTE: Make sure you don't add radosNamespace option to a currently in use # NOTE: Make sure you don't add radosNamespace option to a currently in use
# configuration as it will cause issues. # configuration as it will cause issues.
# The field "cephFS.subvolumeGroup" is optional and defaults to "csi". # The field "cephFS.subvolumeGroup" is optional and defaults to "csi".
# The "cephFS.netNamespaceFilePath" fields are the various network namespace
# path for the Ceph cluster identified by the <cluster-id>, This will be used
# by the CephFS CSI plugin to execute the mount -t in the
# network namespace specified by the "cephFS.netNamespaceFilePath".
# The "rbd.netNamespaceFilePath" fields are the various network namespace # The "rbd.netNamespaceFilePath" fields are the various network namespace
# path for the Ceph cluster identified by the <cluster-id>, This will be used # path for the Ceph cluster identified by the <cluster-id>, This will be used
# by the RBD CSI plugin to execute the rbd map/unmap in the # by the RBD CSI plugin to execute the rbd map/unmap in the
@ -54,6 +58,7 @@ data:
], ],
"cephFS": { "cephFS": {
"subvolumeGroup": "<subvolumegroup for cephFS volumes>" "subvolumeGroup": "<subvolumegroup for cephFS volumes>"
"netNamespaceFilePath": "<kubeletRootPath>/plugins/cephfs.csi.ceph.com/net",
} }
} }
] ]

View File

@ -126,6 +126,12 @@ func (ns *NodeServer) NodeStageVolume(
} }
defer volOptions.Destroy() defer volOptions.Destroy()
volOptions.NetNamespaceFilePath, err = util.GetCephFSNetNamespaceFilePath(
util.CsiConfigFile,
volOptions.ClusterID)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
mnt, err := mounter.New(volOptions) mnt, err := mounter.New(volOptions)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to create mounter for volume %s: %v", volID, err) log.ErrorLog(ctx, "failed to create mounter for volume %s: %v", volID, err)

View File

@ -46,6 +46,8 @@ type ClusterInfo struct {
Monitors []string `json:"monitors"` Monitors []string `json:"monitors"`
// CephFS contains CephFS specific options // CephFS contains CephFS specific options
CephFS struct { CephFS struct {
// symlink filepath for the network namespace where we need to execute commands.
NetNamespaceFilePath string `json:"netNamespaceFilePath"`
// SubvolumeGroup contains the name of the SubvolumeGroup for CSI volumes // SubvolumeGroup contains the name of the SubvolumeGroup for CSI volumes
SubvolumeGroup string `json:"subvolumeGroup"` SubvolumeGroup string `json:"subvolumeGroup"`
} `json:"cephFS"` } `json:"cephFS"`
@ -182,3 +184,13 @@ func GetRBDNetNamespaceFilePath(pathToConfig, clusterID string) (string, error)
return cluster.RBD.NetNamespaceFilePath, nil return cluster.RBD.NetNamespaceFilePath, nil
} }
// GetCephFSNetNamespaceFilePath returns the netNamespaceFilePath for CephFS volumes.
func GetCephFSNetNamespaceFilePath(pathToConfig, clusterID string) (string, error) {
cluster, err := readClusterInfo(pathToConfig, clusterID)
if err != nil {
return "", err
}
return cluster.CephFS.NetNamespaceFilePath, nil
}

View File

@ -215,3 +215,79 @@ func TestGetRBDNetNamespaceFilePath(t *testing.T) {
}) })
} }
} }
func TestGetCephFSNetNamespaceFilePath(t *testing.T) {
t.Parallel()
tests := []struct {
name string
clusterID string
want string
}{
{
name: "get cephFS specific NetNamespaceFilePath for cluster-1",
clusterID: "cluster-1",
want: "/var/lib/kubelet/plugins/cephfs.ceph.csi.com/cluster1-net",
},
{
name: "get cephFS specific NetNamespaceFilePath for cluster-2",
clusterID: "cluster-2",
want: "/var/lib/kubelet/plugins/cephfs.ceph.csi.com/cluster2-net",
},
{
name: "when cephFS specific NetNamespaceFilePath is empty",
clusterID: "cluster-3",
want: "",
},
}
csiConfig := []ClusterInfo{
{
ClusterID: "cluster-1",
Monitors: []string{"ip-1", "ip-2"},
CephFS: struct {
NetNamespaceFilePath string `json:"netNamespaceFilePath"`
SubvolumeGroup string `json:"subvolumeGroup"`
}{
NetNamespaceFilePath: "/var/lib/kubelet/plugins/cephfs.ceph.csi.com/cluster1-net",
},
},
{
ClusterID: "cluster-2",
Monitors: []string{"ip-3", "ip-4"},
CephFS: struct {
NetNamespaceFilePath string `json:"netNamespaceFilePath"`
SubvolumeGroup string `json:"subvolumeGroup"`
}{
NetNamespaceFilePath: "/var/lib/kubelet/plugins/cephfs.ceph.csi.com/cluster2-net",
},
},
{
ClusterID: "cluster-3",
Monitors: []string{"ip-5", "ip-6"},
},
}
csiConfigFileContent, err := json.Marshal(csiConfig)
if err != nil {
t.Errorf("failed to marshal csi config info %v", err)
}
tmpConfPath := t.TempDir() + "/ceph-csi.json"
err = os.WriteFile(tmpConfPath, csiConfigFileContent, 0o600)
if err != nil {
t.Errorf("failed to write %s file content: %v", CsiConfigFile, err)
}
for _, tt := range tests {
ts := tt
t.Run(ts.name, func(t *testing.T) {
t.Parallel()
got, err := GetCephFSNetNamespaceFilePath(tmpConfPath, ts.clusterID)
if err != nil {
t.Errorf("GetCephFSNetNamespaceFilePath() error = %v", err)
return
}
if got != ts.want {
t.Errorf("GetCephFSNetNamespaceFilePath() = %v, want %v", got, ts.want)
}
})
}
}