Merge "Handle diskless hardware connected to remote iscsi"

This commit is contained in:
Jenkins 2016-07-21 14:39:36 +00:00 committed by Gerrit Code Review
commit 5d012b43bd
4 changed files with 55 additions and 6 deletions

@ -73,6 +73,27 @@ def _udev_settle():
return return
def _check_for_iscsi():
"""Connect iSCSI shared connected via iBFT or OF.
iscsistart -f will print the iBFT or OF info.
In case such connection exists, we would like to issue
iscsistart -b to create a session to the target.
- if no connection is detected we simply return.
"""
try:
utils.execute('iscsistart', '-f')
except (processutils.ProcessExecutionError, EnvironmentError) as e:
LOG.debug("No iscsi connection detected. Skipping iscsi. "
"Error: %s", e)
return
try:
utils.execute('iscsistart', '-b')
except processutils.ProcessExecutionError as e:
LOG.warning("Something went wrong executing 'iscsistart -b' "
"Error: %s", e)
def list_all_block_devices(block_type='disk'): def list_all_block_devices(block_type='disk'):
"""List all physical block devices """List all physical block devices
@ -86,7 +107,6 @@ def list_all_block_devices(block_type='disk'):
:param block_type: Type of block device to find :param block_type: Type of block device to find
:return: A list of BlockDevices :return: A list of BlockDevices
""" """
_udev_settle() _udev_settle()
columns = ['KNAME', 'MODEL', 'SIZE', 'ROTA', 'TYPE'] columns = ['KNAME', 'MODEL', 'SIZE', 'ROTA', 'TYPE']
@ -425,6 +445,7 @@ class GenericHardwareManager(HardwareManager):
def evaluate_hardware_support(self): def evaluate_hardware_support(self):
# Do some initialization before we declare ourself ready # Do some initialization before we declare ourself ready
_check_for_iscsi()
self._wait_for_disks() self._wait_for_disks()
return HardwareSupport.GENERIC return HardwareSupport.GENERIC

