Merge "IBM Storwize with pool-aware-cinder-scheduler"
This commit is contained in:
commit
ca90a150b8
|
@ -45,6 +45,7 @@ from cinder.volume.drivers.ibm.storwize_svc import storwize_svc_common
|
|||
from cinder.volume.drivers.ibm.storwize_svc import storwize_svc_fc
|
||||
from cinder.volume.drivers.ibm.storwize_svc import storwize_svc_iscsi
|
||||
from cinder.volume import qos_specs
|
||||
from cinder.volume import utils as volume_utils
|
||||
from cinder.volume import volume_types
|
||||
|
||||
|
||||
|
@ -379,25 +380,30 @@ class StorwizeSVCManagementSimulator(object):
|
|||
|
||||
# Print mostly made-up stuff in the correct syntax, assume -bytes passed
|
||||
def _cmd_lsmdiskgrp(self, **kwargs):
|
||||
rows = [None] * 4
|
||||
rows[0] = ['id', 'name', 'status', 'mdisk_count',
|
||||
'vdisk_count', 'capacity', 'extent_size',
|
||||
'free_capacity', 'virtual_capacity', 'used_capacity',
|
||||
'real_capacity', 'overallocation', 'warning',
|
||||
'easy_tier', 'easy_tier_status']
|
||||
rows[1] = ['1', self._flags['storwize_svc_volpool_name'], 'online',
|
||||
'1', six.text_type(len(self._volumes_list)),
|
||||
'3573412790272', '256', '3529926246400', '1693247906775',
|
||||
'277841182', '38203734097', '47', '80', 'auto',
|
||||
'inactive']
|
||||
rows[2] = ['2', 'openstack2', 'online',
|
||||
'1', '0', '3573412790272', '256',
|
||||
'3529432325160', '1693247906775', '277841182',
|
||||
'38203734097', '47', '80', 'auto', 'inactive']
|
||||
rows[3] = ['3', 'openstack3', 'online',
|
||||
'1', '0', '3573412790272', '128',
|
||||
'3529432325160', '1693247906775', '277841182',
|
||||
'38203734097', '47', '80', 'auto', 'inactive']
|
||||
pool_num = len(self._flags['storwize_svc_volpool_name'])
|
||||
rows = []
|
||||
rows.append(['id', 'name', 'status', 'mdisk_count',
|
||||
'vdisk_count', 'capacity', 'extent_size',
|
||||
'free_capacity', 'virtual_capacity', 'used_capacity',
|
||||
'real_capacity', 'overallocation', 'warning',
|
||||
'easy_tier', 'easy_tier_status'])
|
||||
for i in range(0, pool_num):
|
||||
row_data = [str(i + 1),
|
||||
self._flags['storwize_svc_volpool_name'][i], 'online',
|
||||
'1', six.text_type(len(self._volumes_list)),
|
||||
'3573412790272', '256', '3529926246400',
|
||||
'1693247906775',
|
||||
'26843545600', '38203734097', '47', '80', 'auto',
|
||||
'inactive']
|
||||
rows.append(row_data)
|
||||
rows.append([str(pool_num + 1), 'openstack2', 'online',
|
||||
'1', '0', '3573412790272', '256',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive'])
|
||||
rows.append([str(pool_num + 2), 'openstack3', 'online',
|
||||
'1', '0', '3573412790272', '128',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive'])
|
||||
if 'obj' not in kwargs:
|
||||
return self._print_info_cmd(rows=rows, **kwargs)
|
||||
else:
|
||||
|
@ -405,19 +411,20 @@ class StorwizeSVCManagementSimulator(object):
|
|||
if pool_name == kwargs['obj']:
|
||||
raise exception.InvalidInput(
|
||||
reason=_('obj missing quotes %s') % kwargs['obj'])
|
||||
elif pool_name == self._flags['storwize_svc_volpool_name']:
|
||||
row = rows[1]
|
||||
elif pool_name in self._flags['storwize_svc_volpool_name']:
|
||||
for each_row in rows:
|
||||
if pool_name in each_row:
|
||||
row = each_row
|
||||
break
|
||||
elif pool_name == 'openstack2':
|
||||
row = rows[2]
|
||||
row = rows[-2]
|
||||
elif pool_name == 'openstack3':
|
||||
row = rows[3]
|
||||
row = rows[-1]
|
||||
else:
|
||||
return self._errors['CMMVC5754E']
|
||||
|
||||
objrows = []
|
||||
for idx, val in enumerate(rows[0]):
|
||||
objrows.append([val, row[idx]])
|
||||
|
||||
if 'nohdr' in kwargs:
|
||||
for index in range(len(objrows)):
|
||||
objrows[index] = ' '.join(objrows[index][1:])
|
||||
|
@ -428,6 +435,19 @@ class StorwizeSVCManagementSimulator(object):
|
|||
|
||||
return ('%s' % '\n'.join(objrows), '')
|
||||
|
||||
def _get_mdiskgrp_id(self, mdiskgrp):
|
||||
grp_num = len(self._flags['storwize_svc_volpool_name'])
|
||||
if mdiskgrp in self._flags['storwize_svc_volpool_name']:
|
||||
for i in range(grp_num):
|
||||
if mdiskgrp == self._flags['storwize_svc_volpool_name'][i]:
|
||||
return i + 1
|
||||
elif mdiskgrp == 'openstack2':
|
||||
return grp_num + 1
|
||||
elif mdiskgrp == 'openstack3':
|
||||
return grp_num + 2
|
||||
else:
|
||||
return None
|
||||
|
||||
# Print mostly made-up stuff in the correct syntax
|
||||
def _cmd_lsnodecanister(self, **kwargs):
|
||||
rows = [None] * 3
|
||||
|
@ -622,6 +642,14 @@ port_speed!N/A
|
|||
volume_info['id'] = self._find_unused_id(self._volumes_list)
|
||||
volume_info['uid'] = ('ABCDEF' * 3) + ('0' * 14) + volume_info['id']
|
||||
|
||||
mdiskgrp = kwargs['mdiskgrp'].strip('\'\"')
|
||||
if mdiskgrp == kwargs['mdiskgrp']:
|
||||
raise exception.InvalidInput(
|
||||
reason=_('mdiskgrp missing quotes %s') % kwargs['mdiskgrp'])
|
||||
mdiskgrp_id = self._get_mdiskgrp_id(mdiskgrp)
|
||||
volume_info['mdisk_grp_name'] = mdiskgrp
|
||||
volume_info['mdisk_grp_id'] = str(mdiskgrp_id)
|
||||
|
||||
if 'name' in kwargs:
|
||||
volume_info['name'] = kwargs['name'].strip('\'\"')
|
||||
else:
|
||||
|
@ -679,17 +707,12 @@ port_speed!N/A
|
|||
'status': 'online',
|
||||
'sync': 'yes',
|
||||
'primary': 'yes',
|
||||
'mdisk_grp_id': '1',
|
||||
'mdisk_grp_name': self._flags['storwize_svc_volpool_name'],
|
||||
'mdisk_grp_id': str(mdiskgrp_id),
|
||||
'mdisk_grp_name': mdiskgrp,
|
||||
'easy_tier': volume_info['easy_tier'],
|
||||
'compressed_copy': volume_info['compressed_copy']}
|
||||
volume_info['copies'] = {'0': vol_cp}
|
||||
|
||||
mdiskgrp = kwargs['mdiskgrp'].strip('\'\"')
|
||||
if mdiskgrp == kwargs['mdiskgrp']:
|
||||
raise exception.InvalidInput(
|
||||
reason=_('mdiskgrp missing quotes %s') % kwargs['mdiskgrp'])
|
||||
|
||||
if volume_info['name'] in self._volumes_list:
|
||||
return self._errors['CMMVC6035E']
|
||||
else:
|
||||
|
@ -775,13 +798,12 @@ port_speed!N/A
|
|||
rows.append([six.text_type(vol['id']), vol['name'],
|
||||
vol['IO_group_id'],
|
||||
vol['IO_group_name'], 'online', '0',
|
||||
self._flags['storwize_svc_volpool_name'],
|
||||
self._flags['storwize_svc_volpool_name'][0],
|
||||
cap, 'striped',
|
||||
fcmap_info['fc_id'], fcmap_info['fc_name'],
|
||||
'', '', vol['uid'],
|
||||
fcmap_info['fc_map_count'], '1', 'empty',
|
||||
'1', 'no'])
|
||||
|
||||
if 'obj' not in kwargs:
|
||||
return self._print_info_cmd(rows=rows, **kwargs)
|
||||
else:
|
||||
|
@ -1512,12 +1534,8 @@ port_speed!N/A
|
|||
copy_info['sync'] = 'no'
|
||||
copy_info['primary'] = 'no'
|
||||
copy_info['mdisk_grp_name'] = mdiskgrp
|
||||
if mdiskgrp == self._flags['storwize_svc_volpool_name']:
|
||||
copy_info['mdisk_grp_id'] = '1'
|
||||
elif mdiskgrp == 'openstack2':
|
||||
copy_info['mdisk_grp_id'] = '2'
|
||||
elif mdiskgrp == 'openstack3':
|
||||
copy_info['mdisk_grp_id'] = '3'
|
||||
copy_info['mdisk_grp_id'] = str(self._get_mdiskgrp_id(mdiskgrp))
|
||||
|
||||
if 'easytier' in kwargs:
|
||||
if kwargs['easytier'] == 'on':
|
||||
copy_info['easy_tier'] = 'on'
|
||||
|
@ -1778,7 +1796,7 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
|
|||
self._def_flags = {'san_ip': 'hostname',
|
||||
'san_login': 'user',
|
||||
'san_password': 'pass',
|
||||
'storwize_svc_volpool_name': 'openstack',
|
||||
'storwize_svc_volpool_name': ['openstack'],
|
||||
'storwize_svc_flashcopy_timeout': 20,
|
||||
'storwize_svc_flashcopy_rate': 49,
|
||||
'storwize_svc_multipath_enabled': False,
|
||||
|
@ -1792,7 +1810,7 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
|
|||
'host': 'storwize-svc-test',
|
||||
'wwpns': wwpns,
|
||||
'initiator': initiator}
|
||||
self.sim = StorwizeSVCManagementSimulator('openstack')
|
||||
self.sim = StorwizeSVCManagementSimulator(['openstack'])
|
||||
|
||||
self.iscsi_driver.set_fake_storage(self.sim)
|
||||
self.ctxt = context.get_admin_context()
|
||||
|
@ -1816,6 +1834,12 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
|
|||
self._set_flag(k, v)
|
||||
|
||||
def _create_volume(self, **kwargs):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
prop = {'host': 'openstack@svc#%s' % pool,
|
||||
'size': 1}
|
||||
for p in prop.keys():
|
||||
if p not in kwargs:
|
||||
kwargs[p] = prop[p]
|
||||
vol = testutils.create_volume(self.ctxt, **kwargs)
|
||||
self.iscsi_driver.create_volume(vol)
|
||||
return vol
|
||||
|
@ -1825,6 +1849,7 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
|
|||
self.db.volume_destroy(self.ctxt, volume['id'])
|
||||
|
||||
def _generate_vol_info(self, vol_name, vol_id):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
rand_id = six.text_type(random.randint(10000, 99999))
|
||||
if vol_name:
|
||||
return {'name': 'snap_volume%s' % rand_id,
|
||||
|
@ -1832,13 +1857,14 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
|
|||
'id': rand_id,
|
||||
'volume_id': vol_id,
|
||||
'volume_size': 10,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool}
|
||||
else:
|
||||
return {'name': 'test_volume%s' % rand_id,
|
||||
'size': 10,
|
||||
'id': rand_id,
|
||||
'volume_type_id': None,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
|
||||
def _assert_vol_exists(self, name, exists):
|
||||
is_vol_defined = self.iscsi_driver._helpers.is_vdisk_defined(name)
|
||||
|
@ -2106,7 +2132,8 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
|
|||
self._def_flags = {'san_ip': 'hostname',
|
||||
'san_login': 'user',
|
||||
'san_password': 'pass',
|
||||
'storwize_svc_volpool_name': 'openstack',
|
||||
'storwize_svc_volpool_name':
|
||||
['openstack', 'openstack1'],
|
||||
'storwize_svc_flashcopy_timeout': 20,
|
||||
'storwize_svc_flashcopy_rate': 49,
|
||||
'storwize_svc_multipath_enabled': False,
|
||||
|
@ -2120,7 +2147,8 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
|
|||
'host': 'storwize-svc-test',
|
||||
'wwpns': wwpns,
|
||||
'initiator': initiator}
|
||||
self.sim = StorwizeSVCManagementSimulator('openstack')
|
||||
self.sim = StorwizeSVCManagementSimulator(['openstack',
|
||||
'openstack1'])
|
||||
|
||||
self.fc_driver.set_fake_storage(self.sim)
|
||||
self.ctxt = context.get_admin_context()
|
||||
|
@ -2144,6 +2172,12 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
|
|||
self._set_flag(k, v)
|
||||
|
||||
def _create_volume(self, **kwargs):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
prop = {'host': 'openstack@svc#%s' % pool,
|
||||
'size': 1}
|
||||
for p in prop.keys():
|
||||
if p not in kwargs:
|
||||
kwargs[p] = prop[p]
|
||||
vol = testutils.create_volume(self.ctxt, **kwargs)
|
||||
self.fc_driver.create_volume(vol)
|
||||
return vol
|
||||
|
@ -2153,6 +2187,7 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
|
|||
self.db.volume_destroy(self.ctxt, volume['id'])
|
||||
|
||||
def _generate_vol_info(self, vol_name, vol_id):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
rand_id = six.text_type(random.randint(10000, 99999))
|
||||
if vol_name:
|
||||
return {'name': 'snap_volume%s' % rand_id,
|
||||
|
@ -2160,13 +2195,14 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
|
|||
'id': rand_id,
|
||||
'volume_id': vol_id,
|
||||
'volume_size': 10,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool}
|
||||
else:
|
||||
return {'name': 'test_volume%s' % rand_id,
|
||||
'size': 10,
|
||||
'id': '%s' % rand_id,
|
||||
'volume_type_id': None,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
|
||||
def _assert_vol_exists(self, name, exists):
|
||||
is_vol_defined = self.fc_driver._helpers.is_vdisk_defined(name)
|
||||
|
@ -2534,7 +2570,8 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
'storwize_san_secondary_ip': 'secondaryname',
|
||||
'san_login': 'user',
|
||||
'san_password': 'pass',
|
||||
'storwize_svc_volpool_name': 'openstack',
|
||||
'storwize_svc_volpool_name':
|
||||
['openstack', 'openstack1'],
|
||||
'storwize_svc_flashcopy_timeout': 20,
|
||||
'storwize_svc_flashcopy_rate': 49,
|
||||
'storwize_svc_allow_tenant_qos': True}
|
||||
|
@ -2547,7 +2584,8 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
'host': 'storwize-svc-test',
|
||||
'wwpns': wwpns,
|
||||
'initiator': initiator}
|
||||
self.sim = StorwizeSVCManagementSimulator('openstack')
|
||||
self.sim = StorwizeSVCManagementSimulator(['openstack',
|
||||
'openstack1'])
|
||||
|
||||
self.driver.set_fake_storage(self.sim)
|
||||
self.ctxt = context.get_admin_context()
|
||||
|
@ -2698,6 +2736,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
max_size=self._driver.configuration.ssh_max_pool_conn)
|
||||
|
||||
def _generate_vol_info(self, vol_name, vol_id):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
rand_id = six.text_type(random.randint(10000, 99999))
|
||||
if vol_name:
|
||||
return {'name': 'snap_volume%s' % rand_id,
|
||||
|
@ -2705,15 +2744,22 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
'id': rand_id,
|
||||
'volume_id': vol_id,
|
||||
'volume_size': 10,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool}
|
||||
else:
|
||||
return {'name': 'test_volume%s' % rand_id,
|
||||
'size': 10,
|
||||
'id': '%s' % rand_id,
|
||||
'volume_type_id': None,
|
||||
'mdisk_grp_name': 'openstack'}
|
||||
'mdisk_grp_name': pool,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
|
||||
def _create_volume(self, **kwargs):
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
prop = {'host': 'openstack@svc#%s' % pool,
|
||||
'size': 1}
|
||||
for p in prop.keys():
|
||||
if p not in kwargs:
|
||||
kwargs[p] = prop[p]
|
||||
vol = testutils.create_volume(self.ctxt, **kwargs)
|
||||
self.driver.create_volume(vol)
|
||||
return vol
|
||||
|
@ -3020,7 +3066,8 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
attributes = self.driver._helpers.get_vdisk_attributes(volume['name'])
|
||||
attr_size = float(attributes['capacity']) / units.Gi # bytes to GB
|
||||
self.assertEqual(attr_size, float(volume['size']))
|
||||
pool = self.driver.configuration.local_conf.storwize_svc_volpool_name
|
||||
pool =\
|
||||
self.driver.configuration.local_conf.storwize_svc_volpool_name[0]
|
||||
self.assertEqual(attributes['mdisk_grp_name'], pool)
|
||||
|
||||
# Try to create the volume again (should fail)
|
||||
|
@ -3106,10 +3153,12 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
self.driver.do_setup(None)
|
||||
|
||||
rand_id = random.randint(10000, 99999)
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
volume1 = {'name': u'unicode1_volume%s' % rand_id,
|
||||
'size': 2,
|
||||
'id': 1,
|
||||
'volume_type_id': None}
|
||||
'volume_type_id': None,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
self.driver.create_volume(volume1)
|
||||
self._assert_vol_exists(volume1['name'], True)
|
||||
|
||||
|
@ -3225,15 +3274,39 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
def test_storwize_svc_get_volume_stats(self):
|
||||
self._set_flag('reserved_percentage', 25)
|
||||
stats = self.driver.get_volume_stats()
|
||||
self.assertLessEqual(stats['free_capacity_gb'],
|
||||
stats['total_capacity_gb'])
|
||||
self.assertEqual(25, stats['reserved_percentage'])
|
||||
pool = self.driver.configuration.local_conf.storwize_svc_volpool_name
|
||||
for each_pool in stats['pools']:
|
||||
self.assertIn(each_pool['pool_name'],
|
||||
self._def_flags['storwize_svc_volpool_name'])
|
||||
self.assertLessEqual(each_pool['free_capacity_gb'],
|
||||
each_pool['total_capacity_gb'])
|
||||
self.assertLessEqual(each_pool['allocated_capacity_gb'],
|
||||
each_pool['total_capacity_gb'])
|
||||
self.assertEqual(25, each_pool['reserved_percentage'])
|
||||
if self.USESIM:
|
||||
expected = 'storwize-svc-sim_' + pool
|
||||
expected = 'storwize-svc-sim'
|
||||
self.assertEqual(expected, stats['volume_backend_name'])
|
||||
self.assertAlmostEqual(3328.0, stats['total_capacity_gb'])
|
||||
self.assertAlmostEqual(3287.5, stats['free_capacity_gb'])
|
||||
for each_pool in stats['pools']:
|
||||
self.assertIn(each_pool['pool_name'],
|
||||
self._def_flags['storwize_svc_volpool_name'])
|
||||
self.assertAlmostEqual(3328.0, each_pool['total_capacity_gb'])
|
||||
self.assertAlmostEqual(3287.5, each_pool['free_capacity_gb'])
|
||||
self.assertAlmostEqual(25.0,
|
||||
each_pool['allocated_capacity_gb'])
|
||||
|
||||
def test_get_pool(self):
|
||||
ctxt = testutils.get_test_admin_context()
|
||||
type_ref = volume_types.create(ctxt, 'testtype', None)
|
||||
volume = self._generate_vol_info(None, None)
|
||||
type_id = type_ref['id']
|
||||
type_ref = volume_types.get_volume_type(ctxt, type_id)
|
||||
volume['volume_type_id'] = type_id
|
||||
volume['volume_type'] = type_ref
|
||||
self.driver.create_volume(volume)
|
||||
self.assertEqual(volume['mdisk_grp_name'],
|
||||
self.driver.get_pool(volume))
|
||||
|
||||
self.driver.delete_volume(volume)
|
||||
volume_types.destroy(ctxt, type_ref['id'])
|
||||
|
||||
def test_storwize_svc_extend_volume(self):
|
||||
volume = self._create_volume()
|
||||
|
@ -3326,7 +3399,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
loc = ('StorwizeSVCDriver:' + self.driver._state['system_id'] +
|
||||
':openstack2')
|
||||
cap = {'location_info': loc, 'extent_size': '256'}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack2', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
volume = self._create_volume()
|
||||
volume['volume_type_id'] = None
|
||||
|
@ -3444,7 +3517,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
key_specs_old = {'easytier': False, 'warning': 2, 'autoexpand': True}
|
||||
|
@ -3458,7 +3531,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
volume = self._generate_vol_info(None, None)
|
||||
old_type = volume_types.get_volume_type(ctxt, old_type_ref['id'])
|
||||
volume['volume_type'] = old_type
|
||||
volume['host'] = host
|
||||
volume['host'] = 'openstack@svc#openstack'
|
||||
new_type = volume_types.get_volume_type(ctxt, new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
|
@ -3534,7 +3607,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
key_specs_old = {'iogrp': 0}
|
||||
|
@ -3548,7 +3621,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
volume = self._generate_vol_info(None, None)
|
||||
old_type = volume_types.get_volume_type(ctxt, old_type_ref['id'])
|
||||
volume['volume_type'] = old_type
|
||||
volume['host'] = host
|
||||
volume['host'] = 'openstack@svc#openstack'
|
||||
new_type = volume_types.get_volume_type(ctxt, new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
|
@ -3569,7 +3642,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
key_specs_old = {'compression': True, 'iogrp': 0}
|
||||
|
@ -3583,7 +3656,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
volume = self._generate_vol_info(None, None)
|
||||
old_type = volume_types.get_volume_type(ctxt, old_type_ref['id'])
|
||||
volume['volume_type'] = old_type
|
||||
volume['host'] = host
|
||||
volume['host'] = 'openstack@svc#openstack'
|
||||
new_type = volume_types.get_volume_type(ctxt, new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
|
@ -3688,7 +3761,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
ctxt = testutils.get_test_admin_context()
|
||||
volume = self._create_volume()
|
||||
driver = self.driver
|
||||
dest_pool = self.driver.configuration.storwize_svc_volpool_name
|
||||
dest_pool = volume_utils.extract_host(volume['host'], 'pool')
|
||||
new_ops = driver._helpers.add_vdisk_copy(volume['name'], dest_pool,
|
||||
None, self.driver._state,
|
||||
self.driver.configuration)
|
||||
|
@ -3864,7 +3937,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
disable_type = self._create_replication_volume_type(False)
|
||||
|
@ -3875,7 +3948,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
enable_type['id'])
|
||||
|
||||
volume = self._generate_vol_info(None, None)
|
||||
volume['host'] = host
|
||||
volume['host'] = 'openstack@svc#openstack'
|
||||
volume['volume_type_id'] = disable_type['id']
|
||||
volume['volume_type'] = disable_type
|
||||
volume['replication_status'] = None
|
||||
|
@ -3900,7 +3973,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'foo', 'capabilities': cap}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
volume = self._generate_vol_info(None, None)
|
||||
|
@ -3908,6 +3981,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
volume['volume_type'] = None
|
||||
volume['replication_status'] = "disabled"
|
||||
volume['replication_extended_status'] = None
|
||||
volume['host'] = 'openstack@svc#openstack'
|
||||
|
||||
# Create volume which is not volume replication
|
||||
model_update = self.driver.create_volume(volume)
|
||||
|
@ -4048,14 +4122,16 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
cg_type = self._create_consistency_group_volume_type()
|
||||
self.ctxt.user_id = 'fake_user_id'
|
||||
self.ctxt.project_id = 'fake_project_id'
|
||||
|
||||
pool = self._def_flags['storwize_svc_volpool_name'][0]
|
||||
# Create cg in db
|
||||
cg = self._create_consistencygroup_in_db(volume_type_id=cg_type['id'])
|
||||
# Create volumes in db
|
||||
testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
consistencygroup_id=cg['id'],
|
||||
host='openstack@svc#%s' % pool)
|
||||
testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
consistencygroup_id=cg['id'],
|
||||
host='openstack@svc#%s' % pool)
|
||||
volumes = (
|
||||
self.db.volume_get_all_by_group(self.ctxt.elevated(), cg['id']))
|
||||
|
||||
|
@ -4073,6 +4149,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
cgsnapshot, snapshots = self._create_cgsnapshot(source_cg['id'])
|
||||
|
||||
# Create cg from source cg
|
||||
|
||||
model_update, volumes_model_update = (
|
||||
self.driver.create_consistencygroup_from_src(self.ctxt,
|
||||
cg,
|
||||
|
@ -4336,7 +4413,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||
|
||||
new_volume['volume_type_id'] = type_thick_ref['id']
|
||||
no_exist_pool = 'i-dont-exist-%s' % random.randint(10000, 99999)
|
||||
self._set_flag('storwize_svc_volpool_name', no_exist_pool)
|
||||
new_volume['host'] = 'openstack@svc#%s' % no_exist_pool
|
||||
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
|
||||
self.driver.manage_existing, new_volume, ref)
|
||||
|
||||
|
@ -4654,13 +4731,15 @@ class StorwizeSVCReplicationMirrorTestCase(test.TestCase):
|
|||
self.svc_driver.replication_factory(self.rep_type, fake_target))
|
||||
self.ctxt = context.get_admin_context()
|
||||
rand_id = six.text_type(uuid.uuid4())
|
||||
pool = self.svc_driver.configuration.storwize_svc_volpool_name[0]
|
||||
self.volume = {'name': 'volume-%s' % rand_id,
|
||||
'size': 10, 'id': '%s' % rand_id,
|
||||
'volume_type_id': None,
|
||||
'mdisk_grp_name': 'openstack',
|
||||
'replication_status': 'disabled',
|
||||
'replication_extended_status': None,
|
||||
'volume_metadata': None}
|
||||
'volume_metadata': None,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': extra_spec_rep_type}
|
||||
type_ref = volume_types.create(self.ctxt, "replication", spec)
|
||||
|
@ -4731,13 +4810,15 @@ class StorwizeSVCReplicationMirrorTestCase(test.TestCase):
|
|||
get_vdisk_params.return_value = {'replication': None,
|
||||
'qos': None}
|
||||
rand_id = six.text_type(random.randint(10000, 99999))
|
||||
pool = self.svc_driver.configuration.storwize_svc_volpool_name[0]
|
||||
target_volume = {'name': 'test_volume%s' % rand_id,
|
||||
'size': 10, 'id': '%s' % rand_id,
|
||||
'volume_type_id': None,
|
||||
'mdisk_grp_name': 'openstack',
|
||||
'replication_status': 'disabled',
|
||||
'replication_extended_status': None,
|
||||
'volume_metadata': None}
|
||||
'volume_metadata': None,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
target_volume['volume_type_id'] = self.replication_type['id']
|
||||
target_volume['volume_type'] = self.replication_type
|
||||
model_update = self.svc_driver.create_cloned_volume(
|
||||
|
|
|
@ -52,9 +52,10 @@ DEFAULT_TIMEOUT = 15
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
storwize_svc_opts = [
|
||||
cfg.StrOpt('storwize_svc_volpool_name',
|
||||
default='volpool',
|
||||
help='Storage system storage pool for volumes'),
|
||||
cfg.ListOpt('storwize_svc_volpool_name',
|
||||
default=['volpool'],
|
||||
help='Comma separated list of storage system storage '
|
||||
'pools for volumes.'),
|
||||
cfg.IntOpt('storwize_svc_vol_rsize',
|
||||
default=2,
|
||||
min=-1, max=100,
|
||||
|
@ -1293,11 +1294,12 @@ class StorwizeHelpers(object):
|
|||
for source, target in zip(sources, targets):
|
||||
opts = self.get_vdisk_params(config, state,
|
||||
source['volume_type_id'])
|
||||
pool = utils.extract_host(target['host'], 'pool')
|
||||
self.create_flashcopy_to_consistgrp(source['name'],
|
||||
target['name'],
|
||||
fc_consistgrp,
|
||||
config, opts,
|
||||
True)
|
||||
True, pool=pool)
|
||||
self.prepare_fc_consistgrp(fc_consistgrp, timeout)
|
||||
self.start_fc_consistgrp(fc_consistgrp)
|
||||
self.delete_fc_consistgrp(fc_consistgrp)
|
||||
|
@ -1367,7 +1369,7 @@ class StorwizeHelpers(object):
|
|||
src_size = src_attrs['capacity']
|
||||
# In case we need to use a specific pool
|
||||
if not pool:
|
||||
pool = config.storwize_svc_volpool_name
|
||||
pool = src_attrs['mdisk_grp_name']
|
||||
self.create_vdisk(target, src_size, 'b', pool, opts)
|
||||
|
||||
self.ssh.mkfcmap(source, target, full_copy,
|
||||
|
@ -1554,7 +1556,7 @@ class StorwizeHelpers(object):
|
|||
src_size = src_attrs['capacity']
|
||||
# In case we need to use a specific pool
|
||||
if not pool:
|
||||
pool = config.storwize_svc_volpool_name
|
||||
pool = src_attrs['mdisk_grp_name']
|
||||
self.create_vdisk(tgt, src_size, 'b', pool, opts)
|
||||
timeout = config.storwize_svc_flashcopy_timeout
|
||||
try:
|
||||
|
@ -1898,12 +1900,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
self.replication = storwize_rep.StorwizeSVCReplication.factory(self)
|
||||
|
||||
# Validate that the pool exists
|
||||
pool = self.configuration.storwize_svc_volpool_name
|
||||
try:
|
||||
self._helpers.get_pool_attrs(pool)
|
||||
except exception.VolumeBackendAPIException:
|
||||
msg = _('Failed getting details for pool %s.') % pool
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
self._validate_pools_exist()
|
||||
|
||||
# Check if compression is supported
|
||||
self._state['compression_enabled'] = (self._helpers.
|
||||
|
@ -1940,6 +1937,16 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
# v2 replication setup
|
||||
self._do_replication_setup()
|
||||
|
||||
def _validate_pools_exist(self):
|
||||
# Validate that the pool exists
|
||||
pools = self.configuration.storwize_svc_volpool_name
|
||||
for pool in pools:
|
||||
try:
|
||||
self._helpers.get_pool_attrs(pool)
|
||||
except exception.VolumeBackendAPIException:
|
||||
msg = _('Failed getting details for pool %s.') % pool
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
def check_for_setup_error(self):
|
||||
"""Ensure that the flags are set properly."""
|
||||
LOG.debug('enter: check_for_setup_error')
|
||||
|
@ -2096,7 +2103,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
opts = self._get_vdisk_params(volume['volume_type_id'],
|
||||
volume_metadata=
|
||||
volume.get('volume_metadata'))
|
||||
pool = self.configuration.storwize_svc_volpool_name
|
||||
pool = utils.extract_host(volume['host'], 'pool')
|
||||
self._helpers.create_vdisk(volume['name'], str(volume['size']),
|
||||
'gb', pool, opts)
|
||||
if opts['qos']:
|
||||
|
@ -2142,10 +2149,11 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
msg = (_('create_snapshot: get source volume failed.'))
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
pool = utils.extract_host(source_vol['host'], 'pool')
|
||||
opts = self._get_vdisk_params(source_vol['volume_type_id'])
|
||||
self._helpers.create_copy(snapshot['volume_name'], snapshot['name'],
|
||||
snapshot['volume_id'], self.configuration,
|
||||
opts, False)
|
||||
opts, False, pool=pool)
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
self._helpers.delete_vdisk(snapshot['name'], False)
|
||||
|
@ -2160,9 +2168,10 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
opts = self._get_vdisk_params(volume['volume_type_id'],
|
||||
volume_metadata=
|
||||
volume.get('volume_metadata'))
|
||||
pool = utils.extract_host(volume['host'], 'pool')
|
||||
self._helpers.create_copy(snapshot['name'], volume['name'],
|
||||
snapshot['id'], self.configuration,
|
||||
opts, True)
|
||||
opts, True, pool=pool)
|
||||
if opts['qos']:
|
||||
self._helpers.add_vdisk_qos(volume['name'], opts['qos'])
|
||||
|
||||
|
@ -2190,9 +2199,10 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
opts = self._get_vdisk_params(tgt_volume['volume_type_id'],
|
||||
volume_metadata=
|
||||
tgt_volume.get('volume_metadata'))
|
||||
pool = utils.extract_host(tgt_volume['host'], 'pool')
|
||||
self._helpers.create_copy(src_volume['name'], tgt_volume['name'],
|
||||
src_volume['id'], self.configuration,
|
||||
opts, True)
|
||||
opts, True, pool=pool)
|
||||
if opts['qos']:
|
||||
self._helpers.add_vdisk_qos(tgt_volume['name'], opts['qos'])
|
||||
|
||||
|
@ -2626,8 +2636,8 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
elif key in no_copy_keys:
|
||||
vdisk_changes.append(key)
|
||||
|
||||
dest_location = host['capabilities'].get('location_info')
|
||||
if self._stats['location_info'] != dest_location:
|
||||
if (utils.extract_host(volume['host'], 'pool') !=
|
||||
utils.extract_host(host['host'], 'pool')):
|
||||
need_copy = True
|
||||
|
||||
if need_copy:
|
||||
|
@ -2772,9 +2782,8 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
{'vdisk_iogrp': vdisk['IO_group_name'],
|
||||
'opt_iogrp': opts['iogrp']})
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
if (vdisk['mdisk_grp_name'] !=
|
||||
self.configuration.storwize_svc_volpool_name):
|
||||
pool = utils.extract_host(volume['host'], 'pool')
|
||||
if vdisk['mdisk_grp_name'] != pool:
|
||||
msg = (_("Failed to manage existing volume due to the "
|
||||
"pool of the volume to be managed does not "
|
||||
"match the backend pool. Pool of the "
|
||||
|
@ -2944,6 +2953,17 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
|
||||
return model_update, snapshots_model
|
||||
|
||||
def get_pool(self, volume):
|
||||
attr = self._helpers.get_vdisk_attributes(volume['name'])
|
||||
|
||||
if attr is None:
|
||||
msg = (_('get_pool: Failed to get attributes for volume '
|
||||
'%s') % volume['name'])
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
return attr['mdisk_grp_name']
|
||||
|
||||
def _update_volume_stats(self):
|
||||
"""Retrieve stats info from volume group."""
|
||||
|
||||
|
@ -2953,47 +2973,64 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||
data['vendor_name'] = 'IBM'
|
||||
data['driver_version'] = self.VERSION
|
||||
data['storage_protocol'] = self.protocol
|
||||
data['pools'] = []
|
||||
|
||||
data['total_capacity_gb'] = 0 # To be overwritten
|
||||
data['free_capacity_gb'] = 0 # To be overwritten
|
||||
data['reserved_percentage'] = self.configuration.reserved_percentage
|
||||
data['multiattach'] = (self.configuration.
|
||||
storwize_svc_multihostmap_enabled)
|
||||
data['QoS_support'] = True
|
||||
data['consistencygroup_support'] = True
|
||||
|
||||
pool = self.configuration.storwize_svc_volpool_name
|
||||
backend_name = self.configuration.safe_get('volume_backend_name')
|
||||
if not backend_name:
|
||||
backend_name = '%s_%s' % (self._state['system_name'], pool)
|
||||
data['volume_backend_name'] = backend_name
|
||||
|
||||
attributes = self._helpers.get_pool_attrs(pool)
|
||||
if not attributes:
|
||||
LOG.error(_LE('Could not get pool data from the storage.'))
|
||||
exception_message = (_('_update_volume_stats: '
|
||||
'Could not get storage pool data.'))
|
||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||
|
||||
data['total_capacity_gb'] = (float(attributes['capacity']) /
|
||||
units.Gi)
|
||||
data['free_capacity_gb'] = (float(attributes['free_capacity']) /
|
||||
units.Gi)
|
||||
data['easytier_support'] = attributes['easy_tier'] in ['on', 'auto']
|
||||
data['compression_support'] = self._state['compression_enabled']
|
||||
data['location_info'] = ('StorwizeSVCDriver:%(sys_id)s:%(pool)s' %
|
||||
{'sys_id': self._state['system_id'],
|
||||
'pool': pool})
|
||||
|
||||
if self._replication_enabled:
|
||||
data['replication_enabled'] = self._replication_enabled
|
||||
data['replication_type'] = self._supported_replication_types
|
||||
data['replication_count'] = len(self._replication_targets)
|
||||
elif self.replication:
|
||||
data.update(self.replication.get_replication_info())
|
||||
data['volume_backend_name'] = (backend_name or
|
||||
self._state['system_name'])
|
||||
|
||||
data['pools'] = [self._build_pool_stats(pool)
|
||||
for pool in
|
||||
self.configuration.storwize_svc_volpool_name]
|
||||
self._stats = data
|
||||
|
||||
def _build_pool_stats(self, pool):
|
||||
"""Build pool status"""
|
||||
QoS_support = True
|
||||
pool_stats = {}
|
||||
try:
|
||||
pool_data = self._helpers.get_pool_attrs(pool)
|
||||
if pool_data:
|
||||
easy_tier = pool_data['easy_tier'] in ['on', 'auto']
|
||||
total_capacity_gb = float(pool_data['capacity']) / units.Gi
|
||||
free_capacity_gb = float(pool_data['free_capacity']) / units.Gi
|
||||
allocated_capacity_gb = (float(pool_data['used_capacity']) /
|
||||
units.Gi)
|
||||
location_info = ('StorwizeSVCDriver:%(sys_id)s:%(pool)s' %
|
||||
{'sys_id': self._state['system_id'],
|
||||
'pool': pool_data['name']})
|
||||
pool_stats = {
|
||||
'pool_name': pool_data['name'],
|
||||
'total_capacity_gb': total_capacity_gb,
|
||||
'free_capacity_gb': free_capacity_gb,
|
||||
'allocated_capacity_gb': allocated_capacity_gb,
|
||||
'easytier_support': easy_tier,
|
||||
'compression_support': self._state['compression_enabled'],
|
||||
'reserved_percentage':
|
||||
self.configuration.reserved_percentage,
|
||||
'QoS_support': QoS_support,
|
||||
'consistencygroup_support': True,
|
||||
'location_info': location_info,
|
||||
'easytier_support': easy_tier
|
||||
}
|
||||
if self._replication_enabled:
|
||||
pool_stats.update({
|
||||
'replication_enabled': self._replication_enabled,
|
||||
'replication_type': self._supported_replication_types,
|
||||
'replication_count': len(self._replication_targets)
|
||||
})
|
||||
elif self.replication:
|
||||
pool_stats.update(self.replication.get_replication_info())
|
||||
|
||||
except exception.VolumeBackendAPIException:
|
||||
msg = _('Failed getting details for pool %s.') % pool
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
return pool_stats
|
||||
|
||||
def _manage_input_check(self, ref):
|
||||
"""Verify the input of manage function."""
|
||||
# Check that the reference is valid
|
||||
|
|
|
@ -79,9 +79,10 @@ class StorwizeSVCFCDriver(storwize_common.StorwizeSVCCommonDriver):
|
|||
1.3.3 - Update driver to use ABC metaclasses
|
||||
2.0 - Code refactor, split init file and placed shared methods for
|
||||
FC and iSCSI within the StorwizeSVCCommonDriver class
|
||||
2.0.1 - Added support for multiple pools with model update
|
||||
"""
|
||||
|
||||
VERSION = "2.0"
|
||||
VERSION = "2.0.1"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(StorwizeSVCFCDriver, self).__init__(*args, **kwargs)
|
||||
|
|
|
@ -79,9 +79,10 @@ class StorwizeSVCISCSIDriver(storwize_common.StorwizeSVCCommonDriver):
|
|||
1.3.3 - Update driver to use ABC metaclasses
|
||||
2.0 - Code refactor, split init file and placed shared methods for
|
||||
FC and iSCSI within the StorwizeSVCCommonDriver class
|
||||
2.0.1 - Added support for multiple pools with model update
|
||||
"""
|
||||
|
||||
VERSION = "2.0"
|
||||
VERSION = "2.0.1"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(StorwizeSVCISCSIDriver, self).__init__(*args, **kwargs)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
features:
|
||||
- Add multiple pools support to Storwize SVC driver.
|
Loading…
Reference in New Issue