Failed to discovery when iscsi multipath and CHAP both enabled
Storage server may be configured to protect target discovering phase with CHAP authentication, in this case existing discovery command will be failed. The authentication properties are: "discovery.sendtargets.auth.authmethod", "discovery.sendtargets.auth.username", "discovery.sendtargets.auth.password" Cinder Storage driver need to send discovery auth properties in this case, and the properties are: iscsi_properties['discovery_auth_method'] iscsi_properties['discovery_auth_username'] iscsi_properties['discovery_auth_password'] Change-Id: Ic70426d7d0fd8126879840f05341731ed92d6392 Closes-Bug: #1367189
This commit is contained in:
parent
4f59f773e4
commit
45227bbbfd
|
@ -280,6 +280,27 @@ class LibvirtVolumeTestCase(test.NoDBTestCase):
|
|||
ret['data']['auth_password'] = 'bar'
|
||||
return ret
|
||||
|
||||
def iscsi_connection_discovery_chap_enable(self, volume, location, iqn):
|
||||
dev_name = 'ip-%s-iscsi-%s-lun-1' % (location, iqn)
|
||||
dev_path = '/dev/disk/by-path/%s' % (dev_name)
|
||||
return {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': {
|
||||
'volume_id': volume['id'],
|
||||
'target_portal': location,
|
||||
'target_iqn': iqn,
|
||||
'target_lun': 1,
|
||||
'device_path': dev_path,
|
||||
'discovery_auth_method': 'CHAP',
|
||||
'discovery_auth_username': "testuser",
|
||||
'discovery_auth_password': '123456',
|
||||
'qos_specs': {
|
||||
'total_bytes_sec': '102400',
|
||||
'read_iops_sec': '200',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def generate_device(self, transport=None, lun=1, short=False):
|
||||
dev_format = "ip-%s-iscsi-%s-lun-%s" % (self.location, self.iqn, lun)
|
||||
if transport:
|
||||
|
@ -682,6 +703,51 @@ Setting up iSCSI targets: unused
|
|||
self.assertEqual(tree.find('./auth/secret').get('uuid'), SECRET_UUID)
|
||||
libvirt_driver.disconnect_volume(connection_info, 'vde')
|
||||
|
||||
def test_libvirt_iscsi_driver_discovery_chap_enable(self):
|
||||
# NOTE(vish) exists is to make driver assume connecting worked
|
||||
self.stubs.Set(os.path, 'exists', lambda x: True)
|
||||
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
|
||||
libvirt_driver.use_multipath = True
|
||||
connection_info = self.iscsi_connection_discovery_chap_enable(
|
||||
self.vol, self.location,
|
||||
self.iqn)
|
||||
mpdev_filepath = '/dev/mapper/foo'
|
||||
libvirt_driver._get_multipath_device_name = lambda x: mpdev_filepath
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
expected_commands = [('iscsiadm', '-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', self.location, '--op', 'update',
|
||||
'-n', 'discovery.sendtargets.auth.authmethod',
|
||||
'-v', 'CHAP',
|
||||
'-n', 'discovery.sendtargets.auth.username',
|
||||
'-v', 'testuser',
|
||||
'-n', 'discovery.sendtargets.auth.password',
|
||||
'-v', '123456'),
|
||||
('iscsiadm', '-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', self.location, '--discover'),
|
||||
('iscsiadm', '-m', 'node', '--rescan'),
|
||||
('iscsiadm', '-m', 'session', '--rescan'),
|
||||
('multipath', '-r'),
|
||||
('iscsiadm', '-m', 'node', '--rescan'),
|
||||
('iscsiadm', '-m', 'session', '--rescan'),
|
||||
('multipath', '-r'),
|
||||
('iscsiadm', '-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', self.location, '--op', 'update',
|
||||
'-n', 'discovery.sendtargets.auth.authmethod',
|
||||
'-v', 'CHAP',
|
||||
'-n', 'discovery.sendtargets.auth.username',
|
||||
'-v', 'testuser',
|
||||
'-n', 'discovery.sendtargets.auth.password',
|
||||
'-v', '123456'),
|
||||
('iscsiadm', '-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', self.location, '--discover'),
|
||||
('multipath', '-r')]
|
||||
self.assertEqual(self.executes, expected_commands)
|
||||
|
||||
def test_libvirt_kvm_volume(self):
|
||||
self.stubs.Set(os.path, 'exists', lambda x: True)
|
||||
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
|
||||
|
|
|
@ -345,18 +345,12 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
|
|||
"""Attach the volume to instance_name."""
|
||||
iscsi_properties = connection_info['data']
|
||||
|
||||
# multipath installed, discovering other targets if available
|
||||
# multipath should be configured on the nova-compute node,
|
||||
# in order to fit storage vendor
|
||||
out = None
|
||||
if self.use_multipath:
|
||||
# multipath installed, discovering other targets if available
|
||||
# multipath should be configured on the nova-compute node,
|
||||
# in order to fit storage vendor
|
||||
out = self._run_iscsiadm_bare(['-m',
|
||||
'discovery',
|
||||
'-t',
|
||||
'sendtargets',
|
||||
'-p',
|
||||
iscsi_properties['target_portal']],
|
||||
check_exit_code=[0, 255])[0] \
|
||||
or ""
|
||||
out = self._run_iscsiadm_discover(iscsi_properties)
|
||||
|
||||
# There are two types of iSCSI multipath devices. One which shares
|
||||
# the same iqn between multiple portals, and the other which use
|
||||
|
@ -441,6 +435,60 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
|
|||
|
||||
connection_info['data']['device_path'] = host_device
|
||||
|
||||
def _run_iscsiadm_discover(self, iscsi_properties):
|
||||
def run_iscsiadm_update_discoverydb():
|
||||
return utils.execute(
|
||||
'iscsiadm',
|
||||
'-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', iscsi_properties['target_portal'],
|
||||
'--op', 'update',
|
||||
'-n', "discovery.sendtargets.auth.authmethod",
|
||||
'-v', iscsi_properties['discovery_auth_method'],
|
||||
'-n', "discovery.sendtargets.auth.username",
|
||||
'-v', iscsi_properties['discovery_auth_username'],
|
||||
'-n', "discovery.sendtargets.auth.password",
|
||||
'-v', iscsi_properties['discovery_auth_password'],
|
||||
run_as_root=True)
|
||||
|
||||
out = None
|
||||
if iscsi_properties.get('discovery_auth_method'):
|
||||
try:
|
||||
run_iscsiadm_update_discoverydb()
|
||||
except processutils.ProcessExecutionError as exc:
|
||||
# iscsiadm returns 6 for "db record not found"
|
||||
if exc.exit_code == 6:
|
||||
(out, err) = utils.execute(
|
||||
'iscsiadm',
|
||||
'-m', 'discoverydb',
|
||||
'-t', 'sendtargets',
|
||||
'-p', iscsi_properties['target_portal'],
|
||||
'--op', 'new',
|
||||
run_as_root=True)
|
||||
run_iscsiadm_update_discoverydb()
|
||||
else:
|
||||
raise
|
||||
|
||||
out = self._run_iscsiadm_bare(
|
||||
['-m',
|
||||
'discoverydb',
|
||||
'-t',
|
||||
'sendtargets',
|
||||
'-p',
|
||||
iscsi_properties['target_portal'],
|
||||
'--discover'],
|
||||
check_exit_code=[0, 255])[0] or ""
|
||||
else:
|
||||
out = self._run_iscsiadm_bare(
|
||||
['-m',
|
||||
'discovery',
|
||||
'-t',
|
||||
'sendtargets',
|
||||
'-p',
|
||||
iscsi_properties['target_portal']],
|
||||
check_exit_code=[0, 255])[0] or ""
|
||||
return out
|
||||
|
||||
@utils.synchronized('connect_volume')
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
"""Detach the volume from instance_name."""
|
||||
|
@ -518,14 +566,7 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
|
|||
# Do a discovery to find all targets.
|
||||
# Targets for multiple paths for the same multipath device
|
||||
# may not be the same.
|
||||
out = self._run_iscsiadm_bare(['-m',
|
||||
'discovery',
|
||||
'-t',
|
||||
'sendtargets',
|
||||
'-p',
|
||||
iscsi_properties['target_portal']],
|
||||
check_exit_code=[0, 255])[0] \
|
||||
or ""
|
||||
out = self._run_iscsiadm_discover(iscsi_properties)
|
||||
|
||||
# Extract targets for the current multipath device.
|
||||
ips_iqns = []
|
||||
|
|
Loading…
Reference in New Issue