Add CG capability to generic groups in Huawei driver

This patch adds the consistency group capability to generic group in
Huawei driver. Consistency groups will be used as generic groups.

DocImpact:
Implements: blueprint huawei-generic-group
Change-Id: I16937c0ccd9f5a4ffad79f35c49ab32ee6092620
This commit is contained in:
huyang 2017-03-23 17:52:58 +08:00
parent d1b5a11325
commit 2e06995ad5
5 changed files with 182 additions and 145 deletions

View File

@ -25,9 +25,10 @@ from xml.dom import minidom
from cinder import context from cinder import context
from cinder import exception from cinder import exception
from cinder.objects import fields
from cinder import test from cinder import test
from cinder.tests.unit.consistencygroup import fake_cgsnapshot from cinder.tests.unit import fake_group
from cinder.tests.unit.consistencygroup import fake_consistencygroup from cinder.tests.unit import fake_group_snapshot
from cinder.tests.unit import fake_snapshot from cinder.tests.unit import fake_snapshot
from cinder.tests.unit import fake_volume from cinder.tests.unit import fake_volume
from cinder.tests.unit import utils from cinder.tests.unit import utils
@ -42,6 +43,7 @@ from cinder.volume.drivers.huawei import replication
from cinder.volume.drivers.huawei import rest_client from cinder.volume.drivers.huawei import rest_client
from cinder.volume.drivers.huawei import smartx from cinder.volume.drivers.huawei import smartx
from cinder.volume import qos_specs from cinder.volume import qos_specs
from cinder.volume import utils as volume_utils
from cinder.volume import volume_types from cinder.volume import volume_types
admin_contex = context.get_admin_context() admin_contex = context.get_admin_context()
@ -382,7 +384,7 @@ FAKE_POOLS_SUPPORT_REPORT = {
'max_over_subscription_ratio': 20.0, 'max_over_subscription_ratio': 20.0,
'luncopy': True, 'luncopy': True,
'hypermetro': True, 'hypermetro': True,
'consistencygroup_support': True 'consistent_group_snapshot_enabled': True
} }
FAKE_LUN_GET_SUCCESS_RESPONSE = """ FAKE_LUN_GET_SUCCESS_RESPONSE = """
@ -2020,6 +2022,15 @@ MAP_COMMAND_TO_FAKE_RESPONSE['/mappingview/associate/portgroup?TYPE=245&ASSOC'
REPLICA_BACKEND_ID = 'huawei-replica-1' REPLICA_BACKEND_ID = 'huawei-replica-1'
def cg_or_cg_snapshot(func):
def wrapper(self, *args, **kwargs):
self.mock_object(volume_utils,
'is_group_a_cg_snapshot_type',
return_value=True)
return func(self, *args, **kwargs)
return wrapper
class FakeHuaweiConf(huawei_conf.HuaweiConf): class FakeHuaweiConf(huawei_conf.HuaweiConf):
def __init__(self, conf, protocol): def __init__(self, conf, protocol):
self.conf = conf self.conf = conf
@ -2241,10 +2252,10 @@ class HuaweiTestBase(test.TestCase):
admin_contex, id=ID, provider_location=PROVIDER_LOCATION, admin_contex, id=ID, provider_location=PROVIDER_LOCATION,
name_id=ID) name_id=ID)
self.cgsnapshot = fake_cgsnapshot.fake_cgsnapshot_obj( self.group_snapshot = fake_group_snapshot.fake_group_snapshot_obj(
admin_contex, id=ID, consistencygroup_id=ID, status='available') admin_contex, id=ID, group_id=ID, status='available')
self.cg = fake_consistencygroup.fake_consistencyobject_obj( self.group = fake_group.fake_group_obj(
admin_contex, id=ID, status='available') admin_contex, id=ID, status='available')
def test_encode_name(self): def test_encode_name(self):
@ -4286,49 +4297,52 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
iqn = self.driver.client._get_tgt_iqn_from_rest(ip) iqn = self.driver.client._get_tgt_iqn_from_rest(ip)
self.assertIsNone(iqn) self.assertIsNone(iqn)
def test_create_cgsnapshot(self): @cg_or_cg_snapshot
def test_create_group_snapshot(self):
test_snapshots = [self.snapshot] test_snapshots = [self.snapshot]
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
model, snapshots = self.driver.create_cgsnapshot(ctxt, model, snapshots = (
self.cgsnapshot, self.driver.create_group_snapshot(ctxt, self.group_snapshot,
test_snapshots) test_snapshots))
snapshots_model_update = [{'id': '21ec7341-9256-497b-97d9' snapshots_model_update = [{'id': '21ec7341-9256-497b-97d9'
'-ef48edcf0635', '-ef48edcf0635',
'status': 'available', 'status': 'available',
'provider_location': 11}] 'provider_location': 11}]
self.assertEqual(snapshots_model_update, snapshots) self.assertEqual(snapshots_model_update, snapshots)
self.assertEqual('available', model['status']) self.assertEqual(fields.GroupSnapshotStatus.AVAILABLE, model['status'])
def test_create_cgsnapshot_create_snapshot_fail(self): @cg_or_cg_snapshot
def test_create_group_snapshot_with_create_snapshot_fail(self):
test_snapshots = [self.snapshot] test_snapshots = [self.snapshot]
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
self.mock_object(rest_client.RestClient, 'create_snapshot', self.mock_object(rest_client.RestClient, 'create_snapshot',
side_effect=( side_effect=(
exception.VolumeBackendAPIException(data='err'))) exception.VolumeBackendAPIException(data='err')))
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.create_cgsnapshot, self.driver.create_group_snapshot,
ctxt, ctxt,
self.cgsnapshot, self.group_snapshot,
test_snapshots) test_snapshots)
def test_create_cgsnapshot_active_snapshot_fail(self): @cg_or_cg_snapshot
def test_create_group_snapshot_with_active_snapshot_fail(self):
test_snapshots = [self.snapshot] test_snapshots = [self.snapshot]
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
self.mock_object(rest_client.RestClient, 'activate_snapshot', self.mock_object(rest_client.RestClient, 'activate_snapshot',
side_effect=( side_effect=(
exception.VolumeBackendAPIException(data='err'))) exception.VolumeBackendAPIException(data='err')))
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.create_cgsnapshot, self.driver.create_group_snapshot,
ctxt, ctxt,
self.cgsnapshot, self.group_snapshot,
test_snapshots) test_snapshots)
def test_delete_cgsnapshot(self): @cg_or_cg_snapshot
def test_delete_group_snapshot(self):
test_snapshots = [self.snapshot] test_snapshots = [self.snapshot]
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
self.driver.delete_cgsnapshot(ctxt, self.driver.delete_group_snapshot(ctxt, self.group_snapshot,
self.cgsnapshot, test_snapshots)
test_snapshots)
class FCSanLookupService(object): class FCSanLookupService(object):
@ -5109,95 +5123,81 @@ class HuaweiFCDriverTestCase(HuaweiTestBase):
self.assertFalse(res) self.assertFalse(res)
@mock.patch.object(huawei_driver.HuaweiBaseDriver, @mock.patch.object(huawei_driver.HuaweiBaseDriver,
'_get_consistencygroup_type', '_get_group_type',
return_value={"hypermetro": "true"}) return_value=[{"hypermetro": "true"}])
def test_create_hypermetro_consistencygroup_success(self, mock_grouptype): @cg_or_cg_snapshot
"""Test that create_consistencygroup return successfully.""" def test_create_hypermetro_group_success(self, mock_grouptype):
"""Test that create_group return successfully."""
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
# Create consistency group # Create group
model_update = self.driver.create_consistencygroup(ctxt, self.cg) model_update = self.driver.create_group(ctxt, self.group)
self.assertEqual('available', self.assertEqual(fields.GroupStatus.AVAILABLE,
model_update['status'], model_update['status'],
"Consistency Group created failed") "Group created failed")
@mock.patch.object(huawei_driver.HuaweiBaseDriver, @mock.patch.object(huawei_driver.HuaweiBaseDriver,
'_get_consistencygroup_type', '_get_group_type',
return_value={"hypermetro": "false"}) return_value=[{"hypermetro": "false"}])
def test_create_normal_consistencygroup_success(self, @cg_or_cg_snapshot
mock_grouptype): def test_create_normal_group_success(self, mock_grouptype):
"""Test that create_consistencygroup return successfully.""" """Test that create_group return successfully."""
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
# Create consistency group # Create group
model_update = self.driver.create_consistencygroup(ctxt, self.cg) model_update = self.driver.create_group(ctxt, self.group)
self.assertEqual('available', self.assertEqual(fields.GroupStatus.AVAILABLE,
model_update['status'], model_update['status'],
"Consistency Group created failed") "Group created failed")
@mock.patch.object(huawei_driver.HuaweiBaseDriver, @mock.patch.object(huawei_driver.HuaweiBaseDriver,
'_get_consistencygroup_type', '_get_group_type',
return_value={"hypermetro": "true"}) return_value=[{"hypermetro": "true"}])
def test_delete_hypermetro_consistencygroup_success(self, mock_grouptype): @cg_or_cg_snapshot
"""Test that create_consistencygroup return successfully.""" def test_delete_hypermetro_group_success(self, mock_grouptype):
"""Test that delete_group return successfully."""
test_volumes = [self.volume] test_volumes = [self.volume]
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
# Create consistency group # Delete group
model, volumes = self.driver.delete_consistencygroup(ctxt, model, volumes = self.driver.delete_group(ctxt, self.group,
self.cg, test_volumes)
test_volumes) self.assertEqual(fields.GroupStatus.DELETED,
self.assertEqual('available',
model['status'], model['status'],
"Consistency Group created failed") "Group deleted failed")
def test_delete_normal_consistencygroup_success(self):
ctxt = context.get_admin_context()
test_volumes = [self.volume]
self.mock_object(huawei_driver.HuaweiBaseDriver,
'_get_consistencygroup_type',
return_value={"hypermetro": "false"})
model, volumes = self.driver.delete_consistencygroup(ctxt,
self.cg,
test_volumes)
self.assertEqual('available',
model['status'],
"Consistency Group created failed")
@mock.patch.object(huawei_driver.HuaweiBaseDriver, @mock.patch.object(huawei_driver.HuaweiBaseDriver,
'_get_consistencygroup_type', '_get_group_type',
return_value={"hypermetro": "true"}) return_value=[{"hypermetro": "false"}])
@cg_or_cg_snapshot
def test_delete_normal_group_success(self, mock_grouptype):
"""Test that delete_group return successfully."""
ctxt = context.get_admin_context()
test_volumes = [self.volume]
# Delete group
model, volumes = self.driver.delete_group(ctxt, self.group,
test_volumes)
self.assertEqual(fields.GroupStatus.DELETED,
model['status'],
"Group deleted failed")
@mock.patch.object(huawei_driver.HuaweiBaseDriver,
'_get_group_type',
return_value=[{"hypermetro": "true"}])
@mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata', @mock.patch.object(huawei_driver.huawei_utils, 'get_volume_metadata',
return_value={'hypermetro_id': '3400a30d844d0007', return_value={'hypermetro_id': '3400a30d844d0007',
'remote_lun_id': '59'}) 'remote_lun_id': '59'})
def test_update_consistencygroup_success(self, @cg_or_cg_snapshot
mock_grouptype, def test_update_group_success(self, mock_grouptype, mock_metadata):
mock_metadata): """Test that update_group return successfully."""
"""Test that create_consistencygroup return successfully."""
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
add_volumes = [self.volume] add_volumes = [self.volume]
remove_volumes = [self.volume] remove_volumes = [self.volume]
# Create consistency group # Update group
model_update = self.driver.update_consistencygroup(ctxt, model_update = self.driver.update_group(ctxt, self.group,
self.cg, add_volumes, remove_volumes)
add_volumes, self.assertEqual(fields.GroupStatus.AVAILABLE,
remove_volumes)
self.assertEqual('available',
model_update[0]['status'], model_update[0]['status'],
"Consistency Group update failed") "Group update failed")
def test_create_hypermetro_consistencygroup_success_2(self):
ctxt = context.get_admin_context()
# Create consistency group
temp_cg = copy.deepcopy(self.cg)
temp_cg['volume_type_id'] = '550c089b-bfdd-4f7f-86e1-3ba88125555c,'
self.mock_object(volume_types, 'get_volume_type',
return_value=test_hypermetro_type)
model_update = self.driver.create_consistencygroup(ctxt, temp_cg)
self.assertEqual('available',
model_update['status'],
"Consistency Group created failed")
def test_is_initiator_associated_to_host_raise(self): def test_is_initiator_associated_to_host_raise(self):
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,

