From 5b0ec703c9c5dd13e1ffb2871ae24973ab6ae459 Mon Sep 17 00:00:00 2001 From: Arne Wiebalck Date: Mon, 4 Mar 2019 17:02:52 +0100 Subject: [PATCH] Software RAID: Trigger grub installation on the holder disks Ironic triggers the bootloader installation only for partition images (as whole disk images should come with the bootloader). When a software RAID device is used for deployment, however, the bootloader needs to be installed on the holder disks by the IPA, so we need to detect and trigger this. Change-Id: I6732bfbcabfa1c74aa5ab6fa990e977589a50b92 Story: #2004581 Task: #29105 Depends-on: https://review.opendev.org/639390 --- ironic/drivers/modules/agent_base_vendor.py | 20 +++++++++++-- .../drivers/modules/test_agent_base_vendor.py | 28 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/ironic/drivers/modules/agent_base_vendor.py b/ironic/drivers/modules/agent_base_vendor.py index 8ee24b0841..60638ef47a 100644 --- a/ironic/drivers/modules/agent_base_vendor.py +++ b/ironic/drivers/modules/agent_base_vendor.py @@ -723,8 +723,24 @@ class AgentDeployMixin(HeartbeatMixin): """ node = task.node LOG.debug('Configuring local boot for node %s', node.uuid) - if not node.driver_internal_info.get( - 'is_whole_disk_image') and root_uuid: + + # If the target RAID configuration is set to 'software' for the + # 'controller', we need to trigger the installation of grub on + # the holder disks of the desired Software RAID. + internal_info = node.driver_internal_info + raid_config = node.target_raid_config + logical_disks = raid_config.get('logical_disks', []) + software_raid = False + for logical_disk in logical_disks: + if logical_disk['controller'] == 'software': + LOG.debug('Node %s has a Software RAID configuration', + node.uuid) + software_raid = True + root_uuid = internal_info.get('root_uuid_or_disk_id') + break + + whole_disk_image = internal_info.get('is_whole_disk_image') + if software_raid or (root_uuid and not whole_disk_image): LOG.debug('Installing the bootloader for node %(node)s on ' 'partition %(part)s, EFI system partition %(efi)s', {'node': node.uuid, 'part': root_uuid, diff --git a/ironic/tests/unit/drivers/modules/test_agent_base_vendor.py b/ironic/tests/unit/drivers/modules/test_agent_base_vendor.py index 8de0c569fd..0ad57996be 100644 --- a/ironic/tests/unit/drivers/modules/test_agent_base_vendor.py +++ b/ironic/tests/unit/drivers/modules/test_agent_base_vendor.py @@ -879,6 +879,34 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest): try_set_boot_device_mock.assert_called_once_with( task, boot_devices.DISK, persistent=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_on_software_raid( + self, install_bootloader_mock, try_set_boot_device_mock): + with task_manager.acquire(self.context, self.node['uuid'], + shared=False) as task: + task.node.driver_internal_info['is_whole_disk_image'] = True + task.node.target_raid_config = { + "logical_disks": [ + { + "size_gb": 100, + "raid_level": "1", + "controller": "software", + }, + { + "size_gb": 'MAX', + "raid_level": "0", + "controller": "software", + } + ] + } + + self.deploy.configure_local_boot(task) + self.assertTrue(install_bootloader_mock.called) + try_set_boot_device_mock.assert_called_once_with( + task, boot_devices.DISK, persistent=True) + @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(agent_client.AgentClient, 'install_bootloader', autospec=True)