From 2da949da1f79a0121d75c50eecdd102382287bda Mon Sep 17 00:00:00 2001 From: Yong Huang Date: Thu, 21 Jun 2018 07:47:40 +0000 Subject: [PATCH] [Unity] Compressed volume support Support operations are: Create/delete/clone/extend/attach/detach compressed volumes Change-Id: I43d840875ebb99744d23d87482603e34551c3882 Implements: blueprint unity-compressed-volume-support --- .../drivers/dell_emc/unity/test_adapter.py | 13 +++++++- .../drivers/dell_emc/unity/test_client.py | 3 +- .../volume/drivers/dell_emc/unity/adapter.py | 31 ++++++++++++++++--- .../volume/drivers/dell_emc/unity/client.py | 7 +++-- .../volume/drivers/dell_emc/unity/driver.py | 3 +- .../drivers/dell-emc-unity-driver.rst | 16 ++++++++++ ...essed-volume-support-4998dee84534a324.yaml | 4 +++ 7 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/unity-compressed-volume-support-4998dee84534a324.yaml diff --git a/cinder/tests/unit/volume/drivers/dell_emc/unity/test_adapter.py b/cinder/tests/unit/volume/drivers/dell_emc/unity/test_adapter.py index 6a7b0eeb7bd..ae84079ae78 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/unity/test_adapter.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/unity/test_adapter.py @@ -79,7 +79,7 @@ class MockClient(object): @staticmethod def create_lun(name, size, pool, description=None, io_limit_policy=None, - is_thin=None): + is_thin=None, is_compressed=None): lun_id = name if is_thin is not None and not is_thin: lun_id += '_thick' @@ -391,6 +391,16 @@ class CommonAdapterTest(test.TestCase): expected = get_lun_pl('lun_3_thick') self.assertEqual(expected, ret['provider_location']) + @patch_for_unity_adapter + def test_create_compressed_volume(self): + volume_type = MockOSResource( + extra_specs={'compression_support': ' True'}) + volume = MockOSResource(name='lun_3', size=5, host='unity#pool1', + volume_type=volume_type) + ret = self.adapter.create_volume(volume) + expected = get_lun_pl('lun_3') + self.assertEqual(expected, ret['provider_location']) + def test_create_snapshot(self): volume = MockOSResource(provider_location='id^lun_43') snap = MockOSResource(volume=volume, name='abc-def_snap') @@ -431,6 +441,7 @@ class CommonAdapterTest(test.TestCase): self.assertEqual(5, stats['reserved_percentage']) self.assertTrue(stats['thick_provisioning_support']) self.assertTrue(stats['thin_provisioning_support']) + self.assertTrue(stats['compression_support']) def test_update_volume_stats(self): stats = self.adapter.update_volume_stats() diff --git a/cinder/tests/unit/volume/drivers/dell_emc/unity/test_client.py b/cinder/tests/unit/volume/drivers/dell_emc/unity/test_client.py index fb06b61bb94..8fc03b52807 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/unity/test_client.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/unity/test_client.py @@ -49,6 +49,7 @@ class MockResource(object): self._storage_resource = None self.host_cache = [] self.is_thin = None + self.is_all_flash = True @property def id(self): @@ -113,7 +114,7 @@ class MockResource(object): @staticmethod def create_lun(lun_name, size_gb, description=None, io_limit_policy=None, - is_thin=None): + is_thin=None, is_compression=None): if lun_name == 'in_use': raise ex.UnityLunNameInUseError() ret = MockResource(lun_name, 'lun_2') diff --git a/cinder/volume/drivers/dell_emc/unity/adapter.py b/cinder/volume/drivers/dell_emc/unity/adapter.py index c64ed0542d9..5b958c59cdf 100644 --- a/cinder/volume/drivers/dell_emc/unity/adapter.py +++ b/cinder/volume/drivers/dell_emc/unity/adapter.py @@ -58,6 +58,7 @@ class VolumeParams(object): self._pool = None self._io_limit_policy = None self._is_thick = None + self._is_compressed = None @property def volume_id(self): @@ -118,12 +119,27 @@ class VolumeParams(object): self._is_thick = (provision == 'thick' and support == ' True') return self._is_thick + @property + def is_compressed(self): + if self._is_compressed is None: + provision = utils.get_extra_spec(self._volume, 'provisioning:type') + compression = utils.get_extra_spec(self._volume, + 'compression_support') + if provision == 'compressed' and compression == ' True': + self._is_compressed = True + return self._is_compressed + + @is_compressed.setter + def is_compressed(self, value): + self._is_compressed = value + def __eq__(self, other): return (self.volume_id == other.volume_id and self.name == other.name and self.size == other.size and self.io_limit_policy == other.io_limit_policy and - self.is_thick == other.is_thick) + self.is_thick == other.is_thick and + self.is_compressed == other.is_compressed) class CommonAdapter(object): @@ -285,12 +301,14 @@ class CommonAdapter(object): 'description': params.description, 'pool': params.pool, 'io_limit_policy': params.io_limit_policy, - 'is_thick': params.is_thick + 'is_thick': params.is_thick, + 'is_compressed': params.is_compressed } LOG.info('Create Volume: %(name)s, size: %(size)s, description: ' '%(description)s, pool: %(pool)s, io limit policy: ' - '%(io_limit_policy)s, thick: %(is_thick)s.', log_params) + '%(io_limit_policy)s, thick: %(is_thick)s, ' + '%(is_compressed)s.', log_params) return self.makeup_model( self.client.create_lun(name=params.name, @@ -298,7 +316,8 @@ class CommonAdapter(object): pool=params.pool, description=params.description, io_limit_policy=params.io_limit_policy, - is_thin=False if params.is_thick else None)) + is_thin=False if params.is_thick else None, + is_compressed=params.is_compressed)) def delete_volume(self, volume): lun_id = self.get_lun_id(volume) @@ -442,6 +461,7 @@ class CommonAdapter(object): 'array_serial': self.serial_number}), 'thin_provisioning_support': True, 'thick_provisioning_support': True, + 'compression_support': pool.is_all_flash, 'max_over_subscription_ratio': ( self.max_over_subscription_ratio)} @@ -597,7 +617,8 @@ class CommonAdapter(object): name=vol_params.name, size=vol_params.size, pool=vol_params.pool, description=vol_params.description, io_limit_policy=vol_params.io_limit_policy, - is_thin=False if vol_params.is_thick else None) + is_thin=False if vol_params.is_thick else None, + is_compressed=vol_params.is_compressed) src_id = src_snap.get_id() try: conn_props = cinder_utils.brick_get_connector_properties() diff --git a/cinder/volume/drivers/dell_emc/unity/client.py b/cinder/volume/drivers/dell_emc/unity/client.py index 21e3f087d1d..8ecba335de1 100644 --- a/cinder/volume/drivers/dell_emc/unity/client.py +++ b/cinder/volume/drivers/dell_emc/unity/client.py @@ -57,7 +57,8 @@ class UnityClient(object): return self.system.serial_number def create_lun(self, name, size, pool, description=None, - io_limit_policy=None, is_thin=None): + io_limit_policy=None, is_thin=None, + is_compressed=None): """Creates LUN on the Unity system. :param name: lun name @@ -66,13 +67,15 @@ class UnityClient(object): :param description: lun description :param io_limit_policy: io limit on the LUN :param is_thin: if False, a thick LUN will be created + :param is_compressed: is compressed LUN enabled :return: UnityLun object """ try: lun = pool.create_lun(lun_name=name, size_gb=size, description=description, io_limit_policy=io_limit_policy, - is_thin=is_thin) + is_thin=is_thin, + is_compression=is_compressed) except storops_ex.UnityLunNameInUseError: LOG.debug("LUN %s already exists. Return the existing one.", name) diff --git a/cinder/volume/drivers/dell_emc/unity/driver.py b/cinder/volume/drivers/dell_emc/unity/driver.py index 8be43634493..99a1b9b84b6 100644 --- a/cinder/volume/drivers/dell_emc/unity/driver.py +++ b/cinder/volume/drivers/dell_emc/unity/driver.py @@ -58,9 +58,10 @@ class UnityDriver(driver.ManageableVD, 3.0.0 - Add IPv6 support 3.1.0 - Support revert to snapshot API 4.0.0 - Support remove empty host + 4.2.0 - Support compressed volume """ - VERSION = '04.00.00' + VERSION = '04.02.00' VENDOR = 'Dell EMC' # ThirdPartySystems wiki page CI_WIKI_NAME = "EMC_UNITY_CI" diff --git a/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst b/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst index a0d65e1322a..f1887a57d6f 100644 --- a/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst +++ b/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst @@ -23,6 +23,7 @@ Supported operations ~~~~~~~~~~~~~~~~~~~~ - Create, delete, attach, and detach volumes. +- Create, delete, attach, and detach compressed volumes. - Create, list, and delete volume snapshots. - Create a volume from a snapshot. - Copy an image to a volume. @@ -248,6 +249,21 @@ following commands to create a thick volume. # openstack volume create --type thick_volume_type thick_volume +Compressed volume support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unity driver supports ``compressed volume`` creation, modification and +deletion. In order to create a compressed volume, a volume type which +enables compression support needs to be created first: + +.. code-block:: console + + $ openstack volume type create CompressedVolumeType + $ openstack volume type set --property provisioning:type=compressed --property compression_support=' True' CompressedVolumeType + +Then create volume and specify the new created volume type. + + QoS support ~~~~~~~~~~~ diff --git a/releasenotes/notes/unity-compressed-volume-support-4998dee84534a324.yaml b/releasenotes/notes/unity-compressed-volume-support-4998dee84534a324.yaml new file mode 100644 index 00000000000..7e52061bf5f --- /dev/null +++ b/releasenotes/notes/unity-compressed-volume-support-4998dee84534a324.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Dell EMC Unity driver: Add compressed volume support.