def setUp(self):
super(TestTgtAdmDriver, self).setUp()
+ self.configuration.get = mock.Mock(side_effect=self.fake_get)
+
self.target = tgt.TgtAdm(root_helper=utils.get_root_helper(),
configuration=self.configuration)
self.testvol_path = \
' ALL"\n' % {'test_vol': self.test_vol,
'bspath': self.testvol_path})
+ def fake_get(self, value, default):
+ if value in ('iscsi_target_flags', 'iscsi_write_cache'):
+ return getattr(self, value, default)
+
def test_iscsi_protocol(self):
self.assertEqual(self.target.iscsi_protocol, 'iscsi')
0,
self.fake_volumes_dir))
+ def test_create_iscsi_target_content(self):
+
+ self.iscsi_target_flags = 'foo'
+ self.iscsi_write_cache = 'bar'
+
+ mock_open = mock.mock_open()
+ with mock.patch('cinder.utils.execute', return_value=('', '')),\
+ mock.patch.object(self.target, '_get_target',
+ side_effect=lambda x: 1),\
+ mock.patch.object(self.target, '_verify_backing_lun',
+ side_effect=lambda x, y: True),\
+ mock.patch('cinder.volume.targets.tgt.open',
+ mock_open, create=True):
+ self.assertEqual(
+ 1,
+ self.target.create_iscsi_target(
+ self.test_vol,
+ 1,
+ 0,
+ self.testvol_path,
+ chap_auth=('chap_foo', 'chap_bar')))
+
+ mock_open.assert_called_once_with(
+ os.path.join(self.fake_volumes_dir, self.test_vol.split(':')[1]),
+ 'w+')
+ expected = ('\n<target iqn.2010-10.org.openstack:volume-%(id)s>\n'
+ ' backing-store %(bspath)s\n'
+ ' driver iscsi\n'
+ ' incominguser chap_foo chap_bar\n'
+ ' bsoflags foo\n'
+ ' write-cache bar\n'
+ '</target>\n' % {'id': self.VOLUME_ID,
+ 'bspath': self.testvol_path})
+ self.assertEqual(expected,
+ mock_open.return_value.write.call_args[0][0])
+
def test_create_iscsi_target_already_exists(self):
def _fake_execute(*args, **kwargs):
if 'update' in args:
'perform write-back(on) or write-through(off). '
'This parameter is valid if iscsi_helper is set '
'to tgtadm or iseradm.'),
+ cfg.StrOpt('iscsi_target_flags',
+ default='',
+ help='Sets the target-specific flags for the iSCSI target. '
+ 'Only used for tgtadm to specify backing device flags '
+ 'using bsoflags option. The specified string is passed '
+ 'as is to the underlying tool.'),
cfg.StrOpt('iscsi_protocol',
default='iscsi',
choices=['iscsi', 'iser'],
import os
import re
+import textwrap
import time
from oslo_concurrency import processutils as putils
etc.
"""
- VOLUME_CONF = """
- <target %s>
- backing-store %s
- driver %s
- write-cache %s
+ VOLUME_CONF = textwrap.dedent("""
+ <target %(name)s>
+ backing-store %(path)s
+ driver %(driver)s
+ %(chap_auth)s
+ %(target_flags)s
+ write-cache %(write_cache)s
</target>
- """
- VOLUME_CONF_WITH_CHAP_AUTH = """
- <target %s>
- backing-store %s
- driver %s
- %s
- write-cache %s
- </target>
- """
+ """)
def __init__(self, *args, **kwargs):
super(TgtAdm, self).__init__(*args, **kwargs)
vol_id = name.split(':')[1]
write_cache = self.configuration.get('iscsi_write_cache', 'on')
driver = self.iscsi_protocol
+ chap_str = ''
- if chap_auth is None:
- volume_conf = self.VOLUME_CONF % (name, path, driver, write_cache)
- else:
+ if chap_auth is not None:
chap_str = 'incominguser %s %s' % chap_auth
- volume_conf = self.VOLUME_CONF_WITH_CHAP_AUTH % (name, path,
- driver, chap_str,
- write_cache)
+
+ target_flags = self.configuration.get('iscsi_target_flags', '')
+ if target_flags:
+ target_flags = 'bsoflags ' + target_flags
+
+ volume_conf = self.VOLUME_CONF % {
+ 'name': name, 'path': path, 'driver': driver,
+ 'chap_auth': chap_str, 'target_flags': target_flags,
+ 'write_cache': write_cache}
+
LOG.debug('Creating iscsi_target for Volume ID: %s', vol_id)
volumes_dir = self.volumes_dir
volume_path = os.path.join(volumes_dir, vol_id)