From fbe0c3fd23f9005986959bade149093c340f6238 Mon Sep 17 00:00:00 2001 From: Adam King Date: Mon, 28 Feb 2022 20:23:10 -0500 Subject: [PATCH] mgr/cephadm: block removing last instance of _admin label Fixes: https://tracker.ceph.com/issues/54425 Signed-off-by: Adam King --- src/pybind/mgr/cephadm/module.py | 14 +++++++++++++- src/pybind/mgr/orchestrator/_interface.py | 2 +- src/pybind/mgr/orchestrator/module.py | 4 ++-- src/pybind/mgr/rook/module.py | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index ae428249e4601..4757c2e182f14 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -1520,7 +1520,19 @@ Then run the following: return 'Added label %s to host %s' % (label, host) @handle_orch_error - def remove_host_label(self, host: str, label: str) -> str: + def remove_host_label(self, host: str, label: str, force: bool = False) -> str: + # if we remove the _admin label from the only host that has it we could end up + # removing the only instance of the config and keyring and cause issues + if not force and label == '_admin': + p = PlacementSpec(label='_admin') + admin_hosts = p.filter_matching_hostspecs(self.inventory.all_specs()) + if len(admin_hosts) == 1 and admin_hosts[0] == host: + raise OrchestratorValidationError(f"Host {host} is the last host with the '_admin'" + " label.\nRemoving the _admin label from this host could cause the removal" + " of the last cluster config/keyring managed by cephadm.\n" + "It is recommended to add the _admin label to another host" + " before completing this operation.\nIf you're certain this is" + " what you want rerun this command with --force.") self.inventory.rm_label(host, label) self.log.info('Removed label %s to host %s' % (label, host)) self._kick_serve_loop() diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index 344dea13854e8..2ed881f6ab533 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -392,7 +392,7 @@ class Orchestrator(object): """ raise NotImplementedError() - def remove_host_label(self, host: str, label: str) -> OrchResult[str]: + def remove_host_label(self, host: str, label: str, force: bool = False) -> OrchResult[str]: """ Remove a host label """ diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index cdf93f7a4bd46..88f24365294b5 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -420,9 +420,9 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule, return HandleCommandResult(stdout=completion.result_str()) @_cli_write_command('orch host label rm') - def _host_label_rm(self, hostname: str, label: str) -> HandleCommandResult: + def _host_label_rm(self, hostname: str, label: str, force: bool = False) -> HandleCommandResult: """Remove a host label""" - completion = self.remove_host_label(hostname, label) + completion = self.remove_host_label(hostname, label, force) raise_if_exception(completion) return HandleCommandResult(stdout=completion.result_str()) diff --git a/src/pybind/mgr/rook/module.py b/src/pybind/mgr/rook/module.py index 22433d44cca71..4300e98d502b1 100644 --- a/src/pybind/mgr/rook/module.py +++ b/src/pybind/mgr/rook/module.py @@ -633,7 +633,7 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator): def add_host_label(self, host: str, label: str) -> OrchResult[str]: return self.rook_cluster.add_host_label(host, label) - def remove_host_label(self, host: str, label: str) -> OrchResult[str]: + def remove_host_label(self, host: str, label: str, force: bool = False) -> OrchResult[str]: return self.rook_cluster.remove_host_label(host, label) """ @handle_orch_error -- 2.39.5