]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm, Add --image to `ceph orch daemon redeploy <what>`
authorSebastian Wagner <sebastian.wagner@suse.com>
Fri, 31 Jul 2020 16:02:34 +0000 (18:02 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Fri, 21 Aug 2020 11:04:01 +0000 (13:04 +0200)
Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
(cherry picked from commit 9d0480d18b6f30f929e8599ee8b32fdc6f91aa27)

src/pybind/mgr/cephadm/inventory.py
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/tests/test_cephadm.py
src/pybind/mgr/orchestrator/_interface.py
src/pybind/mgr/orchestrator/module.py
src/pybind/mgr/test_orchestrator/module.py

index bf621e0365c8b7c2951e9d65a312e89ce8255b71..6fc450e99895f9eb76199ff6865b4021b8df2195 100644 (file)
@@ -360,6 +360,13 @@ class HostCache():
                 r.append(dd)
         return r
 
+    def get_daemon(self, daemon_name: str) -> orchestrator.DaemonDescription:
+        for _, dm in self.daemons.items():
+            for _, dd in dm.items():
+                if dd.name() == daemon_name:
+                    return dd
+        raise orchestrator.OrchestratorError(f'Unable to find {daemon_name} daemon(s)')
+
     def get_daemons_with_volatile_status(self) -> Iterator[Tuple[str, Dict[str, orchestrator.DaemonDescription]]]:
         def alter(host, dd_orig: orchestrator.DaemonDescription) -> orchestrator.DaemonDescription:
             dd = copy(dd_orig)
index 287d4ccdad8595eba204b02c120e9f4d5736eb3c..a2857eab1058af0ab3eb11941513e9428505eaec 100644 (file)
@@ -1581,13 +1581,29 @@ you may want to run:
         ).name()):
             return self._daemon_action(daemon_type, daemon_id, host, action)
 
-    def _daemon_action(self, daemon_type, daemon_id, host, action):
+    def _daemon_action(self, daemon_type, daemon_id, host, action, image=None):
         daemon_spec: CephadmDaemonSpec = CephadmDaemonSpec(
             host=host,
             daemon_id=daemon_id,
             daemon_type=daemon_type,
         )
 
+        if image is not None:
+            if action != 'redeploy':
+                raise OrchestratorError(
+                    f'Cannot execute {action} with new image. `action` needs to be `redeploy`')
+            if daemon_type not in CEPH_TYPES:
+                raise OrchestratorError(
+                    f'Cannot redeploy {daemon_type}.{daemon_id} with a new image: Supported '
+                    f'types are: {", ".join(CEPH_TYPES)}')
+
+            self.check_mon_command({
+                'prefix': 'config set',
+                'name': 'container_image',
+                'value': image,
+                'who': utils.name_to_config_section(daemon_type + '.' + daemon_id),
+            })
+
         if action == 'redeploy':
             # stop, recreate the container+unit, then restart
             return self._create_daemon(daemon_spec)
@@ -1608,24 +1624,17 @@ you may want to run:
             except Exception:
                 self.log.exception(f'`{host}: cephadm unit {name} {a}` failed')
         self.cache.invalidate_host_daemons(daemon_spec.host)
-        return "{} {} from host '{}'".format(action, name, daemon_spec.host)
+        msg = "{} {} from host '{}'".format(action, name, daemon_spec.host)
+        self.events.for_daemon(name, 'INFO', msg)
+        return msg
 
     @trivial_completion
-    def daemon_action(self, action, daemon_type, daemon_id) -> List[str]:
-        args = []
-        for host, dm in self.cache.daemons.items():
-            for name, d in dm.items():
-                if d.daemon_type == daemon_type and d.daemon_id == daemon_id:
-                    args.append((d.daemon_type, d.daemon_id,
-                                 d.hostname, action))
-        if not args:
-            raise orchestrator.OrchestratorError(
-                'Unable to find %s.%s daemon(s)' % (
-                    daemon_type, daemon_id))
-        self.log.info('%s daemons %s' % (
-            action.capitalize(),
-            ','.join(['%s.%s' % (a[0], a[1]) for a in args])))
-        return self._daemon_actions(args)
+    def daemon_action(self, action: str, daemon_name: str, image: Optional[str]=None) -> str:
+        d = self.cache.get_daemon(daemon_name)
+
+        self.log.info(f'{action} daemon {daemon_name}')
+        return self._daemon_action(d.daemon_type, d.daemon_id,
+                                 d.hostname, action, image=image)
 
     @trivial_completion
     def remove_daemons(self, names):
