summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2021-12-13 10:23:54 +0100
committerDmitry Tantsur <dtantsur@protonmail.com>2021-12-15 11:56:58 +0100
commit20a0c23293511b894fb571ac685d4660c689d570 (patch)
treec2a9d6434df971628e66bd2c89420a004c0b644d
parent2e9d2b5ec45b3b7ef0213ee437aef8092d29aebb (diff)
downloadironic-20a0c23293511b894fb571ac685d4660c689d570.tar.gz
Adoption: do not validate boot interface when local booting
We validate the boot interface during adoption because of: a) potential rebuilding, b) non-local boot. Rebuild proved a rarely used feature, and local boot is the default nowadays, so it makes less sense to unconditionally validate the boot interface during adoption. We will run the validation anyway the next time we need to do something with booting. Similarly, do not record is_whole_disk_image None if it cannot be reliably determined. Conflicts: ironic/conductor/manager.py Change-Id: I95252aea808c48ea2d94569449c871f0d483caaa (cherry picked from commit d342b07dd6f8c5478f37a31b14e77bba6bef55e2)
-rw-r--r--ironic/conductor/manager.py17
-rw-r--r--ironic/tests/unit/conductor/test_manager.py53
-rw-r--r--releasenotes/notes/adopt-validation-7249ceb57016f0e4.yaml5
3 files changed, 62 insertions, 13 deletions
diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py
index 7fe4c5959..5aeaaae25 100644
--- a/ironic/conductor/manager.py
+++ b/ironic/conductor/manager.py
@@ -72,6 +72,7 @@ from ironic.conductor import utils
from ironic.conductor import verify
from ironic.conf import CONF
from ironic.drivers import base as drivers_base
+from ironic.drivers.modules import deploy_utils
from ironic import objects
from ironic.objects import base as objects_base
from ironic.objects import fields
@@ -1735,13 +1736,15 @@ class ConductorManager(base_manager.BaseConductorManager):
# supplied.
iwdi = images.is_whole_disk_image(task.context,
task.node.instance_info)
- driver_internal_info = node.driver_internal_info
- driver_internal_info['is_whole_disk_image'] = iwdi
- node.driver_internal_info = driver_internal_info
- # Calling boot validate to ensure that sufficient information
- # is supplied to allow the node to be able to boot if takeover
- # writes items such as kernel/ramdisk data to disk.
- task.driver.boot.validate(task)
+ if iwdi is not None:
+ driver_internal_info = node.driver_internal_info
+ driver_internal_info['is_whole_disk_image'] = iwdi
+ node.driver_internal_info = driver_internal_info
+ if deploy_utils.get_boot_option(node) != 'local':
+ # Calling boot validate to ensure that sufficient information
+ # is supplied to allow the node to be able to boot if takeover
+ # writes items such as kernel/ramdisk data to disk.
+ task.driver.boot.validate(task)
# NOTE(TheJulia): While task.driver.boot.validate() is called
# above, and task.driver.power.validate() could be called, it
# is called as part of the transition from ENROLL to MANAGEABLE
diff --git a/ironic/tests/unit/conductor/test_manager.py b/ironic/tests/unit/conductor/test_manager.py
index e93b3cb78..b2d3cac81 100644
--- a/ironic/tests/unit/conductor/test_manager.py
+++ b/ironic/tests/unit/conductor/test_manager.py
@@ -7280,8 +7280,47 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
mock_prepare.assert_called_once_with(task.driver.deploy, task)
mock_take_over.assert_called_once_with(task.driver.deploy, task)
self.assertFalse(mock_start_console.called)
- self.assertTrue(mock_boot_validate.called)
- self.assertIn('is_whole_disk_image', task.node.driver_internal_info)
+ mock_boot_validate.assert_not_called()
+ self.assertNotIn('is_whole_disk_image', task.node.driver_internal_info)
+
+ @mock.patch('ironic.drivers.modules.fake.FakePower.validate',
+ autospec=True)
+ @mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True)
+ @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console',
+ autospec=True)
+ @mock.patch('ironic.drivers.modules.fake.FakeDeploy.take_over',
+ autospec=True)
+ @mock.patch('ironic.drivers.modules.fake.FakeDeploy.prepare',
+ autospec=True)
+ def test__do_adoption_with_netboot(self,
+ mock_prepare,
+ mock_take_over,
+ mock_start_console,
+ mock_boot_validate,
+ mock_power_validate):
+ """Test a successful node adoption"""
+ self._start_service()
+ node = obj_utils.create_test_node(
+ self.context, driver='fake-hardware',
+ provision_state=states.ADOPTING,
+ instance_info={
+ 'capabilities': {'boot_option': 'netboot'},
+ 'image_source': 'image',
+ })
+ task = task_manager.TaskManager(self.context, node.uuid)
+
+ self.service._do_adoption(task)
+ node.refresh()
+
+ self.assertEqual(states.ACTIVE, node.provision_state)
+ self.assertIsNone(node.last_error)
+ self.assertFalse(node.console_enabled)
+ mock_prepare.assert_called_once_with(task.driver.deploy, task)
+ mock_take_over.assert_called_once_with(task.driver.deploy, task)
+ self.assertFalse(mock_start_console.called)
+ mock_boot_validate.assert_called_once_with(task.driver.boot, task)
+ self.assertTrue(task.node.driver_internal_info.get(
+ 'is_whole_disk_image'))
@mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console',
@@ -7322,8 +7361,7 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
mock_prepare.assert_called_once_with(task.driver.deploy, task)
mock_take_over.assert_called_once_with(task.driver.deploy, task)
self.assertFalse(mock_start_console.called)
- self.assertTrue(mock_boot_validate.called)
- self.assertIn('is_whole_disk_image', task.node.driver_internal_info)
+ mock_boot_validate.assert_not_called()
self.assertEqual(states.NOSTATE, node.power_state)
@mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True)
@@ -7347,7 +7385,10 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
self._start_service()
node = obj_utils.create_test_node(
self.context, driver='fake-hardware',
- provision_state=states.ADOPTING)
+ provision_state=states.ADOPTING,
+ instance_info={
+ 'capabilities': {'boot_option': 'netboot'},
+ })
task = task_manager.TaskManager(self.context, node.uuid)
self.service._do_adoption(task)
@@ -7359,7 +7400,7 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
self.assertFalse(mock_prepare.called)
self.assertFalse(mock_take_over.called)
self.assertFalse(mock_start_console.called)
- self.assertTrue(mock_boot_validate.called)
+ mock_boot_validate.assert_called_once_with(task.driver.boot, task)
@mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
autospec=True)
diff --git a/releasenotes/notes/adopt-validation-7249ceb57016f0e4.yaml b/releasenotes/notes/adopt-validation-7249ceb57016f0e4.yaml
new file mode 100644
index 000000000..c5eee9967
--- /dev/null
+++ b/releasenotes/notes/adopt-validation-7249ceb57016f0e4.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ No longer validates boot interface parameters when adopting a node that
+ uses local boot.