]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
ZFSSA iSCSI driver should support extra specs
authorJuan Zuluaga <juan.c.zuluaga@oracle.com>
Thu, 13 Nov 2014 15:46:37 +0000 (10:46 -0500)
committerJuan Zuluaga <juan.c.zuluaga@oracle.com>
Mon, 8 Dec 2014 02:19:05 +0000 (21:19 -0500)
Support for extra specs at volume creation time,
would allow more flexibility to create custom volumes.
The following scoped keys are supported:
-zfssa:volblocksize
-zfssa:sparse
-zfssa:compression
-zfssa:logbias

Closes-Bug: #1379403
DocImpact

Change-Id: I8768d07f19147dc2544bebc0dbf3392313838e8f

cinder/tests/test_zfssa.py
cinder/volume/drivers/zfssa/zfssaiscsi.py
cinder/volume/drivers/zfssa/zfssarest.py

index b02e7bda653eafa12698502cbe216d86db9e4cdc..8021527ee1b6fd9487679508cc86c58b77f1a47a 100644 (file)
@@ -115,24 +115,21 @@ class FakeZFSSA(object):
     def get_target(self, target):
         return 'iqn.1986-03.com.sun:02:00000-aaaa-bbbb-cccc-ddddd'
 
-    def create_lun(self, pool, project, lun, volsize, targetgroup,
-                   volblocksize, sparse, compression, logbias):
+    def create_lun(self, pool, project, lun, volsize, targetgroup, specs):
         out = {}
         if not self.host and not self.user:
             return out
 
-        out = {"logbias": logbias,
-               "compression": compression,
-               "status": "online",
+        out = {"status": "online",
                "lunguid": "600144F0F8FBD5BD000053CE53AB0001",
                "initiatorgroup": ["fake_initgrp"],
                "volsize": volsize,
                "pool": pool,
-               "volblocksize": volblocksize,
                "name": lun,
                "project": project,
-               "sparse": sparse,
                "targetgroup": targetgroup}
+        if specs:
+            out.update(specs)
 
         return out
 
@@ -273,6 +270,8 @@ class TestZFSSAISCSIDriver(test.TestCase):
         self.configuration.zfssa_target_portal = '1.1.1.1:3260'
         self.configuration.zfssa_target_interfaces = 'e1000g0'
         self.configuration.zfssa_rest_timeout = 60
+        self.configuration.volume_backend_name = 'fake_zfssa'
+        self.configuration.safe_get = self.fake_safe_get
 
     def test_create_delete_volume(self):
         self.drv.create_volume(self.test_vol)
@@ -315,9 +314,32 @@ class TestZFSSAISCSIDriver(test.TestCase):
         self.drv.extend_volume(self.test_vol, 3)
         self.drv.delete_volume(self.test_vol)
 
+    @mock.patch('cinder.volume.volume_types.get_volume_type_extra_specs')
+    def test_get_voltype_specs(self, get_volume_type_extra_specs):
+        volume_type_id = mock.sentinel.volume_type_id
+        volume = {'volume_type_id': volume_type_id}
+        get_volume_type_extra_specs.return_value = {
+            'zfssa:volblocksize': '128k',
+            'zfssa:compression': 'gzip'
+        }
+        ret = self.drv._get_voltype_specs(volume)
+        self.assertEqual(ret.get('volblocksize'), '128k')
+        self.assertEqual(ret.get('sparse'),
+                         self.configuration.zfssa_lun_sparse)
+        self.assertEqual(ret.get('compression'), 'gzip')
+        self.assertEqual(ret.get('logbias'),
+                         self.configuration.zfssa_lun_logbias)
+
     def tearDown(self):
         super(TestZFSSAISCSIDriver, self).tearDown()
 
+    def fake_safe_get(self, value):
+        try:
+            val = getattr(self.configuration, value)
+        except AttributeError:
+            val = None
+        return val
+
 
 class FakeAddIni2InitGrp(object):
 
index a18b8edbe13495975d29e5d8d3b976b31602abad..47334468ae81c9c64b6ce5ba534520fb2c890b17 100644 (file)
@@ -26,6 +26,7 @@ from cinder.openstack.common import log
 from cinder.volume import driver
 from cinder.volume.drivers.san import san
 from cinder.volume.drivers.zfssa import zfssarest
+from cinder.volume import volume_types
 
 CONF = cfg.CONF
 LOG = log.getLogger(__name__)
@@ -70,6 +71,11 @@ ZFSSA_OPTS = [
 
 CONF.register_opts(ZFSSA_OPTS)
 
+ZFSSA_LUN_SPECS = {'zfssa:volblocksize',
+                   'zfssa:sparse',
+                   'zfssa:compression',
+                   'zfssa:logbias'}
+
 
 def factory_zfssa():
     return zfssarest.ZFSSAApi()
@@ -213,15 +219,13 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
         LOG.debug('zfssa.create_volume: volume=' + volume['name'])
         lcfg = self.configuration
         volsize = str(volume['size']) + 'g'
+        specs = self._get_voltype_specs(volume)
         self.zfssa.create_lun(lcfg.zfssa_pool,
                               lcfg.zfssa_project,
                               volume['name'],
                               volsize,
-                              targetgroup=lcfg.zfssa_target_group,
-                              volblocksize=lcfg.zfssa_lun_volblocksize,
-                              sparse=lcfg.zfssa_lun_sparse,
-                              compression=lcfg.zfssa_lun_compression,
-                              logbias=lcfg.zfssa_lun_logbias)
+                              lcfg.zfssa_target_group,
+                              specs)
 
     def delete_volume(self, volume):
         """Deletes a volume with the given volume['name']."""
@@ -429,3 +433,30 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
                                           lcfg.zfssa_project,
                                           volume['name'],
                                           '')
