From: Aashish Sharma Date: Wed, 21 Dec 2022 11:53:37 +0000 (+0530) Subject: mgr/dashboard: fix rbd mirror snapshot creation X-Git-Tag: v16.2.14~96^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a3f7cf80d69244d6767e6de17c22238735372f30;p=ceph.git mgr/dashboard: fix rbd mirror snapshot creation There are two types of snapshots that can be created on a snapshot based mirroring image - Normal Snapshot(same as journal based snapshot) and Nirror Image Snapshot. Till now Dashboard allowed only Mirror image snapshot, this PR intends to enable both the types Signed-off-by: Aashish Sharma (cherry picked from commit 5ea4171ae3d2a28efbe20b825602eff1429ef92d) --- diff --git a/qa/tasks/mgr/dashboard/test_rbd.py b/qa/tasks/mgr/dashboard/test_rbd.py index 997d10f2a801e..633a5151cfddc 100644 --- a/qa/tasks/mgr/dashboard/test_rbd.py +++ b/qa/tasks/mgr/dashboard/test_rbd.py @@ -24,7 +24,7 @@ class RbdTest(DashboardTestCase): def test_create_access_permissions(self): self.create_image('pool', None, 'name', 0) self.assertStatus(403) - self.create_snapshot('pool', None, 'image', 'snapshot') + self.create_snapshot('pool', None, 'image', 'snapshot', False) self.assertStatus(403) self.copy_image('src_pool', None, 'src_image', 'dest_pool', None, 'dest_image') self.assertStatus(403) @@ -110,10 +110,10 @@ class RbdTest(DashboardTestCase): return cls._task_post('/api/block/image/{}%2F{}{}/flatten'.format(pool, namespace, image)) @classmethod - def create_snapshot(cls, pool, namespace, image, snapshot): + def create_snapshot(cls, pool, namespace, image, snapshot, mirrorImageSnapshot): namespace = '{}%2F'.format(namespace) if namespace else '' return cls._task_post('/api/block/image/{}%2F{}{}/snap'.format(pool, namespace, image), - {'snapshot_name': snapshot}) + {'snapshot_name': snapshot, 'mirrorImageSnapshot': mirrorImageSnapshot}) # noqa E501 #pylint: disable=line-too-long @classmethod def remove_snapshot(cls, pool, namespace, image, snapshot): @@ -404,8 +404,8 @@ class RbdTest(DashboardTestCase): self.assertStatus(204) def test_snapshots_and_clone_info(self): - self.create_snapshot('rbd', None, 'img1', 'snap1') - self.create_snapshot('rbd', None, 'img1', 'snap2') + self.create_snapshot('rbd', None, 'img1', 'snap1', False) + self.create_snapshot('rbd', None, 'img1', 'snap2', False) self._rbd_cmd(['snap', 'protect', 'rbd/img1@snap1']) self._rbd_cmd(['clone', 'rbd/img1@snap1', 'rbd_iscsi/img1_clone']) @@ -440,11 +440,11 @@ class RbdTest(DashboardTestCase): def test_disk_usage(self): self._rbd_cmd(['bench', '--io-type', 'write', '--io-total', '50M', 'rbd/img2']) - self.create_snapshot('rbd', None, 'img2', 'snap1') + self.create_snapshot('rbd', None, 'img2', 'snap1', False) self._rbd_cmd(['bench', '--io-type', 'write', '--io-total', '20M', 'rbd/img2']) - self.create_snapshot('rbd', None, 'img2', 'snap2') + self.create_snapshot('rbd', None, 'img2', 'snap2', False) self._rbd_cmd(['bench', '--io-type', 'write', '--io-total', '10M', 'rbd/img2']) - self.create_snapshot('rbd', None, 'img2', 'snap3') + self.create_snapshot('rbd', None, 'img2', 'snap3', False) self._rbd_cmd(['bench', '--io-type', 'write', '--io-total', '5M', 'rbd/img2']) img = self.get_image('rbd', None, 'img2') self.assertStatus(200) @@ -462,9 +462,9 @@ class RbdTest(DashboardTestCase): def test_image_delete(self): self.create_image('rbd', None, 'delete_me', 2**30) self.assertStatus(201) - self.create_snapshot('rbd', None, 'delete_me', 'snap1') + self.create_snapshot('rbd', None, 'delete_me', 'snap1', False) self.assertStatus(201) - self.create_snapshot('rbd', None, 'delete_me', 'snap2') + self.create_snapshot('rbd', None, 'delete_me', 'snap2', False) self.assertStatus(201) img = self.get_image('rbd', None, 'delete_me') @@ -488,9 +488,9 @@ class RbdTest(DashboardTestCase): def test_image_delete_with_snapshot(self): self.create_image('rbd', None, 'delete_me', 2**30) self.assertStatus(201) - self.create_snapshot('rbd', None, 'delete_me', 'snap1') + self.create_snapshot('rbd', None, 'delete_me', 'snap1', False) self.assertStatus(201) - self.create_snapshot('rbd', None, 'delete_me', 'snap2') + self.create_snapshot('rbd', None, 'delete_me', 'snap2', False) self.assertStatus(201) img = self.get_image('rbd', None, 'delete_me') @@ -605,7 +605,7 @@ class RbdTest(DashboardTestCase): self.assertStatus(204) def test_update_snapshot(self): - self.create_snapshot('rbd', None, 'img1', 'snap5') + self.create_snapshot('rbd', None, 'img1', 'snap5', False) self.assertStatus(201) img = self.get_image('rbd', None, 'img1') self._validate_snapshot_list(img['snapshots'], 'snap5', is_protected=False) @@ -633,7 +633,7 @@ class RbdTest(DashboardTestCase): features=["layering", "exclusive-lock", "fast-diff", "object-map"]) self.assertStatus(201) - self.create_snapshot('rbd', None, 'rollback_img', 'snap1') + self.create_snapshot('rbd', None, 'rollback_img', 'snap1', False) self.assertStatus(201) img = self.get_image('rbd', None, 'rollback_img') @@ -662,7 +662,7 @@ class RbdTest(DashboardTestCase): def test_clone(self): self.create_image('rbd', None, 'cimg', 2**30, features=["layering"]) self.assertStatus(201) - self.create_snapshot('rbd', None, 'cimg', 'snap1') + self.create_snapshot('rbd', None, 'cimg', 'snap1', False) self.assertStatus(201) self.update_snapshot('rbd', None, 'cimg', 'snap1', None, True) self.assertStatus(200) @@ -720,7 +720,7 @@ class RbdTest(DashboardTestCase): self.assertStatus(204) def test_flatten(self): - self.create_snapshot('rbd', None, 'img1', 'snapf') + self.create_snapshot('rbd', None, 'img1', 'snapf', False) self.update_snapshot('rbd', None, 'img1', 'snapf', None, True) self.clone_image('rbd', None, 'img1', 'snapf', 'rbd_iscsi', None, 'img1_snapf_clone') diff --git a/src/pybind/mgr/dashboard/controllers/rbd.py b/src/pybind/mgr/dashboard/controllers/rbd.py index 728b2dc417936..d6177acb2c712 100644 --- a/src/pybind/mgr/dashboard/controllers/rbd.py +++ b/src/pybind/mgr/dashboard/controllers/rbd.py @@ -336,15 +336,14 @@ class RbdSnapshot(RESTController): RESOURCE_ID = "snapshot_name" @RbdTask('snap/create', - ['{image_spec}', '{snapshot_name}'], 2.0) - def create(self, image_spec, snapshot_name): + ['{image_spec}', '{snapshot_name}', '{mirrorImageSnapshot}'], 2.0) + def create(self, image_spec, snapshot_name, mirrorImageSnapshot): pool_name, namespace, image_name = parse_image_spec(image_spec) def _create_snapshot(ioctx, img, snapshot_name): mirror_info = img.mirror_image_get_info() mirror_mode = img.mirror_image_get_mode() - if (mirror_info['state'] == rbd.RBD_MIRROR_IMAGE_ENABLED - and mirror_mode == rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT): + if (mirror_info['state'] == rbd.RBD_MIRROR_IMAGE_ENABLED and mirror_mode == rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT) and mirrorImageSnapshot: # noqa E501 #pylint: disable=line-too-long img.mirror_image_create_snapshot() else: img.create_snap(snapshot_name) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html index 598e3fd3843ec..fb246a44451b1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html @@ -19,18 +19,34 @@ placeholder="Snapshot name..." id="snapshotName" name="snapshotName" - [attr.disabled]="(mirroring === 'snapshot') ? true : null" + [attr.disabled]="((mirroring === 'snapshot') ? true : null) && (snapshotForm.getValue('mirrorImageSnapshot') === true) ? true: null" formControlName="snapshotName" autofocus> This field is required.

- Snapshot mode is enabled on image {{ imageName }}: snapshot names are auto generated +
+
+
+
+ + +
+
+
+
-