Merge "Support manage/unmanage and extra-specs in K2"
This commit is contained in:
commit
b32787ee30
cinder
tests/unit/volume/drivers
volume/drivers/kaminario
releasenotes/notes
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
"""Unit tests for kaminario driver."""
|
||||
import mock
|
||||
from oslo_utils import units
|
||||
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -46,6 +47,9 @@ class FakeSaveObject(FakeK2Obj):
|
||||
self.snapshot = FakeK2Obj()
|
||||
self.name = 'test'
|
||||
self.pwwn = '50024f4053300300'
|
||||
self.volume_group = self
|
||||
self.is_dedup = True
|
||||
self.size = units.Mi
|
||||
|
||||
def save(self):
|
||||
return FakeSaveObject()
|
||||
@ -103,6 +107,7 @@ class TestKaminarioISCSI(test.TestCase):
|
||||
self.context = context.get_admin_context()
|
||||
self.vol = fake_volume.fake_volume_obj(self.context)
|
||||
self.vol.volume_type = fake_volume.fake_volume_type_obj(self.context)
|
||||
self.vol.volume_type.extra_specs = {'foo': None}
|
||||
self.snap = fake_snapshot.fake_snapshot_obj(self.context)
|
||||
self.snap.volume = self.vol
|
||||
|
||||
@ -265,6 +270,42 @@ class TestKaminarioISCSI(test.TestCase):
|
||||
result = self.driver.k2_initialize_connection(self.vol, CONNECTOR)
|
||||
self.assertEqual(548, result)
|
||||
|
||||
def test_manage_existing(self):
|
||||
"""Test manage_existing."""
|
||||
self.driver._get_replica_status = mock.Mock(return_value=False)
|
||||
result = self.driver.manage_existing(self.vol, {'source-name': 'test'})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_manage_existing_exp(self):
|
||||
self.driver._get_replica_status = mock.Mock(return_value=True)
|
||||
self.assertRaises(exception.ManageExistingInvalidReference,
|
||||
self.driver.manage_existing, self.vol,
|
||||
{'source-name': 'test'})
|
||||
|
||||
def test_manage_existing_get_size(self):
|
||||
"""Test manage_existing_get_size."""
|
||||
self.driver.client.search().hits[0].size = units.Mi
|
||||
result = self.driver.manage_existing_get_size(self.vol,
|
||||
{'source-name': 'test'})
|
||||
self.assertEqual(1, result)
|
||||
|
||||
def test_get_is_dedup(self):
|
||||
"""Test _get_is_dedup."""
|
||||
result = self.driver._get_is_dedup(self.vol.volume_type)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_get_is_dedup_false(self):
|
||||
"""Test _get_is_dedup_false."""
|
||||
specs = {'kaminario:thin_prov_type': 'nodedup'}
|
||||
self.vol.volume_type.extra_specs = specs
|
||||
result = self.driver._get_is_dedup(self.vol.volume_type)
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_get_replica_status(self):
|
||||
"""Test _get_replica_status."""
|
||||
result = self.driver._get_replica_status(self.vol)
|
||||
self.assertTrue(result)
|
||||
|
||||
|
||||
class TestKaminarioFC(TestKaminarioISCSI):
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
"""Volume driver for Kaminario K2 all-flash arrays."""
|
||||
|
||||
import math
|
||||
import re
|
||||
import six
|
||||
|
||||
@ -25,7 +26,7 @@ from oslo_utils import versionutils
|
||||
|
||||
import cinder
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder.i18n import _, _LE, _LW, _LI
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import utils as vol_utils
|
||||
@ -38,7 +39,9 @@ kaminario1_opts = [
|
||||
default='K2-nodedup',
|
||||
help="If volume-type name contains this substring "
|
||||
"nodedup volume will be created, otherwise "
|
||||
"dedup volume wil be created.")]
|
||||
"dedup volume wil be created. Note: this option is "
|
||||
"deprecated in favour of 'kaminario:thin_prov_type' in "
|
||||
"extra-specs and will be removed in the Ocata release.")]
|
||||
kaminario2_opts = [
|
||||
cfg.BoolOpt('auto_calc_max_oversubscription_ratio',
|
||||
default=False,
|
||||
@ -73,7 +76,6 @@ def kaminario_logger(func):
|
||||
|
||||
class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
||||
VENDOR = "Kaminario"
|
||||
VERSION = "1.0"
|
||||
stats = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -132,10 +134,7 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
||||
"""
|
||||
vg_name = self.get_volume_group_name(volume.id)
|
||||
vol_name = self.get_volume_name(volume.id)
|
||||
if CONF.kaminario_nodedup_substring in volume.volume_type.name:
|
||||
prov_type = False
|
||||
else:
|
||||
prov_type = True
|
||||
prov_type = self._get_is_dedup(volume.get('volume_type'))
|
||||
try:
|
||||
LOG.debug("Creating volume group with name: %(name)s, "
|
||||
"quota: unlimited and dedup_support: %(dedup)s",
|
||||
@ -375,7 +374,8 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
||||
'total_volumes': total_volumes,
|
||||
'thick_provisioning_support': False,
|
||||
'provisioned_capacity_gb': provisioned_vol / units.Mi,
|
||||
'max_oversubscription_ratio': ratio}
|
||||
'max_oversubscription_ratio': ratio,
|
||||
'kaminario:thin_prov_type': 'dedup/nodedup'}
|
||||
|
||||
@kaminario_logger
|
||||
def get_initiator_host_name(self, connector):
|
||||
@ -511,3 +511,79 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
||||
|
||||
def _get_host_object(self, connector):
|
||||
pass
|
||||
|
||||
def _get_is_dedup(self, vol_type):
|
||||
if vol_type:
|
||||
specs_val = vol_type.get('extra_specs', {}).get(
|
||||
'kaminario:thin_prov_type')
|
||||
if specs_val == 'nodedup':
|
||||
return False
|
||||
elif CONF.kaminario_nodedup_substring in vol_type.name:
|
||||
LOG.info(_LI("'kaminario_nodedup_substring' option is "
|
||||
"deprecated in favour of 'kaminario:thin_prov_"
|
||||
"type' in extra-specs and will be removed in "
|
||||
"the Ocata release."))
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
|
||||
def _get_replica_status(self, vg_name):
|
||||
status = False
|
||||
rvg = self.client.search("replication/peer_volume_groups",
|
||||
name=vg_name)
|
||||
if rvg.total != 0:
|
||||
status = True
|
||||
return status
|
||||
|
||||
def manage_existing(self, volume, existing_ref):
|
||||
vol_name = existing_ref['source-name']
|
||||
new_name = self.get_volume_name(volume.id)
|
||||
vg_new_name = self.get_volume_group_name(volume.id)
|
||||
vg_name = None
|
||||
is_dedup = self._get_is_dedup(volume.get('volume_type'))
|
||||
try:
|
||||
LOG.debug("Searching volume: %s in K2.", vol_name)
|
||||
vol = self.client.search("volumes", name=vol_name).hits[0]
|
||||
vg = vol.volume_group
|
||||
vg_replica = self._get_replica_status(vg.name)
|
||||
vol_map = False
|
||||
if self.client.search("mappings", volume=vol).total != 0:
|
||||
vol_map = True
|
||||
if is_dedup != vg.is_dedup or vg_replica or vol_map:
|
||||
raise exception.ManageExistingInvalidReference(
|
||||
existing_ref=existing_ref,
|
||||
reason=_('Manage volume type invalid.'))
|
||||
vol.name = new_name
|
||||
vg_name = vg.name
|
||||
LOG.debug("Manage new volume name: %s", new_name)
|
||||
vg.name = vg_new_name
|
||||
LOG.debug("Manage volume group name: %s", vg_new_name)
|
||||
vg.save()
|
||||
LOG.debug("Manage volume: %s in K2.", vol_name)
|
||||
vol.save()
|
||||
except Exception as ex:
|
||||
vg_rs = self.client.search("volume_groups", name=vg_new_name)
|
||||
if hasattr(vg_rs, 'hits') and vg_rs.total != 0:
|
||||
vg = vg_rs.hits[0]
|
||||
if vg_name and vg.name == vg_new_name:
|
||||
vg.name = vg_name
|
||||
LOG.debug("Updating vg new name to old name: %s ", vg_name)
|
||||
vg.save()
|
||||
LOG.exception(_LE("manage volume: %s failed."), vol_name)
|
||||
raise exception.ManageExistingInvalidReference(
|
||||
existing_ref=existing_ref,
|
||||
reason=six.text_type(ex.message))
|
||||
|
||||
def manage_existing_get_size(self, volume, existing_ref):
|
||||
vol_name = existing_ref['source-name']
|
||||
v_rs = self.client.search("volumes", name=vol_name)
|
||||
if hasattr(v_rs, 'hits') and v_rs.total != 0:
|
||||
vol = v_rs.hits[0]
|
||||
size = vol.size / units.Mi
|
||||
return math.ceil(size)
|
||||
else:
|
||||
raise exception.ManageExistingInvalidReference(
|
||||
existing_ref=existing_ref,
|
||||
reason=_('Unable to get size of manage volume.'))
|
||||
|
@ -27,7 +27,14 @@ kaminario_logger = common.kaminario_logger
|
||||
|
||||
|
||||
class KaminarioFCDriver(common.KaminarioCinderDriver):
|
||||
"""Kaminario K2 FC Volume Driver."""
|
||||
"""Kaminario K2 FC Volume Driver.
|
||||
|
||||
Version history:
|
||||
1.0 - Initial driver
|
||||
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
||||
"""
|
||||
|
||||
VERSION = '1.1'
|
||||
|
||||
@kaminario_logger
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -29,7 +29,14 @@ kaminario_logger = common.kaminario_logger
|
||||
|
||||
@interface.volumedriver
|
||||
class KaminarioISCSIDriver(common.KaminarioCinderDriver):
|
||||
"""Kaminario K2 iSCSI Volume Driver."""
|
||||
"""Kaminario K2 iSCSI Volume Driver.
|
||||
|
||||
Version history:
|
||||
1.0 - Initial driver
|
||||
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
||||
"""
|
||||
|
||||
VERSION = '1.1'
|
||||
|
||||
@kaminario_logger
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- Add manage/unmanage and extra-specs feature in Kaminario iSCSI and FC Cinder drivers.
|
||||
|
Loading…
x
Reference in New Issue
Block a user