View File

@ -29,6 +29,7 @@ from cinder import context
from cinder import exception from cinder import exception
from cinder.i18n import _ from cinder.i18n import _
from cinder import interface from cinder import interface
from cinder.objects import fields
from cinder import utils from cinder import utils
from cinder.volume import driver from cinder.volume import driver
from cinder.volume.drivers.huawei import constants from cinder.volume.drivers.huawei import constants
@ -191,6 +192,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
pool['thick_provisioning_support'] = True pool['thick_provisioning_support'] = True
pool['thin_provisioning_support'] = True pool['thin_provisioning_support'] = True
pool['smarttier'] = True pool['smarttier'] = True
pool['consistent_group_snapshot_enabled'] = True
if self.configuration.san_product == "Dorado": if self.configuration.san_product == "Dorado":
pool['smarttier'] = False pool['smarttier'] = False
@ -198,8 +200,6 @@ class HuaweiBaseDriver(driver.VolumeDriver):
if self.metro_flag: if self.metro_flag:
pool['hypermetro'] = self.check_func_support("HyperMetroPair") pool['hypermetro'] = self.check_func_support("HyperMetroPair")
pool['consistencygroup_support'] = (
self.check_func_support("HyperMetro_ConsistentGroup"))
# Asign the support function to global paramenter. # Asign the support function to global paramenter.
self.support_func = pool self.support_func = pool
@ -224,17 +224,28 @@ class HuaweiBaseDriver(driver.VolumeDriver):
opts = self._get_volume_params_from_specs(specs) opts = self._get_volume_params_from_specs(specs)
return opts return opts
def _get_consistencygroup_type(self, group): def _get_group_type(self, group):
specs = {} opts = []
opts = {} vol_types = group.volume_types
type_id = group.volume_type_id.split(",")
if type_id[0] and len(type_id) == 2: for vol_type in vol_types:
ctxt = context.get_admin_context() specs = vol_type.extra_specs
volume_type = volume_types.get_volume_type(ctxt, type_id[0]) opts.append(self._get_volume_params_from_specs(specs))
specs = dict(volume_type).get('extra_specs')
opts = self._get_volume_params_from_specs(specs)
return opts return opts
def _check_volume_type_support(self, opts, vol_type):
if not opts:
return False
support = True
for opt in opts:
if opt.get(vol_type) != 'true':
support = False
break
return support
def _get_volume_params_from_specs(self, specs): def _get_volume_params_from_specs(self, specs):
"""Return the volume parameters from extra specs.""" """Return the volume parameters from extra specs."""
opts_capability = { opts_capability = {
@ -1599,24 +1610,26 @@ class HuaweiBaseDriver(driver.VolumeDriver):
self.client.is_host_associated_to_hostgroup(host_id)): self.client.is_host_associated_to_hostgroup(host_id)):
self.client.remove_host(host_id) self.client.remove_host(host_id)
def create_consistencygroup(self, context, group): @huawei_utils.check_whether_operate_consistency_group
"""Creates a consistencygroup.""" def create_group(self, context, group):
model_update = {'status': 'available'} """Creates a group."""
opts = self._get_consistencygroup_type(group) model_update = {'status': fields.GroupStatus.AVAILABLE}
if (opts.get('hypermetro') == 'true'): opts = self._get_group_type(group)
if self._check_volume_type_support(opts, 'hypermetro'):
metro = hypermetro.HuaweiHyperMetro(self.client, metro = hypermetro.HuaweiHyperMetro(self.client,
self.rmt_client, self.rmt_client,
self.configuration) self.configuration)
metro.create_consistencygroup(group) metro.create_consistencygroup(group)
return model_update return model_update
# Array will create CG at create_cgsnapshot time. Cinder will # Array will create group at create_group_snapshot time. Cinder will
# maintain the CG and volumes relationship in the db. # maintain the group and volumes relationship in the db.
return model_update return model_update
def delete_consistencygroup(self, context, group, volumes): @huawei_utils.check_whether_operate_consistency_group
opts = self._get_consistencygroup_type(group) def delete_group(self, context, group, volumes):
if opts.get('hypermetro') == 'true': opts = self._get_group_type(group)
if self._check_volume_type_support(opts, 'hypermetro'):
metro = hypermetro.HuaweiHyperMetro(self.client, metro = hypermetro.HuaweiHyperMetro(self.client,
self.rmt_client, self.rmt_client,
self.configuration) self.configuration)
@ -1624,7 +1637,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
model_update = {} model_update = {}
volumes_model_update = [] volumes_model_update = []
model_update.update({'status': group.status}) model_update.update({'status': fields.GroupStatus.DELETED})
for volume_ref in volumes: for volume_ref in volumes:
try: try:
@ -1637,12 +1650,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
return model_update, volumes_model_update return model_update, volumes_model_update
def update_consistencygroup(self, context, group, @huawei_utils.check_whether_operate_consistency_group
add_volumes, def update_group(self, context, group,
remove_volumes): add_volumes=None, remove_volumes=None):
model_update = {'status': 'available'} model_update = {'status': fields.GroupStatus.AVAILABLE}
opts = self._get_consistencygroup_type(group) opts = self._get_group_type(group)
if opts.get('hypermetro') == 'true': if self._check_volume_type_support(opts, 'hypermetro'):
metro = hypermetro.HuaweiHyperMetro(self.client, metro = hypermetro.HuaweiHyperMetro(self.client,
self.rmt_client, self.rmt_client,
self.configuration) self.configuration)
@ -1651,15 +1664,23 @@ class HuaweiBaseDriver(driver.VolumeDriver):
remove_volumes) remove_volumes)
return model_update, None, None return model_update, None, None
# Array will create CG at create_cgsnapshot time. Cinder will # Array will create group at create_group_snapshot time. Cinder will
# maintain the CG and volumes relationship in the db. # maintain the group and volumes relationship in the db.
return model_update, None, None return model_update, None, None
def create_cgsnapshot(self, context, cgsnapshot, snapshots): @huawei_utils.check_whether_operate_consistency_group
"""Create cgsnapshot.""" def create_group_from_src(self, context, group, volumes,
LOG.info('Create cgsnapshot for consistency group' group_snapshot=None, snapshots=None,
': %(group_id)s', source_group=None, source_vols=None):
{'group_id': cgsnapshot.consistencygroup_id}) err_msg = _("Huawei Storage doesn't support create_group_from_src.")
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)
@huawei_utils.check_whether_operate_consistency_group
def create_group_snapshot(self, context, group_snapshot, snapshots):
"""Create group snapshot."""
LOG.info('Create group snapshot for group'
': %(group_id)s', {'group_id': group_snapshot.group_id})
model_update = {} model_update = {}
snapshots_model_update = [] snapshots_model_update = []
@ -1682,48 +1703,50 @@ class HuaweiBaseDriver(driver.VolumeDriver):
info = self.client.create_snapshot(lun_id, info = self.client.create_snapshot(lun_id,
snapshot_name, snapshot_name,
snapshot_description) snapshot_description)
snapshot_model_update = {'id': snapshot.id, snap_model_update = {'id': snapshot.id,
'status': 'available', 'status': fields.SnapshotStatus.AVAILABLE,
'provider_location': info['ID']} 'provider_location': info['ID']}
snapshots_model_update.append(snapshot_model_update) snapshots_model_update.append(snap_model_update)
added_snapshots_info.append(info) added_snapshots_info.append(info)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error("Create cgsnapshots failed. " LOG.error("Create group snapshots failed. "
"Cgsnapshot id: %s.", cgsnapshot.id) "Group snapshot id: %s.", group_snapshot.id)
snapshot_ids = [added_snapshot['ID'] snapshot_ids = [added_snapshot['ID']
for added_snapshot in added_snapshots_info] for added_snapshot in added_snapshots_info]
try: try:
self.client.activate_snapshot(snapshot_ids) self.client.activate_snapshot(snapshot_ids)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error("Active cgsnapshots failed. " LOG.error("Active group snapshots failed. "
"Cgsnapshot id: %s.", cgsnapshot.id) "Group snapshot id: %s.", group_snapshot.id)
model_update['status'] = 'available' model_update['status'] = fields.GroupSnapshotStatus.AVAILABLE
return model_update, snapshots_model_update return model_update, snapshots_model_update
def delete_cgsnapshot(self, context, cgsnapshot, snapshots): @huawei_utils.check_whether_operate_consistency_group
"""Delete consistency group snapshot.""" def delete_group_snapshot(self, context, group_snapshot, snapshots):
LOG.info('Delete cgsnapshot %(snap_id)s for consistency group: ' """Delete group snapshot."""
LOG.info('Delete group snapshot %(snap_id)s for group: '
'%(group_id)s', '%(group_id)s',
{'snap_id': cgsnapshot.id, {'snap_id': group_snapshot.id,
'group_id': cgsnapshot.consistencygroup_id}) 'group_id': group_snapshot.group_id})
model_update = {} model_update = {}
snapshots_model_update = [] snapshots_model_update = []
model_update['status'] = cgsnapshot.status model_update['status'] = fields.GroupSnapshotStatus.DELETED
for snapshot in snapshots: for snapshot in snapshots:
try: try:
self.delete_snapshot(snapshot) self.delete_snapshot(snapshot)
snapshots_model_update.append({'id': snapshot.id, snapshot_model = {'id': snapshot.id,
'status': 'deleted'}) 'status': fields.SnapshotStatus.DELETED}
snapshots_model_update.append(snapshot_model)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error("Delete cg snapshots failed. " LOG.error("Delete group snapshot failed. "
"Cgsnapshot id: %s", cgsnapshot.id) "Group snapshot id: %s", group_snapshot.id)
return model_update, snapshots_model_update return model_update, snapshots_model_update

