Add hardware type for IPMI using ipmitool

Created a new Python module ironic.drivers.ipmi to contain all
supported IPMI-related drivers (both new and old).
Backward compatible aliases are left at old locations.

Change-Id: I526b8505d08b25b668af76d3fcd8f2feab31e420
Partial-Bug: #1524745
This commit is contained in:
Dmitry Tantsur 2017-01-19 16:35:49 +01:00
parent 919e12d62b
commit 797544316e
11 changed files with 282 additions and 175 deletions

View File

@ -138,9 +138,9 @@ if [[ -n "$BUILD_TIMEOUT" ]]; then
fi fi
# driver / hardware type options # driver / hardware type options
# TODO(jroll) add enabled/default interfaces here
IRONIC_ENABLED_DRIVERS=${IRONIC_ENABLED_DRIVERS:-fake,pxe_ipmitool,agent_ipmitool} IRONIC_ENABLED_DRIVERS=${IRONIC_ENABLED_DRIVERS:-fake,pxe_ipmitool,agent_ipmitool}
IRONIC_ENABLED_HARDWARE_TYPES=${IRONIC_ENABLED_HARDWARE_TYPES:-manual-management} # TODO(jroll) add enabled/default interfaces here
IRONIC_ENABLED_HARDWARE_TYPES=${IRONIC_ENABLED_HARDWARE_TYPES:-ipmi}
# If IRONIC_VM_ENGING is explictly set to "auto" or "kvm", # If IRONIC_VM_ENGING is explictly set to "auto" or "kvm",
# devstack will attempt to use hardware virtualization # devstack will attempt to use hardware virtualization

View File

@ -33,13 +33,12 @@
# Specify the list of hardware types to load during service # Specify the list of hardware types to load during service
# initialization. Missing hardware types, or hardware types # initialization. Missing hardware types, or hardware types
# which fail to initialize, will prevent the conductor service # which fail to initialize, will prevent the conductor service
# from starting. No hardware types are enabled by default now, # from starting. This option defaults to a recommended set of
# but in the future this option will default to a recommended # production-oriented hardware types. A complete list of
# set of production-oriented hardware types. A complete list # hardware types present on your system may be found by
# of hardware types present on your system may be found by
# enumerating the "ironic.hardware.types" entrypoint. (list # enumerating the "ironic.hardware.types" entrypoint. (list
# value) # value)
#enabled_hardware_types = #enabled_hardware_types = ipmi
# Specify the list of boot interfaces to load during service # Specify the list of boot interfaces to load during service
# initialization. Missing boot interfaces, or boot interfaces # initialization. Missing boot interfaces, or boot interfaces
@ -131,7 +130,7 @@
# setting this value, please make sure that every enabled # setting this value, please make sure that every enabled
# hardware type will have the same set of enabled management # hardware type will have the same set of enabled management
# interfaces on every ironic-conductor service. (list value) # interfaces on every ironic-conductor service. (list value)
#enabled_management_interfaces = #enabled_management_interfaces = ipmitool
# Default management interface to be used for nodes that do # Default management interface to be used for nodes that do
# not have management_interface field set. A complete list of # not have management_interface field set. A complete list of
@ -171,7 +170,7 @@
# this value, please make sure that every enabled hardware # this value, please make sure that every enabled hardware
# type will have the same set of enabled power interfaces on # type will have the same set of enabled power interfaces on
# every ironic-conductor service. (list value) # every ironic-conductor service. (list value)
#enabled_power_interfaces = #enabled_power_interfaces = ipmitool
# Default power interface to be used for nodes that do not # Default power interface to be used for nodes that do not
# have power_interface field set. A complete list of power # have power_interface field set. A complete list of power

View File

