]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephadm: osd replacement improvement 50838/head
authorGuillaume Abrioux <gabrioux@ibm.com>
Fri, 31 Mar 2023 09:27:13 +0000 (11:27 +0200)
committerGuillaume Abrioux <gabrioux@ibm.com>
Fri, 14 Apr 2023 12:53:44 +0000 (14:53 +0200)
This adds a new parameter `--no-destroy` to the command
`ceph orch osd rm`.

By default, it removes any VGs/LVs related to the osd being removed.
For specific workflows, this can be useful to preserve them.

Fixes: https://tracker.ceph.com/issues/59289
Signed-off-by: Guillaume Abrioux <gabrioux@ibm.com>
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/services/osd.py
src/pybind/mgr/orchestrator/_interface.py
src/pybind/mgr/orchestrator/module.py
src/pybind/mgr/rook/module.py

index 4de7083c3ec8553008bfffe0c4b5b876723e94a1..555a405ee5e2abc3e12c343222ef0f88562e0a17 100644 (file)
@@ -3172,7 +3172,8 @@ Then run the following:
     def remove_osds(self, osd_ids: List[str],
                     replace: bool = False,
                     force: bool = False,
-                    zap: bool = False) -> str:
+                    zap: bool = False,
+                    no_destroy: bool = False) -> str:
         """
         Takes a list of OSDs and schedules them for removal.
         The function that takes care of the actual removal is
@@ -3194,6 +3195,7 @@ Then run the following:
                                                 replace=replace,
                                                 force=force,
                                                 zap=zap,
+                                                no_destroy=no_destroy,
                                                 hostname=daemon.hostname,
                                                 process_started_at=datetime_now(),
                                                 remove_util=self.to_remove_osds.rm_util))
index 31771fb5fcebe4cdf404dac344d5a630ee51da58..9f404646f384b28cbf035d4cf37c955128b3f39e 100644 (file)
@@ -542,9 +542,12 @@ class RemoveUtil(object):
     def zap_osd(self, osd: "OSD") -> str:
         "Zaps all devices that are associated with an OSD"
         if osd.hostname is not None:
+            cmd = ['--', 'lvm', 'zap', '--osd-id', str(osd.osd_id)]
+            if not osd.no_destroy:
+                cmd.append('--destroy')
             out, err, code = self.mgr.wait_async(CephadmServe(self.mgr)._run_cephadm(
                 osd.hostname, 'osd', 'ceph-volume',
-                ['--', 'lvm', 'zap', '--destroy', '--osd-id', str(osd.osd_id)],
+                cmd,
                 error_ok=True))
             self.mgr.cache.invalidate_host_devices(osd.hostname)
             if code:
@@ -608,7 +611,8 @@ class OSD:
                  replace: bool = False,
                  force: bool = False,
                  hostname: Optional[str] = None,
-                 zap: bool = False):
+                 zap: bool = False,
+                 no_destroy: bool = False):
         # the ID of the OSD
         self.osd_id = osd_id
 
@@ -647,6 +651,8 @@ class OSD:
 
         # Whether devices associated with the OSD should be zapped (DATA ERASED)
         self.zap = zap
+        # Whether all associated LV devices should be destroyed.
+        self.no_destroy = no_destroy
 
     def start(self) -> None:
         if self.started:
index 0321ef878c53bba6ce64ba79416194d0d0f1f80d..4db5372503116690a3d244d0c63069bd16fd9e75 100644 (file)
@@ -589,12 +589,14 @@ class Orchestrator(object):
     def remove_osds(self, osd_ids: List[str],
                     replace: bool = False,
                     force: bool = False,
-                    zap: bool = False) -> OrchResult[str]:
+                    zap: bool = False,
+                    no_destroy: bool = False) -> OrchResult[str]:
         """
         :param osd_ids: list of OSD IDs
         :param replace: marks the OSD as being destroyed. See :ref:`orchestrator-osd-replace`
         :param force: Forces the OSD removal process without waiting for the data to be drained first.
         :param zap: Zap/Erase all devices associated with the OSDs (DESTROYS DATA)
+        :param no_destroy: Do not destroy associated VGs/LVs with the OSD.
 
 
         .. note:: this can only remove OSDs that were successfully
index 963f63259e20e4fdeb0c054a188912e8855e691d..c32a6dfda53e53ac7947c339b7784209381ce071 100644 (file)
@@ -1000,9 +1000,11 @@ Usage:
                       osd_id: List[str],
                       replace: bool = False,
                       force: bool = False,
-                      zap: bool = False) -> HandleCommandResult:
+                      zap: bool = False,
+                      no_destroy: bool = False) -> HandleCommandResult:
         """Remove OSD daemons"""
-        completion = self.remove_osds(osd_id, replace=replace, force=force, zap=zap)
+        completion = self.remove_osds(osd_id, replace=replace, force=force,
+                                      zap=zap, no_destroy=no_destroy)
         raise_if_exception(completion)
         return HandleCommandResult(stdout=completion.result_str())
 
index 370cb6582199d341cd4b00d2459ace424587f899..b67349d1bff6229ba3f76f7b4cd896475c4d1622 100644 (file)
@@ -625,7 +625,12 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
         }
         self.set_store("drive_group_map", json.dumps(json_drive_group_map))
 
-    def remove_osds(self, osd_ids: List[str], replace: bool = False, force: bool = False, zap: bool = False) -> OrchResult[str]:
+    def remove_osds(self,
+                    osd_ids: List[str],
+                    replace: bool = False,
+                    force: bool = False,
+                    zap: bool = False,
+                    no_destroy: bool = False) -> OrchResult[str]:
         assert self._rook_cluster is not None
         if zap:
             raise RuntimeError("Rook does not support zapping devices during OSD removal.")