+
+    def _get_voltype_specs(self, volume):
+        """Get specs suitable for volume creation."""
+        vtype = volume.get('volume_type_id', None)
+        extra_specs = None
+        if vtype:
+            extra_specs = volume_types.get_volume_type_extra_specs(vtype)
+
+        return self._get_specs(extra_specs)
+
+    def _get_specs(self, xspecs):
+        """Return a dict with extra specs and/or config values."""
+        result = {}
+        for spc in ZFSSA_LUN_SPECS:
+            val = None
+            prop = spc.split(':')[1]
+            cfg = 'zfssa_lun_' + prop
+            if xspecs:
+                val = xspecs.pop(spc, None)
+
+            if val is None:
+                val = self.configuration.safe_get(cfg)
+
+            if val is not None and val != '':
+                result.update({prop: val})
+
+        return result
index 92128189c7bbcc3f0f328bf033f14a8fe7b5d94a..d8203666c248f9d57596b157a2547e83163b6973 100644 (file)
@@ -384,12 +384,10 @@ class ZFSSAApi(object):
             LOG.error(exception_msg)
             raise exception.VolumeBackendAPIException(data=exception_msg)
 
-    def create_lun(self, pool, project, lun, volsize, targetgroup,
-                   volblocksize='8k', sparse=False, compression=None,
-                   logbias=None):
+    def create_lun(self, pool, project, lun, volsize, targetgroup, specs):
+
         """Create a LUN.
-           required - pool, project, lun, volsize, targetgroup.
-           optional - volblocksize, sparse, compression, logbias
+           specs - contains volume properties (e.g blocksize, compression).
         """
         svc = '/api/storage/v1/pools/' + pool + '/projects/' + \
               project + '/luns'
@@ -397,14 +395,10 @@ class ZFSSAApi(object):
             'name': lun,
             'volsize': volsize,
             'targetgroup': targetgroup,
-            'initiatorgroup': 'com.sun.ms.vss.hg.maskAll',
-            'volblocksize': volblocksize,
-            'sparse': sparse
+            'initiatorgroup': 'com.sun.ms.vss.hg.maskAll'
         }
-        if compression and compression != '':
-            arg.update({'compression': compression})
-        if logbias and logbias != '':
-            arg.update({'logbias': logbias})
+        if specs:
+            arg.update(specs)
 
         ret = self.rclient.post(svc, arg)
         if ret.status != restclient.Status.CREATED: