Change Huawei driver's private data storing place
This patch is to fix issues at two circumstances:
1. Create volume from image by non-admin user, this operation
will fail because Huawei driver tries to record LUN WWN at admin
metadata, however non-admin user doesn't have the admin metadata
access right, so exception is raised.
2. Restore volume backup to 3rd volume, this operation will also
restore backup volume's metadata to the 3rd volume, but the data
recorded in metadata is strong correlative to the corresponding
LUN at backend storage, so this will break the one-to-one
relationship between the restored volume and the LUN at storage.
To fix the issues above, we moved all LUN private data to
provider_location, stored as a dict string, not use admin
metadata or metadata to store LUN private data.
Change-Id: Id18622935ecaa1715491b4ede48c7b627e43d3fa
Closes-Bug: #1699109
(cherry picked from commit 2d6ac671f2
)
This commit is contained in:
parent
4c5a29a863
commit
10032adc6b
|
@ -21,11 +21,11 @@ import mock
|
|||
import re
|
||||
import requests
|
||||
import tempfile
|
||||
import unittest
|
||||
from xml.dom import minidom
|
||||
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.objects import fields
|
||||
from cinder import test
|
||||
from cinder.tests.unit.consistencygroup import fake_cgsnapshot
|
||||
from cinder.tests.unit.consistencygroup import fake_consistencygroup
|
||||
|
@ -50,15 +50,25 @@ admin_contex = context.get_admin_context()
|
|||
vol_attrs = ('id', 'lun_type', 'provider_location', 'metadata')
|
||||
Volume = collections.namedtuple('Volume', vol_attrs)
|
||||
|
||||
PROVIDER_LOCATION = '11'
|
||||
PROVIDER_LOCATION = ('{"huawei_lun_id": "11", '
|
||||
'"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}')
|
||||
PROVIDER_LOCATION_WITH_HYPERMETRO = (
|
||||
'{"huawei_lun_id": "11", '
|
||||
'"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003", '
|
||||
'"hypermetro_id": "11", '
|
||||
'"remote_lun_id": "1"}')
|
||||
SNAP_PROVIDER_LOCATION = '{"huawei_snapshot_id": "11"}'
|
||||
|
||||
HOST = 'ubuntu001@backend001#OpenStack_Pool'
|
||||
ID = '21ec7341-9256-497b-97d9-ef48edcf0635'
|
||||
ENCODE_NAME = huawei_utils.encode_name(ID)
|
||||
ADMIN_METADATA = {'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'}
|
||||
METADATA = {}
|
||||
TEST_PAIR_ID = "3400a30d844d0004"
|
||||
REPLICA_DRIVER_DATA = '{"pair_id": "%s", "rmt_lun_id": "1"}' % TEST_PAIR_ID
|
||||
VOL_METADATA = [{'key': 'hypermetro_id', 'value': '11'},
|
||||
{'key': 'remote_lun_id', 'value': '1'}]
|
||||
ADMIN_METADATA = [{'key': 'huawei_lun_wwn', 'value': 'FAKE_WWN'}]
|
||||
REPLICA_DRIVER_DATA = ('{"pair_id": "%s", "rmt_lun_id": "1", '
|
||||
'"rmt_lun_wwn": "FAKE_RMT_LUN_WWN"}') % TEST_PAIR_ID
|
||||
|
||||
hypermetro_devices = """{
|
||||
"remote_device": {
|
||||
|
@ -499,7 +509,7 @@ FAKE_SNAPSHOT_LIST_INFO_RESPONSE = {
|
|||
"description": "0"
|
||||
},
|
||||
"data": [{
|
||||
"ID": 11,
|
||||
"ID": "11",
|
||||
"NAME": ENCODE_NAME
|
||||
}, ]
|
||||
}
|
||||
|
@ -512,7 +522,7 @@ FAKE_CREATE_SNAPSHOT_INFO_RESPONSE = """
|
|||
"code": 0
|
||||
},
|
||||
"data": {
|
||||
"ID": 11,
|
||||
"ID": "11",
|
||||
"NAME": "YheUoRwbSX2BxN7"
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +536,7 @@ FAKE_GET_SNAPSHOT_INFO_RESPONSE = """
|
|||
"description": "0"
|
||||
},
|
||||
"data": {
|
||||
"ID": 11,
|
||||
"ID": "11",
|
||||
"NAME": "YheUoRwbSX2BxN7"
|
||||
}
|
||||
}
|
||||
|
@ -2194,6 +2204,7 @@ class FakeFCStorage(huawei_driver.HuaweiFCDriver):
|
|||
self.configuration)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class HuaweiTestBase(test.TestCase):
|
||||
"""Base class for Huawei test cases.
|
||||
|
||||
|
@ -2208,21 +2219,22 @@ class HuaweiTestBase(test.TestCase):
|
|||
|
||||
self.volume = fake_volume.fake_volume_obj(
|
||||
admin_contex, host=HOST, provider_location=PROVIDER_LOCATION,
|
||||
admin_metadata=ADMIN_METADATA, id=ID)
|
||||
metadata=METADATA, id=ID)
|
||||
|
||||
self.snapshot = fake_snapshot.fake_snapshot_obj(
|
||||
admin_contex, provider_location=PROVIDER_LOCATION, id=ID)
|
||||
admin_contex, provider_location=SNAP_PROVIDER_LOCATION, id=ID)
|
||||
|
||||
self.snapshot.volume = self.volume
|
||||
|
||||
self.replica_volume = fake_volume.fake_volume_obj(
|
||||
admin_contex, host=HOST, provider_location=PROVIDER_LOCATION,
|
||||
admin_metadata=ADMIN_METADATA, replication_status='disabled',
|
||||
metadata=METADATA, replication_status='disabled',
|
||||
replication_driver_data=REPLICA_DRIVER_DATA, id=ID)
|
||||
|
||||
self.hyper_volume = fake_volume.fake_volume_obj(
|
||||
admin_contex, host=HOST, provider_location=PROVIDER_LOCATION,
|
||||
volume_metadata=VOL_METADATA, id=ID)
|
||||
admin_contex, host=HOST,
|
||||
provider_location=PROVIDER_LOCATION_WITH_HYPERMETRO,
|
||||
id=ID)
|
||||
|
||||
self.original_volume = fake_volume.fake_volume_obj(admin_contex,
|
||||
id=ID)
|
||||
|
@ -2248,12 +2260,83 @@ class HuaweiTestBase(test.TestCase):
|
|||
@mock.patch.object(rest_client, 'RestClient')
|
||||
def test_create_snapshot_success(self, mock_client):
|
||||
lun_info = self.driver.create_snapshot(self.snapshot)
|
||||
self.assertEqual(11, lun_info['provider_location'])
|
||||
self.assertDictEqual({"huawei_snapshot_id": "11"},
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
self.snapshot.volume_id = ID
|
||||
self.snapshot.volume = self.volume
|
||||
lun_info = self.driver.create_snapshot(self.snapshot)
|
||||
self.assertEqual(11, lun_info['provider_location'])
|
||||
self.assertDictEqual({"huawei_snapshot_id": "11"},
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data(
|
||||
{
|
||||
'volume': fake_volume.fake_volume_obj(
|
||||
admin_contex,
|
||||
provider_location=PROVIDER_LOCATION),
|
||||
'expect': {'huawei_lun_id': '11',
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'}
|
||||
},
|
||||
{
|
||||
'volume': fake_volume.fake_volume_obj(
|
||||
admin_contex,
|
||||
provider_location=None),
|
||||
'expect': {}
|
||||
},
|
||||
{
|
||||
'volume': fake_volume.fake_volume_obj(
|
||||
admin_contex,
|
||||
provider_location=''),
|
||||
'expect': {}
|
||||
},
|
||||
{
|
||||
'volume': fake_volume.fake_volume_obj(
|
||||
admin_contex,
|
||||
provider_location='11',
|
||||
volume_admin_metadata=ADMIN_METADATA,
|
||||
volume_metadata=VOL_METADATA
|
||||
),
|
||||
'expect': {'huawei_lun_id': '11',
|
||||
'huawei_lun_wwn': 'FAKE_WWN',
|
||||
'hypermetro_id': '11',
|
||||
'remote_lun_id': '1'}
|
||||
}
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_get_lun_metadata(self, volume, expect):
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
self.assertEqual(expect, metadata)
|
||||
|
||||
@ddt.data(
|
||||
{
|
||||
'snapshot': fake_snapshot.fake_snapshot_obj(
|
||||
admin_contex,
|
||||
provider_location=SNAP_PROVIDER_LOCATION),
|
||||
'expect': {'huawei_snapshot_id': '11'}
|
||||
},
|
||||
{
|
||||
'snapshot': fake_snapshot.fake_snapshot_obj(
|
||||
admin_contex,
|
||||
provider_location=None),
|
||||
'expect': {}
|
||||
},
|
||||
{
|
||||
'snapshot': fake_snapshot.fake_snapshot_obj(
|
||||
admin_contex,
|
||||
provider_location=''),
|
||||
'expect': {}
|
||||
},
|
||||
{
|
||||
'snapshot': fake_snapshot.fake_snapshot_obj(
|
||||
admin_contex,
|
||||
provider_location='11'),
|
||||
'expect': {'huawei_snapshot_id': '11'}
|
||||
}
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_get_snapshot_metadata(self, snapshot, expect):
|
||||
metadata = huawei_utils.get_snapshot_metadata(snapshot)
|
||||
self.assertEqual(expect, metadata)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
@ -2338,12 +2421,18 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.volume.host = 'ubuntu001@backend001#OpenStack_Pool'
|
||||
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
# No pool info in the volume.
|
||||
self.volume.host = 'ubuntu001@backend001'
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
def test_delete_replication_fail(self, pool_data):
|
||||
|
@ -2536,7 +2625,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
def test_delete_snapshot_success(self):
|
||||
self.driver.delete_snapshot(self.snapshot)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_create_volume_from_snapsuccess(self):
|
||||
self.mock_object(
|
||||
huawei_driver.HuaweiBaseDriver,
|
||||
|
@ -2544,13 +2632,17 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
return_value={'extra_specs': sync_replica_specs})
|
||||
self.mock_object(replication.ReplicaCommonDriver, 'sync')
|
||||
model_update = self.driver.create_volume_from_snapshot(self.volume,
|
||||
self.volume)
|
||||
self.assertEqual('1', model_update['provider_location'])
|
||||
self.snapshot)
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(model_update['provider_location']))
|
||||
|
||||
driver_data = {'pair_id': TEST_PAIR_ID,
|
||||
'rmt_lun_id': '1'}
|
||||
driver_data = replication.to_string(driver_data)
|
||||
self.assertEqual(driver_data, model_update['replication_driver_data'])
|
||||
'rmt_lun_id': '1',
|
||||
'rmt_lun_wwn': '6643e8c1004c5f6723e9f454003'}
|
||||
self.assertDictEqual(
|
||||
driver_data, json.loads(model_update['replication_driver_data']))
|
||||
self.assertEqual('available', model_update['replication_status'])
|
||||
|
||||
@mock.patch.object(huawei_driver.HuaweiISCSIDriver,
|
||||
|
@ -2737,19 +2829,19 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.driver.extend_volume,
|
||||
self.volume, 3)
|
||||
|
||||
def test_get_admin_metadata(self):
|
||||
def test_get_volume_metadata(self):
|
||||
metadata = [{'key': 'huawei_lun_wwn', 'value': '1'}]
|
||||
tmp_volume = fake_volume.fake_volume_obj(
|
||||
admin_contex, volume_admin_metadata=metadata)
|
||||
admin_contex, volume_metadata=metadata)
|
||||
expected_value = {'huawei_lun_wwn': '1'}
|
||||
admin_metadata = huawei_utils.get_admin_metadata(tmp_volume)
|
||||
self.assertEqual(expected_value, admin_metadata)
|
||||
metadata = huawei_utils.get_volume_metadata(tmp_volume)
|
||||
self.assertEqual(expected_value, metadata)
|
||||
|
||||
metadata = {'huawei_lun_wwn': '1'}
|
||||
expected_value = {'huawei_lun_wwn': '1'}
|
||||
tmp_volume = fake_volume.fake_volume_obj(admin_contex)
|
||||
tmp_volume.admin_metadata = metadata
|
||||
admin_metadata = huawei_utils.get_admin_metadata(tmp_volume)
|
||||
self.assertEqual(expected_value, admin_metadata)
|
||||
tmp_volume.metadata = expected_value
|
||||
metadata = huawei_utils.get_volume_metadata(tmp_volume)
|
||||
self.assertEqual(expected_value, metadata)
|
||||
|
||||
def test_login_fail(self):
|
||||
self.driver.client.test_fail = True
|
||||
|
@ -2900,7 +2992,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
def test_create_smartqos(self, mock_qos_value, pool_data):
|
||||
self.driver.support_func = pool_data
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@mock.patch.object(huawei_driver.HuaweiBaseDriver, '_get_volume_params',
|
||||
return_value={'smarttier': 'true',
|
||||
|
@ -2923,7 +3018,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
mock_volume_params):
|
||||
self.driver.support_func = FAKE_POOLS_SUPPORT_REPORT
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data([{'specs': {'maxBandWidth': '100', 'IOType': '3'}},
|
||||
FAKE_POOLS_UNSUPPORT_REPORT],
|
||||
|
@ -2989,7 +3087,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
mock_array_version):
|
||||
self.driver.support_func = FAKE_POOLS_SUPPORT_REPORT
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@mock.patch.object(smartx.SmartQos, 'get_qos_by_volume_type',
|
||||
return_value={'MINIOPS': '100',
|
||||
|
@ -3004,7 +3105,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
mock_array_version):
|
||||
self.driver.support_func = FAKE_POOLS_SUPPORT_REPORT
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@mock.patch.object(smartx.SmartQos, 'get_qos_by_volume_type',
|
||||
return_value={'MINIOPS': '100',
|
||||
|
@ -3092,7 +3196,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
'partitionname': 'partition-test'})
|
||||
def test_create_smartx(self, mock_volume_types, mock_add_lun_to_partition):
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data([{'smarttier': 'true', 'smartcache': 'true',
|
||||
'smartpartition': 'true',
|
||||
|
@ -3235,10 +3342,13 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
mock_pool_info,
|
||||
mock_all_pool_info,
|
||||
mock_login_return):
|
||||
metadata = {"hypermetro_id": '11',
|
||||
"remote_lun_id": '1'}
|
||||
location = {"huawei_lun_id": "1",
|
||||
"hypermetro_id": "11",
|
||||
"remote_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
lun_info = self.driver.create_volume(self.hyper_volume)
|
||||
self.assertEqual(metadata, lun_info['metadata'])
|
||||
self.assertDictEqual(location,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
@mock.patch.object(huawei_driver.HuaweiBaseDriver, '_get_volume_params',
|
||||
|
@ -3479,12 +3589,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
external_ref = {'source-name': 'LUN1'}
|
||||
model_update = self.driver.manage_existing(self.volume,
|
||||
external_ref)
|
||||
expected_val = {
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'
|
||||
},
|
||||
'provider_location': 'ID1'}
|
||||
self.assertEqual(expected_val, model_update)
|
||||
location = {"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003",
|
||||
"huawei_lun_id": "ID1"}
|
||||
self.assertDictEqual(location,
|
||||
json.loads(model_update['provider_location']))
|
||||
|
||||
@ddt.data([[{'PRILUNID': 'ID1'}], []],
|
||||
[[{'PRILUNID': 'ID2'}], ['ID1', 'ID2']])
|
||||
|
@ -3580,12 +3688,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.driver.support_func = pool_data
|
||||
model_update = self.driver.manage_existing(self.volume,
|
||||
external_ref)
|
||||
expected_val = {
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'
|
||||
},
|
||||
'provider_location': 'ID1'}
|
||||
self.assertEqual(expected_val, model_update)
|
||||
expected = {"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003",
|
||||
"huawei_lun_id": "ID1"}
|
||||
self.assertDictEqual(expected,
|
||||
json.loads(model_update['provider_location']))
|
||||
|
||||
def test_unmanage(self):
|
||||
self.driver.unmanage(self.volume)
|
||||
|
@ -3635,12 +3741,14 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
external_ref = {'source-name': 'test1'}
|
||||
model_update = self.driver.manage_existing_snapshot(self.snapshot,
|
||||
external_ref)
|
||||
self.assertEqual({'provider_location': 'ID1'}, model_update)
|
||||
expect_value = {'provider_location': '{"huawei_snapshot_id": "ID1"}'}
|
||||
self.assertEqual(expect_value, model_update)
|
||||
|
||||
external_ref = {'source-id': 'ID1'}
|
||||
model_update = self.driver.manage_existing_snapshot(self.snapshot,
|
||||
external_ref)
|
||||
self.assertEqual({'provider_location': 'ID1'}, model_update)
|
||||
expect_value = {'provider_location': '{"huawei_snapshot_id": "ID1"}'}
|
||||
self.assertEqual(expect_value, model_update)
|
||||
|
||||
@mock.patch.object(rest_client.RestClient, 'get_snapshot_info',
|
||||
return_value={'ID': 'ID1',
|
||||
|
@ -3696,9 +3804,10 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
|
||||
model_update = self.driver.create_volume(self.replica_volume)
|
||||
driver_data = {'pair_id': TEST_PAIR_ID,
|
||||
'rmt_lun_id': '1'}
|
||||
driver_data = replication.to_string(driver_data)
|
||||
self.assertEqual(driver_data, model_update['replication_driver_data'])
|
||||
'rmt_lun_id': '1',
|
||||
'rmt_lun_wwn': '6643e8c1004c5f6723e9f454003'}
|
||||
self.assertDictEqual(
|
||||
driver_data, json.loads(model_update['replication_driver_data']))
|
||||
self.assertEqual('available', model_update['replication_status'])
|
||||
|
||||
@ddt.data(
|
||||
|
@ -3815,7 +3924,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
return_value=False)
|
||||
self.driver.delete_volume(self.replica_volume)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_wait_volume_online(self):
|
||||
replica = FakeReplicaPairManager(self.driver.client,
|
||||
self.driver.replica_client,
|
||||
|
@ -3834,7 +3942,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.driver.client,
|
||||
lun_info)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_wait_second_access(self):
|
||||
pair_id = '1'
|
||||
access_ro = constants.REPLICA_SECOND_RO
|
||||
|
@ -3851,7 +3958,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
common_driver.wait_second_access, pair_id, access_rw)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_wait_replica_ready(self):
|
||||
normal_status = {
|
||||
'RUNNINGSTATUS': constants.REPLICA_RUNNING_STATUS_NORMAL,
|
||||
|
@ -3979,12 +4085,19 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
v_id = volumes_update[0]['volume_id']
|
||||
v_update = volumes_update[0]['updates']
|
||||
self.assertEqual(self.replica_volume.id, v_id)
|
||||
self.assertEqual('1', v_update['provider_location'])
|
||||
|
||||
expect_location = {"huawei_lun_wwn": "FAKE_RMT_LUN_WWN",
|
||||
"huawei_lun_id": "1"}
|
||||
self.assertDictEqual(
|
||||
expect_location, json.loads(v_update['provider_location']))
|
||||
self.assertEqual('failed-over', v_update['replication_status'])
|
||||
|
||||
metadata = huawei_utils.get_lun_metadata(self.replica_volume)
|
||||
new_drv_data = {'pair_id': TEST_PAIR_ID,
|
||||
'rmt_lun_id': self.replica_volume.provider_location}
|
||||
new_drv_data = replication.to_string(new_drv_data)
|
||||
self.assertEqual(new_drv_data, v_update['replication_driver_data'])
|
||||
'rmt_lun_id': metadata['huawei_lun_id'],
|
||||
'rmt_lun_wwn': metadata['huawei_lun_wwn']}
|
||||
self.assertDictEqual(
|
||||
new_drv_data, json.loads(v_update['replication_driver_data']))
|
||||
|
||||
@ddt.data({}, {'pair_id': TEST_PAIR_ID})
|
||||
def test_failover_replica_volumes_invalid_drv_data(self, mock_drv_data):
|
||||
|
@ -4037,12 +4150,19 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
v_id = volumes_update[0]['volume_id']
|
||||
v_update = volumes_update[0]['updates']
|
||||
self.assertEqual(self.replica_volume.id, v_id)
|
||||
self.assertEqual('1', v_update['provider_location'])
|
||||
|
||||
expect_location = {"huawei_lun_wwn": "FAKE_RMT_LUN_WWN",
|
||||
"huawei_lun_id": "1"}
|
||||
self.assertDictEqual(
|
||||
expect_location, json.loads(v_update['provider_location']))
|
||||
self.assertEqual('available', v_update['replication_status'])
|
||||
|
||||
metadata = huawei_utils.get_lun_metadata(self.replica_volume)
|
||||
new_drv_data = {'pair_id': TEST_PAIR_ID,
|
||||
'rmt_lun_id': self.replica_volume.provider_location}
|
||||
new_drv_data = replication.to_string(new_drv_data)
|
||||
self.assertEqual(new_drv_data, v_update['replication_driver_data'])
|
||||
'rmt_lun_id': metadata['huawei_lun_id'],
|
||||
'rmt_lun_wwn': metadata['huawei_lun_wwn']}
|
||||
self.assertDictEqual(
|
||||
new_drv_data, json.loads(v_update['replication_driver_data']))
|
||||
|
||||
@ddt.data({}, {'pair_id': TEST_PAIR_ID})
|
||||
def test_failback_replica_volumes_invalid_drv_data(self, mock_drv_data):
|
||||
|
@ -4072,7 +4192,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
self.assertEqual(self.replica_volume.id, v_id)
|
||||
self.assertEqual('error', v_update['replication_status'])
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
|
||||
new=utils.ZeroIntervalLoopingCall)
|
||||
@mock.patch.object(replication.PairOp, 'is_primary',
|
||||
|
@ -4128,7 +4247,6 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
common_driver.protect_second(replica_id)
|
||||
common_driver.unprotect_second(replica_id)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_replication_driver_sync(self):
|
||||
replica_id = TEST_PAIR_ID
|
||||
op = replication.PairOp(self.driver.client)
|
||||
|
@ -4235,15 +4353,16 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
|||
def test_create_cgsnapshot(self):
|
||||
test_snapshots = [self.snapshot]
|
||||
ctxt = context.get_admin_context()
|
||||
model, snapshots = self.driver.create_cgsnapshot(ctxt,
|
||||
self.cgsnapshot,
|
||||
test_snapshots)
|
||||
snapshots_model_update = [{'id': '21ec7341-9256-497b-97d9'
|
||||
'-ef48edcf0635',
|
||||
'status': 'available',
|
||||
'provider_location': 11}]
|
||||
self.assertEqual(snapshots_model_update, snapshots)
|
||||
self.assertEqual('available', model['status'])
|
||||
model, snapshots = (
|
||||
self.driver.create_cgsnapshot(ctxt, self.cgsnapshot,
|
||||
test_snapshots))
|
||||
|
||||
self.assertEqual('21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
snapshots[0]['id'])
|
||||
self.assertEqual('available', snapshots[0]['status'])
|
||||
self.assertDictEqual({'huawei_snapshot_id': '11'},
|
||||
json.loads(snapshots[0]['provider_location']))
|
||||
self.assertEqual(fields.GroupSnapshotStatus.AVAILABLE, model['status'])
|
||||
|
||||
def test_create_cgsnapshot_create_snapshot_fail(self):
|
||||
test_snapshots = [self.snapshot]
|
||||
|
@ -4304,7 +4423,10 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
|
||||
def test_create_volume_success(self):
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
def test_delete_volume_success(self, pool_data):
|
||||
|
@ -4314,11 +4436,13 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
def test_delete_snapshot_success(self):
|
||||
self.driver.delete_snapshot(self.snapshot)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_create_volume_from_snapsuccess(self):
|
||||
lun_info = self.driver.create_volume_from_snapshot(self.volume,
|
||||
self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
self.snapshot)
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@mock.patch.object(huawei_driver.HuaweiFCDriver,
|
||||
'initialize_connection',
|
||||
|
@ -4530,7 +4654,6 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
'12')
|
||||
self.assertFalse(result)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
@mock.patch.object(rest_client, 'RestClient')
|
||||
def test_migrate_volume_success(self, mock_add_lun_to_partition,
|
||||
|
@ -4612,13 +4735,15 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
self.assertFalse(is_valid)
|
||||
# storage_protocol is not match current protocol and volume status is
|
||||
# 'in-use'.
|
||||
location = ('{"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003", '
|
||||
'"huawei_lun_id": "11"}')
|
||||
volume_in_use = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 2,
|
||||
'volume_name': 'vol1',
|
||||
'id': ID,
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_attachment': 'in-use',
|
||||
'provider_location': '11'}
|
||||
'provider_location': location}
|
||||
invalid_host2 = {'host': 'ubuntu001@backend002#OpenStack_Pool',
|
||||
'capabilities':
|
||||
{'location_info': '210235G7J20000000001',
|
||||
|
@ -4667,7 +4792,6 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
test_new_type, None, test_host)
|
||||
self.assertTrue(retype)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
@mock.patch.object(rest_client, 'RestClient')
|
||||
@mock.patch.object(
|
||||
|
@ -4858,7 +4982,10 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
def test_multi_resturls_success(self):
|
||||
self.driver.client.test_multi_url_flag = True
|
||||
lun_info = self.driver.create_volume(self.volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
expect_value = {"huawei_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
self.assertDictEqual(expect_value,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
def test_get_id_from_result(self):
|
||||
result = {}
|
||||
|
@ -4922,10 +5049,13 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
mock_volume_ready,
|
||||
mock_logout):
|
||||
|
||||
metadata = {"hypermetro_id": '11',
|
||||
"remote_lun_id": '1'}
|
||||
location = {"huawei_lun_id": "1",
|
||||
"hypermetro_id": "11",
|
||||
"remote_lun_id": "1",
|
||||
"huawei_lun_wwn": "6643e8c1004c5f6723e9f454003"}
|
||||
lun_info = self.driver.create_volume(self.hyper_volume)
|
||||
self.assertEqual(metadata, lun_info['metadata'])
|
||||
self.assertDictEqual(location,
|
||||
json.loads(lun_info['provider_location']))
|
||||
|
||||
@ddt.data(FAKE_POOLS_UNSUPPORT_REPORT, FAKE_POOLS_SUPPORT_REPORT)
|
||||
@mock.patch.object(huawei_driver.HuaweiBaseDriver, '_get_volume_params',
|
||||
|
@ -4954,7 +5084,7 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.metro.create_hypermetro, "11", {})
|
||||
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_lun_metadata',
|
||||
return_value={'hypermetro_id': '3400a30d844d0007',
|
||||
'remote_lun_id': '1'})
|
||||
@mock.patch.object(rest_client.RestClient, 'do_mapping',
|
||||
|
@ -4968,13 +5098,13 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
mock_map.assert_called_once_with('1', '0', '1',
|
||||
hypermetro_lun=True)
|
||||
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_lun_metadata',
|
||||
return_value={'hypermetro_id': '3400a30d844d0007',
|
||||
'remote_lun_id': '1'})
|
||||
def test_terminate_hypermetro_connection_success(self, mock_metradata):
|
||||
self.driver.metro.disconnect_volume_fc(self.volume, FakeConnector)
|
||||
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_lun_metadata',
|
||||
return_value={'hypermetro_id': '3400a30d844d0007',
|
||||
'remote_lun_id': None})
|
||||
@mock.patch.object(rest_client.RestClient, 'get_lun_id_by_name',
|
||||
|
@ -4982,15 +5112,14 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
def test_hypermetroid_none_fail(self, mock_metadata, moke_metro_name):
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.metro.connect_volume_fc,
|
||||
self.volume,
|
||||
self.hyper_volume,
|
||||
FakeConnector)
|
||||
|
||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
||||
def test_wait_volume_ready_success(self):
|
||||
flag = self.driver.metro._wait_volume_ready("11")
|
||||
self.assertIsNone(flag)
|
||||
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_lun_metadata',
|
||||
return_value={'hypermetro_id': '3400a30d844d0007',
|
||||
'remote_lun_id': '1'})
|
||||
@mock.patch.object(rest_client.RestClient, 'get_online_free_wwns',
|
||||
|
@ -5002,7 +5131,7 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
mock_host_initiators):
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.metro.connect_volume_fc,
|
||||
self.volume,
|
||||
self.hyper_volume,
|
||||
FakeConnector)
|
||||
|
||||
def test_create_snapshot_fail_hypermetro(self):
|
||||
|
@ -5120,7 +5249,7 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
|
|||
@mock.patch.object(huawei_driver.HuaweiBaseDriver,
|
||||
'_get_consistencygroup_type',
|
||||
return_value={"hypermetro": "true"})
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
|
||||
@mock.patch.object(huawei_driver.huawei_utils, 'get_lun_metadata',
|
||||
return_value={'hypermetro_id': '3400a30d844d0007',
|
||||
'remote_lun_id': '59'})
|
||||
def test_update_consistencygroup_success(self,
|
||||
|
|
|
@ -29,6 +29,7 @@ from cinder import context
|
|||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.huawei import constants
|
||||
|
@ -333,17 +334,13 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
{'volume': volume.id, 'params': params})
|
||||
return params
|
||||
|
||||
def _create_volume(self, volume, lun_params):
|
||||
def _create_volume(self, lun_params):
|
||||
# Create LUN on the array.
|
||||
model_update = {}
|
||||
lun_info = self.client.create_lun(lun_params)
|
||||
model_update['provider_location'] = lun_info['ID']
|
||||
metadata = {'huawei_lun_id': lun_info['ID'],
|
||||
'huawei_lun_wwn': lun_info['WWN']}
|
||||
model_update = {'metadata': metadata}
|
||||
|
||||
admin_metadata = huawei_utils.get_admin_metadata(volume)
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
model_update['admin_metadata'] = admin_metadata
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
model_update['metadata'] = metadata
|
||||
return lun_info, model_update
|
||||
|
||||
def _create_base_type_volume(self, opts, volume, volume_type):
|
||||
|
@ -352,7 +349,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
Base type is the service type which doesn't conflict with the other.
|
||||
"""
|
||||
lun_params = self._get_lun_params(volume, opts)
|
||||
lun_info, model_update = self._create_volume(volume, lun_params)
|
||||
lun_info, model_update = self._create_volume(lun_params)
|
||||
lun_id = lun_info['ID']
|
||||
|
||||
try:
|
||||
|
@ -427,10 +424,15 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
|
||||
model_update = self._add_extend_type_to_volume(opts, lun_params,
|
||||
lun_info, model_update)
|
||||
|
||||
model_update['provider_location'] = huawei_utils.to_string(
|
||||
**model_update.pop('metadata'))
|
||||
|
||||
return model_update
|
||||
|
||||
def _delete_volume(self, volume):
|
||||
lun_id = volume.provider_location
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = metadata.get('huawei_lun_id')
|
||||
if not lun_id:
|
||||
return
|
||||
|
||||
|
@ -459,7 +461,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
smart_qos = smartx.SmartQos(self.client)
|
||||
smart_qos.remove(qos_id, lun_id)
|
||||
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
if 'hypermetro_id' in metadata:
|
||||
metro = hypermetro.HuaweiHyperMetro(self.client,
|
||||
self.rmt_client,
|
||||
|
@ -647,7 +649,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
pool_info = self.client.get_pool_info(pool_name, pools)
|
||||
src_volume_name = huawei_utils.encode_name(volume.id)
|
||||
dst_volume_name = six.text_type(hash(src_volume_name))
|
||||
src_id = volume.provider_location
|
||||
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
src_id = metadata['huawei_lun_id']
|
||||
|
||||
opts = None
|
||||
qos = None
|
||||
|
@ -667,9 +671,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
|
||||
lun_info = self.client.get_lun_info(src_id)
|
||||
|
||||
policy = lun_info['DATATRANSFERPOLICY']
|
||||
if opts['policy']:
|
||||
policy = opts['policy']
|
||||
else:
|
||||
policy = lun_info.get('DATATRANSFERPOLICY',
|
||||
self.configuration.lun_policy)
|
||||
|
||||
lun_params = {
|
||||
'NAME': dst_volume_name,
|
||||
'PARENTID': pool_info['ID'],
|
||||
|
@ -681,8 +688,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
'PREFETCHPOLICY': lun_info['PREFETCHPOLICY'],
|
||||
'PREFETCHVALUE': lun_info['PREFETCHVALUE'],
|
||||
'DATATRANSFERPOLICY': policy,
|
||||
'READCACHEPOLICY': lun_info['READCACHEPOLICY'],
|
||||
'WRITECACHEPOLICY': lun_info['WRITECACHEPOLICY'],
|
||||
'READCACHEPOLICY': lun_info.get(
|
||||
'READCACHEPOLICY',
|
||||
self.configuration.lun_read_cache_policy),
|
||||
'WRITECACHEPOLICY': lun_info.get(
|
||||
'WRITECACHEPOLICY',
|
||||
self.configuration.lun_write_cache_policy),
|
||||
'OWNINGCONTROLLER': lun_info['OWNINGCONTROLLER'], }
|
||||
|
||||
for item in lun_params.keys():
|
||||
|
@ -724,7 +735,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
raise exception.VolumeBackendAPIException(data=err_msg)
|
||||
|
||||
snapshotname = huawei_utils.encode_name(snapshot.id)
|
||||
snapshot_id = snapshot.provider_location
|
||||
metadata = huawei_utils.get_snapshot_metadata(snapshot)
|
||||
snapshot_id = metadata.get('huawei_snapshot_id')
|
||||
if snapshot_id is None:
|
||||
snapshot_id = self.client.get_snapshot_id_by_name(snapshotname)
|
||||
if snapshot_id is None:
|
||||
|
@ -738,7 +750,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
lun_params, lun_info, model_update = (
|
||||
self._create_base_type_volume(opts, volume, volume_type))
|
||||
|
||||
tgt_lun_id = model_update['provider_location']
|
||||
tgt_lun_id = lun_info['ID']
|
||||
luncopy_name = huawei_utils.encode_name(volume.id)
|
||||
LOG.info(_LI(
|
||||
'create_volume_from_snapshot: src_lun_id: %(src_lun_id)s, '
|
||||
|
@ -768,6 +780,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
# now, not hypermetro.
|
||||
model_update = self._add_extend_type_to_volume(opts, lun_params,
|
||||
lun_info, model_update)
|
||||
model_update['provider_location'] = huawei_utils.to_string(
|
||||
**model_update.pop('metadata'))
|
||||
|
||||
return model_update
|
||||
|
||||
def create_cloned_volume(self, volume, src_vref):
|
||||
|
@ -807,7 +822,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
If not exists, raise or log warning.
|
||||
"""
|
||||
# Firstly, try to find LUN ID by volume.provider_location.
|
||||
lun_id = volume.provider_location
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = metadata.get('huawei_lun_id')
|
||||
# If LUN ID not recorded, find LUN ID by LUN NAME.
|
||||
if not lun_id:
|
||||
volume_name = huawei_utils.encode_name(volume.id)
|
||||
|
@ -821,8 +837,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
return
|
||||
|
||||
metadata = huawei_utils.get_admin_metadata(volume)
|
||||
lun_wwn = metadata.get('huawei_lun_wwn') if metadata else None
|
||||
lun_wwn = metadata.get('huawei_lun_wwn')
|
||||
if not lun_wwn:
|
||||
LOG.debug("No LUN WWN recorded for volume %s.", volume.id)
|
||||
|
||||
|
@ -898,7 +913,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
snapshot_id = snapshot_info['ID']
|
||||
self.client.activate_snapshot(snapshot_id)
|
||||
|
||||
return {'provider_location': snapshot_info['ID'],
|
||||
location = huawei_utils.to_string(huawei_snapshot_id=snapshot_id)
|
||||
return {'provider_location': location,
|
||||
'lun_info': snapshot_info}
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
|
@ -911,7 +927,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
{'snapshot': snapshotname,
|
||||
'volume': volume_name},)
|
||||
|
||||
snapshot_id = snapshot.provider_location
|
||||
metadata = huawei_utils.get_snapshot_metadata(snapshot)
|
||||
snapshot_id = metadata.get('huawei_snapshot_id')
|
||||
if snapshot_id is None:
|
||||
snapshot_id = self.client.get_snapshot_id_by_name(snapshotname)
|
||||
|
||||
|
@ -1186,7 +1203,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
'replication_type': None,
|
||||
}
|
||||
|
||||
lun_id = volume.provider_location
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = metadata['huawei_lun_id']
|
||||
old_opts = self.get_lun_specs(lun_id)
|
||||
|
||||
new_specs = new_type['extra_specs']
|
||||
|
@ -1463,12 +1481,10 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
{'old_name': lun_info.get('NAME'),
|
||||
'new_name': new_name})
|
||||
self.client.rename_lun(lun_id, new_name, description)
|
||||
metadata = huawei_utils.get_admin_metadata(volume)
|
||||
metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
|
||||
model_update = {}
|
||||
model_update.update({'admin_metadata': metadata})
|
||||
model_update.update({'provider_location': lun_id})
|
||||
location = huawei_utils.to_string(huawei_lun_id=lun_id,
|
||||
huawei_lun_wwn=lun_info['WWN'])
|
||||
model_update = {'provider_location': location}
|
||||
|
||||
if new_opts and new_opts.get('replication_enabled'):
|
||||
LOG.debug("Manage volume need to create replication.")
|
||||
|
@ -1552,9 +1568,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
def manage_existing_snapshot(self, snapshot, existing_ref):
|
||||
snapshot_info = self._get_snapshot_info_by_ref(existing_ref)
|
||||
snapshot_id = snapshot_info.get('ID')
|
||||
volume = snapshot.volume
|
||||
lun_id = volume.provider_location
|
||||
if lun_id != snapshot_info.get('PARENTID'):
|
||||
parent_metadata = huawei_utils.get_lun_metadata(snapshot.volume)
|
||||
parent_lun_id = parent_metadata.get('huawei_lun_id')
|
||||
if parent_lun_id != snapshot_info.get('PARENTID'):
|
||||
msg = (_("Can't import snapshot %s to Cinder. "
|
||||
"Snapshot doesn't belong to volume."), snapshot_id)
|
||||
raise exception.ManageExistingInvalidReference(
|
||||
|
@ -1574,7 +1590,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
{'old_name': snapshot_info.get('NAME'),
|
||||
'new_name': snapshot_name})
|
||||
|
||||
return {'provider_location': snapshot_id}
|
||||
location = huawei_utils.to_string(huawei_snapshot_id=snapshot_id)
|
||||
return {'provider_location': location}
|
||||
|
||||
def manage_existing_snapshot_get_size(self, snapshot, existing_ref):
|
||||
"""Get the size of the existing snapshot."""
|
||||
|
@ -1679,10 +1696,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
info = self.client.create_snapshot(lun_id,
|
||||
snapshot_name,
|
||||
snapshot_description)
|
||||
snapshot_model_update = {'id': snapshot.id,
|
||||
'status': 'available',
|
||||
'provider_location': info['ID']}
|
||||
snapshots_model_update.append(snapshot_model_update)
|
||||
location = huawei_utils.to_string(
|
||||
huawei_snapshot_id=info['ID'])
|
||||
snap_model_update = {'id': snapshot.id,
|
||||
'status': fields.SnapshotStatus.AVAILABLE,
|
||||
'provider_location': location}
|
||||
snapshots_model_update.append(snap_model_update)
|
||||
added_snapshots_info.append(info)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -1849,7 +1868,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
|||
|
||||
def get_lun_id_and_type(self, volume):
|
||||
if hasattr(volume, 'lun_type'):
|
||||
lun_id = volume.provider_location
|
||||
metadata = huawei_utils.get_snapshot_metadata(volume)
|
||||
lun_id = metadata['huawei_snapshot_id']
|
||||
lun_type = constants.SNAPSHOT_TYPE
|
||||
else:
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
|
@ -2171,7 +2191,7 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
|||
# Add host into hostgroup.
|
||||
hostgroup_id = self.client.add_host_to_hostgroup(host_id)
|
||||
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
LOG.info(_LI("initialize_connection, metadata is: %s."), metadata)
|
||||
hypermetro_lun = 'hypermetro_id' in metadata
|
||||
|
||||
|
@ -2330,7 +2350,7 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
|||
self.client.delete_mapping_view(view_id)
|
||||
|
||||
# Deal with hypermetro connection.
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
LOG.info(_LI("Detach Volume, metadata is: %s."), metadata)
|
||||
|
||||
if 'hypermetro_id' in metadata:
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import six
|
||||
import time
|
||||
|
||||
|
@ -112,3 +113,37 @@ def get_snapshot_metadata_value(snapshot):
|
|||
return {item['key']: item['value'] for item in metadata}
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
def to_string(**kwargs):
|
||||
return json.dumps(kwargs) if kwargs else ''
|
||||
|
||||
|
||||
def get_lun_metadata(volume):
|
||||
if not volume.provider_location:
|
||||
return {}
|
||||
|
||||
info = json.loads(volume.provider_location)
|
||||
if isinstance(info, dict):
|
||||
return info
|
||||
|
||||
# To keep compatible with old driver version
|
||||
admin_metadata = get_admin_metadata(volume)
|
||||
metadata = get_volume_metadata(volume)
|
||||
return {'huawei_lun_id': six.text_type(info),
|
||||
'huawei_lun_wwn': admin_metadata.get('huawei_lun_wwn'),
|
||||
'hypermetro_id': metadata.get('hypermetro_id'),
|
||||
'remote_lun_id': metadata.get('remote_lun_id')
|
||||
}
|
||||
|
||||
|
||||
def get_snapshot_metadata(snapshot):
|
||||
if not snapshot.provider_location:
|
||||
return {}
|
||||
|
||||
info = json.loads(snapshot.provider_location)
|
||||
if isinstance(info, dict):
|
||||
return info
|
||||
|
||||
# To keep compatible with old driver version
|
||||
return {'huawei_snapshot_id': six.text_type(info)}
|
||||
|
|
|
@ -74,7 +74,7 @@ class HuaweiHyperMetro(object):
|
|||
|
||||
def delete_hypermetro(self, volume):
|
||||
"""Delete hypermetro."""
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
metro_id = metadata['hypermetro_id']
|
||||
remote_lun_id = metadata['remote_lun_id']
|
||||
|
||||
|
@ -111,7 +111,7 @@ class HuaweiHyperMetro(object):
|
|||
{'wwpns': wwns,
|
||||
'volume': volume_name})
|
||||
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = metadata['remote_lun_id']
|
||||
|
||||
if lun_id is None:
|
||||
|
@ -184,7 +184,7 @@ class HuaweiHyperMetro(object):
|
|||
"""Delete map between a volume and a host for FC."""
|
||||
wwns = connector['wwpns']
|
||||
volume_name = huawei_utils.encode_name(volume.id)
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = metadata['remote_lun_id']
|
||||
host_name = connector['host']
|
||||
left_lunnum = -1
|
||||
|
@ -332,7 +332,7 @@ class HuaweiHyperMetro(object):
|
|||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
def check_metro_need_to_stop(self, volume):
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
metro_id = metadata['hypermetro_id']
|
||||
metro_existed = self.client.check_hypermetro_exist(metro_id)
|
||||
|
||||
|
|
|
@ -506,7 +506,8 @@ class ReplicaPairManager(object):
|
|||
|
||||
model_update = {}
|
||||
driver_data = {'pair_id': pair_id,
|
||||
'rmt_lun_id': rmt_lun_id}
|
||||
'rmt_lun_id': rmt_lun_id,
|
||||
'rmt_lun_wwn': rmt_lun_info['WWN']}
|
||||
model_update['replication_driver_data'] = to_string(driver_data)
|
||||
model_update['replication_status'] = 'available'
|
||||
LOG.debug('Create replication, return info: %s.', model_update)
|
||||
|
@ -583,16 +584,18 @@ class ReplicaPairManager(object):
|
|||
# Switch replication pair role, and start synchronize.
|
||||
self.rmt_driver.enable(pair_id)
|
||||
|
||||
lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
|
||||
admin_metadata = huawei_utils.get_admin_metadata(v)
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
new_drv_data = {'pair_id': pair_id,
|
||||
'rmt_lun_id': v.provider_location}
|
||||
new_drv_data = to_string(new_drv_data)
|
||||
v_update['updates'] = {'provider_location': rmt_lun_id,
|
||||
local_metadata = huawei_utils.get_lun_metadata(v)
|
||||
new_drv_data = to_string(
|
||||
{'pair_id': pair_id,
|
||||
'rmt_lun_id': local_metadata.get('huawei_lun_id'),
|
||||
'rmt_lun_wwn': local_metadata.get('huawei_lun_wwn')})
|
||||
location = huawei_utils.to_string(
|
||||
huawei_lun_id=rmt_lun_id,
|
||||
huawei_lun_wwn=drv_data.get('rmt_lun_wwn'))
|
||||
|
||||
v_update['updates'] = {'provider_location': location,
|
||||
'replication_status': 'available',
|
||||
'replication_driver_data': new_drv_data,
|
||||
'admin_metadata': admin_metadata}
|
||||
'replication_driver_data': new_drv_data}
|
||||
volumes_update.append(v_update)
|
||||
|
||||
return volumes_update
|
||||
|
@ -623,17 +626,18 @@ class ReplicaPairManager(object):
|
|||
|
||||
self.rmt_driver.failover(pair_id)
|
||||
|
||||
lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
|
||||
admin_metadata = huawei_utils.get_admin_metadata(v)
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
local_metadata = huawei_utils.get_lun_metadata(v)
|
||||
new_drv_data = to_string(
|
||||
{'pair_id': pair_id,
|
||||
'rmt_lun_id': local_metadata.get('huawei_lun_id'),
|
||||
'rmt_lun_wwn': local_metadata.get('huawei_lun_wwn')})
|
||||
location = huawei_utils.to_string(
|
||||
huawei_lun_id=rmt_lun_id,
|
||||
huawei_lun_wwn=drv_data.get('rmt_lun_wwn'))
|
||||
|
||||
new_drv_data = {'pair_id': pair_id,
|
||||
'rmt_lun_id': v.provider_location}
|
||||
new_drv_data = to_string(new_drv_data)
|
||||
v_update['updates'] = {'provider_location': rmt_lun_id,
|
||||
v_update['updates'] = {'provider_location': location,
|
||||
'replication_status': 'failed-over',
|
||||
'replication_driver_data': new_drv_data,
|
||||
'admin_metadata': admin_metadata}
|
||||
'replication_driver_data': new_drv_data}
|
||||
volumes_update.append(v_update)
|
||||
|
||||
return volumes_update
|
||||
|
|
|
@ -26,6 +26,7 @@ from cinder import exception
|
|||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.huawei import constants
|
||||
from cinder.volume.drivers.huawei import huawei_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -322,8 +323,10 @@ class RestClient(object):
|
|||
return result['data']
|
||||
|
||||
def get_lun_id(self, volume, volume_name):
|
||||
lun_id = (volume.provider_location or
|
||||
metadata = huawei_utils.get_lun_metadata(volume)
|
||||
lun_id = (metadata.get('huawei_lun_id') or
|
||||
self.get_lun_id_by_name(volume_name))
|
||||
|
||||
if not lun_id:
|
||||
msg = (_("Can't find lun info on the array. "
|
||||
"volume: %(id)s, lun name: %(name)s.") %
|
||||
|
|
Loading…
Reference in New Issue