13925f672b
Move the following specs from approved/ to liberty-implemented/ - cisco-imc-pxe-driver - deprecate-bash-ramdisk - new-boot-interface - remove-swift-dependency-for-ilo-drivers Change-Id: I5db53639e39a05e106e25e87f48c49eb30c39f38
274 lines
8.9 KiB
ReStructuredText
274 lines
8.9 KiB
ReStructuredText
..
|
|
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
|
License.
|
|
|
|
http://creativecommons.org/licenses/by/3.0/legalcode
|
|
|
|
========================
|
|
Boot Interface in Ironic
|
|
========================
|
|
|
|
https://blueprints.launchpad.net/ironic/+spec/new-boot-interface
|
|
|
|
This spec talks about refactoring the boot logic out of the current Ironic
|
|
"deploy" drivers into a new boot interface.
|
|
|
|
Problem description
|
|
===================
|
|
|
|
Current we have a DeployInterface in Ironic. All the current implementations
|
|
of this interface are responsible for two things:
|
|
|
|
* Booting the bare metal node - both deploy ramdisk and the deployed instance.
|
|
* Actual deployment of an image on a bare metal node.
|
|
|
|
These are two separate functions and therefore should be abstracted
|
|
separately. This makes it easy to mix and match various boot mechanisms (like
|
|
PXE, iPXE, virtual media) with various deploy mechanisms (iscsi deploy, agent
|
|
deploy and various other deploy mechanisms which may be possible like
|
|
deploying with torrent, multicast, etc in which discussions have been
|
|
initiated) without duplicating code.
|
|
|
|
Proposed change
|
|
===============
|
|
|
|
* A new ``BootInterface`` needs to be added. The interface will recommend the
|
|
following methods for the implementor::
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class BootInterface(object):
|
|
"""Interface for inspection-related actions."""
|
|
|
|
@abc.abstractmethod
|
|
def get_properties(self):
|
|
"""Return the properties of the interface.
|
|
|
|
:returns: dictionary of <property name>:<property description>
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def validate(self, task):
|
|
"""Validate the driver-specific info for booting.
|
|
|
|
This method validates the driver-specific info for booting a ramdisk
|
|
and an instance on the node. If invalid, raises an exception;
|
|
otherwise returns None.
|
|
|
|
:param task: a task from TaskManager.
|
|
:raises: InvalidParameterValue
|
|
:raises: MissingParameterValue
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def prepare_ramdisk(self, task, ramdisk_params):
|
|
"""Prepares the boot of Ironic ramdisk.
|
|
|
|
This method prepares the boot of the deploy ramdisk after reading
|
|
relevant information from the node's database.
|
|
|
|
:param task: a task from TaskManager.
|
|
:param ramdisk_params: the options to be passed to the ironic ramdisk.
|
|
Different interfaces might want to boot the ramdisk in different
|
|
ways by passing parameters to them. For example,
|
|
* When DIB ramdisk is booted to deploy a node, it takes the
|
|
parameters iscsi_target_iqn, deployment_id, ironic_api_url, etc.
|
|
* When Agent ramdisk is booted to deploy a node, it takes the
|
|
parameters ipa-driver-name, ipa-api-url, root_device, etc.
|
|
Other interfaces can make use of ramdisk_params to pass such
|
|
information. Different implementations of boot interface will
|
|
have different ways of passing parameters to the ramdisk.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def clean_up_ramdisk(self, task):
|
|
"""Tears down the boot of Ironic ramdisk.
|
|
|
|
This method tears down the boot of the deploy ramdisk after reading
|
|
relevant information from the node's database.
|
|
|
|
:param task: a task from TaskManager.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def prepare_instance(self, task):
|
|
"""Prepares the boot of instance.
|
|
|
|
This method prepares the boot of the instance after reading
|
|
relevant information from the node's database.
|
|
|
|
:param task: a task from TaskManager.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def clean_up_instance(self, task):
|
|
"""Tears down the boot of instance.
|
|
|
|
This method tears down the boot of the instance after reading
|
|
relevant information from the node's database.
|
|
|
|
:param task: a task from TaskManager.
|
|
"""
|
|
|
|
* The following new implementations of ``BootInterface`` will be created.
|
|
|
|
+ ``pxe.PXEBoot`` - Booting a bare metal node using PXE
|
|
+ ``ipxe.IPXEBoot`` - Booting a bare metal node using iPXE
|
|
+ ``ilo.boot.IloVirtualMediaBoot`` - Booting a bare metal node using iLO
|
|
Virtual Media.
|
|
|
|
.. note::
|
|
Even though IPXEBoot and PXEBoot are in same deploy driver currently, the
|
|
steps for preparing a bare metal to boot from PXE and iPXE are different
|
|
(even though they share some common code). We will refactor both of them
|
|
as separate boot interfaces. The Kilo behaviour of using only either of
|
|
PXE or iPXE at same time will be retained - drivers will instantiate
|
|
pxe.PXEBoot or ipxe.IPXEBoot depending on CONF.pxe.ipxe_enabled.
|
|
|
|
* The code for the above implementations of ``BootInterface`` will be taken
|
|
from ``pxe.PXEDeploy``, ``agent.AgentDeploy``,
|
|
``ilo.IloVirtualMediaIscsiDeploy`` and ``ilo.IloVirtualMediaAgentDeploy``.
|
|
These implementations of ``DeployInterface`` will be freed of any logic
|
|
dealing with booting of bare metal node.
|
|
|
|
* ``pxe.PXEDeploy`` will be refactored into ``pxe.PXEBoot`` and
|
|
``iscsi_deploy.ISCSIDeploy``.
|
|
|
|
* Each driver will mention what is the ``BootInterface`` implementation that it
|
|
wishes to instantiate. For example, the ``pxe_ipmitool`` driver will look
|
|
like the following::
|
|
|
|
class PXEAndIPMIToolDriver(base.BaseDriver):
|
|
"""PXE + IPMITool driver"""
|
|
|
|
def __init__(self):
|
|
self.power = ipmitool.IPMIPower()
|
|
self.console = ipmitool.IPMIShellinaboxConsole()
|
|
self.boot = pxe.PXEBoot()
|
|
self.deploy = iscsi_deploy.ISCSIDeploy()
|
|
self.management = ipmitool.IPMIManagement()
|
|
self.vendor = pxe.VendorPassthru()
|
|
self.inspect = discoverd.DiscoverdInspect.create_if_enabled(
|
|
'PXEAndIPMIToolDriver')
|
|
|
|
|
|
.. note::
|
|
|
|
It might make sense to rename the drivers to include the boot interface as
|
|
well as deploy interface after this is implemented. As such, this requires
|
|
a better thought out process to rename the drivers, address issues of
|
|
backward compatibility, etc. Hence it is out of scope of this spec. That
|
|
can be addressed later after this is implemented.
|
|
|
|
Alternatives
|
|
------------
|
|
We can continue to keep the boot and deploy logic together but this will
|
|
lead to code duplications and unnecessary refactorings when additional deploy
|
|
mechanisms and boot mechanisms are added in the future.
|
|
|
|
Data model impact
|
|
-----------------
|
|
None.
|
|
|
|
State Machine Impact
|
|
--------------------
|
|
None.
|
|
|
|
REST API impact
|
|
---------------
|
|
None.
|
|
|
|
RPC API impact
|
|
--------------
|
|
None.
|
|
|
|
Client (CLI) impact
|
|
-------------------
|
|
None.
|
|
|
|
Driver API impact
|
|
-----------------
|
|
This adds the a new ``BootInterface`` (as described above) which driver
|
|
writers may use with the deploy drivers. ``BootInterface`` is not a
|
|
mandatory interface.
|
|
|
|
Nova driver impact
|
|
------------------
|
|
None.
|
|
|
|
Security impact
|
|
---------------
|
|
None.
|
|
|
|
Other end user impact
|
|
---------------------
|
|
None.
|
|
|
|
Scalability impact
|
|
------------------
|
|
None.
|
|
|
|
Performance Impact
|
|
------------------
|
|
None.
|
|
|
|
Other deployer impact
|
|
---------------------
|
|
None.
|
|
|
|
Developer impact
|
|
----------------
|
|
New driver developers adding new deploy mechanisms in Ironic will be
|
|
encouraged to separate boot and deploy logic so that it can reused easily.
|
|
|
|
Implementation
|
|
==============
|
|
|
|
Assignee(s)
|
|
-----------
|
|
rameshg87
|
|
|
|
Work Items
|
|
----------
|
|
* Add new boot interface
|
|
* Create ``pxe.PXEBoot``, ``ipxe.IPXEBoot`` and refactor ``pxe.PXEDeploy``
|
|
into ``iscsi_deploy.ISCSIDeploy`` to make use of these boot interfaces.
|
|
* Refactor ``agent.AgentDeploy`` to use new ``pxe.PXEBoot`` and
|
|
``ipxe.IPXEBoot`` (Yes, we are adding iPXE support for agent deploy).
|
|
* Create ``ilo.boot.IloVirtualMediaBoot``, and refactor
|
|
``IloVirtualMediaIscsiDriver``, ``IloVirtualMediaAgentDriver`` to make
|
|
use of the new boot interface.
|
|
|
|
Dependencies
|
|
============
|
|
None.
|
|
|
|
Testing
|
|
=======
|
|
Unit tests will be updated for the new interfaces. Since this change doesn't
|
|
add any new functionality, the current upstream CI testing should be enough.
|
|
|
|
Upgrades and Backwards Compatibility
|
|
====================================
|
|
This doesn't break out-of-tree deploy drivers. Still it will be possible
|
|
to implement deploy drivers for provisioning bare metal nodes without a boot
|
|
interface- i.e without separate boot and deploy interfaces. This is because
|
|
the conductor will still be using all the published interfaces of
|
|
``DeployInterface`` for deploying a bare metal node.
|
|
|
|
This change proposes the addition of new optional boot interface which can be
|
|
used as a helper for ``DeployInterface`` and refactors all upstream deploy
|
|
drivers to follow this logic.
|
|
|
|
Documentation Impact
|
|
====================
|
|
Changes to the existing interface will be documented. Also, new developer
|
|
documentation will be updated to encourage splitting deploy logic into separate
|
|
boot and deploy interfaces.
|
|
|
|
References
|
|
==========
|
|
Not according to this spec, but a POC how it will look like:
|
|
* https://review.openstack.org/#/c/166512/
|
|
* https://review.openstack.org/#/c/166513/
|
|
* https://review.openstack.org/#/c/166521/
|