})
extra = self.extra_ceph_conf().conf
if extra:
- config += extra.strip().replace('[global]','') + '\n'
+ try:
+ config = self._combine_confs(config, extra)
+ except Exception as e:
+ self.log.error(f'Failed to add extra ceph conf settings to minimal ceph conf: {e}')
return config
+ def _combine_confs(self, conf1: str, conf2: str) -> str:
+ section_to_option: Dict[str, List[str]] = {}
+ final_conf: str = ''
+ for conf in [conf1, conf2]:
+ if not conf:
+ continue
+ section = ''
+ for line in conf.split('\n'):
+ if line.strip().startswith('#') or not line.strip():
+ continue
+ if line.strip().startswith('[') and line.strip().endswith(']'):
+ section = line.strip().replace('[', '').replace(']', '')
+ if section not in section_to_option:
+ section_to_option[section] = []
+ else:
+ section_to_option[section].append(line.strip())
+
+ first_section = True
+ for section, options in section_to_option.items():
+ if not first_section:
+ final_conf += '\n'
+ final_conf += f'[{section}]\n'
+ for option in options:
+ final_conf += f'{option}\n'
+ first_section = False
+
+ return final_conf
+
def _invalidate_daemons_and_kick_serve(self, filter_host: Optional[str] = None) -> None:
if filter_host:
self.cache.invalidate_host_daemons(filter_host)
'--config-json', '-',
'--reconfig',
],
- stdin='{"config": "\\n\\n[mon]\\nk=v\\n[mon.test]\\npublic network = 127.0.0.0/8\\n", '
+ stdin='{"config": "[mon]\\nk=v\\n[mon.test]\\npublic network = 127.0.0.0/8\\n", '
+ '"keyring": "", "files": {"config": "[mon.test]\\npublic network = 127.0.0.0/8\\n"}}',
image='')
CephadmServe(cephadm_module)._write_all_client_files()
_write_file.assert_has_calls([mock.call('test',
'/etc/ceph/ceph.conf',
- b'\n\n[mon]\nk=v\n', 0o644, 0, 0, None),
+ b'[mon]\nk=v\n', 0o644, 0, 0, None),
mock.call('test',
'/var/lib/ceph/fsid/config/ceph.conf',
- b'\n\n[mon]\nk=v\n', 0o644, 0, 0, None)])
+ b'[mon]\nk=v\n', 0o644, 0, 0, None)])
# reload
cephadm_module.cache.last_client_files = {}
cephadm_module.cache.load()
with with_cephadm_module({'manage_etc_ceph_ceph_conf': True}) as m:
assert m.manage_etc_ceph_ceph_conf is True
+ @mock.patch("cephadm.CephadmOrchestrator.check_mon_command")
+ @mock.patch("cephadm.CephadmOrchestrator.extra_ceph_conf")
+ def test_extra_ceph_conf(self, _extra_ceph_conf, _check_mon_cmd, cephadm_module: CephadmOrchestrator):
+ # settings put into the [global] section in the extra conf
+ # need to be appended to existing [global] section in given
+ # minimal ceph conf, but anything in another section (e.g. [mon])
+ # needs to continue to be its own section
+
+ # this is the conf "ceph generate-minimal-conf" will return in this test
+ _check_mon_cmd.return_value = (0, """[global]
+global_k1 = global_v1
+global_k2 = global_v2
+[mon]
+mon_k1 = mon_v1
+[osd]
+osd_k1 = osd_v1
+osd_k2 = osd_v2
+""", '')
+
+ # test with extra ceph conf that has some of the sections from minimal conf
+ _extra_ceph_conf.return_value = CephadmOrchestrator.ExtraCephConf(conf="""[mon]
+mon_k2 = mon_v2
+[global]
+global_k3 = global_v3
+""", last_modified=datetime_now())
+
+ expected_combined_conf = """[global]
+global_k1 = global_v1
+global_k2 = global_v2
+global_k3 = global_v3
+[mon]
+mon_k1 = mon_v1
+mon_k2 = mon_v2
+[osd]
+osd_k1 = osd_v1
+osd_k2 = osd_v2
+"""
+
+ assert cephadm_module.get_minimal_ceph_conf() == expected_combined_conf
+
@mock.patch("cephadm.serve.CephadmServe._run_cephadm")
def test_registry_login(self, _run_cephadm, cephadm_module: CephadmOrchestrator):
def check_registry_credentials(url, username, password):