@ -79,14 +79,13 @@ driver_opts = [
'entrypoint. An example may be found in the ' 'entrypoint. An example may be found in the '
'developer documentation online.')), 'developer documentation online.')),
cfg.ListOpt('enabled_hardware_types', cfg.ListOpt('enabled_hardware_types',
default=[], default=['ipmi'],
help=_('Specify the list of hardware types to load during ' help=_('Specify the list of hardware types to load during '
'service initialization. Missing hardware types, or ' 'service initialization. Missing hardware types, or '
'hardware types which fail to initialize, will prevent ' 'hardware types which fail to initialize, will prevent '
'the conductor service from starting. No hardware ' 'the conductor service from starting. This option '
'types are enabled by default now, but in the future ' 'defaults to a recommended set of production-oriented '
'this option will default to a recommended set of ' 'hardware types. '
'production-oriented hardware types. '
'A complete list of hardware types present on your ' 'A complete list of hardware types present on your '
'system may be found by enumerating the ' 'system may be found by enumerating the '
'"ironic.hardware.types" entrypoint.')), '"ironic.hardware.types" entrypoint.')),
@ -111,7 +110,7 @@ driver_opts = [
cfg.StrOpt('default_inspect_interface', cfg.StrOpt('default_inspect_interface',
help=_DEFAULT_IFACE_HELP.format('inspect')), help=_DEFAULT_IFACE_HELP.format('inspect')),
cfg.ListOpt('enabled_management_interfaces', cfg.ListOpt('enabled_management_interfaces',
default=[], default=['ipmitool'],
help=_ENABLED_IFACE_HELP.format('management')), help=_ENABLED_IFACE_HELP.format('management')),
cfg.StrOpt('default_management_interface', cfg.StrOpt('default_management_interface',
help=_DEFAULT_IFACE_HELP.format('management')), help=_DEFAULT_IFACE_HELP.format('management')),
@ -121,7 +120,7 @@ driver_opts = [
cfg.StrOpt('default_network_interface', cfg.StrOpt('default_network_interface',
help=_DEFAULT_IFACE_HELP.format('network')), help=_DEFAULT_IFACE_HELP.format('network')),
cfg.ListOpt('enabled_power_interfaces', cfg.ListOpt('enabled_power_interfaces',
default=[], default=['ipmitool'],
help=_ENABLED_IFACE_HELP.format('power')), help=_ENABLED_IFACE_HELP.format('power')),
cfg.StrOpt('default_power_interface', cfg.StrOpt('default_power_interface',
help=_DEFAULT_IFACE_HELP.format('power')), help=_DEFAULT_IFACE_HELP.format('power')),

View File

@ -17,12 +17,12 @@ from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
from ironic.common.i18n import _ from ironic.common.i18n import _
from ironic.drivers import base from ironic.drivers import base
from ironic.drivers import ipmi
from ironic.drivers.modules import agent from ironic.drivers.modules import agent
from ironic.drivers.modules.cimc import management as cimc_mgmt from ironic.drivers.modules.cimc import management as cimc_mgmt
from ironic.drivers.modules.cimc import power as cimc_power from ironic.drivers.modules.cimc import power as cimc_power
from ironic.drivers.modules import inspector from ironic.drivers.modules import inspector
from ironic.drivers.modules import ipminative from ironic.drivers.modules import ipminative
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import pxe from ironic.drivers.modules import pxe
from ironic.drivers.modules import ssh from ironic.drivers.modules import ssh
from ironic.drivers.modules.ucs import management as ucs_mgmt from ironic.drivers.modules.ucs import management as ucs_mgmt
@ -30,46 +30,9 @@ from ironic.drivers.modules.ucs import power as ucs_power
from ironic.drivers.modules import virtualbox from ironic.drivers.modules import virtualbox
class AgentAndIPMIToolDriver(base.BaseDriver): # For backward compatibility
"""Agent + IPMITool driver. AgentAndIPMIToolDriver = ipmi.AgentAndIPMIToolDriver
AgentAndIPMIToolAndSocatDriver = ipmi.AgentAndIPMIToolAndSocatDriver
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` (for power on/off and
reboot) with :class:`ironic.drivers.modules.agent.AgentDeploy` (for
image deployment).
Implementations are in those respective classes; this class is merely the
glue between them.
"""
def __init__(self):
self.power = ipmitool.IPMIPower()
self.boot = pxe.PXEBoot()
self.deploy = agent.AgentDeploy()
self.management = ipmitool.IPMIManagement()
self.console = ipmitool.IPMIShellinaboxConsole()
self.vendor = ipmitool.VendorPassthru()
self.raid = agent.AgentRAID()
self.inspect = inspector.Inspector.create_if_enabled(
'AgentAndIPMIToolDriver')
class AgentAndIPMIToolAndSocatDriver(AgentAndIPMIToolDriver):
"""Agent + IPMITool + socat driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` (for power on/off and
reboot) with :class:`ironic.drivers.modules.agent.AgentDeploy` (for
image deployment) and with
:class:`ironic.drivers.modules.ipmitool.IPMISocatConsole`.
This driver uses the socat console interface instead of the shellinabox
one.
Implementations are in those respective classes; this class is merely the
glue between them.
"""
def __init__(self):
AgentAndIPMIToolDriver.__init__(self)
self.console = ipmitool.IPMISocatConsole()
class AgentAndIPMINativeDriver(base.BaseDriver): class AgentAndIPMINativeDriver(base.BaseDriver):

131
ironic/drivers/ipmi.py Normal file
View File

@ -0,0 +1,131 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Hardware types and classic drivers for IPMI (using ipmitool).
"""
from ironic.drivers import base
from ironic.drivers import generic
from ironic.drivers.modules import agent
from ironic.drivers.modules import inspector
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import iscsi_deploy
from ironic.drivers.modules import noop
from ironic.drivers.modules import pxe
class IPMIHardware(generic.GenericHardware):
"""IPMI hardware type.
Uses ``ipmitool`` to implement power and management.
Provides serial console implementations via ``shellinabox`` or ``socat``.
"""
@property
def supported_console_interfaces(self):
"""List of supported console interfaces."""
return [ipmitool.IPMISocatConsole, ipmitool.IPMIShellinaboxConsole,
noop.NoConsole]
@property
def supported_management_interfaces(self):
"""List of supported management interfaces."""
return [ipmitool.IPMIManagement]
@property
def supported_power_interfaces(self):
"""List of supported power interfaces."""
return [ipmitool.IPMIPower]
class PXEAndIPMIToolDriver(base.BaseDriver):
"""PXE + IPMITool driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` for power on/off
and reboot with
:class:`ironic.drivers.modules.iscsi_deploy.ISCSIDeploy` for
image deployment. Implementations are in those respective
classes; this class is merely the glue between them.
"""
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.inspect = inspector.Inspector.create_if_enabled(
'PXEAndIPMIToolDriver')
self.vendor = ipmitool.VendorPassthru()
self.raid = agent.AgentRAID()
class PXEAndIPMIToolAndSocatDriver(PXEAndIPMIToolDriver):
"""PXE + IPMITool + socat driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` for power on/off
and reboot with
:class:`ironic.drivers.modules.iscsi_deploy.ISCSIDeploy` (for
image deployment) and with
:class:`ironic.drivers.modules.ipmitool.IPMISocatConsole`.
This driver uses the socat console interface instead of the shellinabox
one.
Implementations are in those respective
classes; this class is merely the glue between them.
"""
def __init__(self):
PXEAndIPMIToolDriver.__init__(self)
self.console = ipmitool.IPMISocatConsole()
class AgentAndIPMIToolDriver(base.BaseDriver):
"""Agent + IPMITool driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` (for power on/off and
reboot) with :class:`ironic.drivers.modules.agent.AgentDeploy` (for
image deployment).
Implementations are in those respective classes; this class is merely the
glue between them.
"""
def __init__(self):
self.power = ipmitool.IPMIPower()
self.boot = pxe.PXEBoot()
self.deploy = agent.AgentDeploy()
self.management = ipmitool.IPMIManagement()
self.console = ipmitool.IPMIShellinaboxConsole()
self.vendor = ipmitool.VendorPassthru()
self.raid = agent.AgentRAID()
self.inspect = inspector.Inspector.create_if_enabled(
'AgentAndIPMIToolDriver')
class AgentAndIPMIToolAndSocatDriver(AgentAndIPMIToolDriver):
"""Agent + IPMITool + socat driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmitool.IPMIPower` (for power on/off and
reboot) with :class:`ironic.drivers.modules.agent.AgentDeploy` (for
image deployment) and with
:class:`ironic.drivers.modules.ipmitool.IPMISocatConsole`.
This driver uses the socat console interface instead of the shellinabox
one.
Implementations are in those respective classes; this class is merely the
glue between them.
"""
def __init__(self):
AgentAndIPMIToolDriver.__init__(self)
self.console = ipmitool.IPMISocatConsole()

View File

@ -22,6 +22,7 @@ from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
from ironic.common.i18n import _ from ironic.common.i18n import _
from ironic.drivers import base from ironic.drivers import base
from ironic.drivers import ipmi
from ironic.drivers.modules import agent from ironic.drivers.modules import agent
from ironic.drivers.modules.cimc import management as cimc_mgmt from ironic.drivers.modules.cimc import management as cimc_mgmt
from ironic.drivers.modules.cimc import power as cimc_power from ironic.drivers.modules.cimc import power as cimc_power
@ -49,45 +50,9 @@ from ironic.drivers.modules.ucs import power as ucs_power
from ironic.drivers.modules import virtualbox from ironic.drivers.modules import virtualbox
class PXEAndIPMIToolDriver(base.BaseDriver): # For backward compatibility
"""PXE + IPMITool driver. PXEAndIPMIToolDriver = ipmi.PXEAndIPMIToolDriver
PXEAndIPMIToolAndSocatDriver = ipmi.PXEAndIPMIToolAndSocatDriver
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmi.IPMI` for power on/off
and reboot with
:class:`ironic.drivers.modules.iscsi_deploy.ISCSIDeploy` for
image deployment. Implementations are in those respective
classes; this class is merely the glue between them.
"""
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.inspect = inspector.Inspector.create_if_enabled(
'PXEAndIPMIToolDriver')
self.vendor = ipmitool.VendorPassthru()
self.raid = agent.AgentRAID()
class PXEAndIPMIToolAndSocatDriver(PXEAndIPMIToolDriver):
"""PXE + IPMITool + socat driver.
This driver implements the `core` functionality, combining
:class:`ironic.drivers.modules.ipmi.IPMI` for power on/off
and reboot with
:class:`ironic.drivers.modules.iscsi_deploy.ISCSIDeploy` (for
image deployment) and with
:class:`ironic.drivers.modules.ipmitool.IPMISocatConsole`.
This driver uses the socat console interface instead of the shellinabox
one.
Implementations are in those respective
classes; this class is merely the glue between them.
"""
def __init__(self):
PXEAndIPMIToolDriver.__init__(self)
self.console = ipmitool.IPMISocatConsole()
class PXEAndSSHDriver(base.BaseDriver): class PXEAndSSHDriver(base.BaseDriver):

View File

@ -1,51 +0,0 @@
# Copyright 2015 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Test class for Agent Deploy Driver
"""
from ironic.drivers import agent
from ironic.drivers.modules import agent as agent_module
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import pxe
from ironic.tests import base
class AgentAndIPMIToolDriverTestCase(base.TestCase):
def test___init__(self):
driver = agent.AgentAndIPMIToolDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMIShellinaboxConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, agent_module.AgentDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent_module.AgentRAID)
class AgentAndIPMIToolAndSocatDriverTestCase(base.TestCase):
def test___init__(self):
driver = agent.AgentAndIPMIToolAndSocatDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMISocatConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, agent_module.AgentDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent_module.AgentRAID)

View File

@ -0,0 +1,112 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import testtools
from ironic.conductor import task_manager
from ironic.drivers import ipmi
from ironic.drivers.modules import agent
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import iscsi_deploy
from ironic.drivers.modules import noop
from ironic.drivers.modules import pxe
from ironic.tests.unit.db import base as db_base
from ironic.tests.unit.objects import utils as obj_utils
class IPMIHardwareTestCase(db_base.DbTestCase):
def setUp(self):
super(IPMIHardwareTestCase, self).setUp()
self.config(enabled_hardware_types=['ipmi'],
enabled_power_interfaces=['ipmitool'],
enabled_management_interfaces=['ipmitool'],
enabled_raid_interfaces=['no-raid', 'agent'],
enabled_console_interfaces=['no-console'])
def test_default_interfaces(self):
node = obj_utils.create_test_node(self.context, driver='ipmi')
with task_manager.acquire(self.context, node.id) as task:
self.assertIsInstance(task.driver.management,
ipmitool.IPMIManagement)
self.assertIsInstance(task.driver.power, ipmitool.IPMIPower)
self.assertIsInstance(task.driver.boot, pxe.PXEBoot)
self.assertIsInstance(task.driver.deploy, iscsi_deploy.ISCSIDeploy)
self.assertIsInstance(task.driver.console, noop.NoConsole)
self.assertIsInstance(task.driver.raid, noop.NoRAID)
def test_override_with_shellinabox(self):
self.config(enabled_console_interfaces=['ipmitool-shellinabox',
'ipmitool-socat'])
node = obj_utils.create_test_node(
self.context, driver='ipmi',
deploy_interface='direct',
raid_interface='agent',
console_interface='ipmitool-shellinabox')
with task_manager.acquire(self.context, node.id) as task:
self.assertIsInstance(task.driver.management,
ipmitool.IPMIManagement)
self.assertIsInstance(task.driver.power, ipmitool.IPMIPower)
self.assertIsInstance(task.driver.boot, pxe.PXEBoot)
self.assertIsInstance(task.driver.deploy, agent.AgentDeploy)
self.assertIsInstance(task.driver.console,
ipmitool.IPMIShellinaboxConsole)
self.assertIsInstance(task.driver.raid, agent.AgentRAID)
class IPMIClassicDriversTestCase(testtools.TestCase):
def test_pxe_ipmitool_driver(self):
driver = ipmi.PXEAndIPMIToolDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMIShellinaboxConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, iscsi_deploy.ISCSIDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsNone(driver.inspect)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)
def test_pxe_ipmitool_socat_driver(self):
driver = ipmi.PXEAndIPMIToolAndSocatDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMISocatConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, iscsi_deploy.ISCSIDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsNone(driver.inspect)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)
def test_agent_ipmitool_driver(self):
driver = ipmi.AgentAndIPMIToolDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMIShellinaboxConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, agent.AgentDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)
def test_agent_ipmitool_socat_driver(self):
driver = ipmi.AgentAndIPMIToolAndSocatDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMISocatConsole)
self.assertIsInstance(driver.boot, pxe.PXEBoot)
self.assertIsInstance(driver.deploy, agent.AgentDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)

View File

@ -47,30 +47,6 @@ from ironic.drivers import pxe
class PXEDriversTestCase(testtools.TestCase): class PXEDriversTestCase(testtools.TestCase):
def test_pxe_ipmitool_driver(self):
driver = pxe.PXEAndIPMIToolDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMIShellinaboxConsole)
self.assertIsInstance(driver.boot, pxe_module.PXEBoot)
self.assertIsInstance(driver.deploy, iscsi_deploy.ISCSIDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsNone(driver.inspect)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)
def test_pxe_ipmitool_socat_driver(self):
driver = pxe.PXEAndIPMIToolAndSocatDriver()
self.assertIsInstance(driver.power, ipmitool.IPMIPower)
self.assertIsInstance(driver.console, ipmitool.IPMISocatConsole)
self.assertIsInstance(driver.boot, pxe_module.PXEBoot)
self.assertIsInstance(driver.deploy, iscsi_deploy.ISCSIDeploy)
self.assertIsInstance(driver.management, ipmitool.IPMIManagement)
self.assertIsNone(driver.inspect)
self.assertIsInstance(driver.vendor, ipmitool.VendorPassthru)
self.assertIsInstance(driver.raid, agent.AgentRAID)
def test_pxe_ssh_driver(self): def test_pxe_ssh_driver(self):
driver = pxe.PXEAndSSHDriver() driver = pxe.PXEAndSSHDriver()

View File

@ -0,0 +1,8 @@
---
features:
- |
Introduces new hardware type ``ipmi`` for IPMI-compatible hardware.
This type is enabled by default. Uses ``ipmitool`` utility under the hood,
similar to existing classic drivers ``pxe_ipmitool`` and
``agent_ipmitool``. Supports both types of serial console: via
``shellinabox`` and via ``socat``, both are disabled by default.

View File

@ -43,8 +43,8 @@ ironic.dhcp =
ironic.drivers = ironic.drivers =
agent_ilo = ironic.drivers.ilo:IloVirtualMediaAgentDriver agent_ilo = ironic.drivers.ilo:IloVirtualMediaAgentDriver
agent_ipmitool = ironic.drivers.agent:AgentAndIPMIToolDriver agent_ipmitool = ironic.drivers.ipmi:AgentAndIPMIToolDriver
agent_ipmitool_socat = ironic.drivers.agent:AgentAndIPMIToolAndSocatDriver agent_ipmitool_socat = ironic.drivers.ipmi:AgentAndIPMIToolAndSocatDriver
agent_irmc = ironic.drivers.irmc:IRMCVirtualMediaAgentDriver agent_irmc = ironic.drivers.irmc:IRMCVirtualMediaAgentDriver
agent_pxe_oneview = ironic.drivers.oneview:AgentPXEOneViewDriver agent_pxe_oneview = ironic.drivers.oneview:AgentPXEOneViewDriver
agent_pyghmi = ironic.drivers.agent:AgentAndIPMINativeDriver agent_pyghmi = ironic.drivers.agent:AgentAndIPMINativeDriver
@ -73,8 +73,8 @@ ironic.drivers =
iscsi_ilo = ironic.drivers.ilo:IloVirtualMediaIscsiDriver iscsi_ilo = ironic.drivers.ilo:IloVirtualMediaIscsiDriver
iscsi_irmc = ironic.drivers.irmc:IRMCVirtualMediaIscsiDriver iscsi_irmc = ironic.drivers.irmc:IRMCVirtualMediaIscsiDriver
iscsi_pxe_oneview = ironic.drivers.oneview:ISCSIPXEOneViewDriver iscsi_pxe_oneview = ironic.drivers.oneview:ISCSIPXEOneViewDriver
pxe_ipmitool = ironic.drivers.pxe:PXEAndIPMIToolDriver pxe_ipmitool = ironic.drivers.ipmi:PXEAndIPMIToolDriver
pxe_ipmitool_socat = ironic.drivers.pxe:PXEAndIPMIToolAndSocatDriver pxe_ipmitool_socat = ironic.drivers.ipmi:PXEAndIPMIToolAndSocatDriver
pxe_ipminative = ironic.drivers.pxe:PXEAndIPMINativeDriver pxe_ipminative = ironic.drivers.pxe:PXEAndIPMINativeDriver
pxe_ssh = ironic.drivers.pxe:PXEAndSSHDriver pxe_ssh = ironic.drivers.pxe:PXEAndSSHDriver
pxe_vbox = ironic.drivers.pxe:PXEAndVirtualBoxDriver pxe_vbox = ironic.drivers.pxe:PXEAndVirtualBoxDriver
@ -95,6 +95,8 @@ ironic.hardware.interfaces.boot =
ironic.hardware.interfaces.console = ironic.hardware.interfaces.console =
fake = ironic.drivers.modules.fake:FakeConsole fake = ironic.drivers.modules.fake:FakeConsole
ipmitool-shellinabox = ironic.drivers.modules.ipmitool:IPMIShellinaboxConsole
ipmitool-socat = ironic.drivers.modules.ipmitool:IPMISocatConsole
no-console = ironic.drivers.modules.noop:NoConsole no-console = ironic.drivers.modules.noop:NoConsole
ironic.hardware.interfaces.deploy = ironic.hardware.interfaces.deploy =
@ -109,6 +111,7 @@ ironic.hardware.interfaces.inspect =
ironic.hardware.interfaces.management = ironic.hardware.interfaces.management =
fake = ironic.drivers.modules.fake:FakeManagement fake = ironic.drivers.modules.fake:FakeManagement
ipmitool = ironic.drivers.modules.ipmitool:IPMIManagement
ironic.hardware.interfaces.network = ironic.hardware.interfaces.network =
flat = ironic.drivers.modules.network.flat:FlatNetwork flat = ironic.drivers.modules.network.flat:FlatNetwork
@ -117,6 +120,7 @@ ironic.hardware.interfaces.network =
ironic.hardware.interfaces.power = ironic.hardware.interfaces.power =
fake = ironic.drivers.modules.fake:FakePower fake = ironic.drivers.modules.fake:FakePower
ipmitool = ironic.drivers.modules.ipmitool:IPMIPower
ironic.hardware.interfaces.raid = ironic.hardware.interfaces.raid =
agent = ironic.drivers.modules.agent:AgentRAID agent = ironic.drivers.modules.agent:AgentRAID
@ -137,6 +141,7 @@ ironic.hardware.interfaces.vendor =
ironic.hardware.types = ironic.hardware.types =
fake-hardware = ironic.drivers.fake_hardware:FakeHardware fake-hardware = ironic.drivers.fake_hardware:FakeHardware
manual-management = ironic.drivers.generic:ManualManagementHardware manual-management = ironic.drivers.generic:ManualManagementHardware
ipmi = ironic.drivers.ipmi:IPMIHardware
ironic.database.migration_backend = ironic.database.migration_backend =
sqlalchemy = ironic.db.sqlalchemy.migration sqlalchemy = ironic.db.sqlalchemy.migration