From: Adam King Date: Mon, 13 Feb 2023 20:01:59 +0000 (-0500) Subject: mgr/cephadm: add commands to set services to managed/unmanaged X-Git-Tag: v18.1.0~130^2~37 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=01a57bf8b08a64e68c3b2682257a7242d14db901;p=ceph-ci.git mgr/cephadm: add commands to set services to managed/unmanaged Fixes: https://tracker.ceph.com/issues/58713 Signed-off-by: Adam King (cherry picked from commit b0d8c0846cbe0ebae69dbdeb3f2982213ab56a58) --- diff --git a/doc/cephadm/services/index.rst b/doc/cephadm/services/index.rst index ab87326c119..6596a8acdb4 100644 --- a/doc/cephadm/services/index.rst +++ b/doc/cephadm/services/index.rst @@ -686,6 +686,22 @@ To disable the automatic management of dameons, set ``unmanaged=True`` in the ceph orch apply -i mgr.yaml +Cephadm also supports setting the unmanaged parameter to true or false +using the ``ceph orch set-unmanaged`` and ``ceph orch set-managed`` commands. +The commands take the service name (as reported in ``ceph orch ls``) as +the only argument. For example, + +.. prompt:: bash # + + ceph orch set-unmanaged mon + +would set ``unmanaged: true`` for the mon service and + +.. prompt:: bash # + + ceph orch set-managed mon + +would set ``unmanaged: false`` for the mon service .. note:: @@ -693,6 +709,13 @@ To disable the automatic management of dameons, set ``unmanaged=True`` in the longer deploy any new daemons (even if the placement specification matches additional hosts). +.. note:: + + The "osd" service used to track OSDs that are not tied to any specific + service spec is special and will always be marked unmanaged. Attempting + to modify it with ``ceph orch set-unmanaged`` or ``ceph orch set-managed`` + will result in a message ``No service of name osd found. Check "ceph orch ls" for all known services`` + Deploying a daemon on a host manually ------------------------------------- diff --git a/src/pybind/mgr/cephadm/inventory.py b/src/pybind/mgr/cephadm/inventory.py index bb7be85f67f..ad6f02f8ffe 100644 --- a/src/pybind/mgr/cephadm/inventory.py +++ b/src/pybind/mgr/cephadm/inventory.py @@ -326,6 +326,15 @@ class SpecStore(): def get_created(self, spec: ServiceSpec) -> Optional[datetime.datetime]: return self.spec_created.get(spec.service_name()) + def set_unmanaged(self, service_name: str, value: bool) -> str: + if service_name not in self._specs: + return f'No service of name {service_name} found. Check "ceph orch ls" for all known services' + if self._specs[service_name].unmanaged == value: + return f'Service {service_name}{" already " if value else " not "}marked unmanaged. No action taken.' + self._specs[service_name].unmanaged = value + self.save(self._specs[service_name]) + return f'Set unmanaged to {str(value)} for service {service_name}' + class ClientKeyringSpec(object): """ diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 42bb65a7279..4d90bfcaf05 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -3014,6 +3014,10 @@ Then run the following: def apply_snmp_gateway(self, spec: ServiceSpec) -> str: return self._apply(spec) + @handle_orch_error + def set_unmanaged(self, service_name: str, value: bool) -> str: + return self.spec_store.set_unmanaged(service_name, value) + @handle_orch_error def upgrade_check(self, image: str, version: str) -> str: if self.inventory.get_host_with_state("maintenance"): diff --git a/src/pybind/mgr/cephadm/tests/test_cephadm.py b/src/pybind/mgr/cephadm/tests/test_cephadm.py index db5c2aa70c6..f3132c12750 100644 --- a/src/pybind/mgr/cephadm/tests/test_cephadm.py +++ b/src/pybind/mgr/cephadm/tests/test_cephadm.py @@ -2139,3 +2139,11 @@ Traceback (most recent call last): cephadm_module.inventory.all_specs = mock.Mock( return_value=[mock.Mock().hostname, mock.Mock().hostname]) cephadm_module._validate_tuned_profile_spec(spec) + + def test_set_unmanaged(self, cephadm_module): + cephadm_module.spec_store._specs['crash'] = ServiceSpec('crash', unmanaged=False) + assert not cephadm_module.spec_store._specs['crash'].unmanaged + cephadm_module.spec_store.set_unmanaged('crash', True) + assert cephadm_module.spec_store._specs['crash'].unmanaged + cephadm_module.spec_store.set_unmanaged('crash', False) + assert not cephadm_module.spec_store._specs['crash'].unmanaged diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index 40235553227..d08e76d8d79 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -502,6 +502,14 @@ class Orchestrator(object): return OrchResult(l_res) return raise_if_exception(reduce(merge, [fns[spec.service_type](spec) for spec in specs], OrchResult([]))) + def set_unmanaged(self, service_name: str, value: bool) -> OrchResult[str]: + """ + Set unmanaged parameter to True/False for a given service + + :return: None + """ + raise NotImplementedError() + def plan(self, spec: Sequence["GenericSpec"]) -> OrchResult[List]: """ Plan (Dry-run, Preview) a List of Specs. diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index 9c98736b64a..607cd4fad79 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -1443,6 +1443,22 @@ Usage: specs: List[ServiceSpec] = spec.get_tracing_specs() return self._apply_misc(specs, dry_run, format, no_overwrite) + @_cli_write_command('orch set-unmanaged') + def _set_unmanaged(self, service_name: str) -> HandleCommandResult: + """Set 'unmanaged: true' for the given service name""" + completion = self.set_unmanaged(service_name, True) + raise_if_exception(completion) + out = completion.result_str() + return HandleCommandResult(stdout=out) + + @_cli_write_command('orch set-managed') + def _set_managed(self, service_name: str) -> HandleCommandResult: + """Set 'unmanaged: false' for the given service name""" + completion = self.set_unmanaged(service_name, False) + raise_if_exception(completion) + out = completion.result_str() + return HandleCommandResult(stdout=out) + @_cli_write_command('orch set backend') def _set_backend(self, module_name: Optional[str] = None) -> HandleCommandResult: """