Migrate the remaining classic drivers to hardware types

I've tried my best to provide a correct matching for these, but
there are two exceptions:

* fake_drac uses iscsi deploy with None boot, which cannot work,
  so changing both to fake
* some fake drivers are migrated to the 'fake' power interface,
  which is changed to include soft power as well.

The latter means that all fake classic drivers now support fake
soft power actions, while previously only fake_soft_power did.
Now fake_soft_power is identical to fake and is left for backward
compatibility

Also wrote more tests to check correctness of this migration.

Change-Id: I00c9c6ed698b10f035e65428e1a20d733c7e544a
Partial-Bug: #1690185
This commit is contained in:
Dmitry Tantsur 2018-01-31 16:40:23 +01:00
parent 8f464b909a
commit d1062cfbdd
10 changed files with 338 additions and 20 deletions

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from oslo_config import cfg
from oslo_utils import importutils from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
@ -27,6 +28,9 @@ from ironic.drivers.modules.ucs import management as ucs_mgmt
from ironic.drivers.modules.ucs import power as ucs_power from ironic.drivers.modules.ucs import power as ucs_power
CONF = cfg.CONF
# For backward compatibility # For backward compatibility
AgentAndIPMIToolDriver = ipmi.AgentAndIPMIToolDriver AgentAndIPMIToolDriver = ipmi.AgentAndIPMIToolDriver
AgentAndIPMIToolAndSocatDriver = ipmi.AgentAndIPMIToolAndSocatDriver AgentAndIPMIToolAndSocatDriver = ipmi.AgentAndIPMIToolAndSocatDriver
@ -55,6 +59,21 @@ class AgentAndUcsDriver(base.BaseDriver):
self.inspect = inspector.Inspector.create_if_enabled( self.inspect = inspector.Inspector.create_if_enabled(
'AgentAndUcsDriver') 'AgentAndUcsDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'inspector'
else:
inspect_interface = 'no-inspect'
return 'cisco-ucs-managed', {'boot': 'pxe',
'deploy': 'direct',
'inspect': inspect_interface,
'management': 'ucsm',
'power': 'ucsm'}
class AgentAndCIMCDriver(base.BaseDriver): class AgentAndCIMCDriver(base.BaseDriver):
"""Agent + Cisco CIMC driver. """Agent + Cisco CIMC driver.
@ -78,3 +97,18 @@ class AgentAndCIMCDriver(base.BaseDriver):
self.management = cimc_mgmt.CIMCManagement() self.management = cimc_mgmt.CIMCManagement()
self.inspect = inspector.Inspector.create_if_enabled( self.inspect = inspector.Inspector.create_if_enabled(
'AgentAndCIMCDriver') 'AgentAndCIMCDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'inspector'
else:
inspect_interface = 'no-inspect'
return 'cisco-ucs-standalone', {'boot': 'pxe',
'deploy': 'direct',
'inspect': inspect_interface,
'management': 'cimc',
'power': 'cimc'}

View File

@ -15,6 +15,7 @@
DRAC Driver for remote system management using Dell Remote Access Card. DRAC Driver for remote system management using Dell Remote Access Card.
""" """
from oslo_config import cfg
from oslo_utils import importutils from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
@ -32,6 +33,9 @@ from ironic.drivers.modules import noop
from ironic.drivers.modules import pxe from ironic.drivers.modules import pxe
CONF = cfg.CONF
class IDRACHardware(generic.GenericHardware): class IDRACHardware(generic.GenericHardware):
"""integrated Dell Remote Access Controller hardware type""" """integrated Dell Remote Access Controller hardware type"""
@ -85,6 +89,16 @@ class PXEDracDriver(base.BaseDriver):
self.vendor = vendor_passthru.DracVendorPassthru() self.vendor = vendor_passthru.DracVendorPassthru()
self.inspect = drac_inspect.DracInspect() self.inspect = drac_inspect.DracInspect()
@classmethod
def to_hardware_type(cls):
return 'idrac', {'boot': 'pxe',
'deploy': 'iscsi',
'inspect': 'idrac',
'management': 'idrac',
'power': 'idrac',
'raid': 'idrac',
'vendor': 'idrac'}
class PXEDracInspectorDriver(PXEDracDriver): class PXEDracInspectorDriver(PXEDracDriver):
"""Drac driver using PXE for deploy and OOB inspection interface.""" """Drac driver using PXE for deploy and OOB inspection interface."""
@ -93,3 +107,20 @@ class PXEDracInspectorDriver(PXEDracDriver):
super(PXEDracInspectorDriver, self).__init__() super(PXEDracInspectorDriver, self).__init__()
self.inspect = inspector.Inspector.create_if_enabled( self.inspect = inspector.Inspector.create_if_enabled(
'PXEDracInspectorDriver') 'PXEDracInspectorDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'inspector'
else:
inspect_interface = 'no-inspect'
return 'idrac', {'boot': 'pxe',
'deploy': 'iscsi',
'inspect': inspect_interface,
'management': 'idrac',
'power': 'idrac',
'raid': 'idrac',
'vendor': 'idrac'}

View File

@ -80,10 +80,8 @@ class FakeDriver(base.BaseDriver):
class FakeSoftPowerDriver(FakeDriver): class FakeSoftPowerDriver(FakeDriver):
"""Example implementation of a Driver.""" """Example implementation of a Driver."""
# NOTE(dtantsur): identical to FakeDriver now, will be removed with other
def __init__(self): # classic drivers
super(FakeSoftPowerDriver, self).__init__()
self.power = fake.FakeSoftPower()
class FakeIPMIToolDriver(base.BaseDriver): class FakeIPMIToolDriver(base.BaseDriver):
@ -181,6 +179,16 @@ class FakeIloDriver(base.BaseDriver):
self.management = ilo_management.IloManagement() self.management = ilo_management.IloManagement()
self.inspect = ilo_inspect.IloInspect() self.inspect = ilo_inspect.IloInspect()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
'deploy': 'fake',
'inspect': 'ilo',
'management': 'ilo',
'power': 'ilo'
}
class FakeDracDriver(base.BaseDriver): class FakeDracDriver(base.BaseDriver):
"""Fake Drac driver.""" """Fake Drac driver."""
@ -198,6 +206,21 @@ class FakeDracDriver(base.BaseDriver):
self.vendor = drac_vendor.DracVendorPassthru() self.vendor = drac_vendor.DracVendorPassthru()
self.inspect = drac_inspect.DracInspect() self.inspect = drac_inspect.DracInspect()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
# NOTE(dtantsur): the classic driver uses boot=None and
# deploy=iscsi. This cannot work, so correcting it based on the
# intended purpose of these fake drivers.
'deploy': 'fake',
'inspect': 'idrac',
'management': 'idrac',
'power': 'idrac',
'raid': 'idrac',
'vendor': 'idrac'
}
class FakeSNMPDriver(base.BaseDriver): class FakeSNMPDriver(base.BaseDriver):
"""Fake SNMP driver.""" """Fake SNMP driver."""
@ -212,7 +235,7 @@ class FakeSNMPDriver(base.BaseDriver):
@classmethod @classmethod
def to_hardware_type(cls): def to_hardware_type(cls):
return 'snmp', { return 'fake-hardware', {
'boot': 'fake', 'boot': 'fake',
'deploy': 'fake', 'deploy': 'fake',
'management': 'fake', 'management': 'fake',
@ -233,6 +256,16 @@ class FakeIRMCDriver(base.BaseDriver):
self.management = irmc_management.IRMCManagement() self.management = irmc_management.IRMCManagement()
self.inspect = irmc_inspect.IRMCInspect() self.inspect = irmc_inspect.IRMCInspect()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
'deploy': 'fake',
'inspect': 'irmc',
'management': 'irmc',
'power': 'irmc'
}
class FakeIPMIToolInspectorDriver(base.BaseDriver): class FakeIPMIToolInspectorDriver(base.BaseDriver):
"""Fake Inspector driver.""" """Fake Inspector driver."""
@ -257,6 +290,7 @@ class FakeIPMIToolInspectorDriver(base.BaseDriver):
'inspect': 'inspector', 'inspect': 'inspector',
'management': 'ipmitool', 'management': 'ipmitool',
'power': 'ipmitool', 'power': 'ipmitool',
'vendor': 'ipmitool',
} }
@ -272,6 +306,15 @@ class FakeUcsDriver(base.BaseDriver):
self.deploy = fake.FakeDeploy() self.deploy = fake.FakeDeploy()
self.management = ucs_mgmt.UcsManagement() self.management = ucs_mgmt.UcsManagement()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
'deploy': 'fake',
'management': 'ucsm',
'power': 'ucsm'
}
class FakeCIMCDriver(base.BaseDriver): class FakeCIMCDriver(base.BaseDriver):
"""Fake CIMC driver.""" """Fake CIMC driver."""
@ -285,6 +328,15 @@ class FakeCIMCDriver(base.BaseDriver):
self.deploy = fake.FakeDeploy() self.deploy = fake.FakeDeploy()
self.management = cimc_mgmt.CIMCManagement() self.management = cimc_mgmt.CIMCManagement()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
'deploy': 'fake',
'management': 'cimc',
'power': 'cimc'
}
class FakeOneViewDriver(base.BaseDriver): class FakeOneViewDriver(base.BaseDriver):
"""Fake OneView driver. For testing purposes.""" """Fake OneView driver. For testing purposes."""
@ -300,3 +352,13 @@ class FakeOneViewDriver(base.BaseDriver):
self.boot = fake.FakeBoot() self.boot = fake.FakeBoot()
self.deploy = fake.FakeDeploy() self.deploy = fake.FakeDeploy()
self.inspect = fake.FakeInspect() self.inspect = fake.FakeInspect()
@classmethod
def to_hardware_type(cls):
return 'fake-hardware', {
'boot': 'fake',
'deploy': 'fake',
'inspect': 'fake',
'management': 'oneview',
'power': 'oneview'
}

