Don't require root partition when installing a whole disk image
With the change to find the bootloader on disk (https://review.opendev.org/#/c/696914/)
install_bootloader should now be invoked when doing an iscsi_deploy even if the root
partition cannot be found.
Depends-On: I7167e71e5d2352a045565289b200e5530d0ba11d
Change-Id: I4f2cecdc0af366364b18232dbd8ea4ffdd3165d2
(cherry picked from commit d614d86eef
)
This commit is contained in:
parent
d661f34915
commit
8f61636eb9
|
@ -32,6 +32,7 @@ from ironic.conductor import steps as conductor_steps
|
||||||
from ironic.conductor import utils as manager_utils
|
from ironic.conductor import utils as manager_utils
|
||||||
from ironic.conf import CONF
|
from ironic.conf import CONF
|
||||||
from ironic.drivers.modules import agent_client
|
from ironic.drivers.modules import agent_client
|
||||||
|
from ironic.drivers.modules import boot_mode_utils
|
||||||
from ironic.drivers.modules import deploy_utils
|
from ironic.drivers.modules import deploy_utils
|
||||||
from ironic.drivers import utils as driver_utils
|
from ironic.drivers import utils as driver_utils
|
||||||
|
|
||||||
|
@ -830,8 +831,12 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||||
root_uuid = internal_info.get('root_uuid_or_disk_id')
|
root_uuid = internal_info.get('root_uuid_or_disk_id')
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# For whole disk images it is not necessary that the root_uuid
|
||||||
|
# be provided since the bootloaders on the disk will be used
|
||||||
whole_disk_image = internal_info.get('is_whole_disk_image')
|
whole_disk_image = internal_info.get('is_whole_disk_image')
|
||||||
if software_raid or (root_uuid and not whole_disk_image):
|
if (software_raid or (root_uuid and not whole_disk_image) or
|
||||||
|
(whole_disk_image and
|
||||||
|
boot_mode_utils.get_boot_mode(node) == 'uefi')):
|
||||||
LOG.debug('Installing the bootloader for node %(node)s on '
|
LOG.debug('Installing the bootloader for node %(node)s on '
|
||||||
'partition %(part)s, EFI system partition %(efi)s',
|
'partition %(part)s, EFI system partition %(efi)s',
|
||||||
{'node': node.uuid, 'part': root_uuid,
|
{'node': node.uuid, 'part': root_uuid,
|
||||||
|
@ -841,11 +846,20 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||||
efi_system_part_uuid=efi_system_part_uuid,
|
efi_system_part_uuid=efi_system_part_uuid,
|
||||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||||
if result['command_status'] == 'FAILED':
|
if result['command_status'] == 'FAILED':
|
||||||
msg = (_("Failed to install a bootloader when "
|
if not whole_disk_image:
|
||||||
"deploying node %(node)s. Error: %(error)s") %
|
msg = (_("Failed to install a bootloader when "
|
||||||
{'node': node.uuid,
|
"deploying node %(node)s. Error: %(error)s") %
|
||||||
'error': result['command_error']})
|
{'node': node.uuid,
|
||||||
log_and_raise_deployment_error(task, msg)
|
'error': result['command_error']})
|
||||||
|
log_and_raise_deployment_error(task, msg)
|
||||||
|
else:
|
||||||
|
# Its possible the install will fail if the IPA image
|
||||||
|
# has not been updated, log this and continue
|
||||||
|
LOG.info('Could not install bootloader for whole disk '
|
||||||
|
'image for node %(node)s, Error: %(error)s"',
|
||||||
|
{'node': node.uuid,
|
||||||
|
'error': result['command_error']})
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
persistent = True
|
persistent = True
|
||||||
|
|
|
@ -29,6 +29,7 @@ from ironic.drivers import base as drivers_base
|
||||||
from ironic.drivers.modules import agent
|
from ironic.drivers.modules import agent
|
||||||
from ironic.drivers.modules import agent_base_vendor
|
from ironic.drivers.modules import agent_base_vendor
|
||||||
from ironic.drivers.modules import agent_client
|
from ironic.drivers.modules import agent_client
|
||||||
|
from ironic.drivers.modules import boot_mode_utils
|
||||||
from ironic.drivers.modules import deploy_utils
|
from ironic.drivers.modules import deploy_utils
|
||||||
from ironic.drivers.modules import fake
|
from ironic.drivers.modules import fake
|
||||||
from ironic.drivers.modules import pxe
|
from ironic.drivers.modules import pxe
|
||||||
|
@ -1168,6 +1169,7 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||||
autospec=True)
|
autospec=True)
|
||||||
def test_configure_local_boot_whole_disk_image(
|
def test_configure_local_boot_whole_disk_image(
|
||||||
self, install_bootloader_mock, try_set_boot_device_mock):
|
self, install_bootloader_mock, try_set_boot_device_mock):
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node['uuid'],
|
with task_manager.acquire(self.context, self.node['uuid'],
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
self.deploy.configure_local_boot(task)
|
self.deploy.configure_local_boot(task)
|
||||||
|
@ -1188,6 +1190,26 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||||
try_set_boot_device_mock.assert_called_once_with(
|
try_set_boot_device_mock.assert_called_once_with(
|
||||||
task, boot_devices.DISK, persistent=True)
|
task, boot_devices.DISK, persistent=True)
|
||||||
|
|
||||||
|
@mock.patch.object(boot_mode_utils, 'get_boot_mode',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
||||||
|
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||||
|
autospec=True)
|
||||||
|
def test_configure_local_boot_no_root_uuid_whole_disk(
|
||||||
|
self, install_bootloader_mock, try_set_boot_device_mock,
|
||||||
|
boot_mode_mock):
|
||||||
|
with task_manager.acquire(self.context, self.node['uuid'],
|
||||||
|
shared=False) as task:
|
||||||
|
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||||
|
boot_mode_mock.return_value = 'uefi'
|
||||||
|
self.deploy.configure_local_boot(
|
||||||
|
task, root_uuid=None,
|
||||||
|
efi_system_part_uuid='efi-system-part-uuid')
|
||||||
|
install_bootloader_mock.assert_called_once_with(
|
||||||
|
mock.ANY, task.node, root_uuid=None,
|
||||||
|
efi_system_part_uuid='efi-system-part-uuid',
|
||||||
|
prep_boot_part_uuid=None)
|
||||||
|
|
||||||
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
||||||
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
|
@ -1252,6 +1274,8 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||||
driver_info = task.node.driver_info
|
driver_info = task.node.driver_info
|
||||||
driver_info['force_persistent_boot_device'] = 'Default'
|
driver_info['force_persistent_boot_device'] = 'Default'
|
||||||
task.node.driver_info = driver_info
|
task.node.driver_info = driver_info
|
||||||
|
driver_info['force_persistent_boot_device'] = 'Always'
|
||||||
|
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||||
self.deploy.configure_local_boot(task)
|
self.deploy.configure_local_boot(task)
|
||||||
self.assertFalse(install_bootloader_mock.called)
|
self.assertFalse(install_bootloader_mock.called)
|
||||||
try_set_boot_device_mock.assert_called_once_with(
|
try_set_boot_device_mock.assert_called_once_with(
|
||||||
|
@ -1267,6 +1291,7 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||||
driver_info = task.node.driver_info
|
driver_info = task.node.driver_info
|
||||||
driver_info['force_persistent_boot_device'] = 'Always'
|
driver_info['force_persistent_boot_device'] = 'Always'
|
||||||
task.node.driver_info = driver_info
|
task.node.driver_info = driver_info
|
||||||
|
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||||
self.deploy.configure_local_boot(task)
|
self.deploy.configure_local_boot(task)
|
||||||
self.assertFalse(install_bootloader_mock.called)
|
self.assertFalse(install_bootloader_mock.called)
|
||||||
try_set_boot_device_mock.assert_called_once_with(
|
try_set_boot_device_mock.assert_called_once_with(
|
||||||
|
@ -1282,6 +1307,7 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||||
driver_info = task.node.driver_info
|
driver_info = task.node.driver_info
|
||||||
driver_info['force_persistent_boot_device'] = 'Never'
|
driver_info['force_persistent_boot_device'] = 'Never'
|
||||||
task.node.driver_info = driver_info
|
task.node.driver_info = driver_info
|
||||||
|
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||||
self.deploy.configure_local_boot(task)
|
self.deploy.configure_local_boot(task)
|
||||||
self.assertFalse(install_bootloader_mock.called)
|
self.assertFalse(install_bootloader_mock.called)
|
||||||
try_set_boot_device_mock.assert_called_once_with(
|
try_set_boot_device_mock.assert_called_once_with(
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
When installing a whole disk image using iscsi, set up the bootloader even
|
||||||
|
if a root partition can not be found. The bootloaders will be located on
|
||||||
|
the disk.
|
Loading…
Reference in New Issue