Adds support SUM based firmware update as deploy step
SUM based firmware update exists as an inband clean step. This commit adds it as inband deploy step to `ilo` and `ilo5` hardware types. Change-Id: I2ac03dc2148a56aa23e86c6adb29a16bac443de3 Story: #2007923 Task: #40337
This commit is contained in:
parent
35e76ad82d
commit
bc0cc8a8fa
@ -4,7 +4,7 @@
|
|||||||
# python projects they should package as optional dependencies for Ironic.
|
# python projects they should package as optional dependencies for Ironic.
|
||||||
|
|
||||||
# These are available on pypi
|
# These are available on pypi
|
||||||
proliantutils>=2.9.1
|
proliantutils>=2.9.5
|
||||||
pysnmp>=4.3.0,<5.0.0
|
pysnmp>=4.3.0,<5.0.0
|
||||||
python-scciclient>=0.8.0
|
python-scciclient>=0.8.0
|
||||||
python-dracclient>=3.1.0,<5.0.0
|
python-dracclient>=3.1.0,<5.0.0
|
||||||
|
@ -524,12 +524,43 @@ class IloManagement(base.ManagementInterface):
|
|||||||
@base.clean_step(priority=0, abortable=False,
|
@base.clean_step(priority=0, abortable=False,
|
||||||
argsinfo=_FIRMWARE_UPDATE_SUM_ARGSINFO)
|
argsinfo=_FIRMWARE_UPDATE_SUM_ARGSINFO)
|
||||||
def update_firmware_sum(self, task, **kwargs):
|
def update_firmware_sum(self, task, **kwargs):
|
||||||
"""Updates the firmware using Smart Update Manager (SUM).
|
"""Clean step to update the firmware using Smart Update Manager (SUM)
|
||||||
|
|
||||||
:param task: a TaskManager object.
|
:param task: a TaskManager object.
|
||||||
:raises: NodeCleaningFailure, on failure to execute of clean step.
|
:raises: NodeCleaningFailure, on failure to execute of clean step.
|
||||||
|
:returns: states.CLEANWAIT to signify the step will be completed async
|
||||||
|
"""
|
||||||
|
return self._do_update_firmware_sum(task, **kwargs)
|
||||||
|
|
||||||
|
@METRICS.timer('IloManagement.update_firmware_sum')
|
||||||
|
@base.deploy_step(priority=0, argsinfo=_FIRMWARE_UPDATE_SUM_ARGSINFO)
|
||||||
|
def flash_firmware_sum(self, task, **kwargs):
|
||||||
|
"""Deploy step to Update the firmware using Smart Update Manager (SUM).
|
||||||
|
|
||||||
|
:param task: a TaskManager object.
|
||||||
|
:raises: InstanceDeployFailure, on failure to execute of deploy step.
|
||||||
|
:returns: states.DEPLOYWAIT to signify the step will be completed
|
||||||
|
async
|
||||||
|
"""
|
||||||
|
return self._do_update_firmware_sum(task, **kwargs)
|
||||||
|
|
||||||
|
def _do_update_firmware_sum(self, task, **kwargs):
|
||||||
|
"""Update the firmware using Smart Update Manager (SUM).
|
||||||
|
|
||||||
|
:param task: a TaskManager object.
|
||||||
|
:raises: NodeCleaningFailure or InstanceDeployFailure, on failure to
|
||||||
|
execute of clean or deploy step respectively.
|
||||||
|
:returns: states.CLEANWAIT or states.DEPLOYWAIT to signify the step
|
||||||
|
will be completed async for clean or deploy step respectively.
|
||||||
"""
|
"""
|
||||||
node = task.node
|
node = task.node
|
||||||
|
if node.provision_state == states.DEPLOYING:
|
||||||
|
step = node.deploy_step
|
||||||
|
step_type = 'deploy'
|
||||||
|
else:
|
||||||
|
step = node.clean_step
|
||||||
|
step_type = 'clean'
|
||||||
|
|
||||||
# The arguments are validated and sent to the ProliantHardwareManager
|
# The arguments are validated and sent to the ProliantHardwareManager
|
||||||
# to perform SUM based firmware update clean step.
|
# to perform SUM based firmware update clean step.
|
||||||
firmware_processor.get_and_validate_firmware_image_info(kwargs,
|
firmware_processor.get_and_validate_firmware_image_info(kwargs,
|
||||||
@ -538,24 +569,25 @@ class IloManagement(base.ManagementInterface):
|
|||||||
url = kwargs['url']
|
url = kwargs['url']
|
||||||
if urlparse.urlparse(url).scheme == 'swift':
|
if urlparse.urlparse(url).scheme == 'swift':
|
||||||
url = firmware_processor.get_swift_url(urlparse.urlparse(url))
|
url = firmware_processor.get_swift_url(urlparse.urlparse(url))
|
||||||
node.clean_step['args']['url'] = url
|
step['args']['url'] = url
|
||||||
|
|
||||||
# Insert SPP ISO into virtual media CDROM
|
# Insert SPP ISO into virtual media CDROM
|
||||||
ilo_common.attach_vmedia(node, 'CDROM', url)
|
ilo_common.attach_vmedia(node, 'CDROM', url)
|
||||||
|
|
||||||
step = node.clean_step
|
return agent_base.execute_step(task, step, step_type)
|
||||||
return agent_base.execute_clean_step(task, step)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@agent_base.post_deploy_step_hook(
|
||||||
|
interface='management', step='flash_firmware_sum')
|
||||||
@agent_base.post_clean_step_hook(
|
@agent_base.post_clean_step_hook(
|
||||||
interface='management', step='update_firmware_sum')
|
interface='management', step='update_firmware_sum')
|
||||||
def _update_firmware_sum_final(task, command):
|
def _update_firmware_sum_final(task, command):
|
||||||
"""Clean step hook after SUM based firmware update operation.
|
"""Deploy/Clean step hook after SUM based firmware update operation.
|
||||||
|
|
||||||
This method is invoked as a post clean step hook by the Ironic
|
This method is invoked as a post deploy/clean step hook by the Ironic
|
||||||
conductor once firmware update operaion is completed. The clean logs
|
conductor once firmware update operaion is completed. The deploy/clean
|
||||||
are collected and stored according to the configured storage backend
|
logs are collected and stored according to the configured storage
|
||||||
when the node is configured to collect the logs.
|
backend when the node is configured to collect the logs.
|
||||||
|
|
||||||
:param task: a TaskManager instance.
|
:param task: a TaskManager instance.
|
||||||
:param command: A command result structure of the SUM based firmware
|
:param command: A command result structure of the SUM based firmware
|
||||||
@ -565,12 +597,16 @@ class IloManagement(base.ManagementInterface):
|
|||||||
if not _should_collect_logs(command):
|
if not _should_collect_logs(command):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if task.node.provision_state == states.DEPLOYWAIT:
|
||||||
|
log_data = command['command_result']['deploy_result']['Log Data']
|
||||||
|
label = command['command_result']['deploy_step']['step']
|
||||||
|
else:
|
||||||
|
log_data = command['command_result']['clean_result']['Log Data']
|
||||||
|
label = command['command_result']['clean_step']['step']
|
||||||
|
|
||||||
node = task.node
|
node = task.node
|
||||||
try:
|
try:
|
||||||
driver_utils.store_ramdisk_logs(
|
driver_utils.store_ramdisk_logs(node, log_data, label=label)
|
||||||
node,
|
|
||||||
command['command_result']['clean_result']['Log Data'],
|
|
||||||
label='update_firmware_sum')
|
|
||||||
except exception.SwiftOperationError as e:
|
except exception.SwiftOperationError as e:
|
||||||
LOG.error('Failed to store the logs from the node %(node)s '
|
LOG.error('Failed to store the logs from the node %(node)s '
|
||||||
'for "update_firmware_sum" clean step in Swift. '
|
'for "update_firmware_sum" clean step in Swift. '
|
||||||
|
@ -827,177 +827,388 @@ class IloManagementTestCase(test_common.BaseIloTest):
|
|||||||
|
|
||||||
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch.object(agent_base, 'execute_clean_step', autospec=True)
|
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
||||||
def test_update_firmware_sum_mode_with_component(
|
def _test_write_firmware_sum_mode_with_component(
|
||||||
self, execute_mock, attach_vmedia_mock):
|
self, execute_mock, attach_vmedia_mock, step_type='clean'):
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
execute_mock.return_value = states.CLEANWAIT
|
|
||||||
# | GIVEN |
|
# | GIVEN |
|
||||||
firmware_update_args = {
|
firmware_update_args = {
|
||||||
'url': 'http://any_url',
|
'url': 'http://any_url',
|
||||||
'checksum': 'xxxx',
|
'checksum': 'xxxx',
|
||||||
'component': ['CP02345.scexe', 'CP02567.exe']}
|
'component': ['CP02345.scexe', 'CP02567.exe']}
|
||||||
clean_step = {'step': 'update_firmware',
|
step = {'interface': 'management',
|
||||||
'interface': 'management',
|
'args': firmware_update_args}
|
||||||
'args': firmware_update_args}
|
if step_type == 'clean':
|
||||||
task.node.clean_step = clean_step
|
step['step'] = 'update_firmware_sum'
|
||||||
|
task.node.provision_state = states.CLEANING
|
||||||
|
execute_mock.return_value = states.CLEANWAIT
|
||||||
|
task.node.clean_step = step
|
||||||
|
func = task.driver.management.update_firmware_sum
|
||||||
|
exp_ret_state = states.CLEANWAIT
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
task.node.provision_state = states.DEPLOYING
|
||||||
|
execute_mock.return_value = states.DEPLOYWAIT
|
||||||
|
task.node.deploy_step = step
|
||||||
|
func = task.driver.management.flash_firmware_sum
|
||||||
|
exp_ret_state = states.DEPLOYWAIT
|
||||||
# | WHEN |
|
# | WHEN |
|
||||||
return_value = task.driver.management.update_firmware_sum(
|
return_value = func(task, **firmware_update_args)
|
||||||
task, **firmware_update_args)
|
|
||||||
# | THEN |
|
# | THEN |
|
||||||
attach_vmedia_mock.assert_any_call(
|
attach_vmedia_mock.assert_any_call(
|
||||||
task.node, 'CDROM', 'http://any_url')
|
task.node, 'CDROM', 'http://any_url')
|
||||||
self.assertEqual(states.CLEANWAIT, return_value)
|
self.assertEqual(exp_ret_state, return_value)
|
||||||
execute_mock.assert_called_once_with(task, clean_step)
|
execute_mock.assert_called_once_with(task, step, step_type)
|
||||||
|
|
||||||
|
def test_update_firmware_sum_mode_with_component(self):
|
||||||
|
self._test_write_firmware_sum_mode_with_component(step_type='clean')
|
||||||
|
|
||||||
|
def test_flash_firmware_sum_mode_with_component(self):
|
||||||
|
self._test_write_firmware_sum_mode_with_component(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch.object(ilo_management.firmware_processor,
|
@mock.patch.object(ilo_management.firmware_processor,
|
||||||
'get_swift_url', autospec=True)
|
'get_swift_url', autospec=True)
|
||||||
@mock.patch.object(agent_base, 'execute_clean_step', autospec=True)
|
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
||||||
def test_update_firmware_sum_mode_swift_url(
|
def _test_write_firmware_sum_mode_swift_url(
|
||||||
self, execute_mock, swift_url_mock, attach_vmedia_mock):
|
self, execute_mock, swift_url_mock, attach_vmedia_mock,
|
||||||
|
step_type='clean'):
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
swift_url_mock.return_value = "http://path-to-file"
|
|
||||||
execute_mock.return_value = states.CLEANWAIT
|
|
||||||
# | GIVEN |
|
# | GIVEN |
|
||||||
|
swift_url_mock.return_value = "http://path-to-file"
|
||||||
firmware_update_args = {
|
firmware_update_args = {
|
||||||
'url': 'swift://container/object',
|
'url': 'swift://container/object',
|
||||||
'checksum': 'xxxx',
|
'checksum': 'xxxx',
|
||||||
'components': ['CP02345.scexe', 'CP02567.exe']}
|
'components': ['CP02345.scexe', 'CP02567.exe']}
|
||||||
clean_step = {'step': 'update_firmware',
|
step = {'interface': 'management',
|
||||||
'interface': 'management',
|
'args': firmware_update_args}
|
||||||
'args': firmware_update_args}
|
if step_type == 'clean':
|
||||||
task.node.clean_step = clean_step
|
task.node.provision_state = states.CLEANING
|
||||||
|
execute_mock.return_value = states.CLEANWAIT
|
||||||
|
step['step'] = 'update_firmware_sum',
|
||||||
|
task.node.clean_step = step
|
||||||
|
func = task.driver.management.update_firmware_sum
|
||||||
|
exp_ret_state = states.CLEANWAIT
|
||||||
|
args_data = task.node.clean_step['args']
|
||||||
|
else:
|
||||||
|
task.node.provision_state = states.DEPLOYING
|
||||||
|
execute_mock.return_value = states.DEPLOYWAIT
|
||||||
|
step['step'] = 'flash_firmware_sum',
|
||||||
|
task.node.deploy_step = step
|
||||||
|
func = task.driver.management.flash_firmware_sum
|
||||||
|
exp_ret_state = states.DEPLOYWAIT
|
||||||
|
args_data = task.node.deploy_step['args']
|
||||||
# | WHEN |
|
# | WHEN |
|
||||||
return_value = task.driver.management.update_firmware_sum(
|
return_value = func(task, **firmware_update_args)
|
||||||
task, **firmware_update_args)
|
|
||||||
# | THEN |
|
# | THEN |
|
||||||
attach_vmedia_mock.assert_any_call(
|
attach_vmedia_mock.assert_any_call(
|
||||||
task.node, 'CDROM', 'http://path-to-file')
|
task.node, 'CDROM', 'http://path-to-file')
|
||||||
self.assertEqual(states.CLEANWAIT, return_value)
|
self.assertEqual(exp_ret_state, return_value)
|
||||||
self.assertEqual(task.node.clean_step['args']['url'],
|
self.assertEqual(args_data['url'], "http://path-to-file")
|
||||||
"http://path-to-file")
|
|
||||||
|
def test_write_firmware_sum_mode_swift_url_clean(self):
|
||||||
|
self._test_write_firmware_sum_mode_swift_url(step_type='clean')
|
||||||
|
|
||||||
|
def test_write_firmware_sum_mode_swift_url_deploy(self):
|
||||||
|
self._test_write_firmware_sum_mode_swift_url(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
@mock.patch.object(ilo_common, 'attach_vmedia', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch.object(agent_base, 'execute_clean_step', autospec=True)
|
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
||||||
def test_update_firmware_sum_mode_without_component(
|
def _test_write_firmware_sum_mode_without_component(
|
||||||
self, execute_mock, attach_vmedia_mock):
|
self, execute_mock, attach_vmedia_mock, step_type='clean'):
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
execute_mock.return_value = states.CLEANWAIT
|
|
||||||
# | GIVEN |
|
# | GIVEN |
|
||||||
firmware_update_args = {
|
firmware_update_args = {
|
||||||
'url': 'any_valid_url',
|
'url': 'any_valid_url',
|
||||||
'checksum': 'xxxx'}
|
'checksum': 'xxxx'}
|
||||||
clean_step = {'step': 'update_firmware',
|
step = {'interface': 'management',
|
||||||
'interface': 'management',
|
'args': firmware_update_args}
|
||||||
'args': firmware_update_args}
|
if step_type == 'clean':
|
||||||
task.node.clean_step = clean_step
|
task.node.provision_state = states.CLEANING
|
||||||
|
execute_mock.return_value = states.CLEANWAIT
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
task.node.clean_step = step
|
||||||
|
func = task.driver.management.update_firmware_sum
|
||||||
|
exp_ret_state = states.CLEANWAIT
|
||||||
|
else:
|
||||||
|
task.node.provision_state = states.DEPLOYING
|
||||||
|
execute_mock.return_value = states.DEPLOYWAIT
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
task.node.deploy_step = step
|
||||||
|
func = task.driver.management.flash_firmware_sum
|
||||||
|
exp_ret_state = states.DEPLOYWAIT
|
||||||
# | WHEN |
|
# | WHEN |
|
||||||
return_value = task.driver.management.update_firmware_sum(
|
return_value = func(task, **firmware_update_args)
|
||||||
task, **firmware_update_args)
|
|
||||||
# | THEN |
|
# | THEN |
|
||||||
attach_vmedia_mock.assert_any_call(
|
attach_vmedia_mock.assert_any_call(
|
||||||
task.node, 'CDROM', 'any_valid_url')
|
task.node, 'CDROM', 'any_valid_url')
|
||||||
self.assertEqual(states.CLEANWAIT, return_value)
|
self.assertEqual(exp_ret_state, return_value)
|
||||||
execute_mock.assert_called_once_with(task, clean_step)
|
execute_mock.assert_called_once_with(task, step, step_type)
|
||||||
|
|
||||||
def test_update_firmware_sum_mode_invalid_component(self):
|
def test_write_firmware_sum_mode_without_component_clean(self):
|
||||||
|
self._test_write_firmware_sum_mode_without_component(
|
||||||
|
step_type='clean')
|
||||||
|
|
||||||
|
def test_write_firmware_sum_mode_without_component_deploy(self):
|
||||||
|
self._test_write_firmware_sum_mode_without_component(
|
||||||
|
step_type='deploy')
|
||||||
|
|
||||||
|
def _test_write_firmware_sum_mode_invalid_component(self,
|
||||||
|
step_type='clean'):
|
||||||
|
# | GIVEN |
|
||||||
|
firmware_update_args = {
|
||||||
|
'url': 'any_valid_url',
|
||||||
|
'checksum': 'xxxx',
|
||||||
|
'components': ['CP02345']}
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
# | GIVEN |
|
|
||||||
firmware_update_args = {
|
|
||||||
'url': 'any_valid_url',
|
|
||||||
'checksum': 'xxxx',
|
|
||||||
'components': ['CP02345']}
|
|
||||||
# | WHEN & THEN |
|
# | WHEN & THEN |
|
||||||
|
if step_type == 'clean':
|
||||||
|
func = task.driver.management.update_firmware_sum
|
||||||
|
else:
|
||||||
|
func = task.driver.management.flash_firmware_sum
|
||||||
self.assertRaises(exception.InvalidParameterValue,
|
self.assertRaises(exception.InvalidParameterValue,
|
||||||
task.driver.management.update_firmware_sum,
|
func, task, **firmware_update_args)
|
||||||
task,
|
|
||||||
**firmware_update_args)
|
def test_write_firmware_sum_mode_invalid_component_clean(self):
|
||||||
|
self._test_write_firmware_sum_mode_invalid_component(
|
||||||
|
step_type='clean')
|
||||||
|
|
||||||
|
def test_write_firmware_sum_mode_invalid_component_deploy(self):
|
||||||
|
self._test_write_firmware_sum_mode_invalid_component(
|
||||||
|
step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
||||||
def test__update_firmware_sum_final_with_logs(self, store_mock):
|
def _test__write_firmware_sum_final_with_logs(self, store_mock,
|
||||||
|
step_type='clean'):
|
||||||
self.config(deploy_logs_collect='always', group='agent')
|
self.config(deploy_logs_collect='always', group='agent')
|
||||||
command = {'command_status': 'SUCCEEDED',
|
firmware_update_args = {
|
||||||
'command_result': {
|
'url': 'any_valid_url',
|
||||||
'clean_result': {'Log Data': 'aaaabbbbcccdddd'}}
|
'checksum': 'xxxx'}
|
||||||
}
|
step = {'interface': 'management',
|
||||||
|
'args': firmware_update_args}
|
||||||
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
node_state = states.CLEANWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'clean_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'clean_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp_label = 'update_firmware_sum'
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
node_state = states.DEPLOYWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'deploy_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'deploy_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp_label = 'flash_firmware_sum'
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
|
task.node.provision_state = node_state
|
||||||
task.driver.management._update_firmware_sum_final(
|
task.driver.management._update_firmware_sum_final(
|
||||||
task, command)
|
task, command)
|
||||||
store_mock.assert_called_once_with(task.node, 'aaaabbbbcccdddd',
|
store_mock.assert_called_once_with(task.node, 'aaaabbbbcccdddd',
|
||||||
label='update_firmware_sum')
|
label=exp_label)
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_with_logs_clean(self):
|
||||||
|
self._test__write_firmware_sum_final_with_logs(step_type='clean')
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_with_logs_deploy(self):
|
||||||
|
self._test__write_firmware_sum_final_with_logs(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
||||||
def test__update_firmware_sum_final_without_logs(self, store_mock):
|
def _test__write_firmware_sum_final_without_logs(self, store_mock,
|
||||||
|
step_type='clean'):
|
||||||
self.config(deploy_logs_collect='on_failure', group='agent')
|
self.config(deploy_logs_collect='on_failure', group='agent')
|
||||||
command = {'command_status': 'SUCCEEDED',
|
firmware_update_args = {
|
||||||
'command_result': {
|
'url': 'any_valid_url',
|
||||||
'clean_result': {'Log Data': 'aaaabbbbcccdddd'}}
|
'checksum': 'xxxx'}
|
||||||
}
|
step = {'interface': 'management',
|
||||||
|
'args': firmware_update_args}
|
||||||
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'clean_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'clean_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'deploy_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'deploy_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
task.driver.management._update_firmware_sum_final(
|
task.driver.management._update_firmware_sum_final(
|
||||||
task, command)
|
task, command)
|
||||||
self.assertFalse(store_mock.called)
|
self.assertFalse(store_mock.called)
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_without_logs_clean(self):
|
||||||
|
self._test__write_firmware_sum_final_without_logs(step_type='clean')
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_without_logs_deploy(self):
|
||||||
|
self._test__write_firmware_sum_final_without_logs(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
||||||
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
||||||
def test__update_firmware_sum_final_swift_error(self, store_mock,
|
def _test__write_firmware_sum_final_swift_error(self, store_mock,
|
||||||
log_mock):
|
log_mock,
|
||||||
|
step_type='clean'):
|
||||||
self.config(deploy_logs_collect='always', group='agent')
|
self.config(deploy_logs_collect='always', group='agent')
|
||||||
command = {'command_status': 'SUCCEEDED',
|
firmware_update_args = {
|
||||||
'command_result': {
|
'url': 'any_valid_url',
|
||||||
'clean_result': {'Log Data': 'aaaabbbbcccdddd'}}
|
'checksum': 'xxxx'}
|
||||||
}
|
step = {'interface': 'management',
|
||||||
|
'args': firmware_update_args}
|
||||||
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
node_state = states.CLEANWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'clean_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'clean_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
node_state = states.DEPLOYWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'deploy_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'deploy_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
store_mock.side_effect = exception.SwiftOperationError('Error')
|
store_mock.side_effect = exception.SwiftOperationError('Error')
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
|
task.node.provision_state = node_state
|
||||||
task.driver.management._update_firmware_sum_final(
|
task.driver.management._update_firmware_sum_final(
|
||||||
task, command)
|
task, command)
|
||||||
self.assertTrue(log_mock.error.called)
|
self.assertTrue(log_mock.error.called)
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_swift_error_clean(self):
|
||||||
|
self._test__write_firmware_sum_final_swift_error(step_type='clean')
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_swift_error_deploy(self):
|
||||||
|
self._test__write_firmware_sum_final_swift_error(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
||||||
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
||||||
def test__update_firmware_sum_final_environment_error(self, store_mock,
|
def _test__write_firmware_sum_final_environment_error(self, store_mock,
|
||||||
log_mock):
|
log_mock,
|
||||||
|
step_type='clean'):
|
||||||
self.config(deploy_logs_collect='always', group='agent')
|
self.config(deploy_logs_collect='always', group='agent')
|
||||||
command = {'command_status': 'SUCCEEDED',
|
firmware_update_args = {
|
||||||
'command_result': {
|
'url': 'any_valid_url',
|
||||||
'clean_result': {'Log Data': 'aaaabbbbcccdddd'}}
|
'checksum': 'xxxx'}
|
||||||
}
|
step = {'interface': 'management',
|
||||||
|
'args': firmware_update_args}
|
||||||
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
node_state = states.CLEANWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'clean_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'clean_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
node_state = states.DEPLOYWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'deploy_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'deploy_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
store_mock.side_effect = EnvironmentError('Error')
|
store_mock.side_effect = EnvironmentError('Error')
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
|
task.node.provision_state = node_state
|
||||||
task.driver.management._update_firmware_sum_final(
|
task.driver.management._update_firmware_sum_final(
|
||||||
task, command)
|
task, command)
|
||||||
self.assertTrue(log_mock.exception.called)
|
self.assertTrue(log_mock.exception.called)
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_environment_error_clean(self):
|
||||||
|
self._test__write_firmware_sum_final_environment_error(
|
||||||
|
step_type='clean')
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_environment_error_deploy(self):
|
||||||
|
self._test__write_firmware_sum_final_environment_error(
|
||||||
|
step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
@mock.patch.object(ilo_management, 'LOG', spec_set=True, autospec=True)
|
||||||
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
@mock.patch.object(driver_utils, 'store_ramdisk_logs')
|
||||||
def test__update_firmware_sum_final_unknown_exception(self, store_mock,
|
def _test__write_firmware_sum_final_unknown_exception(self, store_mock,
|
||||||
log_mock):
|
log_mock,
|
||||||
|
step_type='clean'):
|
||||||
self.config(deploy_logs_collect='always', group='agent')
|
self.config(deploy_logs_collect='always', group='agent')
|
||||||
command = {'command_status': 'SUCCEEDED',
|
firmware_update_args = {
|
||||||
'command_result': {
|
'url': 'any_valid_url',
|
||||||
'clean_result': {'Log Data': 'aaaabbbbcccdddd'}}
|
'checksum': 'xxxx'}
|
||||||
}
|
step = {'interface': 'management',
|
||||||
|
'args': firmware_update_args}
|
||||||
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'update_firmware_sum'
|
||||||
|
node_state = states.CLEANWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'clean_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'clean_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
step['step'] = 'flash_firmware_sum'
|
||||||
|
node_state = states.DEPLOYWAIT
|
||||||
|
command = {
|
||||||
|
'command_status': 'SUCCEEDED',
|
||||||
|
'command_result': {
|
||||||
|
'deploy_result': {'Log Data': 'aaaabbbbcccdddd'},
|
||||||
|
'deploy_step': step,
|
||||||
|
}
|
||||||
|
}
|
||||||
store_mock.side_effect = Exception('Error')
|
store_mock.side_effect = Exception('Error')
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
|
task.node.provision_state = node_state
|
||||||
task.driver.management._update_firmware_sum_final(
|
task.driver.management._update_firmware_sum_final(
|
||||||
task, command)
|
task, command)
|
||||||
self.assertTrue(log_mock.exception.called)
|
self.assertTrue(log_mock.exception.called)
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_unknown_exception_clean(self):
|
||||||
|
self._test__write_firmware_sum_final_unknown_exception(
|
||||||
|
step_type='clean')
|
||||||
|
|
||||||
|
def test__write_firmware_sum_final_unknown_exception_deploy(self):
|
||||||
|
self._test__write_firmware_sum_final_unknown_exception(
|
||||||
|
step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
@mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
def test_set_iscsi_boot_target_with_auth(self, get_ilo_object_mock):
|
def test_set_iscsi_boot_target_with_auth(self, get_ilo_object_mock):
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds inband deploy step ``flash_firmware_sum`` to the ``management``
|
||||||
|
interface of the ``ilo`` and ``ilo5`` hardware types. The required
|
||||||
|
minimum version for the proliantutils library is 2.9.5.
|
||||||
|
other:
|
||||||
|
- |
|
||||||
|
The proliantutils library version 2.9.5 enables ``ssacli`` based
|
||||||
|
in-band deploy step ``apply_configuration`` of ``agent`` RAID
|
||||||
|
interface for ``ilo`` and ``ilo5`` hardware types.
|
Loading…
x
Reference in New Issue
Block a user