diff --git a/ironic/drivers/ilo.py b/ironic/drivers/ilo.py index 0163ac6a49..e8aaeb2e19 100644 --- a/ironic/drivers/ilo.py +++ b/ironic/drivers/ilo.py @@ -20,6 +20,7 @@ from oslo_utils import importutils from ironic.common import exception from ironic.common.i18n import _ from ironic.drivers import base +from ironic.drivers import generic from ironic.drivers.modules import agent from ironic.drivers.modules.ilo import boot from ironic.drivers.modules.ilo import console @@ -27,7 +28,60 @@ from ironic.drivers.modules.ilo import inspect from ironic.drivers.modules.ilo import management from ironic.drivers.modules.ilo import power from ironic.drivers.modules.ilo import vendor +from ironic.drivers.modules import inspector from ironic.drivers.modules import iscsi_deploy +from ironic.drivers.modules import noop + + +class IloHardware(generic.GenericHardware): + """iLO hardware type. + + iLO hardware type is targeted for iLO 4 based Proliant Gen8 + and Gen9 servers. + """ + + @property + def supported_boot_interfaces(self): + """List of supported boot interfaces.""" + return [boot.IloVirtualMediaBoot, boot.IloPXEBoot] + + @property + def supported_deploy_interfaces(self): + """List of supported deploy interfaces.""" + + # Note(stendulker) It does not support ISCSI based deploy + # (iscsi.ISCSIDeploy) mechanism. + # The reason being all the Ironic features supported by ISCSIDeploy + # are supported with agentDeploy as well. There is no additional + # advantage of having iscsi based deploy except for the cases wherein + # instance images(qcow2) are larger than RAM size of the bare metal. + # That also could be overcome by using 'raw' images. + # To avoid the additional driver supportability and reduce test matrix, + # ISCSI based deploy is not supported. However, if any user insists + # for ISCSI based deploy, we would surely enable the same. + + return [agent.AgentDeploy] + + @property + def supported_console_interfaces(self): + """List of supported console interfaces.""" + return [console.IloConsoleInterface, noop.NoConsole] + + @property + def supported_inspect_interfaces(self): + """List of supported inspect interfaces.""" + return [inspect.IloInspect, inspector.Inspector, + noop.NoInspect] + + @property + def supported_management_interfaces(self): + """List of supported management interfaces.""" + return [management.IloManagement] + + @property + def supported_power_interfaces(self): + """List of supported power interfaces.""" + return [power.IloPower] class IloVirtualMediaIscsiDriver(base.BaseDriver): diff --git a/ironic/tests/unit/drivers/test_ilo.py b/ironic/tests/unit/drivers/test_ilo.py index ba3df33150..e15be1012d 100644 --- a/ironic/tests/unit/drivers/test_ilo.py +++ b/ironic/tests/unit/drivers/test_ilo.py @@ -20,6 +20,7 @@ import mock import testtools from ironic.common import exception +from ironic.conductor import task_manager from ironic.drivers import ilo from ironic.drivers.modules import agent from ironic.drivers.modules.ilo import boot @@ -28,7 +29,96 @@ from ironic.drivers.modules.ilo import inspect from ironic.drivers.modules.ilo import management from ironic.drivers.modules.ilo import power from ironic.drivers.modules.ilo import vendor +from ironic.drivers.modules import inspector from ironic.drivers.modules import iscsi_deploy +from ironic.drivers.modules import noop +from ironic.tests.unit.db import base as db_base +from ironic.tests.unit.objects import utils as obj_utils + + +class IloHardwareTestCase(db_base.DbTestCase): + + def setUp(self): + super(IloHardwareTestCase, self).setUp() + self.config(enabled_hardware_types=['ilo'], + enabled_boot_interfaces=['ilo-virtual-media', 'ilo-pxe'], + enabled_console_interfaces=['ilo'], + enabled_deploy_interfaces=['direct'], + enabled_inspect_interfaces=['ilo'], + enabled_management_interfaces=['ilo'], + enabled_power_interfaces=['ilo'], + enabled_raid_interfaces=['no-raid', 'agent'], + enabled_vendor_interfaces=['no-vendor']) + + def test_default_interfaces(self): + node = obj_utils.create_test_node(self.context, + driver='ilo') + with task_manager.acquire(self.context, node.id) as task: + self.assertIsInstance(task.driver.boot, + ilo.boot.IloVirtualMediaBoot) + self.assertIsInstance(task.driver.console, + ilo.console.IloConsoleInterface) + self.assertIsInstance(task.driver.deploy, + agent.AgentDeploy) + self.assertIsInstance(task.driver.inspect, + ilo.inspect.IloInspect) + self.assertIsInstance(task.driver.management, + ilo.management.IloManagement) + self.assertIsInstance(task.driver.power, + ilo.power.IloPower) + self.assertIsInstance(task.driver.raid, + noop.NoRAID) + self.assertIsInstance(task.driver.vendor, + noop.NoVendor) + + def test_override_with_inspector(self): + self.config(enabled_inspect_interfaces=['inspector', 'ilo']) + node = obj_utils.create_test_node( + self.context, driver='ilo', + deploy_interface='direct', + inspect_interface='inspector', + raid_interface='agent') + with task_manager.acquire(self.context, node.id) as task: + self.assertIsInstance(task.driver.boot, + ilo.boot.IloVirtualMediaBoot) + self.assertIsInstance(task.driver.console, + ilo.console.IloConsoleInterface) + self.assertIsInstance(task.driver.deploy, + agent.AgentDeploy) + self.assertIsInstance(task.driver.inspect, + inspector.Inspector) + self.assertIsInstance(task.driver.management, + ilo.management.IloManagement) + self.assertIsInstance(task.driver.power, + ilo.power.IloPower) + self.assertIsInstance(task.driver.raid, + agent.AgentRAID) + self.assertIsInstance(task.driver.vendor, + noop.NoVendor) + + def test_override_with_pxe(self): + node = obj_utils.create_test_node( + self.context, driver='ilo', + deploy_interface='direct', + boot_interface='ilo-pxe', + raid_interface='agent') + with task_manager.acquire(self.context, node.id) as task: + self.assertIsInstance(task.driver.boot, + ilo.boot.IloPXEBoot) + self.assertIsInstance(task.driver.console, + ilo.console.IloConsoleInterface) + self.assertIsInstance(task.driver.deploy, + agent.AgentDeploy) + self.assertIsInstance(task.driver.inspect, + ilo.inspect.IloInspect) + self.assertIsInstance(task.driver.management, + ilo.management.IloManagement) + self.assertIsInstance(task.driver.power, + ilo.power.IloPower) + self.assertIsInstance(task.driver.raid, + agent.AgentRAID) + self.assertIsInstance(task.driver.vendor, + noop.NoVendor) @mock.patch.object(ilo.importutils, 'try_import', spec_set=True, diff --git a/releasenotes/notes/ilo-hardware-type-48fd1c8bccd70659.yaml b/releasenotes/notes/ilo-hardware-type-48fd1c8bccd70659.yaml new file mode 100644 index 0000000000..52f3bbdfcc --- /dev/null +++ b/releasenotes/notes/ilo-hardware-type-48fd1c8bccd70659.yaml @@ -0,0 +1,17 @@ +--- +features: + - | + Adds a new hardware type ``ilo`` for iLO 4 based Proliant Gen 8 + and Gen 9 servers. + ``ilo`` hardware type will support virtual media and PXE based + provisioning using HPE iLO 4 management engine. It supports the + following driver interfaces: + + * boot: ``ilo-virtual-media`` and ``ilo-pxe`` + * console: ``ilo`` and ``no-console`` + * deploy: ``direct`` + * inspect: ``ilo``, ``inspector`` and ``no-inspect`` + * management: ``ilo`` + * network: ``flat``, ``no-op`` and ``neutron`` + * power: ``ilo`` + * raid: ``no-raid`` and ``agent`` diff --git a/setup.cfg b/setup.cfg index 9d626ef488..5e7f184549 100644 --- a/setup.cfg +++ b/setup.cfg @@ -84,39 +84,45 @@ ironic.drivers = ironic.hardware.interfaces.boot = fake = ironic.drivers.modules.fake:FakeBoot - pxe = ironic.drivers.modules.pxe:PXEBoot + ilo-pxe = ironic.drivers.modules.ilo.boot:IloPXEBoot + ilo-virtual-media = ironic.drivers.modules.ilo.boot:IloVirtualMediaBoot irmc-virtual-media = ironic.drivers.modules.irmc.boot:IRMCVirtualMediaBoot + pxe = ironic.drivers.modules.pxe:PXEBoot ironic.hardware.interfaces.console = fake = ironic.drivers.modules.fake:FakeConsole + ilo = ironic.drivers.modules.ilo.console:IloConsoleInterface ipmitool-shellinabox = ironic.drivers.modules.ipmitool:IPMIShellinaboxConsole ipmitool-socat = ironic.drivers.modules.ipmitool:IPMISocatConsole no-console = ironic.drivers.modules.noop:NoConsole ironic.hardware.interfaces.deploy = direct = ironic.drivers.modules.agent:AgentDeploy - iscsi = ironic.drivers.modules.iscsi_deploy:ISCSIDeploy fake = ironic.drivers.modules.fake:FakeDeploy + iscsi = ironic.drivers.modules.iscsi_deploy:ISCSIDeploy ironic.hardware.interfaces.inspect = fake = ironic.drivers.modules.fake:FakeInspect + ilo = ironic.drivers.modules.ilo.inspect:IloInspect inspector = ironic.drivers.modules.inspector:Inspector - no-inspect = ironic.drivers.modules.noop:NoInspect irmc = ironic.drivers.modules.irmc.inspect:IRMCInspect + no-inspect = ironic.drivers.modules.noop:NoInspect ironic.hardware.interfaces.management = fake = ironic.drivers.modules.fake:FakeManagement + ilo = ironic.drivers.modules.ilo.management:IloManagement ipmitool = ironic.drivers.modules.ipmitool:IPMIManagement irmc = ironic.drivers.modules.irmc.management:IRMCManagement redfish = ironic.drivers.modules.redfish.management:RedfishManagement ironic.hardware.interfaces.network = flat = ironic.drivers.modules.network.flat:FlatNetwork - noop = ironic.drivers.modules.network.noop:NoopNetwork neutron = ironic.drivers.modules.network.neutron:NeutronNetwork + noop = ironic.drivers.modules.network.noop:NoopNetwork ironic.hardware.interfaces.power = fake = ironic.drivers.modules.fake:FakePower + ilo = ironic.drivers.modules.ilo.power:IloPower ipmitool = ironic.drivers.modules.ipmitool:IPMIPower irmc = ironic.drivers.modules.irmc.power:IRMCPower redfish = ironic.drivers.modules.redfish.power:RedfishPower @@ -139,9 +145,10 @@ ironic.hardware.interfaces.vendor = ironic.hardware.types = fake-hardware = ironic.drivers.fake_hardware:FakeHardware - manual-management = ironic.drivers.generic:ManualManagementHardware + ilo = ironic.drivers.ilo:IloHardware ipmi = ironic.drivers.ipmi:IPMIHardware irmc = ironic.drivers.irmc:IRMCHardware + manual-management = ironic.drivers.generic:ManualManagementHardware redfish = ironic.drivers.redfish:RedfishHardware ironic.database.migration_backend =