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:
@@ -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):
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user