Skip to content

Commit c0cac61

Browse files
committed
add a noop deploy interface patch
For infrastructure and any other devices that we do not want Ironic to manage, yet they need to be present in the Ironic inventory, we're using fake drivers when enrolling them. This is causing a problem for conductor. This patch will enable us to use noop deploy-interface with driver set to manual-management, which will save resources lookup and management that Ironic is doing.
1 parent 5cd9c8e commit c0cac61

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
From f8a0de8a569ae7498bdb778ab3b903e790c5eb28 Mon Sep 17 00:00:00 2001
2+
From: Afonne-CID <[email protected]>
3+
Date: Tue, 21 Oct 2025 08:43:40 +0100
4+
Subject: [PATCH] Add a `noop` deploy interface
5+
6+
This change adds a NoDeploy class to allow for a truly minimal
7+
deployment interface with no-op implementations for all required
8+
methods.
9+
10+
Closes-Bug: #2106550
11+
Change-Id: Ic6faf34860efef9165ad868d57972cd5007eacd4
12+
Signed-off-by: Afonne-CID <[email protected]>
13+
---
14+
doc/source/admin/interfaces/deploy.rst | 45 +++++++++++++++++++
15+
ironic/drivers/modules/noop.py | 30 +++++++++++++
16+
.../tests/unit/drivers/modules/test_noop.py | 42 +++++++++++++++++
17+
pyproject.toml | 1 +
18+
...oop-deploy-interface-e0b1440f9de92dce.yaml | 8 ++++
19+
5 files changed, 126 insertions(+)
20+
create mode 100644 releasenotes/notes/add-noop-deploy-interface-e0b1440f9de92dce.yaml
21+
22+
diff --git a/ironic/drivers/modules/noop.py b/ironic/drivers/modules/noop.py
23+
index 491e1db61..5a85ac277 100644
24+
--- a/ironic/drivers/modules/noop.py
25+
+++ b/ironic/drivers/modules/noop.py
26+
@@ -20,6 +20,7 @@ exceptions for user-accessible actions.
27+
"""
28+
29+
from ironic.common import exception
30+
+from ironic.common import states
31+
from ironic.drivers import base
32+
33+
34+
@@ -91,3 +92,32 @@ class NoFirmware(FailMixin, base.FirmwareInterface):
35+
36+
def cache_firmware_components(self, task):
37+
pass
38+
+
39+
+
40+
+class NoDeploy(base.DeployInterface):
41+
+ """Deploy interface that does nothing and succeeds."""
42+
+
43+
+ def get_properties(self):
44+
+ return {}
45+
+
46+
+ def validate(self, task):
47+
+ # Intentionally accept any node config for noop deploy.
48+
+ pass
49+
+
50+
+ @base.deploy_step(priority=100)
51+
+ def deploy(self, task):
52+
+ # Synchronous success (mirrors FakeDeploy behavior).
53+
+ return None
54+
+
55+
+ def tear_down(self, task):
56+
+ # Indicate the node is torn down.
57+
+ return states.DELETED
58+
+
59+
+ def prepare(self, task):
60+
+ pass
61+
+
62+
+ def clean_up(self, task):
63+
+ pass
64+
+
65+
+ def take_over(self, task):
66+
+ pass
67+
diff --git a/ironic/tests/unit/drivers/modules/test_noop.py b/ironic/tests/unit/drivers/modules/test_noop.py
68+
index 692b5aa04..dcf0f67d1 100644
69+
--- a/ironic/tests/unit/drivers/modules/test_noop.py
70+
+++ b/ironic/tests/unit/drivers/modules/test_noop.py
71+
@@ -73,3 +73,45 @@ class NoInterfacesTestCase(base.TestCase):
72+
self.assertEqual({}, inst.get_properties())
73+
self.assertRaises(exception.UnsupportedDriverExtension,
74+
inst.validate, self.task)
75+
+
76+
+
77+
+class NoDeployTestCase(base.TestCase):
78+
+
79+
+ def setUp(self):
80+
+ super(NoDeployTestCase, self).setUp()
81+
+ self.task = mock.Mock(node=mock.Mock(driver='fake', spec=['driver']),
82+
+ spec=['node'])
83+
+ self.deploy = noop.NoDeploy()
84+
+
85+
+ def test_get_properties(self):
86+
+ self.assertEqual({}, self.deploy.get_properties())
87+
+
88+
+ def test_validate(self):
89+
+ # Should not raise
90+
+ self.assertIsNone(self.deploy.validate(self.task))
91+
+
92+
+ def test_deploy(self):
93+
+ # Should return None for synchronous completion
94+
+ self.assertIsNone(self.deploy.deploy(self.task))
95+
+
96+
+ def test_tear_down(self):
97+
+ from ironic.common import states
98+
+ # Should return DELETED state
99+
+ self.assertEqual(states.DELETED, self.deploy.tear_down(self.task))
100+
+
101+
+ def test_prepare(self):
102+
+ # Should not raise
103+
+ self.assertIsNone(self.deploy.prepare(self.task))
104+
+
105+
+ def test_clean_up(self):
106+
+ # Should not raise
107+
+ self.assertIsNone(self.deploy.clean_up(self.task))
108+
+
109+
+ def test_take_over(self):
110+
+ # Should not raise
111+
+ self.assertIsNone(self.deploy.take_over(self.task))
112+
+
113+
+ def test_load_by_name(self):
114+
+ inst = noop.NoDeploy()
115+
+ self.assertIsInstance(inst, noop.NoDeploy)
116+
+ self.assertEqual({}, inst.get_properties())
117+
diff --git a/setup.cfg b/setup.cfg
118+
index 6e8a19236..d9c516a1c 100644
119+
--- a/setup.cfg
120+
+++ b/setup.cfg
121+
@@ -102,6 +102,7 @@ ironic.hardware.interfaces.deploy =
122+
custom-agent = ironic.drivers.modules.agent:CustomAgentDeploy
123+
direct = ironic.drivers.modules.agent:AgentDeploy
124+
fake = ironic.drivers.modules.fake:FakeDeploy
125+
+ noop = ironic.drivers.modules.noop:NoDeploy
126+
ramdisk = ironic.drivers.modules.ramdisk:RamdiskDeploy
127+
128+
ironic.hardware.interfaces.firmware =
129+
--
130+
2.39.2 (Apple Git-143)

containers/ironic/patches/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
0001-pass-along-physical_network-to-neutron-from-the-bare.patch
44
0001-Solve-IPMI-call-issue-results-in-UTF-8-format-error-.patch
55
0001-fix-local_link_connection-inspection-hook-does-not-f.patch
6+
0001-Add-a-noop-deploy-interface.patch

0 commit comments

Comments
 (0)