diff options
author | Pere Diaz Bou <pdiazbou@redhat.com> | 2022-05-13 17:15:33 +0200 |
---|---|---|
committer | Pere Diaz Bou <pdiazbou@redhat.com> | 2022-06-06 17:56:47 +0200 |
commit | 489a385a95d6ffa5dbd4c5f9c53c1f80ea179142 (patch) | |
tree | 09794bc05336b4bfe453c3d45075db1cfea8ec23 /src/pybind/mgr/dashboard/services/rbd.py | |
parent | Merge pull request #46426 from idryomov/wip-iscsi-mutual-chap-doc (diff) | |
download | ceph-489a385a95d6ffa5dbd4c5f9c53c1f80ea179142.tar.xz ceph-489a385a95d6ffa5dbd4c5f9c53c1f80ea179142.zip |
mgr/dashboard: snapshot mirroring from dashboard
Enable snapshot mirroring from the Pools -> Image
Also show the mirror-snapshot in the image where snapshot is enabled
When parsing images if an image has the snapshot mode enabled, it will
try to run commands that don't work with that mode. The solution was
not running those for now and appending the mode in the get call.
Fixes: https://tracker.ceph.com/issues/55648
Signed-off-by: Pere Diaz Bou <pdiazbou@redhat.com>
Signed-off-by: Nizamudeen A <nia@redhat.com>
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
Signed-off-by: Avan Thakkar <athakkar@redhat.com>
Diffstat (limited to '')
-rw-r--r-- | src/pybind/mgr/dashboard/services/rbd.py | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/src/pybind/mgr/dashboard/services/rbd.py b/src/pybind/mgr/dashboard/services/rbd.py index 2c255a4fcb6..07b4db9e6a4 100644 --- a/src/pybind/mgr/dashboard/services/rbd.py +++ b/src/pybind/mgr/dashboard/services/rbd.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- # pylint: disable=unused-argument import errno +import json +from enum import IntEnum import cherrypy import rbd from .. import mgr +from ..exceptions import DashboardException from ..tools import ViewCache from .ceph_service import CephService @@ -28,6 +31,20 @@ RBD_FEATURES_NAME_MAPPING = { } +class MIRROR_IMAGE_MODE(IntEnum): + journal = rbd.RBD_MIRROR_IMAGE_MODE_JOURNAL + snapshot = rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT + + +def _rbd_support_remote(method_name: str, *args, **kwargs): + try: + return mgr.remote('rbd_support', method_name, *args, **kwargs) + except ImportError as ie: + raise DashboardException(f'rbd_support module not found {ie}') + except RuntimeError as ie: + raise DashboardException(f'rbd_support.{method_name} error: {ie}') + + def format_bitmask(features): """ Formats the bitmask: @@ -245,10 +262,22 @@ class RbdService(object): return total_used_size, snap_map @classmethod - def _rbd_image(cls, ioctx, pool_name, namespace, image_name): + def _rbd_image(cls, ioctx, pool_name, namespace, image_name): # pylint: disable=R0912 with rbd.Image(ioctx, image_name) as img: - stat = img.stat() + mirror_mode = img.mirror_image_get_mode() + if mirror_mode == rbd.RBD_MIRROR_IMAGE_MODE_JOURNAL: + stat['mirror_mode'] = 'journal' + elif mirror_mode == rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT: + stat['mirror_mode'] = 'snapshot' + schedule_status = json.loads(_rbd_support_remote( + 'mirror_snapshot_schedule_status')[1]) + for scheduled_image in schedule_status['scheduled_images']: + if scheduled_image['image'] == get_image_spec(pool_name, namespace, image_name): + stat['schedule_info'] = scheduled_image + else: + stat['mirror_mode'] = 'unknown' + stat['name'] = image_name if img.old_format(): stat['unique_id'] = get_image_spec(pool_name, namespace, stat['block_name_prefix']) @@ -286,23 +315,34 @@ class RbdService(object): # snapshots stat['snapshots'] = [] for snap in img.list_snaps(): + try: + snap['mirror_mode'] = MIRROR_IMAGE_MODE(img.mirror_image_get_mode()).name + except ValueError as ex: + raise DashboardException(f'Unknown RBD Mirror mode: {ex}') + snap['timestamp'] = "{}Z".format( img.get_snap_timestamp(snap['id']).isoformat()) - snap['is_protected'] = img.is_protected_snap(snap['name']) + + snap['is_protected'] = None + if mirror_mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT: + snap['is_protected'] = img.is_protected_snap(snap['name']) snap['used_bytes'] = None snap['children'] = [] - img.set_snap(snap['name']) - for child_pool_name, child_image_name in img.list_children(): - snap['children'].append({ - 'pool_name': child_pool_name, - 'image_name': child_image_name - }) + + if mirror_mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT: + img.set_snap(snap['name']) + for child_pool_name, child_image_name in img.list_children(): + snap['children'].append({ + 'pool_name': child_pool_name, + 'image_name': child_image_name + }) stat['snapshots'].append(snap) # disk usage img_flags = img.flags() if 'fast-diff' in stat['features_name'] and \ - not rbd.RBD_FLAG_FAST_DIFF_INVALID & img_flags: + not rbd.RBD_FLAG_FAST_DIFF_INVALID & img_flags and \ + mirror_mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT: snaps = [(s['id'], s['size'], s['name']) for s in stat['snapshots']] snaps.sort(key=lambda s: s[0]) @@ -431,7 +471,7 @@ class RBDSchedulerInterval: class RbdMirroringService: @classmethod - def enable_image(cls, image_name: str, pool_name: str, namespace: str, mode: str): + def enable_image(cls, image_name: str, pool_name: str, namespace: str, mode: MIRROR_IMAGE_MODE): rbd_image_call(pool_name, namespace, image_name, lambda ioctx, image: image.mirror_image_enable(mode)) @@ -456,6 +496,10 @@ class RbdMirroringService: lambda ioctx, image: image.mirror_image_resync()) @classmethod - def snapshot_schedule(cls, image_spec: str, interval: str, start_time: str = ''): - mgr.remote('rbd_support', 'mirror_snapshot_schedule_add', image_spec, - str(RBDSchedulerInterval(interval)), start_time) + def snapshot_schedule_add(cls, image_spec: str, interval: str): + _rbd_support_remote('mirror_snapshot_schedule_add', image_spec, + str(RBDSchedulerInterval(interval))) + + @classmethod + def snapshot_schedule_remove(cls, image_spec: str): + _rbd_support_remote('mirror_snapshot_schedule_remove', image_spec) |