Merge "Expand the driver contributor documentation"

This commit is contained in:
Zuul 2021-09-16 18:09:41 +00:00 committed by Gerrit Code Review
commit f651c05b27
4 changed files with 258 additions and 87 deletions

View File

@ -32,6 +32,7 @@ the services.
Booting a Ramdisk or an ISO <ramdisk-boot>
Deploying with anaconda deploy interface <anaconda-deploy-interface>
Hardware Burn-in <hardware-burn-in>
Vendor Passthru <vendor-passthru>
Drivers, Hardware Types and Hardware Interfaces
-----------------------------------------------

View File

@ -0,0 +1,113 @@
Vendor Passthru
===============
The bare metal service allows drivers to expose vendor-specific API known as
*vendor passthru*.
Node Vendor Passthru
--------------------
Drivers may implement a passthrough API, which is accessible via
the ``/v1/nodes/<Node UUID or Name>/vendor_passthru?method={METHOD}``
endpoint. Beyond basic checking, Ironic does not introspect the message
body and simply "passes it through" to the relevant driver.
A method:
* can support one or more HTTP methods (for example, GET, POST)
* is asynchronous or synchronous
+ For asynchronous methods, a 202 (Accepted) HTTP status code is returned
to indicate that the request was received, accepted and is being acted
upon. No body is returned in the response.
+ For synchronous methods, a 200 (OK) HTTP status code is returned to
indicate that the request was fulfilled. The response may include a body.
* can require an exclusive lock on the node. This only occurs if the method
doesn't specify require_exclusive_lock=False in the decorator. If an
exclusive lock is held on the node, other requests for the node will be
delayed and may fail with an HTTP 409 (Conflict) error code.
This endpoint exposes a node's driver directly, and as such, it is
expressly not part of Ironic's standard REST API. There is only a
single HTTP endpoint exposed, and the semantics of the message body
are determined solely by the driver. Ironic makes no guarantees about
backwards compatibility; this is solely up to the discretion of each
driver's author.
To get information about all the methods available via the vendor_passthru
endpoint for a particular node, use CLI:
.. code-block:: console
$ baremetal node passthru list <redfish-node>
+-----------------------+------------------------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+
| Name | Supported HTTP methods | Async | Description | Response is attachment |
+-----------------------+------------------------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+
| create_subscription | POST | False | Creates a subscription on a node. Required argument: a dictionary of {'destination': 'destination_url'} | False |
| delete_subscription | DELETE | False | Delete a subscription on a node. Required argument: a dictionary of {'id': 'subscription_bmc_id'} | False |
| eject_vmedia | POST | True | Eject a virtual media device. If no device is provided then all attached devices will be ejected. Optional arguments: 'boot_device' - the boot device to eject, either 'cd', 'dvd', 'usb', or 'floppy' | False |
| get_all_subscriptions | GET | False | Returns all subscriptions on the node. | False |
| get_subscription | GET | False | Get a subscription on the node. Required argument: a dictionary of {'id': 'subscription_bmc_id'} | False |
+-----------------------+------------------------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+
The response will contain information for each method,
such as the method's name, a description, the HTTP methods supported,
and whether it's asynchronous or synchronous.
You can call a method with CLI, for example:
.. code-block:: console
$ baremetal node passthru call <redfish-node> eject_vmedia
Driver Vendor Passthru
----------------------
Drivers may implement an API for requests not related to any node,
at ``/v1/drivers/<driver name>/vendor_passthru?method={METHOD}``.
A method:
* can support one or more HTTP methods (for example, GET, POST)
* is asynchronous or synchronous
+ For asynchronous methods, a 202 (Accepted) HTTP status code is
returned to indicate that the request was received, accepted and is
being acted upon. No body is returned in the response.
+ For synchronous methods, a 200 (OK) HTTP status code is returned
to indicate that the request was fulfilled. The response may include
a body.
.. note::
Unlike methods in `Node Vendor Passthru`_, a request does not lock any
resource, so it will not delay other requests and will not fail with an
HTTP 409 (Conflict) error code.
Ironic makes no guarantees about the semantics of the message BODY sent
to this endpoint. That is left up to each driver's author.
To get information about all the methods available via the driver
vendor_passthru endpoint, use CLI:
.. code-block:: console
$ baremetal driver passthru list redfish
The response will contain information for each method,
such as the method's name, a description, the HTTP methods supported,
and whether it's asynchronous or synchronous.
.. warning::
Currently only the methods available in the default interfaces of the
hardware type are available.
You can call a method with CLI, for example:
.. code-block:: console
$ baremetal driver passthru call <driver> <method>

