summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ironic/drivers/modules/drac/management.py18
-rw-r--r--ironic/tests/unit/drivers/modules/drac/test_management.py83
-rw-r--r--ironic/tests/unit/drivers/third_party_driver_mock_specs.py5
-rw-r--r--ironic/tests/unit/drivers/third_party_driver_mocks.py5
-rw-r--r--releasenotes/notes/idrac-import-conf-partial-success-86b8bd1983d227f6.yaml6
5 files changed, 114 insertions, 3 deletions
diff --git a/ironic/drivers/modules/drac/management.py b/ironic/drivers/modules/drac/management.py
index 3bacde962..f20493934 100644
--- a/ironic/drivers/modules/drac/management.py
+++ b/ironic/drivers/modules/drac/management.py
@@ -538,9 +538,21 @@ class DracRedfishManagement(redfish_management.RedfishManagement):
info.pop('import_task_monitor_url', None)
node.driver_internal_info = info
+ succeeded = False
if (import_task.task_state == sushy.TASK_STATE_COMPLETED
and import_task.task_status in
[sushy.HEALTH_OK, sushy.HEALTH_WARNING]):
+
+ # Task could complete with errors (partial success)
+ # iDRAC 5.00.00.00 has stopped reporting Critical messages
+ # so checking also by message_id
+ succeeded = not any(m.message for m in import_task.messages
+ if (m.severity
+ and m.severity != sushy.SEVERITY_OK)
+ or (m.message_id and 'SYS055'
+ in m.message_id))
+
+ if succeeded:
LOG.info('Configuration import %(task_monitor_url)s '
'successful for node %(node)s',
{'node': node.uuid,
@@ -570,7 +582,11 @@ class DracRedfishManagement(redfish_management.RedfishManagement):
# Select all messages, skipping OEM messages that don't have
# `message` field populated.
messages = [m.message for m in import_task.messages
- if m.message is not None]
+ if m.message is not None
+ and ((m.severity
+ and m.severity != sushy.SEVERITY_OK)
+ or (m.message_id
+ and 'SYS055' in m.message_id))]
error_msg = (_("Failed import configuration task: "
"%(task_monitor_url)s. Message: '%(message)s'.")
% {'task_monitor_url': task_monitor_url,
diff --git a/ironic/tests/unit/drivers/modules/drac/test_management.py b/ironic/tests/unit/drivers/modules/drac/test_management.py
index ebc958424..92c010184 100644
--- a/ironic/tests/unit/drivers/modules/drac/test_management.py
+++ b/ironic/tests/unit/drivers/modules/drac/test_management.py
@@ -1150,13 +1150,92 @@ class DracRedfishManagementTestCase(test_utils.BaseDracTest):
task.node.driver_internal_info.get('import_task_monitor_url'))
@mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+ def test__check_import_configuration_task_partial_failed(
+ self, mock_get_task_monitor):
+ driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+ self.node.driver_internal_info = driver_internal_info
+ self.node.save()
+
+ mock_message1 = mock.Mock()
+ mock_message1.message_id = 'SYS413'
+ mock_message1.message = 'The operation successfully completed'
+ mock_message1.severity = sushy.SEVERITY_OK
+ mock_message2 = mock.Mock()
+ mock_message2.message_id = 'SYS055'
+ mock_message2.message = 'Firmware upgrade failed'
+ mock_message2.severity = sushy.SEVERITY_CRITICAL
+ mock_import_task = mock.Mock()
+ mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+ mock_import_task.task_status = sushy.HEALTH_OK
+ mock_import_task.messages = [mock_message1, mock_message2]
+ mock_task_monitor = mock.Mock()
+ mock_task_monitor.is_processing = False
+ mock_task_monitor.get_task.return_value = mock_import_task
+ mock_get_task_monitor.return_value = mock_task_monitor
+
+ self.management._set_success = mock.Mock()
+ self.management._set_failed = mock.Mock()
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ self.management._check_import_configuration_task(
+ task, '/TaskService/123')
+
+ self.management._set_failed.assert_called_once_with(
+ task, mock.ANY,
+ "Failed import configuration task: /TaskService/123. Message: "
+ "'Firmware upgrade failed'.")
+ self.management._set_success.assert_not_called()
+ self.assertIsNone(
+ task.node.driver_internal_info.get('import_task_monitor_url'))
+
+ @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+ def test__check_import_configuration_task_partial_failed_idrac5(
+ self, mock_get_task_monitor):
+ driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+ self.node.driver_internal_info = driver_internal_info
+ self.node.save()
+
+ mock_message1 = mock.Mock()
+ mock_message1.message = ('Import of Server Configuration Profile '
+ 'operation completed with errors')
+ mock_message1.message_id = 'IDRAC.2.4.SYS055'
+ mock_import_task = mock.Mock()
+ mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+ mock_import_task.task_status = sushy.HEALTH_OK
+ mock_import_task.messages = [mock_message1]
+ mock_task_monitor = mock.Mock()
+ mock_task_monitor.is_processing = False
+ mock_task_monitor.get_task.return_value = mock_import_task
+ mock_get_task_monitor.return_value = mock_task_monitor
+
+ self.management._set_success = mock.Mock()
+ self.management._set_failed = mock.Mock()
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ self.management._check_import_configuration_task(
+ task, '/TaskService/123')
+
+ self.management._set_failed.assert_called_once_with(
+ task, mock.ANY,
+ "Failed import configuration task: /TaskService/123. Message: "
+ "'Import of Server Configuration Profile "
+ "operation completed with errors'.")
+ self.management._set_success.assert_not_called()
+ self.assertIsNone(
+ task.node.driver_internal_info.get('import_task_monitor_url'))
+
+ @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
def test__check_import_configuration_task(self, mock_get_task_monitor):
driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
self.node.driver_internal_info = driver_internal_info
self.node.save()
mock_message = mock.Mock()
+ mock_message.message_id = 'SYS413'
mock_message.message = 'Configuration import done'
+ mock_message.severity = sushy.SEVERITY_OK
mock_import_task = mock.Mock()
mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
mock_import_task.task_status = sushy.HEALTH_OK
@@ -1189,7 +1268,9 @@ class DracRedfishManagementTestCase(test_utils.BaseDracTest):
self.node.save()
mock_message = mock.Mock()
+ mock_message.message_id = 'SYS413'
mock_message.message = 'Configuration import done'
+ mock_message.severity = sushy.SEVERITY_OK
mock_import_task = mock.Mock()
mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
mock_import_task.task_status = sushy.HEALTH_OK
@@ -1232,7 +1313,9 @@ class DracRedfishManagementTestCase(test_utils.BaseDracTest):
self.node.save()
mock_message = mock.Mock()
+ mock_message.message_id = 'SYS413'
mock_message.message = 'Configuration import done'
+ mock_message.severity = sushy.SEVERITY_OK
mock_import_task = mock.Mock()
mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
mock_import_task.task_status = sushy.HEALTH_OK
diff --git a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py
index 43c89f206..87fb792df 100644
--- a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py
+++ b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py
@@ -166,7 +166,10 @@ SUSHY_SPEC = (
'HEALTH_WARNING',
'SECURE_BOOT_RESET_KEYS_TO_DEFAULT',
'SECURE_BOOT_RESET_KEYS_DELETE_ALL',
- 'VOLUME_TYPE_RAW_DEVICE'
+ 'VOLUME_TYPE_RAW_DEVICE',
+ 'SEVERITY_OK',
+ 'SEVERITY_WARNING',
+ 'SEVERITY_CRITICAL',
)
SUSHY_AUTH_SPEC = (
diff --git a/ironic/tests/unit/drivers/third_party_driver_mocks.py b/ironic/tests/unit/drivers/third_party_driver_mocks.py
index 3c5e2cd7a..cd1b6bb3e 100644
--- a/ironic/tests/unit/drivers/third_party_driver_mocks.py
+++ b/ironic/tests/unit/drivers/third_party_driver_mocks.py
@@ -228,7 +228,10 @@ if not sushy:
HEALTH_WARNING='warning',
SECURE_BOOT_RESET_KEYS_TO_DEFAULT="ResetAllKeysToDefault",
SECURE_BOOT_RESET_KEYS_DELETE_ALL="DeleteAllKeys",
- VOLUME_TYPE_RAW_DEVICE='rawdevice'
+ VOLUME_TYPE_RAW_DEVICE='rawdevice',
+ SEVERITY_OK='ok',
+ SEVERITY_WARNING='warning',
+ SEVERITY_CRITICAL='critical'
)
sys.modules['sushy'] = sushy
diff --git a/releasenotes/notes/idrac-import-conf-partial-success-86b8bd1983d227f6.yaml b/releasenotes/notes/idrac-import-conf-partial-success-86b8bd1983d227f6.yaml
new file mode 100644
index 000000000..01171b949
--- /dev/null
+++ b/releasenotes/notes/idrac-import-conf-partial-success-86b8bd1983d227f6.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Fixes issue in ``idrac-redfish`` clean/deploy step ``import_configuration``
+ where partially successful jobs were treated as fully successful. Such
+ jobs, completed with errors, are now treated as failures.