pxe_ilo driver to call iLO set_boot_device

After switching from uefi to bios boot mode, one system reset is
required in iLO for persistent boot device settings.pxe driver call
set_boot_device() which internally calls ipmitool to set boot device
to pxe, will fail in such scenarios.

This fix proposes to change the management interface for pxe_ilo driver
to call ilo set_boot_device using proliantutils ilo_client functions
instead of IPMI call

Change-Id: Idc0e3a765f447ae1d1118299e4815a06995e5414
Closes-bug: #1370466
This commit is contained in:
Faizan Barmawer 2014-09-24 04:32:38 -04:00
parent 2a5d91b0ee
commit 56dcee473e
3 changed files with 64 additions and 2 deletions

View File

@ -32,6 +32,7 @@ from ironic.drivers import base
from ironic.drivers.modules import agent from ironic.drivers.modules import agent
from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules.ilo import common as ilo_common from ironic.drivers.modules.ilo import common as ilo_common
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import iscsi_deploy from ironic.drivers.modules import iscsi_deploy
from ironic.drivers.modules import pxe from ironic.drivers.modules import pxe
from ironic.drivers import utils as driver_utils from ironic.drivers import utils as driver_utils
@ -52,6 +53,9 @@ CONF.import_opt('pxe_append_params', 'ironic.drivers.modules.iscsi_deploy',
CONF.import_opt('swift_ilo_container', 'ironic.drivers.modules.ilo.common', CONF.import_opt('swift_ilo_container', 'ironic.drivers.modules.ilo.common',
group='ilo') group='ilo')
BOOT_DEVICE_MAPPING_TO_ILO = {'pxe': 'NETWORK', 'disk': 'HDD',
'cdrom': 'CDROM', 'bios': 'BIOS', 'safe': 'SAFE'}
def _get_boot_iso_object_name(node): def _get_boot_iso_object_name(node):
"""Returns the floppy image name for a given node. """Returns the floppy image name for a given node.
@ -440,10 +444,38 @@ class IloPXEDeploy(pxe.PXEDeploy):
:returns: deploy state DEPLOYWAIT. :returns: deploy state DEPLOYWAIT.
""" """
ilo_common.set_boot_device(task.node, 'NETWORK', False) ilo_common.set_boot_device(task.node, 'NETWORK', False)
return super(IloPXEDeploy, self).deploy(task) return super(IloPXEDeploy, self).deploy(task)
class IloManagement(ipmitool.IPMIManagement):
@task_manager.require_exclusive_lock
def set_boot_device(self, task, device, persistent=False):
"""Set the boot device for the task's node.
Set the boot device to use on next reboot of the node.
:param task: a task from TaskManager.
:param device: the boot device, one of
:mod:`ironic.common.boot_devices`.
:param persistent: Boolean value. True if the boot device will
persist to all future boots, False if not.
Default: False.
:raises: InvalidParameterValue if an invalid boot device is specified
:raises: MissingParameterValue if required ilo credentials are missing.
:raises: IloOperationError, if unable to set the boot device.
"""
try:
boot_device = BOOT_DEVICE_MAPPING_TO_ILO[device]
except KeyError:
raise exception.InvalidParameterValue(_(
"Invalid boot device %s specified.") % device)
ilo_common.parse_driver_info(task.node)
ilo_common.set_boot_device(task.node, boot_device, persistent)
class IloPXEVendorPassthru(pxe.VendorPassthru): class IloPXEVendorPassthru(pxe.VendorPassthru):
def vendor_passthru(self, task, **kwargs): def vendor_passthru(self, task, **kwargs):

View File

@ -147,6 +147,8 @@ class PXEAndIloDriver(base.BaseDriver):
This driver implements the `core` functionality using This driver implements the `core` functionality using
:class:ironic.drivers.modules.ilo.power.IloPower for power management :class:ironic.drivers.modules.ilo.power.IloPower for power management
:class:ironic.drivers.modules.ilo.deploy.IloPXEDeploy(pxe.PXEDeploy) :class:ironic.drivers.modules.ilo.deploy.IloPXEDeploy(pxe.PXEDeploy)
:class:ironic.drivers.modules.ilo.deply.IloManagement(
ipmitool.IPMIManagement)
for image deployment. for image deployment.
""" """
@ -160,7 +162,7 @@ class PXEAndIloDriver(base.BaseDriver):
self.deploy = ilo_deploy.IloPXEDeploy() self.deploy = ilo_deploy.IloPXEDeploy()
self.vendor = ilo_deploy.IloPXEVendorPassthru() self.vendor = ilo_deploy.IloPXEVendorPassthru()
self.console = ipmitool.IPMIShellinaboxConsole() self.console = ipmitool.IPMIShellinaboxConsole()
self.management = ipmitool.IPMIManagement() self.management = ilo_deploy.IloManagement()
class PXEAndSNMPDriver(base.BaseDriver): class PXEAndSNMPDriver(base.BaseDriver):

View File

@ -20,6 +20,7 @@ import tempfile
from oslo.config import cfg from oslo.config import cfg
from ironic.common import exception
from ironic.common import images from ironic.common import images
from ironic.common import states from ironic.common import states
from ironic.common import swift from ironic.common import swift
@ -450,6 +451,33 @@ class IloPXEDeployTestCase(base.TestCase):
pxe_deploy_mock.assert_called_once_with(task) pxe_deploy_mock.assert_called_once_with(task)
class IloManagementTestCase(base.TestCase):
def setUp(self):
super(IloManagementTestCase, self).setUp()
self.dbapi = dbapi.get_instance()
self.context = context.get_admin_context()
mgr_utils.mock_the_extension_manager(driver="pxe_ilo")
self.node = obj_utils.create_test_node(self.context,
driver='pxe_ilo', driver_info=INFO_DICT)
@mock.patch.object(ilo_common, 'set_boot_device')
def test_set_boot_device_ok(self, set_persistent_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.set_boot_device(task, 'pxe', True)
set_persistent_mock.assert_called_once_with(task.node,
'NETWORK', True)
@mock.patch.object(ilo_common, 'set_boot_device')
def test_set_boot_device_invalid_device(self, set_persistent_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
self.assertRaises(exception.InvalidParameterValue,
task.driver.management.set_boot_device,
task, 'fake-device')
class IloPXEVendorPassthruTestCase(base.TestCase): class IloPXEVendorPassthruTestCase(base.TestCase):
def setUp(self): def setUp(self):