pass
-def create(backing_device, name, userid, password, initiator_iqns=None):
+def create(backing_device, name, userid, password, iser_enabled,
+ initiator_iqns=None):
try:
rtsroot = rtslib.root.RTSRoot()
except rtslib.utils.RTSLibError:
tpg_new.enable = 1
try:
- rtslib.NetworkPortal(tpg_new, '0.0.0.0', 3260, mode='any')
+ portal = rtslib.NetworkPortal(tpg_new, '0.0.0.0', 3260, mode='any')
except rtslib.utils.RTSLibError:
print(_('Error creating NetworkPortal: ensure port 3260 '
'is not in use by another service.'))
raise
+ try:
+ if iser_enabled == 'True':
+ portal._set_iser(1)
+ except rtslib.utils.RTSLibError:
+ print(_('Error enabling iSER for NetworkPortal: please ensure that '
+ 'RDMA is supported on your iSCSI port.'))
+ raise
+
try:
rtslib.NetworkPortal(tpg_new, '::0', 3260, mode='any')
except rtslib.utils.RTSLibError:
def usage():
print("Usage:")
print(sys.argv[0] +
- " create [device] [name] [userid] [password]" +
+ " create [device] [name] [userid] [password] [iser_enabled]" +
" <initiator_iqn,iqn2,iqn3,...>")
print(sys.argv[0] +
" add-initiator [target_iqn] [userid] [password] [initiator_iqn]")
usage()
if argv[1] == 'create':
- if len(argv) < 6:
+ if len(argv) < 7:
usage()
- if len(argv) > 7:
+ if len(argv) > 8:
usage()
backing_device = argv[2]
name = argv[3]
userid = argv[4]
password = argv[5]
+ iser_enabled = argv[6]
initiator_iqns = None
- if len(argv) > 6:
- initiator_iqns = argv[6]
+ if len(argv) > 7:
+ initiator_iqns = argv[7]
- create(backing_device, name, userid, password, initiator_iqns)
+ create(backing_device, name, userid, password, iser_enabled,
+ initiator_iqns)
elif argv[1] == 'add-initiator':
if len(argv) < 6:
# License for the specific language governing permissions and limitations
# under the License.
+import mock
+
+from cinder.tests.targets import test_lio_driver as test_lio
from cinder.tests.targets import test_tgt_driver as test_tgt
from cinder import utils
from cinder.volume.targets import iser
+from cinder.volume.targets import lio
+from cinder.volume.targets import tgt
class TestIserAdmDriver(test_tgt.TestTgtAdmDriver):
+ """Unit tests for the deprecated ISERTgtAdm flow
+ """
def setUp(self):
super(TestIserAdmDriver, self).setUp()
self.configuration.iser_target_prefix = 'iqn.2010-10.org.openstack:'
self.target = iser.ISERTgtAdm(root_helper=utils.get_root_helper(),
configuration=self.configuration)
+
+ @mock.patch.object(iser.ISERTgtAdm, '_get_iscsi_properties')
+ def test_initialize_connection(self, mock_get_iscsi):
+
+ connector = {'initiator': 'fake_init'}
+
+ # Test the normal case
+ mock_get_iscsi.return_value = {}
+ expected_return = {'driver_volume_type': 'iser',
+ 'data': {}}
+ self.assertEqual(expected_return,
+ self.target.initialize_connection(self.testvol_1,
+ connector))
+
+ def test_iscsi_protocol(self):
+ self.assertEqual(self.target.iscsi_protocol, 'iser')
+
+
+class TestIserTgtDriver(test_tgt.TestTgtAdmDriver):
+ """Unit tests for the iSER TGT flow
+ """
+
+ def setUp(self):
+ super(TestIserTgtDriver, self).setUp()
+ self.configuration.iscsi_protocol = 'iser'
+ self.target = tgt.TgtAdm(root_helper=utils.get_root_helper(),
+ configuration=self.configuration)
+
+ def test_iscsi_protocol(self):
+ self.assertEqual(self.target.iscsi_protocol, 'iser')
+
+ @mock.patch.object(tgt.TgtAdm, '_get_iscsi_properties')
+ def test_initialize_connection(self, mock_get_iscsi):
+
+ connector = {'initiator': 'fake_init'}
+
+ mock_get_iscsi.return_value = {}
+ expected_return = {'driver_volume_type': 'iser',
+ 'data': {}}
+ self.assertEqual(expected_return,
+ self.target.initialize_connection(self.testvol_1,
+ connector))
+
+
+class TestIserLioAdmDriver(test_lio.TestLioAdmDriver):
+ """Unit tests for the iSER LIO flow
+ """
+ def setUp(self):
+ super(TestIserLioAdmDriver, self).setUp()
+ self.configuration.iscsi_protocol = 'iser'
+ with mock.patch.object(lio.LioAdm, '_verify_rtstool'):
+ self.target = lio.LioAdm(root_helper=utils.get_root_helper(),
+ configuration=self.configuration)
+ self.target.db = mock.MagicMock(
+ volume_get=lambda x, y: {'provider_auth': 'IncomingUser foo bar'})
+
+ def test_iscsi_protocol(self):
+ self.assertEqual(self.target.iscsi_protocol, 'iser')
+
+ @mock.patch.object(utils, 'execute')
+ @mock.patch.object(lio.LioAdm, '_get_iscsi_properties')
+ def test_initialize_connection(self, mock_get_iscsi, mock_execute):
+
+ connector = {'initiator': 'fake_init'}
+
+ mock_get_iscsi.return_value = {}
+ ret = self.target.initialize_connection(self.testvol_1, connector)
+ driver_volume_type = ret['driver_volume_type']
+ self.assertEqual(driver_volume_type, 'iser')
self.target.terminate_connection,
self.testvol_1,
connector)
+
+ def test_iscsi_protocol(self):
+ self.assertEqual(self.target.iscsi_protocol, 'iscsi')
'target_iqn': 'iqn.2010-10.org.openstack:volume-%s' %
self.fake_id_2,
'target_lun': 0,
- 'target_portal': '10.10.7.1:3260',
+ 'target_portal': '10.9.8.7:3260',
'volume_id': self.fake_id_2}
self.fake_iscsi_scan =\
def fake_safe_get(self, value):
if value == 'volumes_dir':
return self.fake_volumes_dir
+ elif value == 'iscsi_protocol':
+ return self.configuration.iscsi_protocol
+
+ def test_iscsi_protocol(self):
+ self.assertEqual(self.target.iscsi_protocol, 'iscsi')
def test_get_target(self):
mock.sentinel.backing_device,
mock.sentinel.name,
mock.sentinel.userid,
- mock.sentinel.password)
+ mock.sentinel.password,
+ mock.sentinel.iser_enabled)
def _test_create_rtsllib_error_network_portal(self, ip):
with contextlib.nested(
mock.sentinel.backing_device,
mock.sentinel.name,
mock.sentinel.userid,
- mock.sentinel.password)
+ mock.sentinel.password,
+ mock.sentinel.iser_enabled)
else:
cinder_rtstool.create(mock.sentinel.backing_device,
mock.sentinel.name,
mock.sentinel.userid,
- mock.sentinel.password)
+ mock.sentinel.password,
+ mock.sentinel.iser_enabled)
rts_root.assert_called_once_with()
block_storage_object.assert_called_once_with(
cinder_rtstool.create(mock.sentinel.backing_device,
mock.sentinel.name,
mock.sentinel.userid,
- mock.sentinel.password)
+ mock.sentinel.password,
+ mock.sentinel.iser_enabled)
rts_root.assert_called_once_with()
block_storage_object.assert_called_once_with(
mock.sentinel.name,
mock.sentinel.userid,
mock.sentinel.password,
- mock.sentinel.initiator_iqns]
+ mock.sentinel.initiator_iqns,
+ mock.sentinel.iser_enabled]
rc = cinder_rtstool.main()
mock.sentinel.name,
mock.sentinel.userid,
mock.sentinel.password,
- mock.sentinel.initiator_iqns)
+ mock.sentinel.initiator_iqns,
+ mock.sentinel.iser_enabled)
self.assertEqual(0, rc)
def test_main_add_initiator(self):
'perform write-back(on) or write-through(off). '
'This parameter is valid if iscsi_helper is set '
'to tgtadm or iseradm.'),
+ cfg.StrOpt('iscsi_protocol',
+ default='iscsi',
+ help='Determines the iSCSI protocol for new iSCSI volumes, '
+ 'created with tgtadm or lioadm target helpers. In '
+ 'order to enable RDMA, this parameter should be set '
+ 'with the value "iser". The supported iSCSI protocol '
+ 'values are "iscsi" and "iser".'),
cfg.StrOpt('driver_client_cert_key',
default=None,
help='The path to the client certificate key for verification, '
def __init__(self, *args, **kwargs):
super(LVMISERDriver, self).__init__(*args, **kwargs)
- LOG.warning(_LW('LVMISCSIDriver is deprecated, you should '
+ LOG.warning(_LW('LVMISERDriver is deprecated, you should '
'now just use LVMVolumeDriver and specify '
'target_helper for the target driver you '
- 'wish to use.'))
+ 'wish to use. In order to enable iser, please '
+ 'set iscsi_protocol with the value iser.'))
LOG.debug('Attempting to initialize LVM driver with the '
'following target_driver: '
super(ISCSITarget, self).__init__(*args, **kwargs)
self.iscsi_target_prefix = \
self.configuration.safe_get('iscsi_target_prefix')
+ self.iscsi_protocol = \
+ self.configuration.safe_get('iscsi_protocol')
self.protocol = 'iSCSI'
def _get_iscsi_properties(self, volume):
iscsi_properties = self._get_iscsi_properties(volume)
return {
- 'driver_volume_type': 'iscsi',
+ 'driver_volume_type': self.iscsi_protocol,
'data': iscsi_properties
}
# under the License.
+from cinder.i18n import _LW
from cinder.openstack.common import log as logging
from cinder.volume.targets.tgt import TgtAdm
class ISERTgtAdm(TgtAdm):
VERSION = '0.2'
- VOLUME_CONF = """
- <target %s>
- driver iser
- backing-store %s
- write_cache %s
- </target>
- """
- VOLUME_CONF_WITH_CHAP_AUTH = """
- <target %s>
- driver iser
- backing-store %s
- %s
- write_cache %s
- </target>
- """
-
def __init__(self, *args, **kwargs):
super(ISERTgtAdm, self).__init__(*args, **kwargs)
+
+ LOG.warning(_LW('ISERTgtAdm is deprecated, you should '
+ 'now just use LVMVolumeDriver and specify '
+ 'target_helper for the target driver you '
+ 'wish to use. In order to enable iser, please '
+ 'set iscsi_protocol=iser with lioadm or tgtadm '
+ 'target helpers.'))
+
self.volumes_dir = self.configuration.safe_get('volumes_dir')
+ self.iscsi_protocol = 'iser'
self.protocol = 'iSER'
# backwards compatibility mess
'data': {
'target_discovered': True,
'target_iqn':
- 'iqn.2010-10.org.iser.openstack:volume-00000001',
+ 'iqn.2010-10.org.openstack:volume-00000001',
'target_portal': '127.0.0.0.1:3260',
'volume_id': 1,
}
path,
name,
chap_auth_userid,
- chap_auth_password]
+ chap_auth_password,
+ self.iscsi_protocol == 'iser']
utils.execute(*command_args, run_as_root=True)
except putils.ProcessExecutionError as e:
LOG.error(_LE("Failed to create iscsi target for volume "
iscsi_properties['target_lun'] = 0
return {
- 'driver_volume_type': 'iscsi',
+ 'driver_volume_type': self.iscsi_protocol,
'data': iscsi_properties
}
VOLUME_CONF = """
<target %s>
backing-store %s
- driver iscsi
+ driver %s
write-cache %s
</target>
"""
VOLUME_CONF_WITH_CHAP_AUTH = """
<target %s>
backing-store %s
- driver iscsi
+ driver %s
%s
write-cache %s
</target>
vol_id = name.split(':')[1]
write_cache = kwargs.get('iscsi_write_cache', 'on')
+ driver = self.iscsi_protocol
+
if chap_auth is None:
- volume_conf = self.VOLUME_CONF % (name, path, write_cache)
+ volume_conf = self.VOLUME_CONF % (name, path, driver, write_cache)
else:
chap_str = re.sub('^IncomingUser ', 'incominguser ', chap_auth)
- volume_conf = self.VOLUME_CONF_WITH_CHAP_AUTH % (name,
- path, chap_str,
+ volume_conf = self.VOLUME_CONF_WITH_CHAP_AUTH % (name, path,
+ driver, chap_str,
write_cache)
LOG.debug('Creating iscsi_target for: %s', vol_id)
volumes_dir = self.volumes_dir
def initialize_connection(self, volume, connector):
iscsi_properties = self._get_iscsi_properties(volume)
return {
- 'driver_volume_type': 'iscsi',
+ 'driver_volume_type': self.iscsi_protocol,
'data': iscsi_properties
}