summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2020-10-09 11:22:09 +0200
committerDmitry Tantsur <dtantsur@protonmail.com>2020-10-09 14:33:52 +0200
commit7306c73e7e5ce695d478fbc38c192796d5a4f962 (patch)
treec952333a4a098681c926e4b083d398174df2b7b3
parentd5ebdfe1b39f823d18c47650a089e450b69f87d9 (diff)
downloadironic-python-agent-7306c73e7e5ce695d478fbc38c192796d5a4f962.tar.gz
Do not silently swallow errors in the write_image deploy step6.4.1
Calling join() does not raise, we need to explicitly check the result. Change-Id: I81d3d727af220c2b50358edab8139f07874611f0 Story: #2008240 Task: #41083 (cherry picked from commit 420ebc0d73ccfa7248e93881c58a0e45fda0e718)
-rw-r--r--ironic_python_agent/extensions/base.py11
-rw-r--r--ironic_python_agent/hardware.py2
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_base.py11
-rw-r--r--releasenotes/notes/prepare-image-49744276cef719d5.yaml5
4 files changed, 28 insertions, 1 deletions
diff --git a/ironic_python_agent/extensions/base.py b/ironic_python_agent/extensions/base.py
index 93adfe93..23e47c46 100644
--- a/ironic_python_agent/extensions/base.py
+++ b/ironic_python_agent/extensions/base.py
@@ -79,6 +79,17 @@ class BaseCommandResult(encoding.SerializableComparable):
""":returns: result of completed command."""
return self
+ def wait(self):
+ """Join the result and extract its value.
+
+ Raises if the command failed.
+ """
+ self.join()
+ if self.command_error is not None:
+ raise self.command_error
+ else:
+ return self.command_result
+
class SyncCommandResult(BaseCommandResult):
"""A result from a command that executes synchronously."""
diff --git a/ironic_python_agent/hardware.py b/ironic_python_agent/hardware.py
index 3724effb..f8107b55 100644
--- a/ironic_python_agent/hardware.py
+++ b/ironic_python_agent/hardware.py
@@ -2139,7 +2139,7 @@ class GenericHardwareManager(HardwareManager):
ext = ext_base.get_extension('standby')
cmd = ext.prepare_image(image_info=image_info, configdrive=configdrive)
# The result is asynchronous, wait here.
- cmd.join()
+ return cmd.wait()
def generate_tls_certificate(self, ip_address):
"""Generate a TLS certificate for the IP address."""
diff --git a/ironic_python_agent/tests/unit/extensions/test_base.py b/ironic_python_agent/tests/unit/extensions/test_base.py
index f609e580..2bc4c75b 100644
--- a/ironic_python_agent/tests/unit/extensions/test_base.py
+++ b/ironic_python_agent/tests/unit/extensions/test_base.py
@@ -149,6 +149,12 @@ class TestExtensionDecorators(test_base.IronicAgentTest):
result.command_result)
self.agent.force_heartbeat.assert_called_once_with()
+ def test_wait_async_command_success(self):
+ result = self.extension.execute('fake_async_command', param='v1')
+ self.assertIsInstance(result, base.AsyncCommandResult)
+ result = result.wait()
+ self.assertEqual({'result': 'fake_async_command: v1'}, result)
+
def test_async_command_success_without_agent(self):
extension = FakeExtension(agent=None)
result = extension.execute('fake_async_command', param='v1')
@@ -182,6 +188,11 @@ class TestExtensionDecorators(test_base.IronicAgentTest):
self.assertIsNone(result.command_result)
self.agent.force_heartbeat.assert_called_once_with()
+ def test_wait_async_command_execution_failure(self):
+ result = self.extension.execute('fake_async_command', param='v2')
+ self.assertIsInstance(result, base.AsyncCommandResult)
+ self.assertRaises(ExecutionError, result.wait)
+
def test_async_command_name(self):
self.assertEqual(
'other_async_name',
diff --git a/releasenotes/notes/prepare-image-49744276cef719d5.yaml b/releasenotes/notes/prepare-image-49744276cef719d5.yaml
new file mode 100644
index 00000000..88e0d6d5
--- /dev/null
+++ b/releasenotes/notes/prepare-image-49744276cef719d5.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Fixes the ``write_image`` deploy step to actually check and return any
+ errors during its execution.