View File

@ -97,6 +97,17 @@ class IloVirtualMediaIscsiDriver(base.BaseDriver):
self.inspect = inspect.IloInspect() self.inspect = inspect.IloInspect()
self.raid = agent.AgentRAID() self.raid = agent.AgentRAID()
@classmethod
def to_hardware_type(cls):
return 'ilo', {'boot': 'ilo-virtual-media',
'console': 'ilo',
'deploy': 'iscsi',
'inspect': 'ilo',
'management': 'ilo',
'power': 'ilo',
'raid': 'agent',
'vendor': 'ilo'}
class IloVirtualMediaAgentDriver(base.BaseDriver): class IloVirtualMediaAgentDriver(base.BaseDriver):
"""IloDriver using IloClient interface. """IloDriver using IloClient interface.
@ -121,3 +132,13 @@ class IloVirtualMediaAgentDriver(base.BaseDriver):
self.management = management.IloManagement() self.management = management.IloManagement()
self.inspect = inspect.IloInspect() self.inspect = inspect.IloInspect()
self.raid = agent.AgentRAID() self.raid = agent.AgentRAID()
@classmethod
def to_hardware_type(cls):
return 'ilo', {'boot': 'ilo-virtual-media',
'console': 'ilo',
'deploy': 'direct',
'inspect': 'ilo',
'management': 'ilo',
'power': 'ilo',
'raid': 'agent'}