View File

@ -1,5 +1,8 @@
Developing a new Deploy Step
============================
Developing deploy and clean steps
=================================
Deploy steps basics
-------------------
To support customized deployment step, implement a new method in an interface
class and use the decorator ``deploy_step`` defined in
@ -78,13 +81,139 @@ The above command outputs the ``driver_internal_info`` as following::
}
}
.. note::
Similarly, clean steps can be implemented using the ``clean_step``
decorator.
In-band deploy steps (deploy steps that are run inside the ramdisk) have to be
implemented in a custom :ironic-python-agent-doc:`IPA hardware manager
<contributor/hardware_managers.html#custom-hardwaremanagers-and-deploying>`.
All in-band deploy steps must have priorities between 41 and 99, see
:ref:`node-deployment-core-steps` for details.
Clean steps basics
------------------
Clean steps are written similarly to deploy steps, but are executed during
:doc:`cleaning </admin/cleaning>`. Steps with priority > 0 are executed during
automated cleaning, all steps can be executed explicitly during manual
cleaning. Unlike deploy steps, clean steps are commonly found in these
interfaces:
``bios``
Steps that apply BIOS settings, see `Implementing BIOS settings`_.
``deploy``
Steps that undo the effect of deployment (e.g. erase disks).
``management``
Additional steps that use the node's BMC, such as out-of-band firmware
update or BMC reset.
``raid``
Steps that build or tear down RAID, see `Implementing RAID`_.
.. note::
When designing a new step for your driver, try to make it consistent with
existing steps on other drivers.
Just as deploy steps, in-band clean steps have to be
implemented in a custom :ironic-python-agent-doc:`IPA hardware manager
<contributor/hardware_managers.html#custom-hardwaremanagers-and-cleaning>`.
Implementing RAID
-----------------
RAID is implemented via deploy and clean steps in the ``raid`` interfaces.
By convention they have the following signatures:
.. code-block:: python
from ironic.drivers import base
class MyRAID(base.RAIDInterface):
@base.clean_step(priority=0, abortable=False, argsinfo={
'create_root_volume': {
'description': (
'This specifies whether to create the root volume. '
'Defaults to `True`.'
),
'required': False
},
'create_nonroot_volumes': {
'description': (
'This specifies whether to create the non-root volumes. '
'Defaults to `True`.'
),
'required': False
},
'delete_existing': {
'description': (
'Setting this to `True` indicates to delete existing RAID '
'configuration prior to creating the new configuration. '
'Default value is `False`.'
),
'required': False,
}
})
def create_configuration(self, task, create_root_volume=True,
create_nonroot_volumes=True,
delete_existing=False):
pass
@base.clean_step(priority=0)
@base.deploy_step(priority=0)
def delete_configuration(self, task):
pass
@base.deploy_step(priority=0,
argsinfo=base.RAID_APPLY_CONFIGURATION_ARGSINFO)
def apply_configuration(self, task, raid_config,
create_root_volume=True,
create_nonroot_volumes=False,
delete_existing=False):
pass
Notes:
* ``create_configuration`` only works as a clean step, during deployment
``apply_configuration`` is used instead.
* ``apply_configuration`` accepts the target RAID configuration explicitly,
while ``create_configuration`` uses the node's ``target_raid_config`` field.
* Priorities default to 0 since RAID should not be built by default.
Implementing BIOS settings
--------------------------
BIOS is implemented via deploy and clean steps in the ``raid`` interfaces.
By convention they have the following signatures:
.. code-block:: python
from ironic.drivers import base
_APPLY_CONFIGURATION_ARGSINFO = {
'settings': {
'description': (
'A list of BIOS settings to be applied'
),
'required': True
}
}
class MyBIOS(base.BIOSInterface):
@base.clean_step(priority=0)
@base.deploy_step(priority=0)
@base.cache_bios_settings
def factory_reset(self, task):
pass
@base.clean_step(priority=0, argsinfo=_APPLY_CONFIGURATION_ARGSINFO)
@base.deploy_step(priority=0, argsinfo=_APPLY_CONFIGURATION_ARGSINFO)
@base.cache_bios_settings
def apply_configuration(self, task, settings):
pass
Notes:
* Both ``factory_reset`` and ``apply_configuration`` can be used as deploy
and clean steps.
* The ``cache_bios_settings`` decorator is used to ensure that the settings
cached in the ironic database is updated.
* Priorities default to 0 since BIOS settings should not be modified
by default.