index 500587262d09474dab7a69e21e41543022f9ce17..ff4f2a1eddbb9bc10c6172072668815bf447d6de 100644 (file)
@@ -206,12 +206,12 @@ class TestCephadm(object):
         with with_host(cephadm_module, 'test'):
             with with_daemon(cephadm_module, RGWSpec(service_id='myrgw.foobar'), CephadmOrchestrator.add_rgw, 'test') as daemon_id:
 
-                c = cephadm_module.daemon_action('redeploy', 'rgw', daemon_id)
-                assert wait(cephadm_module, c) == [f"Deployed rgw.{daemon_id} on host 'test'"]
+                c = cephadm_module.daemon_action('redeploy', 'rgw.' + daemon_id)
+                assert wait(cephadm_module, c) == f"Deployed rgw.{daemon_id} on host 'test'"
 
                 for what in ('start', 'stop', 'restart'):
-                    c = cephadm_module.daemon_action(what, 'rgw', daemon_id)
-                    assert wait(cephadm_module, c) == [what + f" rgw.{daemon_id} from host 'test'"]
+                    c = cephadm_module.daemon_action(what, 'rgw.' + daemon_id)
+                    assert wait(cephadm_module, c) == what + f" rgw.{daemon_id} from host 'test'"
 
                 # Make sure, _check_daemons does a redeploy due to monmap change:
                 cephadm_module._store['_ceph_get/mon_map'] = {
index 7431eeab33c5c011afa32b95fa73721d1f02dfb0..39e10777d99f22cb52e70eb36eb7f7967227e444 100644 (file)
@@ -963,13 +963,13 @@ class Orchestrator(object):
         #assert action in ["start", "stop", "reload, "restart", "redeploy"]
         raise NotImplementedError()
 
-    def daemon_action(self, action, daemon_type, daemon_id):
-        # type: (str, str, str) -> Completion[List[str]]
+    def daemon_action(self, action: str, daemon_name: str, image: Optional[str]=None) -> Completion[str]:
         """
         Perform an action (start/stop/reload) on a daemon.
 
         :param action: one of "start", "stop", "restart", "redeploy", "reconfig"
-        :param name: name of daemon
+        :param daemon_name: name of daemon
+        :param image: Container image when redeploying that daemon
         :rtype: Completion
         """
         #assert action in ["start", "stop", "reload, "restart", "redeploy"]
index 8fa804bbe89eb1c8baa7d7e368b7624e2295109e..e8a5e1eed4a6ef85918b806470a7e772c12ad962 100644 (file)
@@ -1092,14 +1092,26 @@ Usage:
 
     @_cli_write_command(
         'orch daemon',
-        "name=action,type=CephChoices,strings=start|stop|restart|redeploy|reconfig "
+        "name=action,type=CephChoices,strings=start|stop|restart|reconfig "
         "name=name,type=CephString",
-        'Start, stop, restart, redeploy, or reconfig a specific daemon')
+        'Start, stop, restart, (redeploy,) or reconfig a specific daemon')
     def _daemon_action(self, action, name):
         if '.' not in name:
             raise OrchestratorError('%s is not a valid daemon name' % name)
-        (daemon_type, daemon_id) = name.split('.', 1)
-        completion = self.daemon_action(action, daemon_type, daemon_id)
+        completion = self.daemon_action(action, name)
+        self._orchestrator_wait([completion])
+        raise_if_exception(completion)
+        return HandleCommandResult(stdout=completion.result_str())
+
+    @_cli_write_command(
+        'orch daemon redeploy',
+        "name=name,type=CephString "
+        "name=image,type=CephString,req=false",
+        'Redeploy a daemon (with a specifc image)')
+    def _daemon_action_redeploy(self, name, image):
+        if '.' not in name:
+            raise OrchestratorError('%s is not a valid daemon name' % name)
+        completion = self.daemon_action("redeploy", name, image=image)
         self._orchestrator_wait([completion])
         raise_if_exception(completion)
         return HandleCommandResult(stdout=completion.result_str())
index f2eabdc5bf0fe68c47d24ffa09f05fcb0b6ee7f2..c73d2f39c043641650c68475854f83ca7da17b20 100644 (file)
@@ -315,7 +315,7 @@ class TestOrchestrator(MgrModule, orchestrator.Orchestrator):
         pass
 
     @deferred_write("daemon_action")
-    def daemon_action(self, action, daemon_type, daemon_id):
+    def daemon_action(self, action, daemon_name, image=None):
         pass
 
     @deferred_write("Adding NFS service")