From 677fc83bf67a9c5e589120e4709a273c38ae632e Mon Sep 17 00:00:00 2001 From: Teoman ONAY Date: Tue, 28 Mar 2023 14:18:14 +0200 Subject: [PATCH] mgr/cephadm: add idmap.conf customization for NFS server Allows idmapd.conf to be customized to control the NFSv4.x server configuration Fixes: https://tracker.ceph.com/issues/64577 Signed-off-by: Teoman ONAY (cherry picked from commit 416425c5fde39a9b42c5d70bb6bda3bd576456c3) --- src/cephadm/cephadm.py | 2 +- src/cephadm/tests/test_nfs.py | 1 + src/pybind/mgr/cephadm/services/nfs.py | 20 +++++++++++++++++++ .../templates/services/nfs/ganesha.conf.j2 | 3 +++ src/pybind/mgr/cephadm/tests/test_services.py | 3 ++- .../ceph/deployment/service_spec.py | 2 ++ .../ceph/tests/test_service_spec.py | 6 ++++++ 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/cephadm/cephadm.py b/src/cephadm/cephadm.py index 99e0ac740a0..d181069e31d 100755 --- a/src/cephadm/cephadm.py +++ b/src/cephadm/cephadm.py @@ -848,7 +848,7 @@ class NFSGanesha(object): entrypoint = '/usr/bin/ganesha.nfsd' daemon_args = ['-F', '-L', 'STDERR'] - required_files = ['ganesha.conf'] + required_files = ['ganesha.conf', 'idmap.conf'] port_map = { 'nfs': 2049, diff --git a/src/cephadm/tests/test_nfs.py b/src/cephadm/tests/test_nfs.py index 0649ef934c1..c9893b32d1f 100644 --- a/src/cephadm/tests/test_nfs.py +++ b/src/cephadm/tests/test_nfs.py @@ -25,6 +25,7 @@ def nfs_json(**kwargs): if kwargs.get("files"): result["files"] = { "ganesha.conf": "", + "idmap.conf": "", } if kwargs.get("rgw_content"): result["rgw"] = dict(kwargs["rgw_content"]) diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index f94a00f5bdf..e0c61b117e7 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -5,6 +5,8 @@ import os import subprocess import tempfile from typing import Dict, Tuple, Any, List, cast, Optional +from configparser import ConfigParser +from io import StringIO from mgr_module import HandleCommandResult from mgr_module import NFS_POOL_NAME as POOL_NAME @@ -79,6 +81,8 @@ class NFSService(CephService): nodeid = f'{daemon_spec.service_name}.{daemon_spec.rank}' + nfs_idmap_conf = '/etc/ganesha/idmap.conf' + # create the RADOS recovery pool keyring rados_user = f'{daemon_type}.{daemon_id}' rados_keyring = self.create_keyring(daemon_spec) @@ -115,12 +119,27 @@ class NFSService(CephService): "port": daemon_spec.ports[0] if daemon_spec.ports else 2049, "bind_addr": bind_addr, "haproxy_hosts": [], + "nfs_idmap_conf": nfs_idmap_conf, } if spec.enable_haproxy_protocol: context["haproxy_hosts"] = self._haproxy_hosts() logger.debug("selected haproxy_hosts: %r", context["haproxy_hosts"]) return self.mgr.template.render('services/nfs/ganesha.conf.j2', context) + # generate the idmap config + def get_idmap_conf() -> str: + idmap_conf = spec.idmap_conf + output = '' + if idmap_conf is not None: + cp = ConfigParser() + out = StringIO() + cp.read_dict(idmap_conf) + cp.write(out) + out.seek(0) + output = out.read() + out.close() + return output + # generate the cephadm config json def get_cephadm_config() -> Dict[str, Any]: config: Dict[str, Any] = {} @@ -130,6 +149,7 @@ class NFSService(CephService): config['extra_args'] = ['-N', 'NIV_EVENT'] config['files'] = { 'ganesha.conf': get_ganesha_conf(), + 'idmap.conf': get_idmap_conf() } config.update( self.get_config_and_keyring( diff --git a/src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 b/src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 index ab8df71923b..7bc0278d7ed 100644 --- a/src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 +++ b/src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 @@ -16,6 +16,9 @@ NFSv4 { Delegations = false; RecoveryBackend = 'rados_cluster'; Minor_Versions = 1, 2; +{% if nfs_idmap_conf %} + IdmapConf = "{{ nfs_idmap_conf }}"; +{% endif %} } RADOS_KV { diff --git a/src/pybind/mgr/cephadm/tests/test_services.py b/src/pybind/mgr/cephadm/tests/test_services.py index 2300b288d29..52f5f3b056f 100644 --- a/src/pybind/mgr/cephadm/tests/test_services.py +++ b/src/pybind/mgr/cephadm/tests/test_services.py @@ -2431,6 +2431,7 @@ class TestIngressService: ' Delegations = false;\n' " RecoveryBackend = 'rados_cluster';\n" ' Minor_Versions = 1, 2;\n' + ' IdmapConf = "/etc/ganesha/idmap.conf";\n' '}\n' '\n' 'RADOS_KV {\n' @@ -2454,7 +2455,7 @@ class TestIngressService: "%url rados://.nfs/foo/conf-nfs.foo" ) nfs_expected_conf = { - 'files': {'ganesha.conf': nfs_ganesha_txt}, + 'files': {'ganesha.conf': nfs_ganesha_txt, 'idmap.conf': ''}, 'config': '', 'extra_args': ['-N', 'NIV_EVENT'], 'keyring': ( diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index bcebf23c208..ea5a88dc033 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -952,6 +952,7 @@ class NFSServiceSpec(ServiceSpec): extra_container_args: Optional[GeneralArgList] = None, extra_entrypoint_args: Optional[GeneralArgList] = None, enable_haproxy_protocol: bool = False, + idmap_conf: Optional[Dict[str, Dict[str, str]]] = None, custom_configs: Optional[List[CustomConfig]] = None, ): assert service_type == 'nfs' @@ -964,6 +965,7 @@ class NFSServiceSpec(ServiceSpec): self.port = port self.virtual_ip = virtual_ip self.enable_haproxy_protocol = enable_haproxy_protocol + self.idmap_conf = idmap_conf def get_port_start(self) -> List[int]: if self.port: diff --git a/src/python-common/ceph/tests/test_service_spec.py b/src/python-common/ceph/tests/test_service_spec.py index 502057f5ca3..01a5265aad9 100644 --- a/src/python-common/ceph/tests/test_service_spec.py +++ b/src/python-common/ceph/tests/test_service_spec.py @@ -384,6 +384,12 @@ service_type: nfs service_id: mynfs service_name: nfs.mynfs spec: + idmap_conf: + general: + local-realms: domain.org + mapping: + nobody-group: nfsnobody + nobody-user: nfsnobody port: 1234 --- service_type: iscsi -- 2.39.5