Merge "Recover node.startup values after discovering"

This commit is contained in:
Zuul 2018-01-03 19:50:46 +00:00 committed by Gerrit Code Review
commit 993d833209
2 changed files with 133 additions and 3 deletions

View File

@ -14,6 +14,7 @@
import collections import collections
import copy
import glob import glob
import os import os
import re import re
@ -412,6 +413,8 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
{'target_portal': connection_properties[ {'target_portal': connection_properties[
'target_portal']}) 'target_portal']})
raise raise
old_node_startups = self._get_node_startup_values(
connection_properties)
out = self._run_iscsiadm_bare( out = self._run_iscsiadm_bare(
['-m', 'discoverydb', ['-m', 'discoverydb',
'-t', 'sendtargets', '-t', 'sendtargets',
@ -419,13 +422,19 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
'-p', connection_properties['target_portal'], '-p', connection_properties['target_portal'],
'--discover'], '--discover'],
check_exit_code=[0, 255])[0] or "" check_exit_code=[0, 255])[0] or ""
self._recover_node_startup_values(connection_properties,
old_node_startups)
else: else:
old_node_startups = self._get_node_startup_values(
connection_properties)
out = self._run_iscsiadm_bare( out = self._run_iscsiadm_bare(
['-m', 'discovery', ['-m', 'discovery',
'-t', 'sendtargets', '-t', 'sendtargets',
'-I', iscsi_transport, '-I', iscsi_transport,
'-p', connection_properties['target_portal']], '-p', connection_properties['target_portal']],
check_exit_code=[0, 255])[0] or "" check_exit_code=[0, 255])[0] or ""
self._recover_node_startup_values(connection_properties,
old_node_startups)
ips, iqns = self._get_target_portals_from_iscsiadm_output(out) ips, iqns = self._get_target_portals_from_iscsiadm_output(out)
luns = self._get_luns(connection_properties, iqns) luns = self._get_luns(connection_properties, iqns)
@ -1037,7 +1046,6 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
{'iqn': target_iqn, 'portal': portal, {'iqn': target_iqn, 'portal': portal,
'err': err.exit_code}) 'err': err.exit_code})
return None, None return None, None
self._iscsiadm_update(connection_properties, self._iscsiadm_update(connection_properties,
"node.startup", "node.startup",
"automatic") "automatic")
@ -1092,3 +1100,47 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
{'multipath_command': multipath_command, {'multipath_command': multipath_command,
'out': out, 'err': err}) 'out': out, 'err': err})
return (out, err) return (out, err)
def _get_node_startup_values(self, connection_properties):
out, __ = self._run_iscsiadm_bare(
['-m', 'node', '--op', 'show', '-p',
connection_properties['target_portal']]) or ""
node_values = out.strip()
node_values = node_values.split("\n")
iqn = None
startup = None
startup_values = {}
for node_value in node_values:
node_keys = node_value.split()
try:
if node_keys[0] == "node.name":
iqn = node_keys[2]
elif node_keys[0] == "node.startup":
startup = node_keys[2]
if iqn and startup:
startup_values[iqn] = startup
iqn = None
startup = None
except IndexError:
pass
return startup_values
def _recover_node_startup_values(self, connection_properties,
old_node_startups):
node_startups = self._get_node_startup_values(connection_properties)
for iqn, node_startup in node_startups.items():
old_node_startup = old_node_startups.get(iqn, None)
if old_node_startup and node_startup != old_node_startup:
# _iscsiadm_update() only uses "target_portal" and "target_iqn"
# of connection_properties.
# And the recovering target belongs to the same target_portal
# as discovering target.
# So target_iqn is updated, and other values aren't updated.
recover_connection = copy.deepcopy(connection_properties)
recover_connection['target_iqn'] = [iqn]
self._iscsiadm_update(recover_connection,
"node.startup",
old_node_startup)

View File

