]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: support removing OSD in OSDs page
authorKiefer Chang <kiefer.chang@suse.com>
Wed, 11 Dec 2019 04:08:01 +0000 (12:08 +0800)
committerKiefer Chang <kiefer.chang@suse.com>
Wed, 11 Mar 2020 06:19:37 +0000 (14:19 +0800)
Add backend codes for deleting an OSD.

- `DELETE /api/osd/<svc_id>`: delete osd.svc_id. An error is returned if
there are any pre-checks fail.
- `DELETE /api/osd/<svc_id>?force=true`: with `force` flag on, the
deleting request is sent to orchestrator even pre-checks fail.

Fixes: https://tracker.ceph.com/issues/43062
Signed-off-by: Kiefer Chang <kiefer.chang@suse.com>
src/pybind/mgr/dashboard/controllers/osd.py
src/pybind/mgr/dashboard/services/orchestrator.py

index 466130d392ae2dce4f54311e12f0c12905b80f09..504e1762166045485bd51745e6e58bb467586b71 100644 (file)
@@ -7,7 +7,7 @@ from ceph.deployment.drive_group import DriveGroupSpecs, DriveGroupValidationErr
 from mgr_util import get_most_recent_rate
 
 from . import ApiController, RESTController, Endpoint, Task
-from . import CreatePermission, ReadPermission, UpdatePermission
+from . import CreatePermission, ReadPermission, UpdatePermission, DeletePermission
 from .orchestrator import raise_if_no_orchestrator
 from .. import mgr
 from ..exceptions import DashboardException
@@ -129,6 +129,20 @@ class Osd(RESTController):
                     'ids': [svc_id]
                 })
 
+    @DeletePermission
+    @raise_if_no_orchestrator
+    @handle_orchestrator_error('osd')
+    def delete(self, svc_id, force=None):
+        orch = OrchClient.instance()
+        if not force:
+            logger.info('Check for removing osd.%s...', svc_id)
+            check = orch.osds.check_remove([svc_id])
+            if not check['safe']:
+                logger.error('Unable to remove osd.%s: %s', svc_id, check['message'])
+                raise DashboardException(component='osd', msg=check['message'])
+        logger.info('Start removing osd.%s...', svc_id)
+        orch.osds.remove([svc_id])
+
     @RESTController.Resource('POST', query_params=['deep'])
     @UpdatePermission
     def scrub(self, svc_id, deep=False):
@@ -265,6 +279,21 @@ class Osd(RESTController):
                 'is_safe_to_destroy': False,
             }
 
+    @Endpoint('GET', query_params=['svc_ids'])
+    @ReadPermission
+    @raise_if_no_orchestrator
+    @handle_orchestrator_error('osd')
+    def safe_to_delete(self, svc_ids):
+        """
+        :type ids: int|[int]
+        """
+        orch = OrchClient.instance()
+        check = orch.osds.check_remove([svc_ids])
+        return {
+            'is_safe_to_delete': check.get('safe', False),
+            'message': check.get('message', '')
+        }
+
     @RESTController.Resource('GET')
     def devices(self, svc_id):
         # (str) -> dict
index b863e20a88196ac8f2a120b4f904b8bf4f9ffa79..75c4f66c98ae870d408e19fcf7b54219b5c7e1ae 100644 (file)
@@ -108,6 +108,14 @@ class OsdManager(ResourceManager):
     def create(self, drive_groups):
         return self.api.create_osds(drive_groups)
 
+    @wait_api_result
+    def remove(self, osd_ids):
+        return self.api.remove_osds(osd_ids)
+
+    @wait_api_result
+    def removing_status(self):
+        return self.api.remove_osds_status()
+
 
 class OrchClient(object):