From: Victor Rodionov Date: Fri, 9 Aug 2013 05:40:02 +0000 (+0400) Subject: Refactor Nexenta driver X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=3541036514ce14ea2ac2c52c6ea8c5f97da74815;p=openstack-build%2Fcinder-build.git Refactor Nexenta driver Moving NEXENTA_OPTIONS out of nexenta/volume.py and splitting the options. This change is to avoid duplication as the iSCSI and NFS driver will use the same configuration options. Change-Id: I3596fec9e852f07aea2ef7f2cd26023de07e7d0b --- diff --git a/cinder/tests/test_nexenta.py b/cinder/tests/test_nexenta.py index 6275b11b3..48758db8d 100644 --- a/cinder/tests/test_nexenta.py +++ b/cinder/tests/test_nexenta.py @@ -22,17 +22,15 @@ Unit tests for OpenStack Cinder volume driver import base64 import urllib2 -from oslo.config import cfg +import mox as mox_lib from cinder import test +from cinder.volume import configuration as conf from cinder.volume.drivers import nexenta from cinder.volume.drivers.nexenta import jsonrpc from cinder.volume.drivers.nexenta import volume -CONF = cfg.CONF - - class TestNexentaDriver(test.TestCase): TEST_VOLUME_NAME = 'volume1' TEST_VOLUME_NAME2 = 'volume2' @@ -57,21 +55,25 @@ class TestNexentaDriver(test.TestCase): def setUp(self): super(TestNexentaDriver, self).setUp() - self.flags( - nexenta_host='1.1.1.1', - nexenta_volume='cinder', - nexenta_target_prefix='iqn:', - nexenta_target_group_prefix='cinder/', - nexenta_blocksize='8K', - nexenta_sparse=True, - ) + self.configuration = mox_lib.MockObject(conf.Configuration) + self.configuration.san_ip = '1.1.1.1' + self.configuration.san_login = 'admin' + self.configuration.san_password = 'nexenta' + self.configuration.nexenta_volume = 'cinder' + self.configuration.nexenta_rest_port = 2000 + self.configuration.nexenta_rest_protocol = 'http' + self.configuration.iscsi_port = 3260 + self.configuration.nexenta_target_prefix = 'iqn:' + self.configuration.nexenta_target_group_prefix = 'cinder/' + self.configuration.nexenta_blocksize = '8K' + self.configuration.nexenta_sparse = True self.nms_mock = self.mox.CreateMockAnything() for mod in ['volume', 'zvol', 'iscsitarget', 'appliance', 'stmf', 'scsidisk', 'snapshot']: setattr(self.nms_mock, mod, self.mox.CreateMockAnything()) self.stubs.Set(jsonrpc, 'NexentaJSONProxy', lambda *_, **__: self.nms_mock) - self.drv = volume.NexentaDriver() + self.drv = volume.NexentaDriver(configuration=self.configuration) self.drv.do_setup({}) def test_setup_error(self): @@ -174,9 +176,9 @@ class TestNexentaDriver(test.TestCase): self.assertEquals( retval, {'provider_location': - '%s:%s,1 %s%s 0' % (CONF.nexenta_host, - CONF.nexenta_iscsi_target_portal_port, - CONF.nexenta_target_prefix, + '%s:%s,1 %s%s 0' % (self.configuration.san_ip, + self.configuration.iscsi_port, + self.configuration.nexenta_target_prefix, self.TEST_VOLUME_NAME)}) def __get_test(i): @@ -229,12 +231,11 @@ class TestNexentaDriver(test.TestCase): 'available': '5368709120G', 'health': 'ONLINE'} self.nms_mock.volume.get_child_props( - CONF.nexenta_volume, + self.configuration.nexenta_volume, 'health|size|used|available').AndReturn(stats) self.mox.ReplayAll() stats = self.drv.get_volume_stats(True) self.assertEquals(stats['storage_protocol'], 'iSCSI') - self.assertEquals(stats['volume_backend_name'], 'NexentaDriver') self.assertEquals(stats['total_capacity_gb'], 5368709120.0) self.assertEquals(stats['free_capacity_gb'], 5368709120.0) self.assertEquals(stats['reserved_percentage'], 0) diff --git a/cinder/volume/drivers/nexenta/options.py b/cinder/volume/drivers/nexenta/options.py new file mode 100644 index 000000000..d0720e652 --- /dev/null +++ b/cinder/volume/drivers/nexenta/options.py @@ -0,0 +1,56 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2013 Nexenta Systems, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +:mod:`nexenta.options` -- Contains configuration options for Nexenta drivers. +============================================================================= + +.. automodule:: nexenta.options +.. moduleauthor:: Victor Rodionov +.. moduleauthor:: Yuriy Taraday +""" + +from oslo.config import cfg + +NEXENTA_CONNECTION_OPTIONS = [ + cfg.IntOpt('nexenta_rest_port', + default=2000, + help='HTTP port to connect to Nexenta REST API server'), + cfg.StrOpt('nexenta_rest_protocol', + default='auto', + help='Use http or https for REST connection (default auto)'), +] + +NEXENTA_ISCSI_OPTIONS = [ + cfg.StrOpt('nexenta_volume', + default='cinder', + help='pool on SA that will hold all volumes'), + cfg.StrOpt('nexenta_target_prefix', + default='iqn.1986-03.com.sun:02:cinder-', + help='IQN prefix for iSCSI targets'), + cfg.StrOpt('nexenta_target_group_prefix', + default='cinder/', + help='prefix for iSCSI target groups on SA'), +] + +NEXENTA_VOLUME_OPTIONS = [ + cfg.StrOpt('nexenta_blocksize', + default='', + help='block size for volumes (blank=default,8KB)'), + cfg.BoolOpt('nexenta_sparse', + default=False, + help='flag to create sparse volumes'), +] diff --git a/cinder/volume/drivers/nexenta/volume.py b/cinder/volume/drivers/nexenta/volume.py index d3965a13c..c71b43fb8 100644 --- a/cinder/volume/drivers/nexenta/volume.py +++ b/cinder/volume/drivers/nexenta/volume.py @@ -30,49 +30,15 @@ from cinder import units from cinder.volume import driver from cinder.volume.drivers import nexenta from cinder.volume.drivers.nexenta import jsonrpc +from cinder.volume.drivers.nexenta import options VERSION = '1.0' LOG = logging.getLogger(__name__) -NEXENTA_OPTS = [ - cfg.StrOpt('nexenta_host', - default='', - help='IP address of Nexenta SA'), - cfg.IntOpt('nexenta_rest_port', - default=2000, - help='HTTP port to connect to Nexenta REST API server'), - cfg.StrOpt('nexenta_rest_protocol', - default='auto', - help='Use http or https for REST connection (default auto)'), - cfg.StrOpt('nexenta_user', - default='admin', - help='User name to connect to Nexenta SA'), - cfg.StrOpt('nexenta_password', - default='nexenta', - help='Password to connect to Nexenta SA', - secret=True), - cfg.IntOpt('nexenta_iscsi_target_portal_port', - default=3260, - help='Nexenta target portal port'), - cfg.StrOpt('nexenta_volume', - default='cinder', - help='pool on SA that will hold all volumes'), - cfg.StrOpt('nexenta_target_prefix', - default='iqn.1986-03.com.sun:02:cinder-', - help='IQN prefix for iSCSI targets'), - cfg.StrOpt('nexenta_target_group_prefix', - default='cinder/', - help='prefix for iSCSI target groups on SA'), - cfg.StrOpt('nexenta_blocksize', - default='', - help='block size for volumes (blank=default,8KB)'), - cfg.BoolOpt('nexenta_sparse', - default=False, - help='flag to create sparse volumes'), -] - CONF = cfg.CONF -CONF.register_opts(NEXENTA_OPTS) +CONF.register_opts(options.NEXENTA_CONNECTION_OPTIONS) +CONF.register_opts(options.NEXENTA_ISCSI_OPTIONS) +CONF.register_opts(options.NEXENTA_VOLUME_OPTIONS) class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 @@ -82,38 +48,46 @@ class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 super(NexentaDriver, self).__init__(*args, **kwargs) self.nms = None if self.configuration: - self.configuration.append_config_values(NEXENTA_OPTS) + self.configuration.append_config_values( + options.NEXENTA_CONNECTION_OPTIONS) + self.configuration.append_config_values( + options.NEXENTA_ISCSI_OPTIONS) + self.configuration.append_config_values( + options.NEXENTA_VOLUME_OPTIONS) def do_setup(self, context): - protocol = CONF.nexenta_rest_protocol + protocol = self.configuration.nexenta_rest_protocol auto = protocol == 'auto' if auto: protocol = 'http' self.nms = jsonrpc.NexentaJSONProxy( - '%s://%s:%s/rest/nms/' % (protocol, CONF.nexenta_host, - CONF.nexenta_rest_port), - CONF.nexenta_user, CONF.nexenta_password, auto=auto) + '%s://%s:%s/rest/nms/' % (protocol, self.configuration.san_ip, + self.configuration.nexenta_rest_port), + self.configuration.san_login, self.configuration.san_password, + auto=auto) def check_for_setup_error(self): """Verify that the volume for our zvols exists. :raise: :py:exc:`LookupError` """ - if not self.nms.volume.object_exists(CONF.nexenta_volume): + if not self.nms.volume.object_exists( + self.configuration.nexenta_volume): raise LookupError(_("Volume %s does not exist in Nexenta SA"), - CONF.nexenta_volume) + self.configuration.nexenta_volume) def _get_zvol_name(self, volume_name): """Return zvol name that corresponds given volume name.""" - return '%s/%s' % (CONF.nexenta_volume, volume_name) + return '%s/%s' % (self.configuration.nexenta_volume, volume_name) def _get_target_name(self, volume_name): """Return iSCSI target name to access volume.""" - return '%s%s' % (CONF.nexenta_target_prefix, volume_name) + return '%s%s' % (self.configuration.nexenta_target_prefix, volume_name) def _get_target_group_name(self, volume_name): """Return Nexenta iSCSI target group name for volume.""" - return '%s%s' % (CONF.nexenta_target_group_prefix, volume_name) + return '%s%s' % (self.configuration.nexenta_target_group_prefix, + volume_name) def _get_clone_snap_name(self, volume): """Return name for snapshot that will be used to clone the volume.""" @@ -127,7 +101,8 @@ class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 self.nms.zvol.create( self._get_zvol_name(volume['name']), '%sG' % (volume['size'],), - CONF.nexenta_blocksize, CONF.nexenta_sparse) + self.configuration.nexenta_blocksize, + self.configuration.nexenta_sparse) def extend_volume(self, volume, new_size): """Extend an existing volume. @@ -297,9 +272,8 @@ class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 raise LOG.info(_('Ignored LUN mapping entry addition error "%s"' ' while ensuring export'), exc) - return '%s:%s,1 %s 0' % (CONF.nexenta_host, - CONF.nexenta_iscsi_target_portal_port, - target_name) + return '%s:%s,1 %s 0' % (self.configuration.san_ip, + self.configuration.iscsi_port, target_name) def create_export(self, _ctx, volume): """Create new export for zvol. @@ -370,8 +344,8 @@ class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 data["driver_version"] = VERSION data["storage_protocol"] = 'iSCSI' - stats = self.nms.volume.get_child_props(CONF.nexenta_volume, - 'health|size|used|available') + stats = self.nms.volume.get_child_props( + self.configuration.nexenta_volume, 'health|size|used|available') total_unit = stats['size'][-1] total_amount = float(stats['size'][:-1]) free_unit = stats['available'][-1] diff --git a/etc/cinder/cinder.conf.sample b/etc/cinder/cinder.conf.sample index d91d7506b..74d3dfd9c 100644 --- a/etc/cinder/cinder.conf.sample +++ b/etc/cinder/cinder.conf.sample @@ -1072,12 +1072,9 @@ # -# Options defined in cinder.volume.drivers.nexenta.volume +# Options defined in cinder.volume.drivers.nexenta.volume.options # -# IP address of Nexenta SA (string value) -#nexenta_host= - # HTTP port to connect to Nexenta REST API server (integer # value) #nexenta_rest_port=2000 @@ -1086,15 +1083,6 @@ # value) #nexenta_rest_protocol=auto -# User name to connect to Nexenta SA (string value) -#nexenta_user=admin - -# Password to connect to Nexenta SA (string value) -#nexenta_password=nexenta - -# Nexenta target portal port (integer value) -#nexenta_iscsi_target_portal_port=3260 - # pool on SA that will hold all volumes (string value) #nexenta_volume=cinder