From: Shweta Bhosale Date: Tue, 26 Nov 2024 06:13:11 +0000 (+0530) Subject: mgr/cephadm: Command to upgrade non-ceph image services X-Git-Tag: v20.0.0~332^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=166b605a39ceab3358433f06b2bf8f8aa304c78b;p=ceph.git mgr/cephadm: Command to upgrade non-ceph image services Fixes: https://tracker.ceph.com/issues/68979 Signed-off-by: Shweta Bhosale --- diff --git a/src/pybind/mgr/cephadm/inventory.py b/src/pybind/mgr/cephadm/inventory.py index 550604fc55b..f858a5315dc 100644 --- a/src/pybind/mgr/cephadm/inventory.py +++ b/src/pybind/mgr/cephadm/inventory.py @@ -522,6 +522,13 @@ class SpecStore(): else: self.mgr.log.warning(f'Attempted to mark unknown service "{name}" as having been configured') + def get_specs_by_type(self, service_type: str) -> Mapping[str, ServiceSpec]: + return { + service_name: spec + for service_name, spec in self._specs.items() + if service_type == spec.service_type + } + class ClientKeyringSpec(object): """ diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 6690153d435..240e0510c81 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -2458,23 +2458,27 @@ Then run the following: result.append(dd) return result - @handle_orch_error - def service_action(self, action: str, service_name: str) -> List[str]: - if service_name not in self.spec_store.all_specs.keys() and service_name != 'osd': - raise OrchestratorError(f'Invalid service name "{service_name}".' - + ' View currently running services using "ceph orch ls"') + def perform_service_action(self, action: str, service_name: str) -> List[str]: dds: List[DaemonDescription] = self.cache.get_daemons_by_service(service_name) if not dds: raise OrchestratorError(f'No daemons exist under service name "{service_name}".' + ' View currently running services using "ceph orch ls"') - if action == 'stop' and service_name.split('.')[0].lower() in ['mgr', 'mon', 'osd']: - return [f'Stopping entire {service_name} service is prohibited.'] self.log.info('%s service %s' % (action.capitalize(), service_name)) return [ self._schedule_daemon_action(dd.name(), action) for dd in dds ] + @handle_orch_error + def service_action(self, action: str, service_name: str) -> List[str]: + if service_name not in self.spec_store.all_specs.keys(): + raise OrchestratorError(f'Invalid service name "{service_name}".' + + ' View currently running services using "ceph orch ls"') + if action == 'stop' and service_name.split('.')[0].lower() in ['mgr', 'mon', 'osd']: + return [f'Stopping entire {service_name} service is prohibited.'] + + return self.perform_service_action(action, service_name) + def _rotate_daemon_key(self, daemon_spec: CephadmDaemonDeploySpec) -> str: self.log.info(f'Rotating authentication key for {daemon_spec.name()}') rc, out, err = self.mon_command({ @@ -3810,6 +3814,10 @@ Then run the following: def upgrade_stop(self) -> str: return self.upgrade.upgrade_stop() + @handle_orch_error + def update_service(self, service_type: str, service_image: str, image: str) -> List[str]: + return self.upgrade.update_service(service_type, service_image, image) + @handle_orch_error def replace_device(self, hostname: str, diff --git a/src/pybind/mgr/cephadm/upgrade.py b/src/pybind/mgr/cephadm/upgrade.py index ed3d26807e5..ff0710003ad 100644 --- a/src/pybind/mgr/cephadm/upgrade.py +++ b/src/pybind/mgr/cephadm/upgrade.py @@ -494,6 +494,21 @@ class CephadmUpgrade: self.mgr.event.set() return 'Stopped upgrade to %s' % target_image + def update_service(self, service_type: str, service_image: str, image: str) -> List[str]: + out = [] + self.mgr.set_module_option(f"container_image_{service_image}", image) + # Redeploy all the service daemons of provided service type + for service_name, spec in self.mgr.spec_store.get_specs_by_type(service_type).items(): + out.append(f'Processing "{service_name}" service\n') + try: + res = self.mgr.perform_service_action('redeploy', service_name) + except Exception as exp: + self.mgr.log.exception(f"Failed to redeploy service {service_name}") + out.append(f'{exp}\n') + else: + out.extend(res) + return out + def continue_upgrade(self) -> bool: """ Returns false, if nothing was done. diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index 4fbc975ae9f..d2002f9fc0e 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -945,6 +945,9 @@ class Orchestrator(object): """ raise NotImplementedError() + def update_service(self, service_type: str, service_image: str, image: str) -> OrchResult: + raise NotImplementedError() + @_hide_in_features def upgrade_available(self) -> OrchResult: """ diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index d5a1bb3da2b..5ab661ad848 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -21,7 +21,7 @@ from ceph.deployment.service_spec import PlacementSpec, ServiceSpec, service_spe from ceph.deployment.hostspec import SpecValidationError from ceph.deployment.utils import unwrap_ipv6 from ceph.utils import datetime_now - +from ceph.cephadm.images import NonCephImageServiceTypes from mgr_util import to_pretty_timedelta, format_bytes from mgr_module import MgrModule, HandleCommandResult, Option from object_format import Format @@ -2420,3 +2420,10 @@ Usage: completion = self.upgrade_stop() raise_if_exception(completion) return HandleCommandResult(stdout=completion.result_str()) + + @_cli_write_command('orch update service') + def _update_service(self, service_type: NonCephImageServiceTypes, image: str) -> HandleCommandResult: + """Update image for non-ceph image daemon""" + completion = self.update_service(service_type.value, service_type.name, image) + raise_if_exception(completion) + return HandleCommandResult(stdout=completion.result_str()) diff --git a/src/python-common/ceph/cephadm/images.py b/src/python-common/ceph/cephadm/images.py index 5b3c7421205..77c979ebd91 100644 --- a/src/python-common/ceph/cephadm/images.py +++ b/src/python-common/ceph/cephadm/images.py @@ -55,3 +55,20 @@ class DefaultImages(Enum): @property def desc(self) -> str: return self.value.desc + + +class NonCephImageServiceTypes(Enum): + prometheus = 'prometheus' + loki = 'loki' + promtail = 'promtail' + node_exporter = 'node-exporter' + alertmanager = 'alertmanager' + grafana = 'grafana' + nvmeof = 'nvmeof' + snmp_gateway = 'snmp-gateway' + elasticsearch = 'elasticsearch' + jaeger_collector = 'jaeger-collector' + jaeger_query = 'jaeger-query' + jaeger_agent = 'jaeger-agent' + samba = 'smb' + oauth2_proxy = 'oauth2-proxy'