summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/services/rbd.py
diff options
context:
space:
mode:
authorPere Diaz Bou <pdiazbou@redhat.com>2022-05-13 17:15:33 +0200
committerPere Diaz Bou <pdiazbou@redhat.com>2022-06-06 17:56:47 +0200
commit489a385a95d6ffa5dbd4c5f9c53c1f80ea179142 (patch)
tree09794bc05336b4bfe453c3d45075db1cfea8ec23 /src/pybind/mgr/dashboard/services/rbd.py
parentMerge pull request #46426 from idryomov/wip-iscsi-mutual-chap-doc (diff)
downloadceph-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.py72
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)