self._exports: Optional[Dict[str, List[Export]]] = export_ls
self.skip_notify_nfs_server = False
+ def _get_cluster_protocols(self, cluster_id: str) -> List[int]:
+ """Get the list of supported NFS protocols for a cluster.
+ """
+ try:
+ import orchestrator
+ from ceph.deployment.service_spec import NFSServiceSpec
+
+ completion = self.mgr.describe_service(service_type='nfs', service_name=f'nfs.{cluster_id}')
+ services = orchestrator.raise_if_exception(completion)
+ for service in services:
+ if service.spec and isinstance(service.spec, NFSServiceSpec):
+ spec = cast(NFSServiceSpec, service.spec)
+ if getattr(spec, 'enable_nfsv3', False):
+ return [3, 4]
+ return [4]
+ except Exception as e:
+ log.debug(f"Failed to get cluster protocols for {cluster_id}: {e}, defaulting to v4 only")
+ return [4]
+
@property
def exports(self) -> Dict[str, List[Export]]:
if self._exports is None:
_validate_cmount_path(cmount_path, path) # type: ignore
pseudo_path = normalize_path(pseudo_path)
+ # Get the protocols based on cluster's enable_nfsv3 setting
+ protocols = self._get_cluster_protocols(cluster_id)
export_dict = {
"pseudo": pseudo_path,
"clients": clients,
"sectype": sectype,
"XprtSec": xprtsec,
+ "protocols": protocols,
}
if transports is not None:
export_dict["transports"] = transports
if not bucket and not user_id:
raise ErrorResponse("Must specify either bucket or user_id")
+ # Get the protocols based on cluster's enable_nfsv3 setting
+ protocols = self._get_cluster_protocols(cluster_id)
+
export_dict = {
"pseudo": pseudo_path,
"path": bucket or '/',
"clients": clients,
"sectype": sectype,
"XprtSec": xprtsec,
+ "protocols": protocols,
}
if transports is not None:
export_dict["transports"] = transports
else:
new_export_dict['fsal']['cmount_path'] = '/'
+ # Set protocols based on cluster's enable_nfsv3 setting if not explicitly specified
+ if 'protocols' not in new_export_dict:
+ new_export_dict['protocols'] = self._get_cluster_protocols(cluster_id)
+
new_export = self.create_export_from_dict(
cluster_id,
new_export_dict.get('export_id', self._gen_export_id(cluster_id)),
ex_dict.get('access_type', 'RO'),
ex_dict.get('squash', 'no_root_squash'),
ex_dict.get('security_label', True),
- ex_dict.get('protocols', [3, 4]),
+ ex_dict.get('protocols', [4]),
ex_dict.get('transports', ['TCP']),
FSAL.from_dict(ex_dict.get('fsal', {})),
[Client.from_dict(client) for client in ex_dict.get('clients', [])],
Path = /;
Pseudo = /cephfs_b/;
Access_Type = RW;
- Protocols = 4;
+ Protocols = 3, 4;
Attr_Expiration_Time = 0;
FSAL {
assert export.pseudo == "/cephfs_b/"
assert export.access_type == "RW"
assert export.squash == "no_root_squash"
- assert export.protocols == [4]
+ assert export.protocols == [3, 4]
assert export.fsal.name == "CEPH"
assert export.fsal.user_id == "nfs.foo.b.lgudhr"
assert export.fsal.fs_name == "b"
assert export.pseudo == "/mybucket"
assert export.access_type == "none"
assert export.squash == "none"
- assert export.protocols == [3, 4]
+ assert export.protocols == [4]
assert export.transports == ["TCP"]
assert export.fsal.name == "RGW"
assert export.fsal.user_id == "bucket_owner_user"
assert export.pseudo == "/mybucket"
assert export.access_type == "none"
assert export.squash == "none"
- assert export.protocols == [3, 4]
+ assert export.protocols == [4]
assert export.transports == ["TCP"]
assert export.fsal.name == "RGW"
assert export.fsal.access_key_id == "the_access_key"
assert export.pseudo == "/mybucket"
assert export.access_type == "none"
assert export.squash == "none"
- assert export.protocols == [3, 4]
+ assert export.protocols == [4]
assert export.transports == ["TCP"]
assert export.fsal.name == "RGW"
assert export.fsal.access_key_id == "the_access_key"
assert export.pseudo == "/cephfs2"
assert export.access_type == "none"
assert export.squash == "none"
- assert export.protocols == [3, 4]
+ assert export.protocols == [4]
assert export.transports == ["TCP"]
assert export.fsal.name == "CEPH"
assert export.fsal.user_id == "nfs.foo.myfs.86ca58ef"
assert export.pseudo == "/cephfs3"
assert export.access_type == "RW"
assert export.squash == "root"
- assert export.protocols == [3, 4]
+ assert export.protocols == [4]
assert export.fsal.name == "CEPH"
assert export.fsal.user_id == "nfs.foo.myfs.86ca58ef"
assert export.fsal.cephx_key == "thekeyforclientabc"