TgtAdm: Don't change CHAP username/password on live migration
As tgtd doesn't update CHAP username/password while the initiator is connected, CHAP username/password must not be changed while a Nova instance are performing live-migration; otherwise the compute node which the instance migrates to cannot login to the volume and the migration process is aborted. This fixes TgtAdm implementation not to regenerate random username/password every time initialize_connection is called. Also, it enables CHAP auth in unit tests of TargetAdmin helpers. Change-Id: I48729a33fada62a7c8e4fe500b1e39533d898701 Closes-Bug: #1383509
This commit is contained in:
parent
c105259736
commit
c22038b900
|
@ -23,6 +23,8 @@ import re
|
|||
import stat
|
||||
import time
|
||||
|
||||
import six
|
||||
|
||||
from cinder.brick import exception
|
||||
from cinder.brick import executor
|
||||
from cinder.i18n import _
|
||||
|
@ -47,6 +49,10 @@ class TargetAdmin(executor.Executor):
|
|||
def _run(self, *args, **kwargs):
|
||||
self._execute(self._cmd, *args, run_as_root=True, **kwargs)
|
||||
|
||||
def _get_target_chap_auth(self, volume_id):
|
||||
"""Get the current chap auth username and password."""
|
||||
return None
|
||||
|
||||
def create_iscsi_target(self, name, tid, lun, path,
|
||||
chap_auth=None, **kwargs):
|
||||
"""Create an iSCSI target and logical unit."""
|
||||
|
@ -159,6 +165,25 @@ class TgtAdm(TargetAdmin):
|
|||
"id:%(vol_id)s: %(e)s")
|
||||
% {'vol_id': name, 'e': e})
|
||||
|
||||
def _get_target_chap_auth(self, name):
|
||||
volumes_dir = self.volumes_dir
|
||||
vol_id = name.split(':')[1]
|
||||
volume_path = os.path.join(volumes_dir, vol_id)
|
||||
|
||||
try:
|
||||
with open(volume_path, 'r') as f:
|
||||
volume_conf = f.read()
|
||||
except Exception as e:
|
||||
LOG.debug('Failed to open config for %(vol_id)s: %(e)s'
|
||||
% {'vol_id': vol_id, 'e': six.text_type(e)})
|
||||
return None
|
||||
|
||||
m = re.search('incominguser (\w+) (\w+)', volume_conf)
|
||||
if m:
|
||||
return (m.group(1), m.group(2))
|
||||
LOG.debug('Failed to find CHAP auth from config for %s' % vol_id)
|
||||
return None
|
||||
|
||||
def create_iscsi_target(self, name, tid, lun, path,
|
||||
chap_auth=None, **kwargs):
|
||||
# Note(jdg) tid and lun aren't used by TgtAdm but remain for
|
||||
|
@ -496,10 +521,6 @@ class LioAdm(TargetAdmin):
|
|||
|
||||
LOG.info(_('Creating iscsi_target for volume: %s') % vol_id)
|
||||
|
||||
# rtstool requires chap_auth, but unit tests don't provide it
|
||||
chap_auth_userid = 'test_id'
|
||||
chap_auth_password = 'test_pass'
|
||||
|
||||
if chap_auth is not None:
|
||||
(chap_auth_userid, chap_auth_password) = chap_auth.split(' ')[1:]
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ class TargetAdminTestCase(object):
|
|||
self.path = '/foo'
|
||||
self.vol_id = 'blaa'
|
||||
self.vol_name = 'volume-blaa'
|
||||
self.chap_username = 'test_id'
|
||||
self.chap_password = 'test_pass'
|
||||
self.write_cache = 'off'
|
||||
self.db = {}
|
||||
|
||||
|
@ -66,7 +68,9 @@ class TargetAdminTestCase(object):
|
|||
return {'tid': self.tid,
|
||||
'target_name': self.target_name,
|
||||
'lun': self.lun,
|
||||
'path': self.path}
|
||||
'path': self.path,
|
||||
'username': self.chap_username,
|
||||
'password': self.chap_password}
|
||||
|
||||
def get_script(self):
|
||||
return self.script_template % self.get_script_params()
|
||||
|
@ -78,10 +82,14 @@ class TargetAdminTestCase(object):
|
|||
def clear_cmds(self):
|
||||
self.cmds = []
|
||||
|
||||
def verify_config(self):
|
||||
pass
|
||||
|
||||
def verify_cmds(self, cmds):
|
||||
self.assertEqual(len(cmds), len(self.cmds))
|
||||
for cmd in self.cmds:
|
||||
self.assertTrue(cmd in cmds)
|
||||
self.verify_config()
|
||||
|
||||
def verify(self):
|
||||
script = self.get_script()
|
||||
|
@ -95,8 +103,11 @@ class TargetAdminTestCase(object):
|
|||
def run_commands(self):
|
||||
target_helper = self.driver.get_target_helper(self.db)
|
||||
target_helper.set_execute(self.fake_execute)
|
||||
chap_auth = target_helper._iscsi_authentication('IncomingUser',
|
||||
self.chap_username,
|
||||
self.chap_password)
|
||||
target_helper.create_iscsi_target(self.target_name, self.tid,
|
||||
self.lun, self.path,
|
||||
self.lun, self.path, chap_auth,
|
||||
write_cache=self.write_cache)
|
||||
target_helper.show_target(self.tid, iqn=self.target_name)
|
||||
target_helper.remove_iscsi_target(self.tid, self.lun, self.vol_id,
|
||||
|
@ -128,6 +139,11 @@ class TgtAdmTestCase(test.TestCase, TargetAdminTestCase):
|
|||
'--delete %(target_name)s',
|
||||
'tgtadm --lld iscsi --op show --mode target'])
|
||||
|
||||
def verify_config(self):
|
||||
target_helper = self.driver.get_target_helper(self.db)
|
||||
self.assertEqual(target_helper._get_target_chap_auth(self.target_name),
|
||||
(self.chap_username, self.chap_password))
|
||||
|
||||
|
||||
class IetAdmTestCase(test.TestCase, TargetAdminTestCase):
|
||||
|
||||
|
@ -139,6 +155,8 @@ class IetAdmTestCase(test.TestCase, TargetAdminTestCase):
|
|||
'ietadm --op new --tid=%(tid)s --params Name=%(target_name)s',
|
||||
'ietadm --op new --tid=%(tid)s --lun=%(lun)s '
|
||||
'--params Path=%(path)s,Type=fileio',
|
||||
'ietadm --op new --tid=%(tid)s --user '
|
||||
'--params=IncomingUser=%(username)s,Password=%(password)s',
|
||||
'ietadm --op show --tid=%(tid)s',
|
||||
'ietadm --op delete --tid=%(tid)s --lun=%(lun)s',
|
||||
'ietadm --op delete --tid=%(tid)s'])
|
||||
|
@ -155,6 +173,8 @@ class IetAdmBlockIOTestCase(test.TestCase, TargetAdminTestCase):
|
|||
'ietadm --op new --tid=%(tid)s --params Name=%(target_name)s',
|
||||
'ietadm --op new --tid=%(tid)s --lun=%(lun)s '
|
||||
'--params Path=%(path)s,Type=blockio',
|
||||
'ietadm --op new --tid=%(tid)s --user '
|
||||
'--params=IncomingUser=%(username)s,Password=%(password)s',
|
||||
'ietadm --op show --tid=%(tid)s',
|
||||
'ietadm --op delete --tid=%(tid)s --lun=%(lun)s',
|
||||
'ietadm --op delete --tid=%(tid)s'])
|
||||
|
@ -171,6 +191,8 @@ class IetAdmFileIOTestCase(test.TestCase, TargetAdminTestCase):
|
|||
'ietadm --op new --tid=%(tid)s --params Name=%(target_name)s',
|
||||
'ietadm --op new --tid=%(tid)s --lun=%(lun)s '
|
||||
'--params Path=%(path)s,Type=fileio',
|
||||
'ietadm --op new --tid=%(tid)s --user '
|
||||
'--params=IncomingUser=%(username)s,Password=%(password)s',
|
||||
'ietadm --op show --tid=%(tid)s',
|
||||
'ietadm --op delete --tid=%(tid)s --lun=%(lun)s',
|
||||
'ietadm --op delete --tid=%(tid)s'])
|
||||
|
@ -188,6 +210,8 @@ class IetAdmAutoIOTestCase(test.TestCase, TargetAdminTestCase):
|
|||
'ietadm --op new --tid=%(tid)s --params Name=%(target_name)s',
|
||||
'ietadm --op new --tid=%(tid)s --lun=%(lun)s '
|
||||
'--params Path=%(path)s,Type=blockio',
|
||||
'ietadm --op new --tid=%(tid)s --user '
|
||||
'--params=IncomingUser=%(username)s,Password=%(password)s',
|
||||
'ietadm --op show --tid=%(tid)s',
|
||||
'ietadm --op delete --tid=%(tid)s --lun=%(lun)s',
|
||||
'ietadm --op delete --tid=%(tid)s'])
|
||||
|
@ -201,7 +225,7 @@ class LioAdmTestCase(test.TestCase, TargetAdminTestCase):
|
|||
self.flags(iscsi_helper='lioadm')
|
||||
self.script_template = "\n".join([
|
||||
'cinder-rtstool create '
|
||||
'%(path)s %(target_name)s test_id test_pass',
|
||||
'%(path)s %(target_name)s %(username)s %(password)s',
|
||||
'cinder-rtstool delete %(target_name)s'])
|
||||
|
||||
|
||||
|
|
|
@ -41,8 +41,12 @@ class _ExportMixin(object):
|
|||
volume,
|
||||
max_targets)
|
||||
|
||||
chap_username = utils.generate_username()
|
||||
chap_password = utils.generate_password()
|
||||
current_chap_auth = self._get_target_chap_auth(iscsi_name)
|
||||
if current_chap_auth:
|
||||
(chap_username, chap_password) = current_chap_auth
|
||||
else:
|
||||
chap_username = utils.generate_username()
|
||||
chap_password = utils.generate_password()
|
||||
chap_auth = self._iscsi_authentication('IncomingUser',
|
||||
chap_username,
|
||||
chap_password)
|
||||
|
|
Loading…
Reference in New Issue