]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Applied Exception Handling
authorSebastian Wagner <sebastian.wagner@suse.com>
Tue, 24 Apr 2018 16:20:59 +0000 (18:20 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Tue, 8 May 2018 14:30:54 +0000 (16:30 +0200)
* Minor changes to CephFS, OSD, Pool, RbdMirroring, Summary and RGW

Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
qa/tasks/mgr/dashboard/test_cephfs.py
qa/tasks/mgr/dashboard/test_pool.py
src/pybind/mgr/dashboard/controllers/cephfs.py
src/pybind/mgr/dashboard/controllers/osd.py
src/pybind/mgr/dashboard/controllers/pool.py
src/pybind/mgr/dashboard/controllers/rbd_mirroring.py
src/pybind/mgr/dashboard/controllers/rgw.py
src/pybind/mgr/dashboard/controllers/summary.py

index 5669e41e07ec4e4b145279f8f40c1f40ef5c25c9..351b8745ee18984527b7a646d225016fcd714640 100644 (file)
@@ -37,3 +37,14 @@ class CephfsTest(DashboardTestCase):
 
         self.assertIsInstance(data, dict)
         self.assertIsNotNone(data)
+
+    @authenticate
+    def test_cephfs_mds_counters_wrong(self):
+        data = self._get("/api/cephfs/mds_counters/baadbaad")
+        self.assertStatus(400)
+        self.assertJsonBody({
+                "component": 'cephfs',
+                "code": "invalid_cephfs_id",
+                "detail": "Invalid cephfs id baadbaad"
+             })
+
index 1330ed7e9c178bcec2830fb9cac0283018d62c9b..e884d2f1cd3737b694f3aa479cef0cb8d42f5492 100644 (file)
@@ -18,9 +18,6 @@ class PoolTest(DashboardTestCase):
             cls._ceph_cmd(['osd', 'pool', 'delete', name, name, '--yes-i-really-really-mean-it'])
         cls._ceph_cmd(['osd', 'erasure-code-profile', 'rm', 'ecprofile'])
 
-
-
-
     @authenticate
     def test_pool_list(self):
         data = self._get("/api/pool")
@@ -145,6 +142,17 @@ class PoolTest(DashboardTestCase):
         for data in pools:
             self._pool_create(data)
 
+    @authenticate
+    def test_pool_create_fail(self):
+        data = {'pool_type': u'replicated', 'rule_name': u'dnf', 'pg_num': u'8', 'pool': u'sadfs'}
+        self._post('/api/pool/', data)
+        self.assertStatus(400)
+        self.assertJsonBody({
+            'component': 'pool',
+            'code': "2",
+            'detail': "specified rule dnf doesn't exist"
+        })
+
     @authenticate
     def test_pool_info(self):
         info_data = self._get("/api/pool/_info")
index 59b57174326beb8c3e45ecf53ae9d8f73678f04e..22acf8d60fc2f8f035b175296bfd5257be8e471d 100644 (file)
@@ -5,6 +5,7 @@ from collections import defaultdict
 
 import cherrypy
 
+from ..exceptions import DashboardException
 from . import ApiController, AuthRequired, BaseController
 from .. import mgr
 from ..services.ceph_service import CephService
@@ -80,7 +81,9 @@ class CephFS(BaseController):
         try:
             return int(fs_id)
         except ValueError:
-            raise cherrypy.HTTPError(400, "Invalid cephfs id {}".format(fs_id))
+            raise DashboardException(code='invalid_cephfs_id',
+                                     msg="Invalid cephfs id {}".format(fs_id),
+                                     component='cephfs')
 
     def _get_mds_names(self, filesystem_id=None):
         names = []
index 4844ee9857e1d6f6f636710871ec1c5e6b6554da..d5a25e20c4bfee87ffda87c0d0ab011c0fd729a4 100644 (file)
@@ -1,13 +1,10 @@
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import
 
-import json
-
-from mgr_module import CommandResult
-
 from . import ApiController, AuthRequired, RESTController
-from .. import logger, mgr
+from .. import mgr
 from ..services.ceph_service import CephService
+from ..services.exception import handle_send_command_error
 
 
 @ApiController('osd')
@@ -51,20 +48,9 @@ class Osd(RESTController):
             osds[str(osd['id'])] = osd
         return osds
 
+    @handle_send_command_error('osd')
     def get(self, svc_id):
-        result = CommandResult('')
-        mgr.send_command(result, 'osd', svc_id,
-                         json.dumps({
-                             'prefix': 'perf histogram dump',
-                         }),
-                         '')
-        r, outb, outs = result.wait()
-        if r != 0:
-            logger.warning('Failed to load histogram for OSD %s', svc_id)
-            logger.debug(outs)
-            histogram = outs
-        else:
-            histogram = json.loads(outb)
+        histogram = CephService.send_command('osd', srv_spec=svc_id, prefix='perf histogram dump')
         return {
             'osd_map': self.get_osd_map()[svc_id],
             'osd_metadata': mgr.get_metadata('osd', svc_id),
index 8288165bc499666a6105fe3fedba601828c9d41b..b9719834347d830bc01c8f09fe268d2bf8421e56 100644 (file)
@@ -6,6 +6,7 @@ import cherrypy
 from . import ApiController, RESTController, AuthRequired
 from .. import mgr
 from ..services.ceph_service import CephService
+from ..services.exception import handle_send_command_error
 
 
 @ApiController('pool')
@@ -55,12 +56,17 @@ class Pool(RESTController):
 
     def get(self, pool_name, attrs=None, stats=False):
         pools = self.list(attrs, stats)
-        return [pool for pool in pools if pool['pool_name'] == pool_name][0]
+        pool = [pool for pool in pools if pool['pool_name'] == pool_name]
+        if not pool:
+            return cherrypy.NotFound('No such pool')
+        return pool[0]
 
+    @handle_send_command_error('pool')
     def delete(self, pool_name):
         return CephService.send_command('mon', 'osd pool delete', pool=pool_name, pool2=pool_name,
                                         sure='--yes-i-really-really-mean-it')
 
+    @handle_send_command_error('pool')
     def create(self, pool, pg_num, pool_type, erasure_code_profile=None, flags=None,
                application_metadata=None, rule_name=None, **kwargs):
         ecp = erasure_code_profile if erasure_code_profile else None
index b90401e1885493a82d277e33d25d0c6e1ee45782..c218a518f82ffaa07e3f4b5709282e1a28dc8ce2 100644 (file)
@@ -13,6 +13,7 @@ from . import ApiController, AuthRequired, BaseController
 from .. import logger, mgr
 from ..services.ceph_service import CephService
 from ..tools import ViewCache
+from ..services.exception import handle_rbd_error
 
 
 @ViewCache()
@@ -94,6 +95,7 @@ def get_daemons_and_pools():  # pylint: disable=R0915
                 mirror_mode = rbdctx.mirror_mode_get(ioctx)
             except:  # noqa pylint: disable=W0702
                 logger.exception("Failed to query mirror mode %s", pool_name)
+                mirror_mode = None
 
             stats = {}
             if mirror_mode == rbd.RBD_MIRROR_MODE_DISABLED:
@@ -163,6 +165,7 @@ class RbdMirror(BaseController):
 
     @cherrypy.expose
     @cherrypy.tools.json_out()
+    @handle_rbd_error()
     def __call__(self):
         status, content_data = self._get_content_data()
         return {'status': status, 'content_data': content_data}
@@ -233,6 +236,7 @@ class RbdMirror(BaseController):
             pass
         except:  # noqa pylint: disable=W0702
             logger.exception("Failed to list mirror image status %s", pool_name)
+            raise
 
         return data
 
@@ -250,9 +254,6 @@ class RbdMirror(BaseController):
 
         pool_names = [pool['pool_name'] for pool in CephService.get_pool_list('rbd')]
         _, data = get_daemons_and_pools()
-        if isinstance(data, Exception):
-            logger.exception("Failed to get rbd-mirror daemons list")
-            raise type(data)(str(data))
         daemons = data.get('daemons', [])
         pool_stats = data.get('pools', {})
 
index 249df76addf71b234f060434e14589d2f4a42e1c..ae0de6305b1004c9077df2669e1223c8a5186e1f 100644 (file)
@@ -46,7 +46,7 @@ class RgwDaemon(RESTController):
         }
         service = CephService.get_service('rgw', svc_id)
         if not service:
-            return daemon
+            raise cherrypy.NotFound('Service rgw {} is not available'.format(svc_id))
 
         metadata = service['metadata']
         status = service['status']
index c2b7c4f601543c86e51ba108d31f297bab81a3cd..da570ceae1e4918f53a57b0afd246eb3865aec2d 100644 (file)
@@ -5,9 +5,10 @@ import json
 
 import cherrypy
 
+from .. import mgr
 from . import AuthRequired, ApiController, BaseController
-from .. import logger, mgr
 from ..controllers.rbd_mirroring import get_daemons_and_pools
+from ..tools import ViewCacheNoDataException
 from ..services.ceph_service import CephService
 from ..tools import TaskManager
 
@@ -34,14 +35,13 @@ class Summary(BaseController):
         ]
 
     def _rbd_mirroring(self):
-        _, data = get_daemons_and_pools()
+        try:
+            _, data = get_daemons_and_pools()
+        except ViewCacheNoDataException:
+            return {}
 
-        if isinstance(data, Exception):
-            logger.exception("Failed to get rbd-mirror daemons and pools")
-            raise type(data)(str(data))
-        else:
-            daemons = data.get('daemons', [])
-            pools = data.get('pools', {})
+        daemons = data.get('daemons', [])
+        pools = data.get('pools', {})
 
         warnings = 0
         errors = 0