View File

@ -56,6 +56,15 @@ class IRMCVirtualMediaIscsiDriver(base.BaseDriver):
self.management = management.IRMCManagement() self.management = management.IRMCManagement()
self.inspect = inspect.IRMCInspect() self.inspect = inspect.IRMCInspect()
@classmethod
def to_hardware_type(cls):
return 'irmc', {'boot': 'irmc-virtual-media',
'console': 'ipmitool-shellinabox',
'deploy': 'iscsi',
'inspect': 'irmc',
'management': 'irmc',
'power': 'irmc'}
class IRMCVirtualMediaAgentDriver(base.BaseDriver): class IRMCVirtualMediaAgentDriver(base.BaseDriver):
"""iRMC Driver using SCCI. """iRMC Driver using SCCI.
@ -80,6 +89,15 @@ class IRMCVirtualMediaAgentDriver(base.BaseDriver):
self.management = management.IRMCManagement() self.management = management.IRMCManagement()
self.inspect = inspect.IRMCInspect() self.inspect = inspect.IRMCInspect()
@classmethod
def to_hardware_type(cls):
return 'irmc', {'boot': 'irmc-virtual-media',
'console': 'ipmitool-shellinabox',
'deploy': 'direct',
'inspect': 'irmc',
'management': 'irmc',
'power': 'irmc'}
class IRMCHardware(generic.GenericHardware): class IRMCHardware(generic.GenericHardware):
"""iRMC hardware type. """iRMC hardware type.

