Fix GPT partition tables after agent writes contents

Fixes errors that were being raised upon restarting the agent
directly written out software raid images as the raidset is
restarted for device consistency and partition updates later
on in the code path of deployment.

Story: 2007455
Task: 39187
Change-Id: I9abf51eb77b262932e70329af5ce1593106a3171
This commit is contained in:
Julia Kreger 2020-03-24 17:23:39 -07:00
parent bf0bb7a87a
commit 55b011cb1f
3 changed files with 28 additions and 2 deletions

View File

@ -196,6 +196,11 @@ def _write_image(image_info, device):
totaltime = time.time() - starttime
LOG.info('Image {} written to device {} in {} seconds'.format(
image, device, totaltime))
try:
disk_utils.fix_gpt_partition(device, node_uuid=None)
except exception.InstanceDeployFailure:
# Note: the catch internal to the helper method logs any errors.
pass
return uuids
@ -518,6 +523,12 @@ class StandbyExtension(base.BaseAgentExtension):
"seconds".format(device, totaltime))
# Verify if the checksum of the streamed image is correct
image_download.verify_image(device)
# Fix any gpt partition
try:
disk_utils.fix_gpt_partition(device, node_uuid=None)
except exception.InstanceDeployFailure:
# Note: the catch internal to the helper method logs any errors.
pass
@base.async_command('cache_image', _validate_image_info)
def cache_image(self, image_info=None, force=False):

View File

@ -15,6 +15,7 @@
import os
import tempfile
from ironic_lib import exception
import mock
from oslo_concurrency import processutils
@ -157,9 +158,10 @@ class TestStandbyExtension(base.IronicAgentTest):
expected_loc = os.path.join(tempfile.gettempdir(), 'fake_id')
self.assertEqual(expected_loc, location)
@mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
@mock.patch('builtins.open', autospec=True)
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
def test_write_image(self, execute_mock, open_mock):
def test_write_image(self, execute_mock, open_mock, fix_gpt_mock):
image_info = _build_fake_image_info()
device = '/dev/sda'
location = standby._image_location(image_info)
@ -169,6 +171,10 @@ class TestStandbyExtension(base.IronicAgentTest):
standby._write_image(image_info, device)
execute_mock.assert_called_once_with(*command, check_exit_code=[0])
fix_gpt_mock.assert_called_once_with(device, node_uuid=None)
fix_gpt_mock.side_effect = exception.InstanceDeployFailure
standby._write_image(image_info, device)
execute_mock.reset_mock()
execute_mock.return_value = ('', '')
@ -1085,11 +1091,12 @@ class TestStandbyExtension(base.IronicAgentTest):
download_mock.assert_called_once_with(image_info)
write_mock.assert_called_once_with(image_info, device)
@mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
@mock.patch('hashlib.md5', autospec=True)
@mock.patch('builtins.open', autospec=True)
@mock.patch('requests.get', autospec=True)
def test_stream_raw_image_onto_device(self, requests_mock, open_mock,
md5_mock):
md5_mock, fix_gpt_mock):
image_info = _build_fake_image_info()
response = requests_mock.return_value
response.status_code = 200
@ -1107,6 +1114,7 @@ class TestStandbyExtension(base.IronicAgentTest):
stream=True, proxies={})
expected_calls = [mock.call('some'), mock.call('content')]
file_mock.write.assert_has_calls(expected_calls)
fix_gpt_mock.assert_called_once_with('/dev/foo', node_uuid=None)
@mock.patch('hashlib.md5', autospec=True)
@mock.patch('builtins.open', autospec=True)

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Fixes an issue where secondary GPT partition tables were not being updated
after the ``ironic-python-agent`` wrote the disk image to the target disk.
The agent now unconditionally attempts to repair the secondary partition
table. Previously, software RAID volumes would report errors upon restart.