From: Shweta Bhosale Date: Thu, 9 Jul 2026 13:29:44 +0000 (+0530) Subject: mgr/cephadm: deduplicate HAProxy_Hosts in NFS ganesha.conf X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e1d196472d280d7488793fe8cac8f0eeaf8e68d0;p=ceph.git mgr/cephadm: deduplicate HAProxy_Hosts in NFS ganesha.conf When enable_haproxy_protocol is set, _haproxy_hosts() can collect the same address more than once. Store collected IPs in a set and return a list so HAProxy_Hosts contains only unique entries. Fixes: https://tracker.ceph.com/issues/78094 Signed-off-by: Shweta Bhosale --- diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index 8227e030965..07ab061d8e8 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -5,7 +5,7 @@ import os import subprocess import tempfile from threading import Lock -from typing import Dict, Tuple, Any, List, cast, Optional, TYPE_CHECKING +from typing import Dict, Tuple, Any, List, Set, cast, Optional, TYPE_CHECKING from configparser import ConfigParser from io import StringIO from cephadm import utils @@ -267,7 +267,7 @@ class NFSService(CephService): } if spec.enable_haproxy_protocol: context["haproxy_hosts"] = self._haproxy_hosts() - if spec.virtual_ip: + if spec.virtual_ip and spec.virtual_ip not in context["haproxy_hosts"]: context["haproxy_hosts"].append(spec.virtual_ip) logger.debug("selected haproxy_hosts: %r", context["haproxy_hosts"]) return self.mgr.template.render('services/nfs/ganesha.conf.j2', context) @@ -527,10 +527,10 @@ class NFSService(CephService): # good enough to prevent acceping haproxy protocol messages # from "rouge" systems that are not under our control. At # least until we learn otherwise. - cluster_ips: List[str] = [] + cluster_ips: Set[str] = set() for host in self.mgr.inventory.keys(): default_addr = self.mgr.inventory.get_addr(host) - cluster_ips.append(default_addr) + cluster_ips.add(default_addr) nets = self.mgr.cache.networks.get(host) if not nets: continue @@ -543,8 +543,8 @@ class NFSService(CephService): addrs: List[str] = sum((addr_list for addr_list in iface.values()), []) if addrs: # one address per interface/subnet is enough - cluster_ips.append(addrs[0]) - return cluster_ips + cluster_ips.add(addrs[0]) + return list(cluster_ips) def get_monitoring_details( self, diff --git a/src/pybind/mgr/cephadm/tests/services/test_ingress.py b/src/pybind/mgr/cephadm/tests/services/test_ingress.py index ae258350003..04e93a4baec 100644 --- a/src/pybind/mgr/cephadm/tests/services/test_ingress.py +++ b/src/pybind/mgr/cephadm/tests/services/test_ingress.py @@ -1196,7 +1196,6 @@ class TestIngressService: ' Enable_UDP = false;\n' ' NFS_Port = 2049;\n' ' allow_set_io_flusher_fail = true;\n' - ' HAProxy_Hosts = 192.168.122.111, 10.10.2.20, 192.168.122.222;\n' ' Monitoring_Port = 9587;\n' '}\n' '\n' @@ -1333,6 +1332,29 @@ class TestIngressService: rank=0, ), ) + ganesha_conf = nfs_generated_conf['files']['ganesha.conf'] + haproxy_hosts = { + ip.strip() + for line in ganesha_conf.splitlines() + if 'HAProxy_Hosts' in line + for ip in line.split('=', 1)[1].strip().rstrip(';').split(',') + } + assert haproxy_hosts == { + '192.168.122.111', + '10.10.2.20', + '192.168.122.222', + } + + def without_haproxy_hosts(conf: str) -> str: + return '\n'.join( + line for line in conf.splitlines() + if 'HAProxy_Hosts' not in line + ) + + nfs_generated_conf['files']['ganesha.conf'] = without_haproxy_hosts(ganesha_conf) + nfs_expected_conf['files']['ganesha.conf'] = without_haproxy_hosts( + nfs_ganesha_txt + ) assert nfs_generated_conf == nfs_expected_conf @patch("cephadm.services.nfs.NFSService.fence_old_ranks", MagicMock())