]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: Command to upgrade non-ceph image services
authorShweta Bhosale <Shweta.Bhosale1@ibm.com>
Tue, 26 Nov 2024 06:13:11 +0000 (11:43 +0530)
committerShweta Bhosale <Shweta.Bhosale1@ibm.com>
Tue, 14 Jan 2025 05:47:07 +0000 (11:17 +0530)
Fixes: https://tracker.ceph.com/issues/68979
Signed-off-by: Shweta Bhosale <Shweta.Bhosale1@ibm.com>
src/pybind/mgr/cephadm/inventory.py
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/upgrade.py
src/pybind/mgr/orchestrator/_interface.py
src/pybind/mgr/orchestrator/module.py
src/python-common/ceph/cephadm/images.py

index 550604fc55be978a75763af25bc0bae012a283f3..f858a5315dcdb6e892d72d6f5eac161b21f50a2c 100644 (file)
@@ -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):
     """
index 6690153d435af4473a02a116bd3da3f919c35bd0..240e0510c817819fd0e93071123d551b3457b9d8 100644 (file)
@@ -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,
index ed3d26807e5ceec3da92d165ea50b1beed5e9c10..ff0710003ad611d0a610d19393fe6e2808bc6e8b 100644 (file)
@@ -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.
index 4fbc975ae9f04daa587d70f88ca766477f38ce8a..d2002f9fc0e7f7580e5312714a9c2e2b99c791bf 100644 (file)
@@ -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:
         """
index d5a1bb3da2bbb9206b56dfff9583d05ab7348ade..5ab661ad848627bb80eeb78d6244f37b1ec7650a 100644 (file)
@@ -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())
index 5b3c742120584c5ce7a341d140c420b5c03433b3..77c979ebd918d6d71c9f2a29e94dab710d6ced16 100644 (file)
@@ -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'