Merge "3PAR: Fixed image cache enabled capability."
This commit is contained in:
@@ -1458,6 +1458,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_not_3par(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
|
||||
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||
'_create_client') as mock_create_client:
|
||||
@@ -1470,7 +1471,8 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_DIFF,
|
||||
self.RETYPE_HOST_NOT3PAR)
|
||||
|
||||
expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
mock_client.assert_has_calls(
|
||||
self.standard_login +
|
||||
expected +
|
||||
@@ -1480,6 +1482,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_volume_not_found(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
mock_client.getVolume.side_effect = hpeexceptions.HTTPNotFound
|
||||
|
||||
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||
@@ -1493,7 +1496,8 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_DIFF,
|
||||
self.RETYPE_HOST)
|
||||
|
||||
expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
mock_client.assert_has_calls(
|
||||
self.standard_login +
|
||||
expected +
|
||||
@@ -1571,6 +1575,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_different_array(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
|
||||
mock_client.getStorageSystemInfo.return_value = {
|
||||
'id': self.CLIENT_ID,
|
||||
@@ -1588,6 +1593,7 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_HOST)
|
||||
|
||||
expected = [
|
||||
mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getStorageSystemInfo()]
|
||||
|
||||
@@ -1600,6 +1606,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_across_cpg_domains(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
|
||||
mock_client.getCPG.side_effect = [
|
||||
{'domain': 'domain1'},
|
||||
@@ -1618,6 +1625,7 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_HOST)
|
||||
|
||||
expected = [
|
||||
mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getStorageSystemInfo(),
|
||||
mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
|
||||
@@ -1633,6 +1641,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_across_snap_cpg_domains(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
|
||||
mock_client.getCPG.side_effect = [
|
||||
{'domain': 'cpg_domain'},
|
||||
@@ -1652,6 +1661,7 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_HOST)
|
||||
|
||||
expected = [
|
||||
mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getStorageSystemInfo(),
|
||||
mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
|
||||
@@ -1669,6 +1679,7 @@ class HPE3PARBaseDriver(object):
|
||||
def test_retype_to_bad_persona(self, _mock_volume_types):
|
||||
_mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_BAD_PERSONA
|
||||
mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
|
||||
mock_client.getVolumeSnapshots.return_value = []
|
||||
|
||||
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||
'_create_client') as mock_create_client:
|
||||
@@ -1681,7 +1692,8 @@ class HPE3PARBaseDriver(object):
|
||||
self.RETYPE_DIFF,
|
||||
self.RETYPE_HOST)
|
||||
|
||||
expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME)]
|
||||
mock_client.assert_has_calls(
|
||||
self.standard_login +
|
||||
expected +
|
||||
@@ -2270,12 +2282,19 @@ class HPE3PARBaseDriver(object):
|
||||
'size': 2, 'status': 'available'}
|
||||
model_update = self.driver.create_cloned_volume(volume, src_vref)
|
||||
self.assertIsNone(model_update)
|
||||
common = hpecommon.HPE3PARCommon(None)
|
||||
vol_name = common._get_3par_vol_name(src_vref['id'])
|
||||
# snapshot name is random
|
||||
snap_name = mock.ANY
|
||||
optional = mock.ANY
|
||||
expectedcall = [
|
||||
mock.call.getStorageSystemInfo()]
|
||||
|
||||
expected = [
|
||||
mock.call.createSnapshot(snap_name, vol_name, optional),
|
||||
mock.call.getVolume(snap_name),
|
||||
mock.call.copyVolume(
|
||||
self.VOLUME_NAME_3PAR,
|
||||
snap_name,
|
||||
'osv-0DM4qZEVSKON-AAAAAAAAA',
|
||||
HPE3PAR_CPG2,
|
||||
{'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
|
||||
@@ -2293,14 +2312,14 @@ class HPE3PARBaseDriver(object):
|
||||
def test_clone_volume_with_vvs(self, _mock_volume_types):
|
||||
# Setup_mock_client drive with default configuration
|
||||
# and return the mock HTTP 3PAR client
|
||||
mock_client = self.setup_driver()
|
||||
conf = self.setup_configuration()
|
||||
mock_client = self.setup_driver(config=conf)
|
||||
|
||||
_mock_volume_types.return_value = {
|
||||
'name': 'gold',
|
||||
'id': 'gold-id',
|
||||
'extra_specs': {'vvs': self.VVS_NAME}}
|
||||
|
||||
mock_client = self.setup_driver()
|
||||
mock_client.getVolume.return_value = {'name': mock.ANY}
|
||||
mock_client.copyVolume.return_value = {'taskid': 1}
|
||||
|
||||
@@ -2323,6 +2342,11 @@ class HPE3PARBaseDriver(object):
|
||||
'volume_type': 'gold',
|
||||
'host': self.FAKE_CINDER_HOST,
|
||||
'volume_type_id': 'gold-id'}
|
||||
# creation of the temp snapshot
|
||||
common = hpecommon.HPE3PARCommon(conf)
|
||||
snap_name = mock.ANY
|
||||
vol_name = common._get_3par_vol_name(src_vref['id'])
|
||||
optional = mock.ANY
|
||||
|
||||
model_update = self.driver.create_cloned_volume(volume_vvs,
|
||||
src_vref)
|
||||
@@ -2334,8 +2358,10 @@ class HPE3PARBaseDriver(object):
|
||||
self.assertEqual(clone_vol_vvs, source_vol_vvs)
|
||||
|
||||
expected = [
|
||||
mock.call.createSnapshot(snap_name, vol_name, optional),
|
||||
mock.call.getVolume(snap_name),
|
||||
mock.call.copyVolume(
|
||||
self.VOLUME_NAME_3PAR,
|
||||
snap_name,
|
||||
'osv-0DM4qZEVSKON-AAAAAAAAA',
|
||||
'OpenStackCPG',
|
||||
{'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
|
||||
@@ -2372,10 +2398,17 @@ class HPE3PARBaseDriver(object):
|
||||
'size': 2, 'status': 'backing-up'}
|
||||
model_update = self.driver.create_cloned_volume(volume, src_vref)
|
||||
self.assertIsNone(model_update)
|
||||
# creation of the temp snapshot
|
||||
common = hpecommon.HPE3PARCommon(None)
|
||||
snap_name = mock.ANY
|
||||
vol_name = common._get_3par_vol_name(src_vref['id'])
|
||||
optional = mock.ANY
|
||||
|
||||
expected = [
|
||||
mock.call.createSnapshot(snap_name, vol_name, optional),
|
||||
mock.call.getVolume(snap_name),
|
||||
mock.call.copyVolume(
|
||||
self.VOLUME_NAME_3PAR,
|
||||
snap_name,
|
||||
'osv-0DM4qZEVSKON-AAAAAAAAA',
|
||||
HPE3PAR_CPG2,
|
||||
{'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
|
||||
@@ -2413,13 +2446,17 @@ class HPE3PARBaseDriver(object):
|
||||
self.assertIsNone(model_update)
|
||||
|
||||
common = hpecommon.HPE3PARCommon(None)
|
||||
snap_name = mock.ANY
|
||||
vol_name = common._get_3par_vol_name(src_vref['id'])
|
||||
optional = mock.ANY
|
||||
|
||||
expected = [
|
||||
mock.call.getVolumeMetaData(vol_name,
|
||||
'HPQ-cinder-CHAP-name'),
|
||||
mock.call.createSnapshot(snap_name, vol_name, optional),
|
||||
mock.call.getVolume(snap_name),
|
||||
mock.call.copyVolume(
|
||||
self.VOLUME_NAME_3PAR,
|
||||
snap_name,
|
||||
'osv-0DM4qZEVSKON-AAAAAAAAA',
|
||||
HPE3PAR_CPG2,
|
||||
{'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
|
||||
@@ -2553,11 +2590,18 @@ class HPE3PARBaseDriver(object):
|
||||
volume['source_volid'] = HPE3PARBaseDriver.CLONE_ID
|
||||
model_update = self.driver.create_cloned_volume(volume, src_vref)
|
||||
self.assertIsNone(model_update)
|
||||
# creation of the temp snapshot
|
||||
common = hpecommon.HPE3PARCommon(None)
|
||||
snap_name = mock.ANY
|
||||
vol_name = common._get_3par_vol_name(src_vref['id'])
|
||||
optional = mock.ANY
|
||||
|
||||
expected = [
|
||||
mock.call.getCPG(expected_cpg),
|
||||
mock.call.createSnapshot(snap_name, vol_name, optional),
|
||||
mock.call.getVolume(snap_name),
|
||||
mock.call.copyVolume(
|
||||
'osv-0DM4qZEVSKON-AAAAAAAAA',
|
||||
snap_name,
|
||||
self.VOLUME_3PAR_NAME,
|
||||
expected_cpg,
|
||||
{'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
|
||||
|
@@ -261,10 +261,12 @@ class HPE3PARCommon(object):
|
||||
3.0.34 - Add cloned volume to vvset in online copy. bug #1664464
|
||||
3.0.35 - Add volume to consistency group if flag enabled. bug #1702317
|
||||
3.0.36 - Swap volume name in migration. bug #1699733
|
||||
3.0.37 - Fixed image cache enabled capability. bug #1686985
|
||||
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "3.0.36"
|
||||
VERSION = "3.0.37"
|
||||
|
||||
stats = {}
|
||||
|
||||
@@ -2151,6 +2153,7 @@ class HPE3PARCommon(object):
|
||||
LOG.debug("Creating a clone of volume, using online copy.")
|
||||
|
||||
type_info = self.get_volume_settings_from_type(volume)
|
||||
snapshot = self._create_temp_snapshot(src_vref)
|
||||
cpg = type_info['cpg']
|
||||
qos = type_info['qos']
|
||||
vvs_name = type_info['vvs_name']
|
||||
@@ -2161,7 +2164,7 @@ class HPE3PARCommon(object):
|
||||
type_info['hpe3par_keys'])
|
||||
# make the 3PAR copy the contents.
|
||||
# can't delete the original until the copy is done.
|
||||
self._copy_volume(src_vol_name, vol_name, cpg=cpg,
|
||||
self._copy_volume(snapshot['name'], vol_name, cpg=cpg,
|
||||
snap_cpg=type_info['snap_cpg'],
|
||||
tpvv=type_info['tpvv'],
|
||||
tdvv=type_info['tdvv'],
|
||||
@@ -3054,10 +3057,32 @@ class HPE3PARCommon(object):
|
||||
'new_type': new_type,
|
||||
'diff': diff,
|
||||
'host': host})
|
||||
self.remove_temporary_snapshots(volume)
|
||||
old_volume_settings = self.get_volume_settings_from_type(volume, host)
|
||||
return self._retype_from_old_to_new(volume, new_type,
|
||||
old_volume_settings, host)
|
||||
|
||||
def remove_temporary_snapshots(self, volume):
|
||||
vol_name = self._get_3par_vol_name(volume['id'])
|
||||
snapshots_list = self.client.getVolumeSnapshots(vol_name)
|
||||
tmp_snapshots_list = [snap
|
||||
for snap in snapshots_list
|
||||
if snap.startswith('tss-')]
|
||||
LOG.debug("temporary snapshot list %(name)s",
|
||||
{'name': tmp_snapshots_list})
|
||||
for temp_snap in tmp_snapshots_list:
|
||||
LOG.debug("Found a temporary snapshot %(name)s",
|
||||
{'name': temp_snap})
|
||||
try:
|
||||
self.client.deleteVolume(temp_snap)
|
||||
except hpeexceptions.HTTPNotFound:
|
||||
# if the volume is gone, it's as good as a
|
||||
# successful delete
|
||||
pass
|
||||
except Exception:
|
||||
msg = _("Volume has a temporary snapshot.")
|
||||
raise exception.VolumeIsBusy(message=msg)
|
||||
|
||||
def find_existing_vlun(self, volume, host):
|
||||
"""Finds an existing VLUN for a volume on a host.
|
||||
|
||||
|
Reference in New Issue
Block a user