From 6fabe14f56aa6efa590b5d656ade49bfe53aac52 Mon Sep 17 00:00:00 2001 From: zengyingzhe Date: Mon, 18 Dec 2017 17:24:09 +0800 Subject: [PATCH] Huawei driver supports snapshot revert Implement the revert_to_snapshot interface in Huawei driver to support this capability. Implements: blueprint huawei-driver-support-snapshot-revert Change-Id: Ib92afcce59bd5ee018b3a99cff47d892c88145e4 --- manila/share/drivers/huawei/base.py | 5 ++++ manila/share/drivers/huawei/huawei_nas.py | 9 +++++++ manila/share/drivers/huawei/v3/connection.py | 13 ++++++++++ manila/share/drivers/huawei/v3/helper.py | 8 ++++++ .../share/drivers/huawei/test_huawei_nas.py | 25 ++++++++++++++++++- ...port-snapshot-revert-1208c586bd8db98e.yaml | 5 ++++ 6 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/huawei-driver-support-snapshot-revert-1208c586bd8db98e.yaml diff --git a/manila/share/drivers/huawei/base.py b/manila/share/drivers/huawei/base.py index ba0bcfefe7..5862ceac1b 100644 --- a/manila/share/drivers/huawei/base.py +++ b/manila/share/drivers/huawei/base.py @@ -120,3 +120,8 @@ class HuaweiBase(object): def delete_replica(self, context, replica_list, replica_snapshots, replica, share_server=None): """Delete a replica.""" + + @abc.abstractmethod + def revert_to_snapshot(self, context, snapshot, share_access_rules, + snapshot_access_rules, share_server=None): + """Revert a snapshot.""" diff --git a/manila/share/drivers/huawei/huawei_nas.py b/manila/share/drivers/huawei/huawei_nas.py index 17e06e29aa..a1bbfdac28 100644 --- a/manila/share/drivers/huawei/huawei_nas.py +++ b/manila/share/drivers/huawei/huawei_nas.py @@ -207,6 +207,7 @@ class HuaweiNasDriver(driver.ShareDriver): free_capacity_gb=0.0, snapshot_support=self.plugin.snapshot_support, create_share_from_snapshot_support=self.plugin.snapshot_support, + revert_to_snapshot_support=self.plugin.snapshot_support, ) # huawei array doesn't support snapshot replication, so driver can't @@ -266,3 +267,11 @@ class HuaweiNasDriver(driver.ShareDriver): replica_snapshots, replica, share_server) + + def revert_to_snapshot(self, context, snapshot, share_access_rules, + snapshot_access_rules, share_server=None): + self.plugin.revert_to_snapshot(context, + snapshot, + share_access_rules, + snapshot_access_rules, + share_server) diff --git a/manila/share/drivers/huawei/v3/connection.py b/manila/share/drivers/huawei/v3/connection.py index d91a88c804..074fc8831b 100644 --- a/manila/share/drivers/huawei/v3/connection.py +++ b/manila/share/drivers/huawei/v3/connection.py @@ -1847,3 +1847,16 @@ class V3StorageConnection(driver.HuaweiBase): LOG.exception('Failed to delete replica %s.', replica['id']) raise + + def revert_to_snapshot(self, context, snapshot, share_access_rules, + snapshot_access_rules, share_server): + fs_id = self.helper.get_fsid_by_name(snapshot['share_name']) + if not fs_id: + msg = _("The source filesystem of snapshot %s " + "not exist.") % snapshot['id'] + LOG.error(msg) + raise exception.ShareResourceNotFound( + share_id=snapshot['share_id']) + + snapshot_id = self.helper._get_snapshot_id(fs_id, snapshot['id']) + self.helper.rollback_snapshot(snapshot_id) diff --git a/manila/share/drivers/huawei/v3/helper.py b/manila/share/drivers/huawei/v3/helper.py index 5eec41f576..f37d8dcedf 100644 --- a/manila/share/drivers/huawei/v3/helper.py +++ b/manila/share/drivers/huawei/v3/helper.py @@ -1447,3 +1447,11 @@ class RestHelper(object): self._assert_rest_result(result, msg) self._assert_data_in_result(result, msg) return result.get('data') + + def rollback_snapshot(self, snap_id): + url = "/FSSNAPSHOT/ROLLBACK_FSSNAPSHOT" + data = jsonutils.dumps({"ID": snap_id}) + result = self.call(url, data, "PUT") + + msg = _('Failed to rollback snapshot %s.') % snap_id + self._assert_rest_result(result, msg) diff --git a/manila/tests/share/drivers/huawei/test_huawei_nas.py b/manila/tests/share/drivers/huawei/test_huawei_nas.py index c8271850b2..cda6c1f831 100644 --- a/manila/tests/share/drivers/huawei/test_huawei_nas.py +++ b/manila/tests/share/drivers/huawei/test_huawei_nas.py @@ -2425,7 +2425,7 @@ class HuaweiShareDriverTestCase(test.TestCase): "qos": True, "snapshot_support": snapshot_support, "create_share_from_snapshot_support": snapshot_support, - "revert_to_snapshot_support": False, + "revert_to_snapshot_support": snapshot_support, "mount_snapshot_support": False, "replication_domain": None, "filter_function": None, @@ -4577,6 +4577,29 @@ class HuaweiShareDriverTestCase(test.TestCase): self.assertEqual(expect_password, result['UserPassword']) ET.parse.assert_called_once_with(self.fake_conf_file) + def test_revert_to_snapshot_success(self): + snapshot = {'id': 'fake-fs-id', + 'share_name': 'share_fake_uuid'} + with mock.patch.object( + self.driver.plugin.helper, 'call') as mock_call: + mock_call.return_value = { + "error": {"code": 0}, + "data": [{"ID": "4", "NAME": "share_fake_uuid"}] + } + self.driver.revert_to_snapshot(None, snapshot, None, None) + expect_snapshot_id = "4@share_snapshot_fake_fs_id" + mock_call.assert_called_with( + "/FSSNAPSHOT/ROLLBACK_FSSNAPSHOT", + jsonutils.dumps({"ID": expect_snapshot_id}), 'PUT') + + def test_revert_to_snapshot_exception(self): + snapshot = {'id': 'fake-snap-id', + 'share_name': 'not_exist_share_name', + 'share_id': 'fake_share_id'} + self.assertRaises(exception.ShareResourceNotFound, + self.driver.revert_to_snapshot, + None, snapshot, None, None) + @ddt.ddt class HuaweiDriverHelperTestCase(test.TestCase): diff --git a/releasenotes/notes/huawei-driver-support-snapshot-revert-1208c586bd8db98e.yaml b/releasenotes/notes/huawei-driver-support-snapshot-revert-1208c586bd8db98e.yaml new file mode 100644 index 0000000000..7a126e5d14 --- /dev/null +++ b/releasenotes/notes/huawei-driver-support-snapshot-revert-1208c586bd8db98e.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Huawei driver implements the snapshot reverting feature, + by Huawei storage's snapshot-rollback capability.