From eb65c0de92c9c895af648a1233e94a275ac95238 Mon Sep 17 00:00:00 2001 From: Derek Higgins Date: Thu, 30 Sep 2021 10:26:00 +0100 Subject: [PATCH] Ensure enable_netboot_fallback writes out pxe config on adopt. without the ipxe config adopted nodes that would have needed the fallback ipxe config to boot from disk will fail (as they continuously attempt to network boot) and instead boot into the discovery image. Story: #2009259 Task: #43471 Change-Id: I42e555a1a01eb4124e3152669578f3403db83801 --- ironic/common/pxe_utils.py | 2 +- ironic/drivers/modules/agent.py | 5 +-- ironic/drivers/modules/pxe_base.py | 3 +- ironic/tests/unit/common/test_pxe_utils.py | 35 +++++++++++++++++++ .../tests/unit/drivers/modules/test_agent.py | 5 ++- .../notes/pxe-onadopt-7214eba4f5822e1a.yaml | 5 +++ 6 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/pxe-onadopt-7214eba4f5822e1a.yaml diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py index 8c61e235dd..a6efb026b7 100644 --- a/ironic/common/pxe_utils.py +++ b/ironic/common/pxe_utils.py @@ -967,7 +967,7 @@ def build_service_pxe_config(task, instance_image_info, # fail if the agent was booted outside the direct actions of the # boot interface. if (node.provision_state in [states.ACTIVE, states.UNRESCUING, - states.DEPLOYING] + states.DEPLOYING, states.ADOPTING] and not os.path.isfile(pxe_config_path)): pxe_options = build_pxe_config_options(task, instance_image_info, service=True, diff --git a/ironic/drivers/modules/agent.py b/ironic/drivers/modules/agent.py index a9b3544b1a..1cb3bb5ff6 100644 --- a/ironic/drivers/modules/agent.py +++ b/ironic/drivers/modules/agent.py @@ -364,10 +364,11 @@ class CustomAgentDeploy(agent_base.AgentBaseMixin, agent_base.AgentDeployMixin, # Alternatively, we could be in a fast track deployment # and again, we should have nothing to do here. return - if node.provision_state in (states.ACTIVE, states.UNRESCUING): + if node.provision_state in (states.ACTIVE, states.UNRESCUING, + states.ADOPTING): # Call is due to conductor takeover task.driver.boot.prepare_instance(task) - elif node.provision_state != states.ADOPTING: + else: if node.provision_state not in (states.RESCUING, states.RESCUEWAIT, states.RESCUE, states.RESCUEFAIL): self._update_instance_info(task) diff --git a/ironic/drivers/modules/pxe_base.py b/ironic/drivers/modules/pxe_base.py index f3ac498902..5053ce0f6a 100644 --- a/ironic/drivers/modules/pxe_base.py +++ b/ironic/drivers/modules/pxe_base.py @@ -283,7 +283,8 @@ class PXEBaseMixin(object): # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes # during takeover - if boot_device and task.node.provision_state != states.ACTIVE: + if boot_device and (task.node.provision_state not in + (states.ACTIVE, states.ADOPTING)): manager_utils.node_set_boot_device(task, boot_device, persistent=True) diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py index a57441f588..f1295cb2cf 100644 --- a/ironic/tests/unit/common/test_pxe_utils.py +++ b/ironic/tests/unit/common/test_pxe_utils.py @@ -2387,6 +2387,41 @@ class iPXEBuildConfigOptionsTestCase(db_base.DbTestCase): os.path.join(CONF.deploy.http_root, self.node.uuid)) +@mock.patch.object(ipxe.iPXEBoot, '__init__', lambda self: None) +class iPXEBuildServicePXEConfigTestCase(db_base.DbTestCase): + def setUp(self): + super(iPXEBuildServicePXEConfigTestCase, self).setUp() + n = { + 'driver': 'fake-hardware', + 'boot_interface': 'ipxe', + 'instance_info': INST_INFO_DICT, + 'driver_info': DRV_INFO_DICT, + 'driver_internal_info': DRV_INTERNAL_INFO_DICT, + } + self.config(enabled_boot_interfaces=['ipxe']) + self.node = object_utils.create_test_node(self.context, **n) + + @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) + @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) + def test_build_service_pxe_config_adopt(self, mock_switch, mock_pxe_utils): + self.node.provision_state = states.ADOPTING + + driver_internal_info = self.node.driver_internal_info + driver_internal_info['is_whole_disk_image'] = True + self.node.driver_internal_info = driver_internal_info + self.node.save() + + image_info = {} + + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + pxe_utils.build_service_pxe_config(task, image_info, 'id', + is_whole_disk_image=True) + + mock_pxe_utils.assert_called() + mock_switch.assert_called() + + @mock.patch.object(ironic_utils, 'unlink_without_raise', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'TFTPImageCache', autospec=True) diff --git a/ironic/tests/unit/drivers/modules/test_agent.py b/ironic/tests/unit/drivers/modules/test_agent.py index 0ada1e2b47..4e92ad2f44 100644 --- a/ironic/tests/unit/drivers/modules/test_agent.py +++ b/ironic/tests/unit/drivers/modules/test_agent.py @@ -984,6 +984,7 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase): self.assertTrue(storage_attach_volumes_mock.called) self.assertEqual(2, should_write_image_mock.call_count) + @mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True) @mock.patch.object(flat_network.FlatNetwork, 'add_provisioning_network', spec_set=True, autospec=True) @mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', autospec=True) @@ -992,7 +993,8 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase): autospec=True) def test_prepare_adopting( self, build_instance_info_mock, build_options_mock, - pxe_prepare_ramdisk_mock, add_provisioning_net_mock): + pxe_prepare_ramdisk_mock, add_provisioning_net_mock, + prepare_instance_mock): with task_manager.acquire( self.context, self.node['uuid'], shared=False) as task: task.node.provision_state = states.ADOPTING @@ -1003,6 +1005,7 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase): self.assertFalse(build_options_mock.called) self.assertFalse(pxe_prepare_ramdisk_mock.called) self.assertFalse(add_provisioning_net_mock.called) + self.assertTrue(prepare_instance_mock.called) @mock.patch.object(flat_network.FlatNetwork, 'add_provisioning_network', spec_set=True, autospec=True) diff --git a/releasenotes/notes/pxe-onadopt-7214eba4f5822e1a.yaml b/releasenotes/notes/pxe-onadopt-7214eba4f5822e1a.yaml new file mode 100644 index 0000000000..b08f6cba1a --- /dev/null +++ b/releasenotes/notes/pxe-onadopt-7214eba4f5822e1a.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes ``enable_netboot_fallback`` to write out pxe config + on adopt.