From 3bad548ce3d34207aa70fde8342082fe243bee31 Mon Sep 17 00:00:00 2001 From: Derek Higgins Date: Fri, 9 Jul 2021 19:58:44 +0100 Subject: Allow reboot to hard disk following iso ramdisk deploy. Re-uses the force_persistent_boot_device driver_info option which can be set to ``Never`` in order to set the virtual media to one time boot. Story: 2009042 Task: 42805 Change-Id: Ida7adb3c02db6279ef934797614eaa7be1f35daa --- doc/source/admin/ramdisk-boot.rst | 15 +++++++ ironic/drivers/modules/redfish/boot.py | 6 ++- .../unit/drivers/modules/redfish/test_boot.py | 52 ++++++++++++++++++++++ .../notes/not-presistent-9c552f4209a84820.yaml | 7 +++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/not-presistent-9c552f4209a84820.yaml diff --git a/doc/source/admin/ramdisk-boot.rst b/doc/source/admin/ramdisk-boot.rst index dba79c017..7ee15721a 100644 --- a/doc/source/admin/ramdisk-boot.rst +++ b/doc/source/admin/ramdisk-boot.rst @@ -135,6 +135,21 @@ or desired. As such, this interface does come with several caveats: still occur with the contents of any local storage being wiped between deployments. +Common options +-------------- + +Disable persistent boot device for ramdisk iso boot +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For iso boot, Ironic sets the boot target to continuously boot from +the iso attached over virtual media. This behaviour may not always be +desired e.g. if the vmedia is installing to hard drive and then +rebooting. In order to instead set the virtual media to be one time +boot Ironic provides the ``force_persistent_boot_device`` flag in the +node's ``driver_info``. Which can be set to ``Never``:: + + $ openstack baremetal node set --driver-info force_persistent_boot_device='Never' + .. _ironic-python-agent-builder: https://opendev.org/openstack/ironic-python-agent-builder .. _openssh-server: https://docs.openstack.org/diskimage-builder/latest/elements/openssh-server/README.html .. _devuser: https://docs.openstack.org/diskimage-builder/latest/elements/devuser/README.html diff --git a/ironic/drivers/modules/redfish/boot.py b/ironic/drivers/modules/redfish/boot.py index f329b06d4..588c00fa2 100644 --- a/ironic/drivers/modules/redfish/boot.py +++ b/ironic/drivers/modules/redfish/boot.py @@ -627,7 +627,11 @@ class RedfishVirtualMediaBoot(base.BootInterface): del managers - self._set_boot_device(task, boot_devices.CDROM, persistent=True) + persistent = True + if node.driver_info.get('force_persistent_boot_device', + 'Default') == 'Never': + persistent = False + self._set_boot_device(task, boot_devices.CDROM, persistent=persistent) LOG.debug("Node %(node)s is set to permanently boot from " "%(device)s", {'node': task.node.uuid, diff --git a/ironic/tests/unit/drivers/modules/redfish/test_boot.py b/ironic/tests/unit/drivers/modules/redfish/test_boot.py index 3ffdd8ff2..b80f3acd6 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_boot.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_boot.py @@ -968,6 +968,58 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase): mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task) + @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot, + '_eject_all', autospec=True) + @mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True) + @mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True) + @mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True) + @mock.patch.object(redfish_boot, '_parse_deploy_info', autospec=True) + @mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device', + autospec=True) + @mock.patch.object(redfish_boot, 'deploy_utils', autospec=True) + @mock.patch.object(redfish_boot, 'boot_mode_utils', autospec=True) + @mock.patch.object(redfish_utils, 'get_system', autospec=True) + def test_prepare_instance_ramdisk_boot_iso_not_persistent( + self, mock_system, mock_boot_mode_utils, mock_deploy_utils, + mock_node_set_boot_device, mock__parse_deploy_info, + mock__insert_vmedia, mock__eject_vmedia, mock_prepare_boot_iso, + mock_clean_up_instance): + + managers = mock_system.return_value.managers + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + task.node.provision_state = states.DEPLOYING + task.node.driver_internal_info[ + 'root_uuid_or_disk_id'] = self.node.uuid + task.node.instance_info['configdrive'] = None + task.node.driver_info['force_persistent_boot_device'] = 'Never' + + mock_deploy_utils.get_boot_option.return_value = 'ramdisk' + + d_info = { + 'deploy_kernel': 'kernel', + 'deploy_ramdisk': 'ramdisk', + 'bootloader': 'bootloader' + } + + mock__parse_deploy_info.return_value = d_info + mock_prepare_boot_iso.return_value = 'image-url' + + task.driver.boot.prepare_instance(task) + + mock_prepare_boot_iso.assert_called_once_with(task, d_info) + + mock__eject_vmedia.assert_called_once_with( + task, managers, sushy.VIRTUAL_MEDIA_CD) + + mock__insert_vmedia.assert_called_once_with( + task, managers, 'image-url', sushy.VIRTUAL_MEDIA_CD) + + mock_node_set_boot_device.assert_called_once_with( + task, boot_devices.CDROM, persistent=False) + + mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task) + @mock.patch.object(redfish_boot.RedfishVirtualMediaBoot, '_eject_all', autospec=True) @mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True) diff --git a/releasenotes/notes/not-presistent-9c552f4209a84820.yaml b/releasenotes/notes/not-presistent-9c552f4209a84820.yaml new file mode 100644 index 000000000..e100f078b --- /dev/null +++ b/releasenotes/notes/not-presistent-9c552f4209a84820.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Allows reboot to hard disk following iso ramdisk deploy. Re-uses the + ``force_persistent_boot_device`` driver_info option which can be + set to ``Never`` in order to set the virtual media to one time + boot. -- cgit v1.2.1