From 105e625328a3ead1fb9b788e54e81a9b5d9af5ab Mon Sep 17 00:00:00 2001 From: Shay Halsband Date: Sun, 13 Mar 2016 16:56:30 +0200 Subject: [PATCH] XtremIO: allow a cloned volume with larger size * In case the new volume is larger than the cloned one, resize the cloned volume. * Added unit test for success and failed resize. Co-Authored-By: Xinli Guan Change-Id: I2346049c2177a9497750c05c0eb9e7edf8c12c22 Closes-Bug: #1554778 --- .../volume/drivers/dell_emc/test_xtremio.py | 46 +++++++++++++++++++ cinder/volume/drivers/dell_emc/xtremio.py | 11 +++++ 2 files changed, 57 insertions(+) diff --git a/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py b/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py index f1b1f8ac13b..06b908d92d2 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py @@ -525,6 +525,52 @@ class XtremIODriverISCSITestCase(BaseXtremIODriverTestCase): 'provider_location': fake_provider}, update) + def test_clone_volume_and_resize(self, req): + req.side_effect = xms_request + self.driver.db = mock.Mock() + (self.driver.db. + image_volume_cache_get_by_volume_id.return_value) = mock.MagicMock() + self.driver.create_volume(self.data.test_volume) + vol = xms_data['volumes'][1] + vol['num-of-dest-snaps'] = 0 + clone = self.data.test_clone.copy() + clone['size'] = 2 + with mock.patch.object(self.driver, + 'extend_volume') as extend: + self.driver.create_cloned_volume(clone, self.data.test_volume) + extend.assert_called_once_with(clone, clone['size']) + + def test_clone_volume_and_resize_fail(self, req): + req.side_effect = xms_request + self.driver.create_volume(self.data.test_volume) + vol = xms_data['volumes'][1] + + def failed_extend(obj_type='volumes', method='GET', data=None, + *args, **kwargs): + if method == 'GET': + return {'content': vol} + elif method == 'POST': + return {'links': [{'href': 'volume/2'}]} + elif method == 'PUT': + if 'name' in data: + return + raise exception.VolumeBackendAPIException('Failed Clone') + + req.side_effect = failed_extend + self.driver.db = mock.Mock() + (self.driver.db. + image_volume_cache_get_by_volume_id.return_value) = mock.MagicMock() + vol['num-of-dest-snaps'] = 0 + clone = self.data.test_clone.copy() + clone['size'] = 2 + with mock.patch.object(self.driver, + 'delete_volume') as delete: + self.assertRaises(exception.VolumeBackendAPIException, + self.driver.create_cloned_volume, + clone, + self.data.test_volume) + self.assertTrue(delete.called) + # ##### Connection ##### def test_no_portals_configured(self, req): req.side_effect = xms_request diff --git a/cinder/volume/drivers/dell_emc/xtremio.py b/cinder/volume/drivers/dell_emc/xtremio.py index 3afdaa25b8d..dd57d6cb964 100644 --- a/cinder/volume/drivers/dell_emc/xtremio.py +++ b/cinder/volume/drivers/dell_emc/xtremio.py @@ -460,6 +460,17 @@ class XtremIOVolumeDriver(san.SanDriver): except exception.XtremIOSnapshotsLimitExceeded as e: raise exception.CinderException(e.message) + # extend the snapped volume if requested size is larger then original + if volume['size'] > src_vref['size']: + try: + self.extend_volume(volume, volume['size']) + except Exception: + LOG.error(_LE('failes to extend volume %s, ' + 'reverting clone operation'), volume['id']) + # remove the volume in case resize failed + self.delete_volume(volume) + raise + if volume.get('consistencygroup_id') and self.client is XtremIOClient4: self.client.add_vol_to_cg(volume['id'], volume['consistencygroup_id'])