Introduce configuration option [ipmi]ipmi_disable_timeout
Some type of BMCs don't support an IPMI option that disable the behavior of boot device timeout, which makes them never get booted from PXE. This patch extends the fix [1] by adding a configuration option, which provides the default ipmi behavior. [1] https://review.openstack.org/#/c/616053 Additionally revising the variable/setting names based upon review feedback and discussion that took place during the 20181210 weekly ironic team meeting. Change-Id: Ie049bbaf45aeab54c1272d1d561c5a6ca00dc34a Story: 2002977 Task: 22985
This commit is contained in:
parent
99d617ed4a
commit
d379357cad
@ -7,7 +7,7 @@
|
|||||||
"image_no_proxy": "A comma-separated list of host names, IP addresses and domain names (with optional :port) that will be excluded from proxying. To denote a domain name, use a dot to prefix the domain name. This value will be ignored if ``image_http_proxy`` and ``image_https_proxy`` are not specified. Optional.",
|
"image_no_proxy": "A comma-separated list of host names, IP addresses and domain names (with optional :port) that will be excluded from proxying. To denote a domain name, use a dot to prefix the domain name. This value will be ignored if ``image_http_proxy`` and ``image_https_proxy`` are not specified. Optional.",
|
||||||
"ipmi_address": "IP address or hostname of the node. Required.",
|
"ipmi_address": "IP address or hostname of the node. Required.",
|
||||||
"ipmi_bridging": "bridging_type; default is \"no\". One of \"single\", \"dual\", \"no\". Optional.",
|
"ipmi_bridging": "bridging_type; default is \"no\". One of \"single\", \"dual\", \"no\". Optional.",
|
||||||
"ipmi_disable_timeout": "By default ironic will send a raw IPMI command to disable the 60 second timeout for booting. Setting this option to False will NOT send that command; default value is True. Optional.",
|
"ipmi_disable_boot_timeout": "By default ironic will send a raw IPMI command to disable the 60 second timeout for booting. Setting this option to False will NOT send that command; default value is True. Optional.",
|
||||||
"ipmi_force_boot_device": "Whether Ironic should specify the boot device to the BMC each time the server is turned on, eg. because the BMC is not capable of remembering the selected boot device across power cycles; default value is False. Optional.",
|
"ipmi_force_boot_device": "Whether Ironic should specify the boot device to the BMC each time the server is turned on, eg. because the BMC is not capable of remembering the selected boot device across power cycles; default value is False. Optional.",
|
||||||
"ipmi_local_address": "local IPMB address for bridged requests. Used only if ipmi_bridging is set to \"single\" or \"dual\". Optional.",
|
"ipmi_local_address": "local IPMB address for bridged requests. Used only if ipmi_bridging is set to \"single\" or \"dual\". Optional.",
|
||||||
"ipmi_password": "password. Optional.",
|
"ipmi_password": "password. Optional.",
|
||||||
|
@ -41,6 +41,14 @@ opts = [
|
|||||||
'node power state if `ipmitool` process does not exit '
|
'node power state if `ipmitool` process does not exit '
|
||||||
'after `command_retry_timeout` timeout expires. '
|
'after `command_retry_timeout` timeout expires. '
|
||||||
'Recommended setting is True')),
|
'Recommended setting is True')),
|
||||||
|
cfg.BoolOpt('disable_boot_timeout',
|
||||||
|
default=True,
|
||||||
|
help=_('Default timeout behavior whether ironic sends a raw '
|
||||||
|
'IPMI command to disable the 60 second timeout for '
|
||||||
|
'booting. Setting this option to False will NOT send '
|
||||||
|
'that command, the default value is True. It may be '
|
||||||
|
'overridden by per-node \'ipmi_disable_boot_timeout\' '
|
||||||
|
'option in node\'s \'driver_info\' field.')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,11 +99,14 @@ OPTIONAL_PROPERTIES = {
|
|||||||
"capable of remembering the selected boot "
|
"capable of remembering the selected boot "
|
||||||
"device across power cycles; default value "
|
"device across power cycles; default value "
|
||||||
"is False. Optional."),
|
"is False. Optional."),
|
||||||
'ipmi_disable_timeout': _('By default ironic will send a raw IPMI '
|
'ipmi_disable_boot_timeout': _('By default ironic will send a raw IPMI '
|
||||||
'command to disable the 60 second timeout '
|
'command to disable the 60 second timeout '
|
||||||
'for booting. Setting this option to '
|
'for booting. Setting this option to '
|
||||||
'False will NOT send that command; default '
|
'False will NOT send that command on '
|
||||||
'value is True. Optional.'),
|
'this node. The '
|
||||||
|
'[ipmi]disable_boot_timeout will be '
|
||||||
|
'used if this option is not set. '
|
||||||
|
'Optional.'),
|
||||||
}
|
}
|
||||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||||
@ -963,8 +966,12 @@ class IPMIManagement(base.ManagementInterface):
|
|||||||
# NOTE(tonyb): Some BMCs do not implement Option 0x03, such as OpenBMC
|
# NOTE(tonyb): Some BMCs do not implement Option 0x03, such as OpenBMC
|
||||||
# and will error when we try to set this. Resulting in an abort. If
|
# and will error when we try to set this. Resulting in an abort. If
|
||||||
# the BMC doesn't support this timeout there isn't a need to disable
|
# the BMC doesn't support this timeout there isn't a need to disable
|
||||||
# it. Let's use a driver option to signify that
|
# it. Let's use a driver option to signify that.
|
||||||
idt = task.node.driver_info.get('ipmi_disable_timeout', True)
|
# NOTE(kaifeng) [ipmi]disable_boot_timeout provides default value if
|
||||||
|
# driver_info/ipmi_disable_boot_timeout is not set.
|
||||||
|
idt = task.node.driver_info.get('ipmi_disable_boot_timeout')
|
||||||
|
if idt is None:
|
||||||
|
idt = CONF.ipmi.disable_boot_timeout
|
||||||
if strutils.bool_from_string(idt):
|
if strutils.bool_from_string(idt):
|
||||||
# note(JayF): IPMI spec indicates unless you send these raw bytes
|
# note(JayF): IPMI spec indicates unless you send these raw bytes
|
||||||
# the boot device setting times out after 60s. Since it's possible
|
# the boot device setting times out after 60s. Since it's possible
|
||||||
@ -975,8 +982,8 @@ class IPMIManagement(base.ManagementInterface):
|
|||||||
send_raw(task, timeout_disable)
|
send_raw(task, timeout_disable)
|
||||||
else:
|
else:
|
||||||
LOG.info('For node %(node_uuid)s, '
|
LOG.info('For node %(node_uuid)s, '
|
||||||
'driver_info[\'ipmi_disable_timeout\'] is set to False, '
|
'driver_info[\'ipmi_disable_boot_timeout\'] is set '
|
||||||
'so not sending ipmi boot-timeout-disable',
|
'to False, so not sending ipmi boot-timeout-disable',
|
||||||
{'node_uuid', task.node.uuid})
|
{'node_uuid', task.node.uuid})
|
||||||
|
|
||||||
if task.node.driver_info.get('ipmi_force_boot_device', False):
|
if task.node.driver_info.get('ipmi_force_boot_device', False):
|
||||||
|
@ -6964,7 +6964,7 @@ class ManagerTestProperties(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
|||||||
'force_persistent_boot_device', 'ipmi_protocol_version',
|
'force_persistent_boot_device', 'ipmi_protocol_version',
|
||||||
'ipmi_force_boot_device', 'deploy_forces_oob_reboot',
|
'ipmi_force_boot_device', 'deploy_forces_oob_reboot',
|
||||||
'rescue_kernel', 'rescue_ramdisk',
|
'rescue_kernel', 'rescue_ramdisk',
|
||||||
'ipmi_disable_timeout']
|
'ipmi_disable_boot_timeout']
|
||||||
self._check_driver_properties("ipmi", expected)
|
self._check_driver_properties("ipmi", expected)
|
||||||
|
|
||||||
def test_driver_properties_snmp(self):
|
def test_driver_properties_snmp(self):
|
||||||
|
@ -1967,19 +1967,31 @@ class IPMIToolDriverTestCase(Base):
|
|||||||
task, 'fake-device')
|
task, 'fake-device')
|
||||||
|
|
||||||
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
||||||
def test_management_interface_set_boot_device_without_timeout(self,
|
def test_management_interface_set_boot_device_without_timeout_1(self,
|
||||||
mock_exec):
|
mock_exec):
|
||||||
mock_exec.return_value = [None, None]
|
mock_exec.return_value = [None, None]
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
driver_info = task.node.driver_info
|
driver_info = task.node.driver_info
|
||||||
driver_info['ipmi_disable_timeout'] = 'False'
|
driver_info['ipmi_disable_boot_timeout'] = 'False'
|
||||||
task.node.driver_info = driver_info
|
task.node.driver_info = driver_info
|
||||||
self.management.set_boot_device(task, boot_devices.PXE)
|
self.management.set_boot_device(task, boot_devices.PXE)
|
||||||
|
|
||||||
mock_calls = [mock.call(self.info, "chassis bootdev pxe")]
|
mock_calls = [mock.call(self.info, "chassis bootdev pxe")]
|
||||||
mock_exec.assert_has_calls(mock_calls)
|
mock_exec.assert_has_calls(mock_calls)
|
||||||
|
|
||||||
|
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
||||||
|
def test_management_interface_set_boot_device_without_timeout_2(self,
|
||||||
|
mock_exec):
|
||||||
|
CONF.set_override('disable_boot_timeout', False, 'ipmi')
|
||||||
|
mock_exec.return_value = [None, None]
|
||||||
|
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
|
self.management.set_boot_device(task, boot_devices.PXE)
|
||||||
|
|
||||||
|
mock_calls = [mock.call(self.info, "chassis bootdev pxe")]
|
||||||
|
mock_exec.assert_has_calls(mock_calls)
|
||||||
|
|
||||||
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
||||||
def test_management_interface_set_boot_device_exec_failed(self, mock_exec):
|
def test_management_interface_set_boot_device_exec_failed(self, mock_exec):
|
||||||
mock_exec.side_effect = processutils.ProcessExecutionError()
|
mock_exec.side_effect = processutils.ProcessExecutionError()
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds a configuration option ``[ipmi]disable_boot_timeout`` which is used
|
||||||
|
to set the default behavior whether ironic should send a raw IPMI command
|
||||||
|
to disable timeout. This configuration option can be overidden by the
|
||||||
|
per-node option ``ipmi_disable_boot_timeout`` in node's ``driver_info``
|
||||||
|
field.
|
||||||
|
See `story 2004266 <https://storyboard.openstack.org/#!/story/2004266>`_
|
||||||
|
and `Story 2002977 <https://storyboard.openstack.org/#!/story/2002977>`_
|
||||||
|
for additional information.
|
@ -6,8 +6,8 @@ fixes:
|
|||||||
received within 60-second timeout (countdown restarts when a Chassis
|
received within 60-second timeout (countdown restarts when a Chassis
|
||||||
Control command is received). Some BMCs do not support setting this; if
|
Control command is received). Some BMCs do not support setting this; if
|
||||||
sent it causes the boot to be aborted instead. For IPMI hardware type a
|
sent it causes the boot to be aborted instead. For IPMI hardware type a
|
||||||
new driver option ``node['driver_info']['ipmi_disable_timeout']`` can be
|
new driver option ``node['driver_info']['ipmi_disable_boot_timeout']`` can
|
||||||
specified. It is ``True`` by default; set it to ``False`` to bypass
|
be specified. It is ``True`` by default; set it to ``False`` to bypass
|
||||||
sending this command. See `story 2004266
|
sending this command. See `story 2004266
|
||||||
<https://storyboard.openstack.org/#!/story/2004266>`_ for additional
|
<https://storyboard.openstack.org/#!/story/2004266>`_ for additional
|
||||||
information.
|
information.
|
||||||
|
Loading…
Reference in New Issue
Block a user