From fcc3566c1df74d2e304afd0802c38b0397a7ac8a 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 --- src/cephadm/cephadmlib/daemons/nfs.py | 2 +- src/cephadm/tests/test_nfs.py | 1 + src/pybind/mgr/cephadm/services/nfs.py | 20 +++++++++++++++++++ .../templates/services/nfs/ganesha.conf.j2 | 3 +++ .../ceph/deployment/service_spec.py | 2 ++ .../ceph/tests/test_service_spec.py | 6 ++++++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cephadm/cephadmlib/daemons/nfs.py b/src/cephadm/cephadmlib/daemons/nfs.py index 6e2f2a945cae57..f09374d5f4648b 100644 --- a/src/cephadm/cephadmlib/daemons/nfs.py +++ b/src/cephadm/cephadmlib/daemons/nfs.py @@ -31,7 +31,7 @@ class NFSGanesha(ContainerDaemonForm): 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 aae8113382dc38..1b468516e67b68 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 f94a00f5bdf944..e0c61b117e7ebc 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -5,6 +5,8 @@ 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 @@ def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[st 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 @@ def get_ganesha_conf() -> str: "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 @@ def get_cephadm_config() -> Dict[str, Any]: 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 ab8df71923b495..7bc0278d7ed12b 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/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index f6d290f071888c..23ac1486715f4d 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1093,6 +1093,7 @@ def __init__(self, enable_haproxy_protocol: bool = False, extra_container_args: Optional[GeneralArgList] = None, extra_entrypoint_args: Optional[GeneralArgList] = None, + idmap_conf: Optional[Dict[str, Dict[str, str]]] = None, custom_configs: Optional[List[CustomConfig]] = None, ): assert service_type == 'nfs' @@ -1105,6 +1106,7 @@ def __init__(self, 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 9a55b0a813598c..ce739107bd56c9 100644 --- a/src/python-common/ceph/tests/test_service_spec.py +++ b/src/python-common/ceph/tests/test_service_spec.py @@ -397,6 +397,12 @@ def test_osd_unmanaged(): service_name: nfs.mynfs spec: port: 1234 +idmap_conf: + general: + local-realms: DOMAIN.ORG + mapping: + nobody-user: nfsnobody + nobody-group: nfsnobody --- service_type: iscsi service_id: iscsi