View File

@ -43,20 +43,9 @@ class FakePower(base.PowerInterface):
def get_power_state(self, task): def get_power_state(self, task):
return task.node.power_state return task.node.power_state
def set_power_state(self, task, power_state, timeout=None):
if power_state not in [states.POWER_ON, states.POWER_OFF]:
raise exception.InvalidParameterValue(
_("set_power_state called with an invalid power "
"state: %s.") % power_state)
task.node.power_state = power_state
def reboot(self, task, timeout=None): def reboot(self, task, timeout=None):
pass pass
class FakeSoftPower(FakePower):
"""Example implementation of a simple soft power operations."""
def set_power_state(self, task, power_state, timeout=None): def set_power_state(self, task, power_state, timeout=None):
if power_state not in [states.POWER_ON, states.POWER_OFF, if power_state not in [states.POWER_ON, states.POWER_OFF,
states.SOFT_REBOOT, states.SOFT_POWER_OFF]: states.SOFT_REBOOT, states.SOFT_POWER_OFF]:
@ -70,6 +59,10 @@ class FakeSoftPower(FakePower):
states.SOFT_REBOOT, states.SOFT_POWER_OFF] states.SOFT_REBOOT, states.SOFT_POWER_OFF]
# NOTE(dtantsur): for backward compatibility
FakeSoftPower = FakePower
class FakeBoot(base.BootInterface): class FakeBoot(base.BootInterface):
"""Example implementation of a simple boot interface.""" """Example implementation of a simple boot interface."""

View File