@ -271,9 +271,10 @@ class TestBaseAgent(test_base.BaseTestCase):
@mock.patch.object(time, 'sleep', autospec=True) @mock.patch.object(time, 'sleep', autospec=True)
@mock.patch('wsgiref.simple_server.make_server', autospec=True) @mock.patch('wsgiref.simple_server.make_server', autospec=True)
@mock.patch.object(hardware, '_check_for_iscsi', autospec=True)
@mock.patch.object(hardware.HardwareManager, 'list_hardware_info') @mock.patch.object(hardware.HardwareManager, 'list_hardware_info')
def test_run_with_sleep(self, mocked_list_hardware, wsgi_server_cls, def test_run_with_sleep(self, mock_check_for_iscsi, mocked_list_hardware,
mocked_sleep): wsgi_server_cls, mocked_sleep):
CONF.set_override('inspection_callback_url', '', enforce_type=True) CONF.set_override('inspection_callback_url', '', enforce_type=True)
wsgi_server = wsgi_server_cls.return_value wsgi_server = wsgi_server_cls.return_value
wsgi_server.start.side_effect = KeyboardInterrupt() wsgi_server.start.side_effect = KeyboardInterrupt()
@ -299,6 +300,7 @@ class TestBaseAgent(test_base.BaseTestCase):
self.agent.heartbeater.start.assert_called_once_with() self.agent.heartbeater.start.assert_called_once_with()
mocked_sleep.assert_called_once_with(10) mocked_sleep.assert_called_once_with(10)
self.assertTrue(mock_check_for_iscsi.called)
def test_async_command_success(self): def test_async_command_success(self):
result = base.AsyncCommandResult('foo_command', {'fail': False}, result = base.AsyncCommandResult('foo_command', {'fail': False},
@ -437,10 +439,11 @@ class TestAdvertiseAddress(test_base.BaseTestCase):
self.assertFalse(mock_exec.called) self.assertFalse(mock_exec.called)
self.assertFalse(mock_gethostbyname.called) self.assertFalse(mock_gethostbyname.called)
@mock.patch.object(hardware, '_check_for_iscsi', autospec=True)
@mock.patch.object(hardware.GenericHardwareManager, 'get_ipv4_addr', @mock.patch.object(hardware.GenericHardwareManager, 'get_ipv4_addr',
autospec=True) autospec=True)
def test_with_network_interface(self, mock_get_ipv4, mock_exec, def test_with_network_interface(self, mock_get_ipv4, mock_check_for_iscsi,
mock_gethostbyname): mock_exec, mock_gethostbyname):
self.agent.network_interface = 'em1' self.agent.network_interface = 'em1'
mock_get_ipv4.return_value = '1.2.3.4' mock_get_ipv4.return_value = '1.2.3.4'
@ -450,10 +453,14 @@ class TestAdvertiseAddress(test_base.BaseTestCase):
mock_get_ipv4.assert_called_once_with(mock.ANY, 'em1') mock_get_ipv4.assert_called_once_with(mock.ANY, 'em1')
self.assertFalse(mock_exec.called) self.assertFalse(mock_exec.called)
self.assertFalse(mock_gethostbyname.called) self.assertFalse(mock_gethostbyname.called)
self.assertTrue(mock_check_for_iscsi.called)
@mock.patch.object(hardware, '_check_for_iscsi', autospec=True)
@mock.patch.object(hardware.GenericHardwareManager, 'get_ipv4_addr', @mock.patch.object(hardware.GenericHardwareManager, 'get_ipv4_addr',
autospec=True) autospec=True)
def test_with_network_interface_failed(self, mock_get_ipv4, mock_exec, def test_with_network_interface_failed(self, mock_get_ipv4,
mock_check_for_iscsi,
mock_exec,
mock_gethostbyname): mock_gethostbyname):
self.agent.network_interface = 'em1' self.agent.network_interface = 'em1'
mock_get_ipv4.return_value = None mock_get_ipv4.return_value = None
@ -464,6 +471,7 @@ class TestAdvertiseAddress(test_base.BaseTestCase):
mock_get_ipv4.assert_called_once_with(mock.ANY, 'em1') mock_get_ipv4.assert_called_once_with(mock.ANY, 'em1')
self.assertFalse(mock_exec.called) self.assertFalse(mock_exec.called)
self.assertFalse(mock_gethostbyname.called) self.assertFalse(mock_gethostbyname.called)
self.assertTrue(mock_check_for_iscsi.called)
def test_route_with_ip(self, mock_exec, mock_gethostbyname): def test_route_with_ip(self, mock_exec, mock_gethostbyname):
self.agent.api_url = 'http://1.2.1.2:8081/v1' self.agent.api_url = 'http://1.2.1.2:8081/v1'

@ -1241,9 +1241,11 @@ class TestGenericHardwareManager(test_base.BaseTestCase):
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices', @mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
autospec=True) autospec=True)
@mock.patch.object(hardware, '_check_for_iscsi', autospec=True)
@mock.patch.object(time, 'sleep', autospec=True) @mock.patch.object(time, 'sleep', autospec=True)
@mock.patch.object(utils, 'guess_root_disk', autospec=True) @mock.patch.object(utils, 'guess_root_disk', autospec=True)
def test_evaluate_hw_waits_for_disks(self, mocked_root_dev, mocked_sleep, def test_evaluate_hw_waits_for_disks(self, mocked_root_dev, mocked_sleep,
mocked_check_for_iscsi,
mocked_block_dev): mocked_block_dev):
mocked_root_dev.side_effect = [ mocked_root_dev.side_effect = [
errors.DeviceNotFound('boom'), errors.DeviceNotFound('boom'),
@ -1252,6 +1254,7 @@ class TestGenericHardwareManager(test_base.BaseTestCase):
result = self.hardware.evaluate_hardware_support() result = self.hardware.evaluate_hardware_support()
self.assertTrue(mocked_check_for_iscsi.called)
self.assertEqual(hardware.HardwareSupport.GENERIC, result) self.assertEqual(hardware.HardwareSupport.GENERIC, result)
mocked_root_dev.assert_called_with(mocked_block_dev.return_value) mocked_root_dev.assert_called_with(mocked_block_dev.return_value)
self.assertEqual(2, mocked_root_dev.call_count) self.assertEqual(2, mocked_root_dev.call_count)
@ -1335,9 +1338,11 @@ class TestGenericHardwareManager(test_base.BaseTestCase):
@mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices', @mock.patch.object(hardware.GenericHardwareManager, 'list_block_devices',
autospec=True) autospec=True)
@mock.patch.object(hardware, '_check_for_iscsi', autospec=True)
@mock.patch.object(time, 'sleep', autospec=True) @mock.patch.object(time, 'sleep', autospec=True)
@mock.patch.object(utils, 'guess_root_disk', autospec=True) @mock.patch.object(utils, 'guess_root_disk', autospec=True)
def test_evaluate_hw_disks_timeout(self, mocked_root_dev, mocked_sleep, def test_evaluate_hw_disks_timeout(self, mocked_root_dev, mocked_sleep,
mocked_check_for_iscsi,
mocked_block_dev): mocked_block_dev):
mocked_root_dev.side_effect = errors.DeviceNotFound('boom') mocked_root_dev.side_effect = errors.DeviceNotFound('boom')
@ -1419,6 +1424,18 @@ class TestModuleFunctions(test_base.BaseTestCase):
hardware._udev_settle() hardware._udev_settle()
mocked_execute.assert_called_once_with('udevadm', 'settle') mocked_execute.assert_called_once_with('udevadm', 'settle')
def test__check_for_iscsi(self, mocked_execute):
hardware._check_for_iscsi()
mocked_execute.assert_has_calls([
mock.call('iscsistart', '-f'),
mock.call('iscsistart', '-b')])
def test__check_for_iscsi_no_iscsi(self, mocked_execute):
mocked_execute.side_effect = processutils.ProcessExecutionError()
hardware._check_for_iscsi()
mocked_execute.assert_has_calls([
mock.call('iscsistart', '-f')])
def create_hdparm_info(supported=False, enabled=False, frozen=False, def create_hdparm_info(supported=False, enabled=False, frozen=False,
enhanced_erase=False): enhanced_erase=False):

@ -0,0 +1,3 @@
---
fixes:
- If iscsi connection present, connect an iSCSI target share before detecting disks.