View File

@ -121,88 +121,16 @@ create entry points for them in the ``setup.cfg`` file::
ironic.hardware.interfaces.management =
my-management = ironic.drivers.modules.my_hardware:MyManagement
Deploy and clean steps
----------------------
Significant parts of the bare metal functionality is implemented via
:doc:`deploy steps </admin/node-deployment>` or :doc:`clean steps
</admin/cleaning>`. See :doc:`deploy-steps` for information on how to write
them.
Supported Drivers
-----------------
For a list of supported drivers (those that are continuously tested on every
upstream commit) please consult the :doc:`drivers page </admin/drivers>`.
Node Vendor Passthru
--------------------
Drivers may implement a passthrough API, which is accessible via
the ``/v1/nodes/<Node UUID or Name>/vendor_passthru?method={METHOD}``
endpoint. Beyond basic checking, Ironic does not introspect the message
body and simply "passes it through" to the relevant driver.
A method:
* can support one or more HTTP methods (for example, GET, POST)
* is asynchronous or synchronous
+ For asynchronous methods, a 202 (Accepted) HTTP status code is returned
to indicate that the request was received, accepted and is being acted
upon. No body is returned in the response.
+ For synchronous methods, a 200 (OK) HTTP status code is returned to
indicate that the request was fulfilled. The response may include a body.
* can require an exclusive lock on the node. This only occurs if the method
doesn't specify require_exclusive_lock=False in the decorator. If an
exclusive lock is held on the node, other requests for the node will be
delayed and may fail with an HTTP 409 (Conflict) error code.
This endpoint exposes a node's driver directly, and as such, it is
expressly not part of Ironic's standard REST API. There is only a
single HTTP endpoint exposed, and the semantics of the message body
are determined solely by the driver. Ironic makes no guarantees about
backwards compatibility; this is solely up to the discretion of each
driver's author.
To get information about all the methods available via the vendor_passthru
endpoint for a particular node, you can issue an HTTP GET request::
GET /v1/nodes/<Node UUID or name>/vendor_passthru/methods
The response's JSON body will contain information for each method,
such as the method's name, a description, the HTTP methods supported,
and whether it's asynchronous or synchronous.
Driver Vendor Passthru
----------------------
Drivers may implement an API for requests not related to any node,
at ``/v1/drivers/<driver name>/vendor_passthru?method={METHOD}``.
A method:
* can support one or more HTTP methods (for example, GET, POST)
* is asynchronous or synchronous
+ For asynchronous methods, a 202 (Accepted) HTTP status code is
returned to indicate that the request was received, accepted and is
being acted upon. No body is returned in the response.
+ For synchronous methods, a 200 (OK) HTTP status code is returned
to indicate that the request was fulfilled. The response may include
a body.
.. note::
Unlike methods in `Node Vendor Passthru`_, a request does not lock any
resource, so it will not delay other requests and will not fail with an
HTTP 409 (Conflict) error code.
Ironic makes no guarantees about the semantics of the message BODY sent
to this endpoint. That is left up to each driver's author.
To get information about all the methods available via the driver
vendor_passthru endpoint, you can issue an HTTP GET request::
GET /v1/drivers/<driver name>/vendor_passthru/methods
The response's JSON body will contain information for each method,
such as the method's name, a description, the HTTP methods supported,
and whether it's asynchronous or synchronous.