View File

@ -24,6 +24,7 @@ from cinder import exception
from cinder.i18n import _ from cinder.i18n import _
from cinder import objects from cinder import objects
from cinder.volume.drivers.huawei import constants from cinder.volume.drivers.huawei import constants
from cinder.volume import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -112,3 +113,14 @@ def get_snapshot_metadata_value(snapshot):
return {item['key']: item['value'] for item in metadata} return {item['key']: item['value'] for item in metadata}
return {} return {}
def check_whether_operate_consistency_group(func):
def wrapper(self, context, group, *args, **kwargs):
if not utils.is_group_a_cg_snapshot_type(group):
msg = _("%s, the group or group snapshot is not cg or "
"cg_snapshot") % func.__name__
LOG.debug(msg)
raise NotImplementedError(msg)
return func(self, context, group, *args, **kwargs)
return wrapper

View File

@ -18,6 +18,7 @@ from oslo_log import log as logging
from cinder import exception from cinder import exception
from cinder.i18n import _ from cinder.i18n import _
from cinder.objects import fields
from cinder.volume.drivers.huawei import constants from cinder.volume.drivers.huawei import constants
from cinder.volume.drivers.huawei import huawei_utils from cinder.volume.drivers.huawei import huawei_utils
@ -286,7 +287,7 @@ class HuaweiHyperMetro(object):
{'group': group.id}) {'group': group.id})
model_update = {} model_update = {}
volumes_model_update = [] volumes_model_update = []
model_update['status'] = group.status model_update['status'] = fields.GroupStatus.DELETED
metrogroup_id = self.check_consistencygroup_need_to_stop(group) metrogroup_id = self.check_consistencygroup_need_to_stop(group)
if metrogroup_id: if metrogroup_id:
self.client.delete_metrogroup(metrogroup_id) self.client.delete_metrogroup(metrogroup_id)
@ -304,8 +305,6 @@ class HuaweiHyperMetro(object):
LOG.info("Update Consistency Group: %(group)s. " LOG.info("Update Consistency Group: %(group)s. "
"This adds or removes volumes from a CG.", "This adds or removes volumes from a CG.",
{'group': group.id}) {'group': group.id})
model_update = {}
model_update['status'] = group.status
metrogroup_id = self.check_consistencygroup_need_to_stop(group) metrogroup_id = self.check_consistencygroup_need_to_stop(group)
if metrogroup_id: if metrogroup_id:
# Deal with add volumes to CG # Deal with add volumes to CG

View File

@ -0,0 +1,3 @@
---
features:
- Add CG capability to generic volume groups in Huawei driver.