Merge "Make iLO BIOS interface clean steps asynchronous"
This commit is contained in:
commit
0a8c9a25ed
ironic
releasenotes/notes
@ -21,12 +21,14 @@ from oslo_utils import importutils
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.common import states
|
||||
from ironic.conductor import utils as manager_utils
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
from ironic.drivers.modules.ilo import common as ilo_common
|
||||
from ironic import objects
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
ilo_error = importutils.try_import('proliantutils.exception')
|
||||
@ -51,6 +53,100 @@ class IloBIOS(base.BIOSInterface):
|
||||
"""
|
||||
ilo_common.parse_driver_info(task.node)
|
||||
|
||||
def _execute_pre_boot_bios_step(self, task, step, data=None):
|
||||
"""Perform operations required prior to the reboot.
|
||||
|
||||
Depending on the clean step, it executes the operations required
|
||||
and moves the node to CLEANWAIT state prior to reboot.
|
||||
:param task: a task from TaskManager.
|
||||
:param step: name of the clean step to be performed
|
||||
:param data: if the clean step is apply_configuration it holds
|
||||
the settings data.
|
||||
:raises: NodeCleaningFailure if it fails any conditions expected
|
||||
"""
|
||||
node = task.node
|
||||
|
||||
if step not in ('apply_configuration', 'factory_reset'):
|
||||
errmsg = _('Could not find the step %(step)s for the '
|
||||
'node %(node)s.')
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'step': step, 'node': node.uuid})
|
||||
|
||||
try:
|
||||
ilo_object = ilo_common.get_ilo_object(node)
|
||||
ilo_object.set_bios_settings(data) if step == (
|
||||
'apply_configuration') else ilo_object.reset_bios_to_default()
|
||||
except (exception.MissingParameterValue,
|
||||
exception.InvalidParameterValue,
|
||||
ilo_error.IloError,
|
||||
ilo_error.IloCommandNotSupportedError) as ir_exception:
|
||||
errmsg = _('Clean step %(step)s failed '
|
||||
'on the node %(node)s with error: %(err)s')
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'step': step, 'node': node.uuid,
|
||||
'err': ir_exception})
|
||||
|
||||
deploy_opts = deploy_utils.build_agent_options(node)
|
||||
task.driver.boot.prepare_ramdisk(task, deploy_opts)
|
||||
manager_utils.node_power_action(task, states.REBOOT)
|
||||
|
||||
driver_internal_info = node.driver_internal_info
|
||||
driver_internal_info['cleaning_reboot'] = True
|
||||
driver_internal_info['skip_current_clean_step'] = False
|
||||
|
||||
if step == 'apply_configuration':
|
||||
driver_internal_info['apply_bios'] = True
|
||||
else:
|
||||
driver_internal_info['reset_bios'] = True
|
||||
|
||||
node.driver_internal_info = driver_internal_info
|
||||
node.save()
|
||||
return states.CLEANWAIT
|
||||
|
||||
def _execute_post_boot_bios_step(self, task, step):
|
||||
"""Perform operations required after the reboot.
|
||||
|
||||
Caches BIOS settings in the database and clear the flags assocated
|
||||
with the clean step post reboot.
|
||||
:param task: a task from TaskManager.
|
||||
:param step: name of the clean step to be performed
|
||||
:raises: NodeCleaningFailure if it fails any conditions expected
|
||||
"""
|
||||
node = task.node
|
||||
|
||||
driver_internal_info = node.driver_internal_info
|
||||
driver_internal_info.pop('apply_bios', None)
|
||||
driver_internal_info.pop('reset_bios', None)
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
task.node.save()
|
||||
|
||||
if step not in ('apply_configuration', 'factory_reset'):
|
||||
errmsg = _('Could not find the step %(step)s for the '
|
||||
'node %(node)s.')
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'step': step, 'node': node.uuid})
|
||||
|
||||
try:
|
||||
ilo_object = ilo_common.get_ilo_object(node)
|
||||
status = ilo_object.get_bios_settings_result()
|
||||
except (exception.MissingParameterValue,
|
||||
exception.InvalidParameterValue,
|
||||
ilo_error.IloError,
|
||||
ilo_error.IloCommandNotSupportedError) as ir_exception:
|
||||
|
||||
errmsg = _('Clean step %(step)s failed '
|
||||
'on the node %(node)s with error: %(err)s')
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'step': step, 'node': node.uuid,
|
||||
'err': ir_exception})
|
||||
|
||||
if status.get('status') == 'failed':
|
||||
errmsg = _('Clean step %(step)s failed '
|
||||
'on the node %(node)s with error: %(err)s')
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'step': step, 'node': node.uuid,
|
||||
'err': status.get('results')})
|
||||
|
||||
@METRICS.timer('IloBIOS.apply_configuration')
|
||||
@base.clean_step(priority=0, abortable=False, argsinfo={
|
||||
'settings': {
|
||||
@ -67,24 +163,17 @@ class IloBIOS(base.BIOSInterface):
|
||||
the node fails.
|
||||
|
||||
"""
|
||||
node = task.node
|
||||
driver_internal_info = node.driver_internal_info
|
||||
data = {}
|
||||
for setting in settings:
|
||||
data.update({setting['name']: setting['value']})
|
||||
|
||||
node = task.node
|
||||
|
||||
errmsg = _("Clean step \"apply_configuration\" failed "
|
||||
"on node %(node)s with error: %(err)s")
|
||||
|
||||
try:
|
||||
ilo_object = ilo_common.get_ilo_object(node)
|
||||
ilo_object.set_bios_settings(data)
|
||||
except (exception.MissingParameterValue,
|
||||
exception.InvalidParameterValue,
|
||||
ilo_error.IloError,
|
||||
ilo_error.IloCommandNotSupportedError) as ir_exception:
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'node': node.uuid, 'err': ir_exception})
|
||||
if not driver_internal_info.get('apply_bios'):
|
||||
return self._execute_pre_boot_bios_step(
|
||||
task, 'apply_configuration', data)
|
||||
else:
|
||||
return self._execute_post_boot_bios_step(
|
||||
task, 'apply_configuration')
|
||||
|
||||
@METRICS.timer('IloBIOS.factory_reset')
|
||||
@base.clean_step(priority=0, abortable=False)
|
||||
@ -97,19 +186,12 @@ class IloBIOS(base.BIOSInterface):
|
||||
|
||||
"""
|
||||
node = task.node
|
||||
driver_internal_info = node.driver_internal_info
|
||||
|
||||
errmsg = _("Clean step \"factory_reset\" failed "
|
||||
"on node %(node)s with error: %(err)s")
|
||||
|
||||
try:
|
||||
ilo_object = ilo_common.get_ilo_object(node)
|
||||
ilo_object.reset_bios_to_default()
|
||||
except (exception.MissingParameterValue,
|
||||
exception.InvalidParameterValue,
|
||||
ilo_error.IloError,
|
||||
ilo_error.IloCommandNotSupportedError) as ir_exception:
|
||||
raise exception.NodeCleaningFailure(
|
||||
errmsg % {'node': node.uuid, 'err': ir_exception})
|
||||
if not driver_internal_info.get('reset_bios'):
|
||||
return self._execute_pre_boot_bios_step(task, 'factory_reset')
|
||||
else:
|
||||
return self._execute_post_boot_bios_step(task, 'factory_reset')
|
||||
|
||||
@METRICS.timer('IloBIOS.cache_bios_settings')
|
||||
def cache_bios_settings(self, task):
|
||||
@ -127,7 +209,7 @@ class IloBIOS(base.BIOSInterface):
|
||||
"on node %(node)s with error: %(err)s")
|
||||
try:
|
||||
ilo_object = ilo_common.get_ilo_object(node)
|
||||
bios_settings = ilo_object.get_pending_bios_settings()
|
||||
bios_settings = ilo_object.get_current_bios_settings()
|
||||
|
||||
except (exception.MissingParameterValue,
|
||||
exception.InvalidParameterValue,
|
||||
|
@ -21,6 +21,10 @@ from oslo_utils import importutils
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.conductor import utils as manager_utils
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
from ironic.drivers.modules.ilo import bios as ilo_bios
|
||||
from ironic.drivers.modules.ilo import boot as ilo_boot
|
||||
from ironic.drivers.modules.ilo import common as ilo_common
|
||||
from ironic import objects
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
@ -48,145 +52,356 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
task.driver.bios.validate(task)
|
||||
mock_drvinfo.assert_called_once_with(task.node)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def _test_ilo_error(self, error_type,
|
||||
test_methods_not_called, method_details, ilo_mock):
|
||||
error_dict = {
|
||||
"missing_parameter": exception.MissingParameterValue,
|
||||
"invalid_parameter": exception.InvalidParameterValue
|
||||
}
|
||||
|
||||
exc = error_dict.get(error_type)('error')
|
||||
ilo_mock.side_effect = exc
|
||||
def _test_ilo_error(self, exc_cls,
|
||||
test_methods_not_called,
|
||||
test_methods_called,
|
||||
method_details, exception_mock):
|
||||
exception_mock.side_effect = exc_cls('error')
|
||||
method = method_details.get("name")
|
||||
args = method_details.get("args")
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
method,
|
||||
*args)
|
||||
for test_method in test_methods_not_called:
|
||||
eval("ilo_mock.return_value.%s.assert_not_called()" % (
|
||||
test_method))
|
||||
test_method.assert_not_called()
|
||||
for called_method in test_methods_called:
|
||||
called_method["name"].assert_called_once_with(
|
||||
*called_method["args"])
|
||||
|
||||
@mock.patch.object(ilo_bios.IloBIOS, '_execute_post_boot_bios_step',
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_bios.IloBIOS, '_execute_pre_boot_bios_step',
|
||||
autospec=True)
|
||||
def test_apply_configuration_pre_boot(self, exe_pre_boot_mock,
|
||||
exe_post_boot_mock):
|
||||
settings = [
|
||||
{
|
||||
"name": "SET_A", "value": "VAL_A",
|
||||
},
|
||||
{
|
||||
"name": "SET_B", "value": "VAL_B",
|
||||
},
|
||||
{
|
||||
"name": "SET_C", "value": "VAL_C",
|
||||
},
|
||||
{
|
||||
"name": "SET_D", "value": "VAL_D",
|
||||
}
|
||||
]
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
driver_internal_info.pop('apply_bios', None)
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
task.node.save()
|
||||
actual_settings = {'SET_A': 'VAL_A', 'SET_B': 'VAL_B',
|
||||
'SET_C': 'VAL_C', 'SET_D': 'VAL_D'}
|
||||
task.driver.bios.apply_configuration(task, settings)
|
||||
|
||||
exe_pre_boot_mock.assert_called_once_with(
|
||||
task.driver.bios, task, 'apply_configuration', actual_settings)
|
||||
self.assertFalse(exe_post_boot_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_bios.IloBIOS, '_execute_post_boot_bios_step',
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_bios.IloBIOS, '_execute_pre_boot_bios_step',
|
||||
autospec=True)
|
||||
def test_apply_configuration_post_boot(self, exe_pre_boot_mock,
|
||||
exe_post_boot_mock):
|
||||
settings = [
|
||||
{
|
||||
"name": "SET_A", "value": "VAL_A",
|
||||
},
|
||||
{
|
||||
"name": "SET_B", "value": "VAL_B",
|
||||
},
|
||||
{
|
||||
"name": "SET_C", "value": "VAL_C",
|
||||
},
|
||||
{
|
||||
"name": "SET_D", "value": "VAL_D",
|
||||
}
|
||||
]
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
driver_internal_info['apply_bios'] = True
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
task.node.save()
|
||||
task.driver.bios.apply_configuration(task, settings)
|
||||
|
||||
exe_post_boot_mock.assert_called_once_with(
|
||||
task.driver.bios, task, 'apply_configuration')
|
||||
self.assertFalse(exe_pre_boot_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_boot.IloVirtualMediaBoot, 'prepare_ramdisk',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'build_agent_options', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test_apply_configuration(self, get_ilo_object_mock):
|
||||
def test__execute_pre_boot_bios_step_apply_configuration(
|
||||
self, get_ilo_object_mock, build_agent_mock,
|
||||
node_power_mock, prepare_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
data = [
|
||||
{
|
||||
"name": "SET_A", "value": "VAL_A",
|
||||
},
|
||||
{
|
||||
"name": "SET_B", "value": "VAL_B",
|
||||
},
|
||||
{
|
||||
"name": "SET_C", "value": "VAL_C",
|
||||
},
|
||||
{
|
||||
"name": "SET_D", "value": "VAL_D",
|
||||
}
|
||||
]
|
||||
task.driver.bios.apply_configuration(task, data)
|
||||
expected = {
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
ilo_object_mock.set_bios_settings.assert_called_once_with(expected)
|
||||
|
||||
def test_apply_configuration_missing_parameter(self):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.apply_configuration,
|
||||
"args": (task, [])
|
||||
}
|
||||
self._test_ilo_error("missing_parameter", ["set_bios_settings"],
|
||||
mdobj)
|
||||
|
||||
def test_apply_configuration_invalid_parameter(self):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.apply_configuration,
|
||||
"args": (task, [])
|
||||
}
|
||||
self._test_ilo_error("invalid_parameter", ["set_bios_settings"],
|
||||
mdobj)
|
||||
step = 'apply_configuration'
|
||||
task.driver.bios._execute_pre_boot_bios_step(task, step, data)
|
||||
driver_info = task.node.driver_internal_info
|
||||
self.assertTrue(
|
||||
all(x in driver_info for x in (
|
||||
'apply_bios', 'cleaning_reboot',
|
||||
'skip_current_clean_step')))
|
||||
ilo_object_mock.set_bios_settings.assert_called_once_with(data)
|
||||
self.assertFalse(ilo_object_mock.reset_bios_to_default.called)
|
||||
build_agent_mock.assert_called_once_with(task.node)
|
||||
self.assertTrue(prepare_mock.called)
|
||||
self.assertTrue(node_power_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_boot.IloVirtualMediaBoot, 'prepare_ramdisk',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'build_agent_options', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test_apply_configuration_with_ilo_error(self, get_ilo_object_mock):
|
||||
def test__execute_pre_boot_bios_step_factory_reset(
|
||||
self, get_ilo_object_mock, build_agent_mock,
|
||||
node_power_mock, prepare_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
data = [
|
||||
{
|
||||
"name": "SET_A", "value": "VAL_A",
|
||||
},
|
||||
{
|
||||
"name": "SET_B", "value": "VAL_B",
|
||||
},
|
||||
]
|
||||
exc = ilo_error.IloError('error')
|
||||
ilo_object_mock.set_bios_settings.side_effect = exc
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios.apply_configuration,
|
||||
task, data)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test_factory_reset(self, get_ilo_object_mock):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
task.driver.bios.factory_reset(task)
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
step = 'factory_reset'
|
||||
task.driver.bios._execute_pre_boot_bios_step(task, step, data)
|
||||
driver_info = task.node.driver_internal_info
|
||||
self.assertTrue(
|
||||
all(x in driver_info for x in (
|
||||
'reset_bios', 'cleaning_reboot',
|
||||
'skip_current_clean_step')))
|
||||
ilo_object_mock.reset_bios_to_default.assert_called_once_with()
|
||||
|
||||
def test_factory_reset_missing_parameter(self):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.factory_reset,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error("missing_parameter",
|
||||
["reset_bios_to_default"], mdobj)
|
||||
|
||||
def test_factory_reset_invalid_parameter(self):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.factory_reset,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error("invalid_parameter",
|
||||
["reset_bios_to_default"], mdobj)
|
||||
self.assertFalse(ilo_object_mock.set_bios_settings.called)
|
||||
build_agent_mock.assert_called_once_with(task.node)
|
||||
self.assertTrue(prepare_mock.called)
|
||||
self.assertTrue(node_power_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test_factory_reset_with_ilo_error(self, get_ilo_object_mock):
|
||||
def test__execute_pre_boot_bios_step_invalid(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
exc = ilo_error.IloError('error')
|
||||
ilo_object_mock.reset_bios_to_default.side_effect = exc
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
step = 'invalid_step'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios.factory_reset, task)
|
||||
task.driver.bios._execute_pre_boot_bios_step,
|
||||
task, step, data)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test_factory_reset_with_unknown_error(self, get_ilo_object_mock):
|
||||
def test__execute_pre_boot_bios_step_iloobj_failed(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
exc = ilo_error.IloCommandNotSupportedError('error')
|
||||
ilo_object_mock.reset_bios_to_default.side_effect = exc
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
get_ilo_object_mock.side_effect = exception.MissingParameterValue(
|
||||
'err')
|
||||
step = 'apply_configuration'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios.factory_reset, task)
|
||||
task.driver.bios._execute_pre_boot_bios_step,
|
||||
task, step, data)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_pre_boot_bios_step_set_bios_failed(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
ilo_object_mock.set_bios_settings.side_effect = ilo_error.IloError(
|
||||
'err')
|
||||
step = 'apply_configuration'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios._execute_pre_boot_bios_step,
|
||||
task, step, data)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_pre_boot_bios_step_reset_bios_failed(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
data = {
|
||||
"SET_A": "VAL_A",
|
||||
"SET_B": "VAL_B",
|
||||
"SET_C": "VAL_C",
|
||||
"SET_D": "VAL_D"
|
||||
}
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
ilo_object_mock.reset_bios_to_default.side_effect = (
|
||||
ilo_error.IloError('err'))
|
||||
step = 'factory_reset'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios._execute_pre_boot_bios_step,
|
||||
task, step, data)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_step_apply_configuration(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'apply_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
step = 'apply_configuration'
|
||||
task.driver.bios._execute_post_boot_bios_step(task, step)
|
||||
driver_info = task.node.driver_internal_info
|
||||
self.assertTrue('apply_bios' not in driver_info)
|
||||
ilo_object_mock.get_bios_settings_result.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_step_factory_reset(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'reset_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
step = 'factory_reset'
|
||||
task.driver.bios._execute_post_boot_bios_step(task, step)
|
||||
driver_info = task.node.driver_internal_info
|
||||
self.assertTrue('reset_bios' not in driver_info)
|
||||
ilo_object_mock.get_bios_settings_result.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_step_invalid(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'apply_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
step = 'invalid_step'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios._execute_post_boot_bios_step,
|
||||
task, step)
|
||||
self.assertTrue(
|
||||
'apply_bios' not in task.node.driver_internal_info)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_step_iloobj_failed(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'apply_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
get_ilo_object_mock.side_effect = exception.MissingParameterValue(
|
||||
'err')
|
||||
step = 'apply_configuration'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios._execute_post_boot_bios_step,
|
||||
task, step)
|
||||
self.assertTrue(
|
||||
'apply_bios' not in task.node.driver_internal_info)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_get_settings_error(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'apply_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
|
||||
step = 'apply_configuration'
|
||||
mdobj = {
|
||||
"name": task.driver.bios._execute_post_boot_bios_step,
|
||||
"args": (task, step,)
|
||||
}
|
||||
|
||||
self._test_ilo_error(ilo_error.IloCommandNotSupportedError,
|
||||
[],
|
||||
[], mdobj,
|
||||
ilo_object_mock.get_bios_settings_result)
|
||||
self.assertTrue(
|
||||
'apply_bios' not in task.node.driver_internal_info)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||
autospec=True)
|
||||
def test__execute_post_boot_bios_get_settings_failed(
|
||||
self, get_ilo_object_mock):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
driver_info = task.node.driver_internal_info
|
||||
driver_info.update({'reset_bios': True})
|
||||
task.node.driver_internal_info = driver_info
|
||||
task.node.save()
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
ilo_object_mock.get_bios_settings_result.return_value = (
|
||||
{'status': 'failed', 'message': 'Some data'})
|
||||
step = 'factory_reset'
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios._execute_post_boot_bios_step,
|
||||
task, step)
|
||||
self.assertTrue(
|
||||
'reset_bios' not in task.node.driver_internal_info)
|
||||
|
||||
@mock.patch.object(objects.BIOSSettingList, 'create')
|
||||
@mock.patch.object(objects.BIOSSettingList, 'save')
|
||||
@ -205,7 +420,7 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
"SET_D": True
|
||||
}
|
||||
|
||||
ilo_object_mock.get_pending_bios_settings.return_value = settings
|
||||
ilo_object_mock.get_current_bios_settings.return_value = settings
|
||||
expected_bios_settings = [
|
||||
{"name": "SET_A", "value": True},
|
||||
{"name": "SET_B", "value": True},
|
||||
@ -230,7 +445,7 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
)
|
||||
sync_node_mock.return_value = all_settings
|
||||
task.driver.bios.cache_bios_settings(task)
|
||||
ilo_object_mock.get_pending_bios_settings.assert_called_once_with()
|
||||
ilo_object_mock.get_current_bios_settings.assert_called_once_with()
|
||||
actual_arg = sorted(sync_node_mock.call_args[0][2],
|
||||
key=lambda x: x.get("name"))
|
||||
expected_arg = sorted(expected_bios_settings,
|
||||
@ -244,25 +459,29 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
delete_mock.assert_called_once_with(
|
||||
self.context, task.node.id, del_names)
|
||||
|
||||
def test_cache_bios_settings_missing_parameter(self):
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
|
||||
def test_cache_bios_settings_missing_parameter(self, get_ilo_object_mock):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.cache_bios_settings,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error("missing_parameter",
|
||||
["get_pending_bios_settings"], mdobj)
|
||||
self._test_ilo_error(exception.MissingParameterValue,
|
||||
[],
|
||||
[], mdobj, get_ilo_object_mock)
|
||||
|
||||
def test_cache_bios_settings_invalid_parameter(self):
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
|
||||
def test_cache_bios_settings_invalid_parameter(self, get_ilo_object_mock):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
mdobj = {
|
||||
"name": task.driver.bios.cache_bios_settings,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error("invalid_parameter",
|
||||
["get_pending_bios_settings"], mdobj)
|
||||
self._test_ilo_error(exception.InvalidParameterValue,
|
||||
[],
|
||||
[], mdobj, get_ilo_object_mock)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
|
||||
def test_cache_bios_settings_with_ilo_error(self, get_ilo_object_mock):
|
||||
@ -270,10 +489,15 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
exc = ilo_error.IloError('error')
|
||||
ilo_object_mock.get_pending_bios_settings.side_effect = exc
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios.cache_bios_settings, task)
|
||||
mdobj = {
|
||||
"name": task.driver.bios.cache_bios_settings,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error(ilo_error.IloError,
|
||||
[],
|
||||
[],
|
||||
mdobj,
|
||||
ilo_object_mock.get_current_bios_settings)
|
||||
|
||||
@mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
|
||||
def test_cache_bios_settings_with_unknown_error(self, get_ilo_object_mock):
|
||||
@ -281,7 +505,13 @@ class IloBiosTestCase(test_common.BaseIloTest):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
ilo_object_mock = get_ilo_object_mock.return_value
|
||||
exc = ilo_error.IloCommandNotSupportedError('error')
|
||||
ilo_object_mock.get_pending_bios_settings.side_effect = exc
|
||||
self.assertRaises(exception.NodeCleaningFailure,
|
||||
task.driver.bios.cache_bios_settings, task)
|
||||
|
||||
mdobj = {
|
||||
"name": task.driver.bios.cache_bios_settings,
|
||||
"args": (task,)
|
||||
}
|
||||
self._test_ilo_error(ilo_error.IloCommandNotSupportedError,
|
||||
[],
|
||||
[],
|
||||
mdobj,
|
||||
ilo_object_mock.get_current_bios_settings)
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Makes all ``ilo`` driver BIOS interface clean steps as asynchronous. This is
|
||||
required to ensure the settings on the baremetal node are consistent with
|
||||
the settings stored in the database irrespective of the node clean step
|
||||
status. Refer bug `2004066
|
||||
<https://storyboard.openstack.org/#!/story/2004066>`_ for details.
|
Loading…
x
Reference in New Issue
Block a user