Fix error handling in the virtual media attach API

Currently, if the image download fails, there are no traces of the
error. This change adds logging and populates last_error.

Change-Id: I73ea2f94fb910daf21a5d4f52d6839aac3bad579
This commit is contained in:
Dmitry Tantsur 2024-03-07 18:48:13 +01:00
parent ae51a14bde
commit 79523c5911
No known key found for this signature in database
GPG Key ID: 315B2AF9FD216C60
3 changed files with 82 additions and 15 deletions

View File

@ -4080,6 +4080,10 @@ def do_sync_power_state(task, count):
def do_attach_virtual_media(task, device_type, image_url, def do_attach_virtual_media(task, device_type, image_url,
image_download_source): image_download_source):
success_msg = "Device %(device_type)s attached to node %(node)s",
error_msg = ("Could not attach device %(device_type)s "
"to node %(node)s: %(exc)s")
try:
assert device_type in boot_devices.VMEDIA_DEVICES assert device_type in boot_devices.VMEDIA_DEVICES
file_name = "%s.%s" % ( file_name = "%s.%s" % (
device_type.lower(), device_type.lower(),
@ -4090,11 +4094,18 @@ def do_attach_virtual_media(task, device_type, image_url,
download_source=image_download_source) download_source=image_download_source)
utils.run_node_action( utils.run_node_action(
task, task.driver.management.attach_virtual_media, task, task.driver.management.attach_virtual_media,
success_msg="Device %(device_type)s attached to node %(node)s", success_msg=success_msg,
error_msg="Could not attach device %(device_type)s " error_msg=error_msg,
"to node %(node)s: %(exc)s",
device_type=device_type, device_type=device_type,
image_url=image_url) image_url=image_url)
except Exception as exc:
error = error_msg % {'node': task.node.uuid,
'device_type': device_type,
'exc': exc}
LOG.error(
error, exc_info=not isinstance(exc, exception.IronicException))
utils.node_history_record(task.node, event=error, error=True)
task.node.save()
def do_detach_virtual_media(task, device_types): def do_detach_virtual_media(task, device_types):

View File

@ -8740,3 +8740,53 @@ class VirtualMediaTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
image_url='https://url', image_download_source='http') image_url='https://url', image_download_source='http')
self.node.refresh() self.node.refresh()
self.assertIsNone(self.node.last_error) self.assertIsNone(self.node.last_error)
@mock.patch.object(redfish.management.RedfishManagement,
'attach_virtual_media', autospec=True)
@mock.patch.object(image_utils, 'prepare_remote_image', autospec=True)
def test_do_attach_virtual_media(self, mock_prepare_image, mock_attach):
with task_manager.acquire(self.context, self.node.id) as task:
manager.do_attach_virtual_media(task, boot_devices.CDROM,
"https://url", "local")
mock_prepare_image.assert_called_once_with(
task, "https://url", file_name="cdrom.iso",
download_source="local")
mock_attach.assert_called_once_with(
task.driver.management, task, device_type=boot_devices.CDROM,
image_url=mock_prepare_image.return_value)
@mock.patch.object(redfish.management.RedfishManagement,
'attach_virtual_media', autospec=True)
@mock.patch.object(image_utils, 'prepare_remote_image', autospec=True)
def test_do_attach_virtual_media_fails_on_prepare(self, mock_prepare_image,
mock_attach):
mock_prepare_image.side_effect = exception.InvalidImageRef
with task_manager.acquire(self.context, self.node.id) as task:
manager.do_attach_virtual_media(task, boot_devices.CDROM,
"https://url", "local")
mock_prepare_image.assert_called_once_with(
task, "https://url", file_name="cdrom.iso",
download_source="local")
mock_attach.assert_not_called()
self.node.refresh()
self.assertIn("Could not attach device cdrom", self.node.last_error)
self.assertIn("Invalid image href", self.node.last_error)
@mock.patch.object(redfish.management.RedfishManagement,
'attach_virtual_media', autospec=True)
@mock.patch.object(image_utils, 'prepare_remote_image', autospec=True)
def test_do_attach_virtual_media_fails_on_attach(self, mock_prepare_image,
mock_attach):
mock_attach.side_effect = exception.UnsupportedDriverExtension
with task_manager.acquire(self.context, self.node.id) as task:
manager.do_attach_virtual_media(task, boot_devices.CDROM,
"https://url", "local")
mock_prepare_image.assert_called_once_with(
task, "https://url", file_name="cdrom.iso",
download_source="local")
mock_attach.assert_called_once_with(
task.driver.management, task, device_type=boot_devices.CDROM,
image_url=mock_prepare_image.return_value)
self.node.refresh()
self.assertIn("Could not attach device cdrom", self.node.last_error)
self.assertIn("disabled or not implemented", self.node.last_error)

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixes error handling in the virtual media attachment API when the image
downloading fails. Now the ``last_error`` field is populated correctly
and the error is logged.