@ -16,6 +16,8 @@
""" """
OneView Driver and supporting meta-classes. OneView Driver and supporting meta-classes.
""" """
from oslo_config import cfg
from oslo_utils import importutils from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
@ -30,6 +32,9 @@ from ironic.drivers.modules.oneview import power
from ironic.drivers.modules import pxe from ironic.drivers.modules import pxe
CONF = cfg.CONF
class OneViewHardware(generic.GenericHardware): class OneViewHardware(generic.GenericHardware):
"""OneView hardware type. """OneView hardware type.
@ -84,6 +89,21 @@ class AgentPXEOneViewDriver(base.BaseDriver):
self.inspect = inspect.OneViewInspect.create_if_enabled( self.inspect = inspect.OneViewInspect.create_if_enabled(
'AgentPXEOneViewDriver') 'AgentPXEOneViewDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'oneview'
else:
inspect_interface = 'no-inspect'
return 'oneview', {'boot': 'pxe',
'deploy': 'oneview-direct',
'inspect': inspect_interface,
'management': 'oneview',
'power': 'oneview'}
class ISCSIPXEOneViewDriver(base.BaseDriver): class ISCSIPXEOneViewDriver(base.BaseDriver):
"""OneViewDriver using OneViewClient interface. """OneViewDriver using OneViewClient interface.
@ -111,3 +131,18 @@ class ISCSIPXEOneViewDriver(base.BaseDriver):
self.deploy = deploy.OneViewIscsiDeploy() self.deploy = deploy.OneViewIscsiDeploy()
self.inspect = inspect.OneViewInspect.create_if_enabled( self.inspect = inspect.OneViewInspect.create_if_enabled(
'ISCSIPXEOneViewDriver') 'ISCSIPXEOneViewDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'oneview'
else:
inspect_interface = 'no-inspect'
return 'oneview', {'boot': 'pxe',
'deploy': 'oneview-iscsi',
'inspect': inspect_interface,
'management': 'oneview',
'power': 'oneview'}

View File

@ -17,6 +17,7 @@
PXE Driver and supporting meta-classes. PXE Driver and supporting meta-classes.
""" """
from oslo_config import cfg
from oslo_utils import importutils from oslo_utils import importutils
from ironic.common import exception from ironic.common import exception
@ -45,6 +46,9 @@ from ironic.drivers.modules.ucs import management as ucs_mgmt
from ironic.drivers.modules.ucs import power as ucs_power from ironic.drivers.modules.ucs import power as ucs_power
CONF = cfg.CONF
# For backward compatibility # For backward compatibility
PXEAndIPMIToolDriver = ipmi.PXEAndIPMIToolDriver PXEAndIPMIToolDriver = ipmi.PXEAndIPMIToolDriver
PXEAndIPMIToolAndSocatDriver = ipmi.PXEAndIPMIToolAndSocatDriver PXEAndIPMIToolAndSocatDriver = ipmi.PXEAndIPMIToolAndSocatDriver
@ -75,6 +79,17 @@ class PXEAndIloDriver(base.BaseDriver):
self.inspect = ilo_inspect.IloInspect() self.inspect = ilo_inspect.IloInspect()
self.raid = agent.AgentRAID() self.raid = agent.AgentRAID()
@classmethod
def to_hardware_type(cls):
return 'ilo', {'boot': 'ilo-pxe',
'console': 'ilo',
'deploy': 'iscsi',
'inspect': 'ilo',
'management': 'ilo',
'power': 'ilo',
'raid': 'agent',
'vendor': 'ilo'}
class PXEAndSNMPDriver(base.BaseDriver): class PXEAndSNMPDriver(base.BaseDriver):
"""PXE + SNMP driver. """PXE + SNMP driver.
@ -130,6 +145,15 @@ class PXEAndIRMCDriver(base.BaseDriver):
self.management = irmc_management.IRMCManagement() self.management = irmc_management.IRMCManagement()
self.inspect = irmc_inspect.IRMCInspect() self.inspect = irmc_inspect.IRMCInspect()
@classmethod
def to_hardware_type(cls):
return 'irmc', {'boot': 'irmc-pxe',
'console': 'ipmitool-shellinabox',
'deploy': 'iscsi',
'inspect': 'irmc',
'management': 'irmc',
'power': 'irmc'}
class PXEAndUcsDriver(base.BaseDriver): class PXEAndUcsDriver(base.BaseDriver):
"""PXE + Cisco UCSM driver. """PXE + Cisco UCSM driver.
@ -153,6 +177,21 @@ class PXEAndUcsDriver(base.BaseDriver):
self.inspect = inspector.Inspector.create_if_enabled( self.inspect = inspector.Inspector.create_if_enabled(
'PXEAndUcsDriver') 'PXEAndUcsDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'inspector'
else:
inspect_interface = 'no-inspect'
return 'cisco-ucs-managed', {'boot': 'pxe',
'deploy': 'iscsi',
'inspect': inspect_interface,
'management': 'ucsm',
'power': 'ucsm'}
class PXEAndCIMCDriver(base.BaseDriver): class PXEAndCIMCDriver(base.BaseDriver):
"""PXE + Cisco IMC driver. """PXE + Cisco IMC driver.
@ -175,3 +214,18 @@ class PXEAndCIMCDriver(base.BaseDriver):
self.management = cimc_mgmt.CIMCManagement() self.management = cimc_mgmt.CIMCManagement()
self.inspect = inspector.Inspector.create_if_enabled( self.inspect = inspector.Inspector.create_if_enabled(
'PXEAndCIMCDriver') 'PXEAndCIMCDriver')
@classmethod
def to_hardware_type(cls):
# NOTE(dtantsur): classic drivers are not affected by the
# enabled_inspect_interfaces configuration option.
if CONF.inspector.enabled:
inspect_interface = 'inspector'
else:
inspect_interface = 'no-inspect'
return 'cisco-ucs-standalone', {'boot': 'pxe',
'deploy': 'iscsi',
'inspect': inspect_interface,
'management': 'cimc',
'power': 'cimc'}

View File

@ -476,18 +476,39 @@ class TestToHardwareType(base.TestCase):
hw_type = driver.to_hardware_type()[0] hw_type = driver.to_hardware_type()[0]
except NotImplementedError: except NotImplementedError:
continue continue
except KeyError:
self.fail('%s does not return a tuple' % driver)
self.assertIn(hw_type, self.hardware_types, self.assertIn(hw_type, self.hardware_types,
'%s returns unknown hardware type %s' % '%s returns unknown hardware type %s' %
(driver, hw_type)) (driver, hw_type))
def test_to_hardware_type_returns_existing_interfaces(self): def test_to_hardware_type_returns_existing_interfaces(self):
self.config(enabled=False, group='inspector')
# Check that all defined implementations of to_hardware_type # Check that all defined implementations of to_hardware_type
# contain only existing interface types # contain only existing interface types
for driver in self.driver_classes: for driver in self.driver_classes:
try: try:
delta = driver.to_hardware_type()[1] delta = driver.to_hardware_type()[1]
except NotImplementedError: except Exception:
continue continue # covered by other tests
for iface, value in delta.items():
self.assertIn(iface, self.existing_ifaces,
'%s returns unknown interface %s' %
(driver, iface))
self.assertIn(value, self.existing_ifaces[iface],
'%s returns unknown %s interface %s' %
(driver, iface, value))
def test_to_hardware_type_returns_existing_interfaces_inspector(self):
self.config(enabled=True, group='inspector')
# Check that all defined implementations of to_hardware_type
# contain only existing interface types
for driver in self.driver_classes:
try:
delta = driver.to_hardware_type()[1]
except Exception:
continue # covered by other tests
for iface, value in delta.items(): for iface, value in delta.items():
self.assertIn(iface, self.existing_ifaces, self.assertIn(iface, self.existing_ifaces,
'%s returns unknown interface %s' % '%s returns unknown interface %s' %
@ -500,9 +521,53 @@ class TestToHardwareType(base.TestCase):
for driver in self.driver_classes: for driver in self.driver_classes:
try: try:
delta = driver.to_hardware_type()[1] delta = driver.to_hardware_type()[1]
except NotImplementedError: except Exception:
continue continue # covered by other tests
for iface in self.mandatory_interfaces: for iface in self.mandatory_interfaces:
self.assertIn(iface, delta, self.assertIn(iface, delta,
'%s does not return mandatory interface %s' % '%s does not return mandatory interface %s' %
(driver, iface)) (driver, iface))
def test_to_hardware_type_for_all_in_tree_drivers(self):
missing = set()
for driver in self.driver_classes:
# We don't want to test out-of-tree drivers installed locally
if not driver.__module__.startswith('ironic.'):
continue
try:
driver.to_hardware_type()
except NotImplementedError:
missing.add(driver.__name__)
if missing:
self.fail('to_hardware_type not implemented for %s' %
', '.join(missing))
def test_to_hardware_type_boot_deploy(self):
for driver in self.driver_classes:
# We don't want to test out-of-tree drivers installed locally
if not driver.__module__.startswith('ironic.'):
continue
try:
delta = driver.to_hardware_type()[1]
boot = delta['boot']
deploy = delta['deploy']
except NotImplementedError:
continue # covered by other tests
name = driver.__name__.lower()
# Try to guess the correct values for boot and deploy based on our
# naming schema
if 'pxe' in name:
self.assertIn('pxe', boot,
'boot interface should be based on pxe for %s' %
driver)
if 'agent' in name:
self.assertIn('direct', deploy,
'deploy interface should be direct for %s' %
driver)
elif 'iscsi' in name or 'pxe' in name:
self.assertIn('iscsi', deploy,
'deploy interface should be iscsi for %s' %
driver)

View File

@ -0,0 +1,5 @@
---
other:
- |
All ``fake`` classic drivers now implement fake soft power actions.
The ``fake_soft_power`` driver is now identical to ``fake``.