From 6e0c0e7fd025dbfdc4f2e6070ad5cdb3079c2cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aija=20Jaunt=C4=93va?= Date: Fri, 17 Sep 2021 10:17:25 -0400 Subject: [PATCH] Fix idrac-wsman having Completed with Errors jobs iDRAC jobs can finish in 'Completed', 'Failed' and also 'Completed with Errors' state. This fix adds handling of 'Completed with Errors' as finished failed job otherwise node stays in wait state as it does not consider such jobs as finished. Change-Id: I5018bf8ef6c86c6d303258f1497fa83d33b3cb76 --- ironic/drivers/modules/drac/bios.py | 3 +- ironic/drivers/modules/drac/raid.py | 3 +- .../unit/drivers/modules/drac/test_bios.py | 28 ++++++++++++++++ .../modules/drac/test_periodic_task.py | 33 +++++++++++++++++++ ...ompleted-with-errors-f65c9a48ed4c02d4.yaml | 8 +++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/idrac-wsman-completed-with-errors-f65c9a48ed4c02d4.yaml diff --git a/ironic/drivers/modules/drac/bios.py b/ironic/drivers/modules/drac/bios.py index 69955f6936..e40089a4ff 100644 --- a/ironic/drivers/modules/drac/bios.py +++ b/ironic/drivers/modules/drac/bios.py @@ -292,7 +292,8 @@ class DracWSManBIOS(base.BIOSInterface): if config_job is None or config_job.status == 'Completed': finished_job_ids.append(config_job_id) - elif config_job.status == 'Failed': + elif (config_job.status == 'Failed' + or config_job.status == 'Completed with Errors'): finished_job_ids.append(config_job_id) job_failed = True diff --git a/ironic/drivers/modules/drac/raid.py b/ironic/drivers/modules/drac/raid.py index cb2e964a43..dd405fc471 100644 --- a/ironic/drivers/modules/drac/raid.py +++ b/ironic/drivers/modules/drac/raid.py @@ -1815,7 +1815,8 @@ class DracWSManRAID(base.RAIDInterface): if config_job is None or config_job.status == 'Completed': finished_job_ids.append(config_job_id) - elif config_job.status == 'Failed': + elif (config_job.status == 'Failed' + or config_job.status == 'Completed with Errors'): finished_job_ids.append(config_job_id) self._set_raid_config_job_failure(node) diff --git a/ironic/tests/unit/drivers/modules/drac/test_bios.py b/ironic/tests/unit/drivers/modules/drac/test_bios.py index ad39b9050b..e24267f95c 100644 --- a/ironic/tests/unit/drivers/modules/drac/test_bios.py +++ b/ironic/tests/unit/drivers/modules/drac/test_bios.py @@ -329,6 +329,34 @@ class DracWSManBIOSConfigurationTestCase(test_utils.BaseDracTest): mock_cleaning_error_handler.assert_called_once_with( task, mock.ANY, "Failed config job: 123. Message: 'Invalid'.") + @mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True) + @mock.patch.object(drac_job, 'get_job', spec_set=True, + autospec=True) + def test__check_node_bios_jobs_completed_with_errors( + self, mock_get_job, mock_cleaning_error_handler): + mock_job = mock.Mock() + mock_job.status = 'Completed with Errors' + mock_job.id = '123' + mock_job.message = 'PR31: Completed with Errors' + mock_get_job.return_value = mock_job + + with task_manager.acquire(self.context, self.node.uuid) as task: + driver_internal_info = task.node.driver_internal_info + driver_internal_info['bios_config_job_ids'] = ['123'] + task.node.driver_internal_info = driver_internal_info + task.node.clean_step = {'priority': 100, 'interface': 'bios', + 'step': 'factory_reset', 'argsinfo': {}} + task.node.save() + + task.driver.bios._check_node_bios_jobs(task) + + self.assertEqual([], + task.node.driver_internal_info.get( + 'bios_config_job_ids')) + mock_cleaning_error_handler.assert_called_once_with( + task, mock.ANY, "Failed config job: 123. Message: " + "'PR31: Completed with Errors'.") + def test__check_last_system_inventory_changed_different_inventory_time( self): with task_manager.acquire(self.context, self.node.uuid, diff --git a/ironic/tests/unit/drivers/modules/drac/test_periodic_task.py b/ironic/tests/unit/drivers/modules/drac/test_periodic_task.py index ec7f4e27c1..6ba590fcd7 100644 --- a/ironic/tests/unit/drivers/modules/drac/test_periodic_task.py +++ b/ironic/tests/unit/drivers/modules/drac/test_periodic_task.py @@ -236,6 +236,39 @@ class DracPeriodicTaskTestCase(db_base.DbTestCase): self.assertEqual({}, self.node.raid_config) mock_cleaning_error_handler.assert_called_once_with(task, mock.ANY) + @mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True) + @mock.patch.object(drac_common, 'get_drac_client', spec_set=True, + autospec=True) + def test__check_node_raid_jobs_with_completed_with_errors_job( + self, mock_get_drac_client, mock_cleaning_error_handler): + # mock node.driver_internal_info and node.clean_step + driver_internal_info = {'raid_config_job_ids': ['42']} + self.node.driver_internal_info = driver_internal_info + self.node.clean_step = {'foo': 'bar'} + self.node.save() + # mock task + task = mock.Mock(node=self.node, context=self.context) + # mock dracclient.get_job + self.job['status'] = 'Completed with Errors' + self.job['message'] = 'PR31: Completed with Errors' + mock_client = mock.Mock() + mock_get_drac_client.return_value = mock_client + mock_client.get_job.return_value = test_utils.dict_to_namedtuple( + values=self.job) + # mock dracclient.list_virtual_disks + mock_client.list_virtual_disks.return_value = [ + test_utils.dict_to_namedtuple(values=self.virtual_disk)] + + self.raid._check_node_raid_jobs(task) + + mock_client.get_job.assert_called_once_with('42') + self.assertEqual(0, mock_client.list_virtual_disks.call_count) + self.node.refresh() + self.assertEqual([], + self.node.driver_internal_info['raid_config_job_ids']) + self.assertEqual({}, self.node.raid_config) + mock_cleaning_error_handler.assert_called_once_with(task, mock.ANY) + @mock.patch.object(manager_utils, 'deploying_error_handler', autospec=True) @mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True) @mock.patch.object(drac_common, 'get_drac_client', spec_set=True, diff --git a/releasenotes/notes/idrac-wsman-completed-with-errors-f65c9a48ed4c02d4.yaml b/releasenotes/notes/idrac-wsman-completed-with-errors-f65c9a48ed4c02d4.yaml new file mode 100644 index 0000000000..1e67473276 --- /dev/null +++ b/releasenotes/notes/idrac-wsman-completed-with-errors-f65c9a48ed4c02d4.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixes ``idrac-wsman`` BIOS and RAID interface steps to correctly check + status of iDRAC job that completed with errors. Now these jobs are treated + as failures. Before this fix node stayed in wait state as it was only + checking for "Completed" or "Failed" job status, but not "Completed + with Errors".