Merge "Make get_partition_uuids work with whole disk images"
This commit is contained in:
commit
e8836e5359
@ -224,12 +224,13 @@ def _message_format(msg, image_info, device, partition_uuids):
|
|||||||
"""Helper method to get and populate different messages."""
|
"""Helper method to get and populate different messages."""
|
||||||
message = None
|
message = None
|
||||||
result_msg = msg
|
result_msg = msg
|
||||||
if image_info.get('image_type') == 'partition':
|
|
||||||
root_uuid = partition_uuids.get('root uuid')
|
root_uuid = partition_uuids.get('root uuid')
|
||||||
efi_system_partition_uuid = (
|
efi_system_partition_uuid = (
|
||||||
partition_uuids.get('efi system partition uuid'))
|
partition_uuids.get('efi system partition uuid'))
|
||||||
if (image_info.get('deploy_boot_mode') == 'uefi'
|
if (image_info.get('deploy_boot_mode') == 'uefi'
|
||||||
and image_info.get('boot_option') == 'local'):
|
and image_info.get('boot_option') == 'local'
|
||||||
|
and efi_system_partition_uuid):
|
||||||
result_msg = msg + 'root_uuid={} efi_system_partition_uuid={}'
|
result_msg = msg + 'root_uuid={} efi_system_partition_uuid={}'
|
||||||
message = result_msg.format(image_info['id'], device,
|
message = result_msg.format(image_info['id'], device,
|
||||||
root_uuid,
|
root_uuid,
|
||||||
@ -237,18 +238,7 @@ def _message_format(msg, image_info, device, partition_uuids):
|
|||||||
else:
|
else:
|
||||||
result_msg = msg + 'root_uuid={}'
|
result_msg = msg + 'root_uuid={}'
|
||||||
message = result_msg.format(image_info['id'], device, root_uuid)
|
message = result_msg.format(image_info['id'], device, root_uuid)
|
||||||
else:
|
|
||||||
try:
|
|
||||||
# NOTE(TheJulia): ironic-lib disk_utils.get_disk_identifier
|
|
||||||
# can raise OSError if hexdump is not found.
|
|
||||||
root_uuid = disk_utils.get_disk_identifier(device)
|
|
||||||
result_msg = msg + 'root_uuid={}'
|
|
||||||
message = result_msg.format(image_info['id'], device, root_uuid)
|
|
||||||
except OSError as e:
|
|
||||||
LOG.warning('Failed to call get_disk_identifier: '
|
|
||||||
'Unable to obtain the root_uuid parameter: '
|
|
||||||
'The hexdump tool may be missing in IPA: %s', e)
|
|
||||||
message = result_msg.format(image_info['id'], device)
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
@ -546,6 +536,22 @@ class StandbyExtension(base.BaseAgentExtension):
|
|||||||
# Note: the catch internal to the helper method logs any errors.
|
# Note: the catch internal to the helper method logs any errors.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _fix_up_partition_uuids(self, image_info, device):
|
||||||
|
if self.partition_uuids is None:
|
||||||
|
self.partition_uuids = {}
|
||||||
|
|
||||||
|
if image_info.get('image_type') == 'partition':
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
root_uuid = disk_utils.get_disk_identifier(device)
|
||||||
|
except OSError as e:
|
||||||
|
LOG.warning('Failed to call get_disk_identifier: '
|
||||||
|
'Unable to obtain the root_uuid parameter: '
|
||||||
|
'The hexdump tool may be missing in IPA: %s', e)
|
||||||
|
else:
|
||||||
|
self.partition_uuids['root uuid'] = root_uuid
|
||||||
|
|
||||||
@base.async_command('cache_image', _validate_image_info)
|
@base.async_command('cache_image', _validate_image_info)
|
||||||
def cache_image(self, image_info=None, force=False):
|
def cache_image(self, image_info=None, force=False):
|
||||||
"""Asynchronously caches specified image to the local OS device.
|
"""Asynchronously caches specified image to the local OS device.
|
||||||
@ -571,6 +577,7 @@ class StandbyExtension(base.BaseAgentExtension):
|
|||||||
self._cache_and_write_image(image_info, device)
|
self._cache_and_write_image(image_info, device)
|
||||||
msg = 'image ({}) cached to device {} '
|
msg = 'image ({}) cached to device {} '
|
||||||
|
|
||||||
|
self._fix_up_partition_uuids(image_info, device)
|
||||||
result_msg = _message_format(msg, image_info, device,
|
result_msg = _message_format(msg, image_info, device,
|
||||||
self.partition_uuids)
|
self.partition_uuids)
|
||||||
|
|
||||||
@ -640,6 +647,8 @@ class StandbyExtension(base.BaseAgentExtension):
|
|||||||
disk_utils.create_config_drive_partition(node_uuid,
|
disk_utils.create_config_drive_partition(node_uuid,
|
||||||
device,
|
device,
|
||||||
configdrive)
|
configdrive)
|
||||||
|
|
||||||
|
self._fix_up_partition_uuids(image_info, device)
|
||||||
msg = 'image ({}) written to device {} '
|
msg = 'image ({}) written to device {} '
|
||||||
result_msg = _message_format(msg, image_info, device,
|
result_msg = _message_format(msg, image_info, device,
|
||||||
self.partition_uuids)
|
self.partition_uuids)
|
||||||
|
@ -711,6 +711,8 @@ class TestStandbyExtension(base.IronicAgentTest):
|
|||||||
execute_mock.assert_called_with('partprobe', 'manager',
|
execute_mock.assert_called_with('partprobe', 'manager',
|
||||||
run_as_root=True,
|
run_as_root=True,
|
||||||
attempts=mock.ANY)
|
attempts=mock.ANY)
|
||||||
|
self.assertEqual({'root uuid': 'ROOT'},
|
||||||
|
self.agent_extension.partition_uuids)
|
||||||
|
|
||||||
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
|
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
|
||||||
@mock.patch('ironic_lib.disk_utils.list_partitions',
|
@mock.patch('ironic_lib.disk_utils.list_partitions',
|
||||||
@ -779,6 +781,8 @@ class TestStandbyExtension(base.IronicAgentTest):
|
|||||||
execute_mock.assert_called_with('partprobe', 'manager',
|
execute_mock.assert_called_with('partprobe', 'manager',
|
||||||
run_as_root=True,
|
run_as_root=True,
|
||||||
attempts=mock.ANY)
|
attempts=mock.ANY)
|
||||||
|
self.assertEqual({'root uuid': 'root_uuid'},
|
||||||
|
self.agent_extension.partition_uuids)
|
||||||
|
|
||||||
@mock.patch('ironic_lib.disk_utils.get_disk_identifier',
|
@mock.patch('ironic_lib.disk_utils.get_disk_identifier',
|
||||||
lambda dev: 'ROOT')
|
lambda dev: 'ROOT')
|
||||||
@ -870,6 +874,59 @@ class TestStandbyExtension(base.IronicAgentTest):
|
|||||||
self.assertFalse(configdrive_copy_mock.called)
|
self.assertFalse(configdrive_copy_mock.called)
|
||||||
self.assertEqual('FAILED', async_result.command_status)
|
self.assertEqual('FAILED', async_result.command_status)
|
||||||
|
|
||||||
|
@mock.patch('ironic_lib.disk_utils.get_disk_identifier',
|
||||||
|
side_effect=OSError, autospec=True)
|
||||||
|
@mock.patch('ironic_python_agent.utils.execute',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch('ironic_lib.disk_utils.list_partitions',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch('ironic_lib.disk_utils.create_config_drive_partition',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch('ironic_python_agent.extensions.standby._write_image',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch('ironic_python_agent.extensions.standby._download_image',
|
||||||
|
autospec=True)
|
||||||
|
def test_prepare_image_no_hexdump(self,
|
||||||
|
download_mock,
|
||||||
|
write_mock,
|
||||||
|
dispatch_mock,
|
||||||
|
configdrive_copy_mock,
|
||||||
|
list_part_mock,
|
||||||
|
execute_mock,
|
||||||
|
disk_id_mock):
|
||||||
|
image_info = _build_fake_image_info()
|
||||||
|
download_mock.return_value = None
|
||||||
|
write_mock.return_value = None
|
||||||
|
dispatch_mock.return_value = 'manager'
|
||||||
|
configdrive_copy_mock.return_value = None
|
||||||
|
list_part_mock.return_value = [mock.MagicMock()]
|
||||||
|
|
||||||
|
async_result = self.agent_extension.prepare_image(
|
||||||
|
image_info=image_info,
|
||||||
|
configdrive='configdrive_data'
|
||||||
|
)
|
||||||
|
async_result.join()
|
||||||
|
|
||||||
|
download_mock.assert_called_once_with(image_info)
|
||||||
|
write_mock.assert_called_once_with(image_info, 'manager')
|
||||||
|
dispatch_mock.assert_called_once_with('get_os_install_device')
|
||||||
|
configdrive_copy_mock.assert_called_once_with(image_info['node_uuid'],
|
||||||
|
'manager',
|
||||||
|
'configdrive_data')
|
||||||
|
|
||||||
|
self.assertEqual('SUCCEEDED', async_result.command_status)
|
||||||
|
self.assertIn('result', async_result.command_result)
|
||||||
|
cmd_result = ('prepare_image: image ({}) written to device {} '
|
||||||
|
'root_uuid=None').format(image_info['id'], 'manager')
|
||||||
|
self.assertEqual(cmd_result, async_result.command_result['result'])
|
||||||
|
list_part_mock.assert_called_with('manager')
|
||||||
|
execute_mock.assert_called_with('partprobe', 'manager',
|
||||||
|
run_as_root=True,
|
||||||
|
attempts=mock.ANY)
|
||||||
|
self.assertEqual({}, self.agent_extension.partition_uuids)
|
||||||
|
|
||||||
@mock.patch('ironic_python_agent.utils.execute', mock.Mock())
|
@mock.patch('ironic_python_agent.utils.execute', mock.Mock())
|
||||||
@mock.patch('ironic_lib.disk_utils.list_partitions',
|
@mock.patch('ironic_lib.disk_utils.list_partitions',
|
||||||
lambda _dev: [mock.Mock()])
|
lambda _dev: [mock.Mock()])
|
||||||
@ -1148,19 +1205,6 @@ class TestStandbyExtension(base.IronicAgentTest):
|
|||||||
# Assert write was only called once and failed!
|
# Assert write was only called once and failed!
|
||||||
file_mock.write.assert_called_once_with('some')
|
file_mock.write.assert_called_once_with('some')
|
||||||
|
|
||||||
@mock.patch('ironic_lib.disk_utils.get_disk_identifier',
|
|
||||||
lambda dev: 'ROOT')
|
|
||||||
def test__message_format_whole_disk(self):
|
|
||||||
image_info = _build_fake_image_info()
|
|
||||||
msg = 'image ({}) already present on device {} '
|
|
||||||
device = '/dev/fake'
|
|
||||||
partition_uuids = {}
|
|
||||||
result_msg = standby._message_format(msg, image_info,
|
|
||||||
device, partition_uuids)
|
|
||||||
expected_msg = ('image (fake_id) already present on device '
|
|
||||||
'/dev/fake root_uuid=ROOT')
|
|
||||||
self.assertEqual(expected_msg, result_msg)
|
|
||||||
|
|
||||||
def test__message_format_partition_bios(self):
|
def test__message_format_partition_bios(self):
|
||||||
image_info = _build_fake_partition_image_info()
|
image_info = _build_fake_partition_image_info()
|
||||||
msg = ('image ({}) already present on device {} ')
|
msg = ('image ({}) already present on device {} ')
|
||||||
@ -1202,21 +1246,6 @@ class TestStandbyExtension(base.IronicAgentTest):
|
|||||||
'efi_system_partition_uuid=efi_id')
|
'efi_system_partition_uuid=efi_id')
|
||||||
self.assertEqual(expected_msg, result_msg)
|
self.assertEqual(expected_msg, result_msg)
|
||||||
|
|
||||||
@mock.patch('ironic_lib.disk_utils.get_disk_identifier',
|
|
||||||
autospec=True)
|
|
||||||
def test__message_format_whole_disk_missing_oserror(self,
|
|
||||||
ident_mock):
|
|
||||||
ident_mock.side_effect = OSError
|
|
||||||
image_info = _build_fake_image_info()
|
|
||||||
msg = 'image ({}) already present on device {}'
|
|
||||||
device = '/dev/fake'
|
|
||||||
partition_uuids = {}
|
|
||||||
result_msg = standby._message_format(msg, image_info,
|
|
||||||
device, partition_uuids)
|
|
||||||
expected_msg = ('image (fake_id) already present on device '
|
|
||||||
'/dev/fake')
|
|
||||||
self.assertEqual(expected_msg, result_msg)
|
|
||||||
|
|
||||||
@mock.patch('ironic_python_agent.utils.determine_time_method',
|
@mock.patch('ironic_python_agent.utils.determine_time_method',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
|
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user