X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fpybind%2Fmgr%2Fdashboard%2Frbd_mirroring.py;fp=src%2Fceph%2Fsrc%2Fpybind%2Fmgr%2Fdashboard%2Frbd_mirroring.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=d8a5241d6016ea58d82f8511ca6c3748dfba3645;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/pybind/mgr/dashboard/rbd_mirroring.py b/src/ceph/src/pybind/mgr/dashboard/rbd_mirroring.py deleted file mode 100644 index d8a5241..0000000 --- a/src/ceph/src/pybind/mgr/dashboard/rbd_mirroring.py +++ /dev/null @@ -1,331 +0,0 @@ - -import json -import re -import rados -import rbd -from remote_view_cache import RemoteViewCache - -class DaemonsAndPools(RemoteViewCache): - def _get(self): - daemons = self.get_daemons() - return { - 'daemons': daemons, - 'pools': self.get_pools(daemons) - } - - def get_daemons(self): - daemons = [] - for server in self._module.list_servers(): - for service in server['services']: - if service['type'] == 'rbd-mirror': - metadata = self._module.get_metadata('rbd-mirror', - service['id']) - status = self._module.get_daemon_status('rbd-mirror', - service['id']) - try: - status = json.loads(status['json']) - except: - status = {} - - # extract per-daemon service data and health - daemon = { - 'id': service['id'], - 'instance_id': metadata['instance_id'], - 'version': metadata['ceph_version'], - 'server_hostname': server['hostname'], - 'service': service, - 'server': server, - 'metadata': metadata, - 'status': status - } - daemon = dict(daemon, **self.get_daemon_health(daemon)) - daemons.append(daemon) - - return sorted(daemons, key=lambda k: k['id']) - - def get_daemon_health(self, daemon): - health = { - 'health_color': 'info', - 'health' : 'Unknown' - } - for pool_id, pool_data in daemon['status'].items(): - if (health['health'] != 'error' and - [k for k,v in pool_data.get('callouts', {}).items() if v['level'] == 'error']): - health = { - 'health_color': 'error', - 'health': 'Error' - } - elif (health['health'] != 'error' and - [k for k,v in pool_data.get('callouts', {}).items() if v['level'] == 'warning']): - health = { - 'health_color': 'warning', - 'health': 'Warning' - } - elif health['health_color'] == 'info': - health = { - 'health_color': 'success', - 'health': 'OK' - } - return health - - def get_pools(self, daemons): - status, pool_names = self._module.rbd_pool_ls.get() - if pool_names is None: - self.log.warning("Failed to get RBD pool list") - return {} - - pool_stats = {} - rbdctx = rbd.RBD() - for pool_name in pool_names: - self.log.debug("Constructing IOCtx " + pool_name) - try: - ioctx = self._module.rados.open_ioctx(pool_name) - except: - self.log.exception("Failed to open pool " + pool_name) - continue - - try: - mirror_mode = rbdctx.mirror_mode_get(ioctx) - except: - self.log.exception("Failed to query mirror mode " + pool_name) - - stats = {} - if mirror_mode == rbd.RBD_MIRROR_MODE_DISABLED: - continue - elif mirror_mode == rbd.RBD_MIRROR_MODE_IMAGE: - mirror_mode = "image" - elif mirror_mode == rbd.RBD_MIRROR_MODE_POOL: - mirror_mode = "pool" - else: - mirror_mode = "unknown" - stats['health_color'] = "warning" - stats['health'] = "Warning" - - pool_stats[pool_name] = dict(stats, **{ - 'mirror_mode': mirror_mode - }) - - for daemon in daemons: - for pool_id, pool_data in daemon['status'].items(): - stats = pool_stats.get(pool_data['name'], None) - if stats is None: - continue - - if pool_data.get('leader', False): - # leader instance stores image counts - stats['leader_id'] = daemon['metadata']['instance_id'] - stats['image_local_count'] = pool_data.get('image_local_count', 0) - stats['image_remote_count'] = pool_data.get('image_remote_count', 0) - - if (stats.get('health_color', '') != 'error' and - pool_data.get('image_error_count', 0) > 0): - stats['health_color'] = 'error' - stats['health'] = 'Error' - elif (stats.get('health_color', '') != 'error' and - pool_data.get('image_warning_count', 0) > 0): - stats['health_color'] = 'warning' - stats['health'] = 'Warning' - elif stats.get('health', None) is None: - stats['health_color'] = 'success' - stats['health'] = 'OK' - - for name, stats in pool_stats.items(): - if stats.get('health', None) is None: - # daemon doesn't know about pool - stats['health_color'] = 'error' - stats['health'] = 'Error' - elif stats.get('leader_id', None) is None: - # no daemons are managing the pool as leader instance - stats['health_color'] = 'warning' - stats['health'] = 'Warning' - return pool_stats - - -class PoolDatum(RemoteViewCache): - def __init__(self, module_inst, pool_name): - super(PoolDatum, self).__init__(module_inst) - self.pool_name = pool_name - - def _get(self): - data = {} - self.log.debug("Constructing IOCtx " + self.pool_name) - try: - ioctx = self._module.rados.open_ioctx(self.pool_name) - except: - self.log.exception("Failed to open pool " + pool_name) - return None - - mirror_state = { - 'down': { - 'health': 'issue', - 'state_color': 'warning', - 'state': 'Unknown', - 'description': None - }, - rbd.MIRROR_IMAGE_STATUS_STATE_UNKNOWN: { - 'health': 'issue', - 'state_color': 'warning', - 'state': 'Unknown' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_ERROR: { - 'health': 'issue', - 'state_color': 'error', - 'state': 'Error' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_SYNCING: { - 'health': 'syncing' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY: { - 'health': 'ok', - 'state_color': 'success', - 'state': 'Starting' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_REPLAYING: { - 'health': 'ok', - 'state_color': 'success', - 'state': 'Replaying' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY: { - 'health': 'ok', - 'state_color': 'success', - 'state': 'Stopping' - }, - rbd.MIRROR_IMAGE_STATUS_STATE_STOPPED: { - 'health': 'ok', - 'state_color': 'info', - 'state': 'Primary' - } - } - - rbdctx = rbd.RBD() - try: - mirror_image_status = rbdctx.mirror_image_status_list(ioctx) - data['mirror_images'] = sorted([ - dict({ - 'name': image['name'], - 'description': image['description'] - }, **mirror_state['down' if not image['up'] else image['state']]) - for image in mirror_image_status - ], key=lambda k: k['name']) - except rbd.ImageNotFound: - pass - except: - self.log.exception("Failed to list mirror image status " + self.pool_name) - - return data - -class Toplevel(RemoteViewCache): - def __init__(self, module_inst, daemons_and_pools): - super(Toplevel, self).__init__(module_inst) - self.daemons_and_pools = daemons_and_pools - - def _get(self): - status, data = self.daemons_and_pools.get() - if data is None: - self.log.warning("Failed to get rbd-mirror daemons and pools") - daemons = {} - daemons = data.get('daemons', []) - pools = data.get('pools', {}) - - warnings = 0 - errors = 0 - for daemon in daemons: - if daemon['health_color'] == 'error': - errors += 1 - elif daemon['health_color'] == 'warning': - warnings += 1 - for pool_name, pool in pools.items(): - if pool['health_color'] == 'error': - errors += 1 - elif pool['health_color'] == 'warning': - warnings += 1 - return {'warnings': warnings, 'errors': errors} - - -class ContentData(RemoteViewCache): - def __init__(self, module_inst, daemons_and_pools, pool_data): - super(ContentData, self).__init__(module_inst) - - self.daemons_and_pools = daemons_and_pools - self.pool_data = pool_data - - def _get(self): - status, pool_names = self._module.rbd_pool_ls.get() - if pool_names is None: - self.log.warning("Failed to get RBD pool list") - return None - - status, data = self.daemons_and_pools.get() - if data is None: - self.log.warning("Failed to get rbd-mirror daemons list") - data = {} - daemons = data.get('daemons', []) - pool_stats = data.get('pools', {}) - - pools = [] - image_error = [] - image_syncing = [] - image_ready = [] - for pool_name in pool_names: - pool = self.get_pool_datum(pool_name) or {} - stats = pool_stats.get(pool_name, {}) - if stats.get('mirror_mode', None) is None: - continue - - mirror_images = pool.get('mirror_images', []) - for mirror_image in mirror_images: - image = { - 'pool_name': pool_name, - 'name': mirror_image['name'] - } - - if mirror_image['health'] == 'ok': - image.update({ - 'state_color': mirror_image['state_color'], - 'state': mirror_image['state'], - 'description': mirror_image['description'] - }) - image_ready.append(image) - elif mirror_image['health'] == 'syncing': - p = re.compile("bootstrapping, IMAGE_COPY/COPY_OBJECT (.*)%") - image.update({ - 'progress': (p.findall(mirror_image['description']) or [0])[0] - }) - image_syncing.append(image) - else: - image.update({ - 'state_color': mirror_image['state_color'], - 'state': mirror_image['state'], - 'description': mirror_image['description'] - }) - image_error.append(image) - - pools.append(dict({ - 'name': pool_name - }, **stats)) - - return { - 'daemons': daemons, - 'pools' : pools, - 'image_error': image_error, - 'image_syncing': image_syncing, - 'image_ready': image_ready - } - - def get_pool_datum(self, pool_name): - pool_datum = self.pool_data.get(pool_name, None) - if pool_datum is None: - pool_datum = PoolDatum(self._module, pool_name) - self.pool_data[pool_name] = pool_datum - - status, value = pool_datum.get() - return value - -class Controller: - def __init__(self, module_inst): - self.daemons_and_pools = DaemonsAndPools(module_inst) - self.pool_data = {} - self.toplevel = Toplevel(module_inst, self.daemons_and_pools) - self.content_data = ContentData(module_inst, self.daemons_and_pools, - self.pool_data) -