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 deploy_utils
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 pxe
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',
group='ilo')
BOOT_DEVICE_MAPPING_TO_ILO = {'pxe': 'NETWORK', 'disk': 'HDD',
'cdrom': 'CDROM', 'bios': 'BIOS', 'safe': 'SAFE'}
def _get_boot_iso_object_name(node):
"""Returns the floppy image name for a given node.
@ -440,10 +444,38 @@ class IloPXEDeploy(pxe.PXEDeploy):
:returns: deploy state DEPLOYWAIT.
"""
ilo_common.set_boot_device(task.node, 'NETWORK', False)
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):
def vendor_passthru(self, task, **kwargs):

View File

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

View File

@ -20,6 +20,7 @@ import tempfile
from oslo.config import cfg
from ironic.common import exception
from ironic.common import images
from ironic.common import states
from ironic.common import swift
@ -450,6 +451,33 @@ class IloPXEDeployTestCase(base.TestCase):
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):
def setUp(self):