ZFSSA iSCSI driver should support extra specs

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
This commit is contained in:
Juan Zuluaga
2014-11-13 10:46:37 -05:00
parent 300e2dc9be
commit d86779a098
3 changed files with 71 additions and 24 deletions

View 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):

View 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

View 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: