mgr/cephadm: Updated NFS default protocol to v4 and v3 is enabled only when enable_nfsv3 is set in the spec

Fixes: https://tracker.ceph.com/issues/74492
Signed-off-by: Shweta Bhosale <Shweta.Bhosale1@ibm.com>
(cherry picked from commit 9b0becfdf2)

 Conflicts:
	doc/cephadm/services/nfs.rst - due to documentation related to RDMA
	doc/mgr/nfs.rst - due to params related to RDMA
	src/pybind/mgr/cephadm/services/nfs.py - due to other extra params
	src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 - due to RDMA
	src/pybind/mgr/cephadm/tests/services/test_ingress.py - not exists on tentacle
	src/pybind/mgr/cephadm/tests/services/test_nfs.py - not exists on tentacle
	src/pybind/mgr/nfs/cluster.py - due to other nfs parameters which are not supported in tentacle
	src/pybind/mgr/nfs/module.py - due to other nfs parameters which are not supported in tentacle
	src/python-common/ceph/deployment/service_spec.py - due to extra variable not supported in tentacle
This commit is contained in:
Shweta Bhosale 2026-01-21 21:13:39 +05:30 committed by Patrick Donnelly
parent 69c6804df7
commit 8c981876c2
No known key found for this signature in database
GPG Key ID: 053758C0A8A3CE2F
8 changed files with 58 additions and 8 deletions

View File

@ -49,9 +49,14 @@ Alternatively, an NFS service can be applied using a YAML specification.
- host2
spec:
port: 12345
monitoring_port: 567
enable_nfsv3: true
In this example, we run the server on the non-default ``port`` of
12345 (instead of the default 2049) on ``host1`` and ``host2``.
By default, only the NFSv4 protocol is enabled. NFSv3 can be enabled by setting
``enable_nfsv3`` to ``true`` in the service specification.
The specification can then be applied by running the following command:

View File

@ -31,7 +31,7 @@ Create NFS Ganesha Cluster
.. prompt:: bash #
ceph nfs cluster create <cluster_id> [<placement>] [--ingress] [--virtual_ip <value>] [--ingress-mode {default|keepalive-only|haproxy-standard|haproxy-protocol}] [--port <int>]
ceph nfs cluster create <cluster_id> [<placement>] [--ingress] [--virtual_ip <value>] [--ingress-mode {default|keepalive-only|haproxy-standard|haproxy-protocol}] [--port <int>] [--enable-nfsv3]
This creates a common recovery pool for all NFS Ganesha daemons, new user based on
``cluster_id``, and a common NFS Ganesha config RADOS object.
@ -62,6 +62,9 @@ cluster)::
NFS can be deployed on a port other than 2049 (the default) with ``--port <port>``.
By default, only NFS v4 protocol is enabled. To enable both NFS v3 and v4 protocols,
add the ``--enable-nfsv3`` flag.
To deploy NFS with a high-availability front-end (virtual IP and load balancer), add the
``--ingress`` flag and specify a virtual IP address. This will deploy a combination
of keepalived and haproxy to provide an high-availability NFS frontend for the NFS

View File

@ -129,6 +129,7 @@ class NFSService(CephService):
"nfs_idmap_conf": nfs_idmap_conf,
"enable_nlm": str(spec.enable_nlm).lower(),
"cluster_id": self.mgr._cluster_fsid,
"protocols": "3, 4" if spec.enable_nfsv3 else "4"
}
if spec.enable_haproxy_protocol:
context["haproxy_hosts"] = self._haproxy_hosts()

View File

@ -2,7 +2,7 @@
NFS_CORE_PARAM {
Enable_NLM = {{ enable_nlm }};
Enable_RQUOTA = false;
Protocols = 3, 4;
Protocols = {{ protocols }};
mount_path_pseudo = true;
Enable_UDP = false;
NFS_Port = {{ port }};

View File

@ -3391,7 +3391,7 @@ class TestIngressService:
'NFS_CORE_PARAM {\n'
' Enable_NLM = true;\n'
' Enable_RQUOTA = false;\n'
' Protocols = 3, 4;\n'
' Protocols = 4;\n'
' mount_path_pseudo = true;\n'
' Enable_UDP = false;\n'
' NFS_Port = 2049;\n'
@ -3518,6 +3518,32 @@ class TestIngressService:
)
assert nfs_generated_conf == nfs_expected_conf
@patch("cephadm.serve.CephadmServe._run_cephadm")
@patch("cephadm.services.nfs.NFSService.fence_old_ranks", MagicMock())
@patch("cephadm.services.nfs.NFSService.run_grace_tool", MagicMock())
@patch("cephadm.services.nfs.NFSService.purge", MagicMock())
@patch("cephadm.services.nfs.NFSService.create_rados_config_obj", MagicMock())
def test_nfs_enable_nfsv3(self, _run_cephadm, cephadm_module: CephadmOrchestrator):
_run_cephadm.side_effect = async_side_effect(('{}', '', 0))
with with_host(cephadm_module, 'test'):
# Test with enable_nfsv3=False (default)
nfs_spec = NFSServiceSpec(service_id="foo", placement=PlacementSpec(hosts=['test']))
with with_service(cephadm_module, nfs_spec) as _:
nfs_generated_conf, _ = service_registry.get_service('nfs').generate_config(
CephadmDaemonDeploySpec(host='test', daemon_id='foo.test.0.0', service_name=nfs_spec.service_name()))
ganesha_conf = nfs_generated_conf['files']['ganesha.conf']
assert "Protocols = 4;" in ganesha_conf
# Test with enable_nfsv3=True
nfs_spec = NFSServiceSpec(service_id="foo", placement=PlacementSpec(hosts=['test']),
enable_nfsv3=True)
with with_service(cephadm_module, nfs_spec) as _:
nfs_generated_conf, _ = service_registry.get_service('nfs').generate_config(
CephadmDaemonDeploySpec(host='test', daemon_id='foo.test.0.0', service_name=nfs_spec.service_name()))
ganesha_conf = nfs_generated_conf['files']['ganesha.conf']
assert "Protocols = 3, 4;" in ganesha_conf
class TestCephFsMirror:
@patch("cephadm.serve.CephadmServe._run_cephadm")

View File

@ -65,6 +65,7 @@ class NFSCluster:
virtual_ip: Optional[str] = None,
ingress_mode: Optional[IngressType] = None,
port: Optional[int] = None,
enable_nfsv3: bool = False,
) -> None:
if not port:
port = 2049 # default nfs port
@ -98,7 +99,8 @@ class NFSCluster:
# use non-default port so we don't conflict with ingress
port=ganesha_port,
virtual_ip=virtual_ip_for_ganesha,
enable_haproxy_protocol=enable_haproxy_protocol)
enable_haproxy_protocol=enable_haproxy_protocol,
enable_nfsv3=enable_nfsv3)
completion = self.mgr.apply_nfs(spec)
orchestrator.raise_if_exception(completion)
ispec = IngressSpec(service_type='ingress',
@ -116,7 +118,8 @@ class NFSCluster:
# standalone nfs
spec = NFSServiceSpec(service_type='nfs', service_id=cluster_id,
placement=PlacementSpec.from_string(placement),
port=port)
port=port,
enable_nfsv3=enable_nfsv3)
completion = self.mgr.apply_nfs(spec)
orchestrator.raise_if_exception(completion)
log.debug("Successfully deployed nfs daemons with cluster id %s and placement %s",
@ -140,6 +143,7 @@ class NFSCluster:
ingress: Optional[bool] = None,
ingress_mode: Optional[IngressType] = None,
port: Optional[int] = None,
enable_nfsv3: bool = False,
) -> None:
try:
if virtual_ip:
@ -163,7 +167,14 @@ class NFSCluster:
self.create_empty_rados_obj(cluster_id)
if cluster_id not in available_clusters(self.mgr):
self._call_orch_apply_nfs(cluster_id, placement, virtual_ip, ingress_mode, port)
self._call_orch_apply_nfs(
cluster_id,
placement,
virtual_ip,
ingress_mode,
port,
enable_nfsv3=enable_nfsv3,
)
return
raise NonFatalError(f"{cluster_id} cluster already exists")
except Exception as e:

View File

@ -133,11 +133,13 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
ingress: Optional[bool] = None,
virtual_ip: Optional[str] = None,
ingress_mode: Optional[IngressType] = None,
port: Optional[int] = None) -> None:
port: Optional[int] = None,
enable_nfsv3: bool = False) -> None:
"""Create an NFS Cluster"""
return self.nfs.create_nfs_cluster(cluster_id=cluster_id, placement=placement,
virtual_ip=virtual_ip, ingress=ingress,
ingress_mode=ingress_mode, port=port)
ingress_mode=ingress_mode, port=port,
enable_nfsv3=enable_nfsv3)
@NFSCLICommand('nfs cluster rm', perm='rw')
@object_format.EmptyResponder()

View File

@ -1185,6 +1185,7 @@ class NFSServiceSpec(ServiceSpec):
extra_entrypoint_args: Optional[GeneralArgList] = None,
idmap_conf: Optional[Dict[str, Dict[str, str]]] = None,
custom_configs: Optional[List[CustomConfig]] = None,
enable_nfsv3: bool = False,
):
assert service_type == 'nfs'
super(NFSServiceSpec, self).__init__(
@ -1199,6 +1200,7 @@ class NFSServiceSpec(ServiceSpec):
self.enable_haproxy_protocol = enable_haproxy_protocol
self.idmap_conf = idmap_conf
self.enable_nlm = enable_nlm
self.enable_nfsv3 = enable_nfsv3
def get_port_start(self) -> List[int]:
if self.port: