diff --git a/components/ironic/values.yaml b/components/ironic/values.yaml index a6e3d9751..e0c6c52ae 100644 --- a/components/ironic/values.yaml +++ b/components/ironic/values.yaml @@ -51,7 +51,7 @@ conf: default_deploy_interface: direct enabled_bios_interfaces: no-bios,redfish,idrac-redfish,ilo enabled_boot_interfaces: http-ipxe,ipxe,redfish-virtual-media,redfish-https,idrac-redfish-virtual-media,ilo-virtual-media,ilo-uefi-https,ilo-ipxe - enabled_deploy_interfaces: direct,ramdisk + enabled_deploy_interfaces: direct,ramdisk,noop enabled_firmware_interfaces: redfish,no-firmware enabled_hardware_types: redfish,idrac,ilo5,ilo enabled_inspect_interfaces: redfish,agent,idrac-redfish,ilo diff --git a/python/ironic-understack/ironic_understack/noop_deploy.py b/python/ironic-understack/ironic_understack/noop_deploy.py new file mode 100644 index 000000000..1d9724aa4 --- /dev/null +++ b/python/ironic-understack/ironic_understack/noop_deploy.py @@ -0,0 +1,82 @@ +from ironic.common import states +from ironic.drivers import base + + +class NoDeploy(base.DeployInterface): + """Deploy interface that does nothing and succeeds. + + This interface allows Ironic to manage bare metal nodes for inventory, + lifecycle tracking, and resource management without performing actual OS + deployment operations. + + All methods succeed immediately without performing actual operations. + Node state transitions occur as expected by Ironic's state machine. + """ + + def get_properties(self): + """Return the properties of the interface. + + Returns: + dict: Empty dictionary as no configuration is required. + """ + return {} + + def validate(self, task): + """Validate the driver-specific Node deployment info. + + This method intentionally accepts any node configuration for noop deploy. + + Args: + task: A TaskManager instance containing the node to act on. + """ + pass + + @base.deploy_step(priority=100) + def deploy(self, task): + """Perform a deployment to a node. + + This method returns None to indicate synchronous success without + performing any actual deployment operations. + + Args: + task: A TaskManager instance containing the node to act on. + + Returns: + None: Indicates synchronous completion. + """ + return None + + def tear_down(self, task): + """Tear down a previous deployment on the task's node. + + Args: + task: A TaskManager instance containing the node to act on. + + Returns: + states.DELETED: Indicates the node is torn down. + """ + return states.DELETED + + def prepare(self, task): + """Prepare the deployment environment for the task's node. + + Args: + task: A TaskManager instance containing the node to act on. + """ + pass + + def clean_up(self, task): + """Clean up the deployment environment for the task's node. + + Args: + task: A TaskManager instance containing the node to act on. + """ + pass + + def take_over(self, task): + """Take over management of this task's node from a dead conductor. + + Args: + task: A TaskManager instance containing the node to act on. + """ + pass diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index 74bda2a10..6d77166c7 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -27,6 +27,9 @@ chassis_model = "ironic_understack.inspect_hook_chassis_model:InspectHookChassis redfish-understack = "ironic_understack.redfish_inspect_understack:UnderstackRedfishInspect" idrac-redfish-understack = "ironic_understack.redfish_inspect_understack:UnderstackDracRedfishInspect" +[project.entry-points."ironic.hardware.interfaces.deploy"] +noop = "ironic_understack.noop_deploy:NoDeploy" + [dependency-groups] test = [ "pytest>=9.0.1,<10",