@ -459,9 +459,11 @@ class ISCSIConnectorTestCase(test_connector.ConnectorTestCase):
'auth_method': discovery_auth_method, 'auth_method': discovery_auth_method,
'username': discovery_auth_username, 'username': discovery_auth_username,
'password': discovery_auth_password}, 'password': discovery_auth_password},
'iscsiadm -m node --op show -p %s' % location,
'iscsiadm -m discoverydb -t sendtargets -I %(iface)s' 'iscsiadm -m discoverydb -t sendtargets -I %(iface)s'
' -p %(location)s --discover' % {'iface': interface, ' -p %(location)s --discover' % {'iface': interface,
'location': location}] 'location': location},
'iscsiadm -m node --op show -p %s' % location]
self.assertEqual(expected_cmds, self.cmds) self.assertEqual(expected_cmds, self.cmds)
# Reset to run with a different transport type # Reset to run with a different transport type
self.cmds = list() self.cmds = list()
@ -504,8 +506,10 @@ class ISCSIConnectorTestCase(test_connector.ConnectorTestCase):
expected_cmds = [ expected_cmds = [
'iscsiadm -m discoverydb -t sendtargets -p %s -I default' 'iscsiadm -m discoverydb -t sendtargets -p %s -I default'
' --op new' % location, ' --op new' % location,
'iscsiadm -m node --op show -p %s' % location,
'iscsiadm -m discoverydb -t sendtargets -I default -p %s' 'iscsiadm -m discoverydb -t sendtargets -I default -p %s'
' --discover' % location] ' --discover' % location,
'iscsiadm -m node --op show -p %s' % location]
self.assertEqual(expected_cmds, self.cmds) self.assertEqual(expected_cmds, self.cmds)
self.assertRaises(exception.TargetPortalNotFound, self.assertRaises(exception.TargetPortalNotFound,
@ -1447,3 +1451,77 @@ Setting up iSCSI targets: unused
mock.call('/dev/disk/by-id/scsi-wwn'), mock.call('/dev/disk/by-id/scsi-wwn'),
mock.call('/dev/disk/by-id/dm-...'), mock.call('/dev/disk/by-id/dm-...'),
mock.call('/dev/disk/by-id/scsi-...')]) mock.call('/dev/disk/by-id/scsi-...')])
@mock.patch.object(iscsi.ISCSIConnector, '_run_iscsiadm_bare')
def test_get_node_startup_values(self, run_iscsiadm_bare_mock):
name1 = 'volume-00000001-1'
name2 = 'volume-00000001-2'
name3 = 'volume-00000001-3'
vol = {'id': 1, 'name': name1}
location = '10.0.2.15:3260'
iqn1 = 'iqn.2010-10.org.openstack:%s' % name1
iqn2 = 'iqn.2010-10.org.openstack:%s' % name2
iqn3 = 'iqn.2010-10.org.openstack:%s' % name3
connection_properties = self.iscsi_connection(vol, [location], [iqn1])
node_startup1 = "manual"
node_startup2 = "automatic"
node_startup3 = "manual"
node_values = (
'# BEGIN RECORD 2.0-873\n'
'node.name = %s\n'
'node.tpgt = 1\n'
'node.startup = %s\n'
'iface.hwaddress = <empty>\n'
'# END RECORD\n'
'# BEGIN RECORD 2.0-873\n'
'node.name = %s\n'
'node.tpgt = 1\n'
'node.startup = %s\n'
'iface.hwaddress = <empty>\n'
'# END RECORD\n'
'# BEGIN RECORD 2.0-873\n'
'node.name = %s\n'
'node.tpgt = 1\n'
'node.startup = %s\n'
'iface.hwaddress = <empty>\n'
'# END RECORD\n') % (iqn1, node_startup1, iqn2, node_startup2,
iqn3, node_startup3)
run_iscsiadm_bare_mock.return_value = (node_values, None)
node_startups =\
self.connector._get_node_startup_values(
connection_properties['data'])
expected_node_startups = {iqn1: node_startup1, iqn2: node_startup2,
iqn3: node_startup3}
self.assertEqual(node_startups, expected_node_startups)
@mock.patch.object(iscsi.ISCSIConnector, '_get_node_startup_values')
@mock.patch.object(iscsi.ISCSIConnector, '_iscsiadm_update')
def test_recover_node_startup_values(self, iscsiadm_update_mock,
get_node_startup_values_mock):
name1 = 'volume-00000001-1'
name2 = 'volume-00000001-2'
name3 = 'volume-00000001-3'
vol = {'id': 1, 'name': name1}
location = '10.0.2.15:3260'
iqn1 = 'iqn.2010-10.org.openstack:%s' % name1
iqn2 = 'iqn.2010-10.org.openstack:%s' % name2
iqn3 = 'iqn.2010-10.org.openstack:%s' % name3
connection_properties = self.iscsi_connection(vol, [location], [iqn1])
recover_connection = self.iscsi_connection(vol, [location], [iqn2])
node_startup1 = "manual"
node_startup2 = "automatic"
node_startup3 = "manual"
get_node_startup_values_mock.return_value = {iqn1: node_startup1,
iqn2: node_startup2,
iqn3: node_startup3}
old_node_startup_values = {iqn1: node_startup1,
iqn2: "manual",
iqn3: node_startup3}
self.connector._recover_node_startup_values(
connection_properties['data'], old_node_startup_values)
iscsiadm_update_mock.assert_called_once_with(
recover_connection['data'], "node.startup", "manual")