Merge "iLO Management Interface"

This commit is contained in:
Jenkins 2014-11-26 17:23:35 +00:00 committed by Gerrit Code Review
commit d1f728cd40
11 changed files with 433 additions and 181 deletions

View File

@ -27,6 +27,7 @@ from ironic.drivers.modules.drac import management as drac_mgmt
from ironic.drivers.modules.drac import power as drac_power
from ironic.drivers.modules import fake
from ironic.drivers.modules import iboot
from ironic.drivers.modules.ilo import management as ilo_management
from ironic.drivers.modules.ilo import power as ilo_power
from ironic.drivers.modules import ipminative
from ironic.drivers.modules import ipmitool
@ -143,6 +144,7 @@ class FakeIloDriver(base.BaseDriver):
reason=_("Unable to import proliantutils library"))
self.power = ilo_power.IloPower()
self.deploy = fake.FakeDeploy()
self.management = ilo_management.IloManagement()
class FakeDracDriver(base.BaseDriver):

View File

@ -22,6 +22,7 @@ from ironic.common.i18n import _
from ironic.drivers import base
from ironic.drivers.modules import agent
from ironic.drivers.modules.ilo import deploy
from ironic.drivers.modules.ilo import management
from ironic.drivers.modules.ilo import power
@ -44,7 +45,7 @@ class IloVirtualMediaIscsiDriver(base.BaseDriver):
self.power = power.IloPower()
self.deploy = deploy.IloVirtualMediaIscsiDeploy()
self.console = deploy.IloConsoleInterface()
self.management = deploy.IloManagement()
self.management = management.IloManagement()
self.vendor = deploy.VendorPassthru()
@ -67,5 +68,5 @@ class IloVirtualMediaAgentDriver(base.BaseDriver):
self.power = power.IloPower()
self.deploy = deploy.IloVirtualMediaAgentDeploy()
self.console = deploy.IloConsoleInterface()
self.management = deploy.IloManagement()
self.management = management.IloManagement()
self.vendor = agent.AgentVendorInterface()

View File

@ -190,6 +190,26 @@ def get_ilo_license(node):
return STANDARD_LICENSE
def update_ipmi_properties(task):
"""Update ipmi properties to node driver_info
:param task: a task from TaskManager.
"""
node = task.node
info = node.driver_info
# updating ipmi credentials
info['ipmi_address'] = info.get('ilo_address')
info['ipmi_username'] = info.get('ilo_username')
info['ipmi_password'] = info.get('ilo_password')
if 'console_port' in info:
info['ipmi_terminal_port'] = info['console_port']
# saving ipmi credentials to task object
task.node.driver_info = info
def _get_floppy_image_name(node):
"""Returns the floppy image name for a given node.
@ -273,30 +293,6 @@ def attach_vmedia(node, device, url):
LOG.info(_LI("Attached virtual media %s successfully."), device)
# TODO(rameshg87): This needs to be moved to iLO's management interface.
def set_boot_device(node, device, persistent=False):
"""Sets the node to boot from a device for the next boot.
:param node: an ironic node object.
:param device: the device to boot from
:raises: IloOperationError if setting boot device failed.
"""
ilo_object = get_ilo_object(node)
try:
if not persistent:
ilo_object.set_one_time_boot(device)
else:
ilo_object.update_persistent_boot([device])
except ilo_client.IloError as ilo_exception:
operation = _("Setting %s as boot device") % device
raise exception.IloOperationError(operation=operation,
error=ilo_exception)
LOG.debug("Node %(uuid)s set to boot from %(device)s.",
{'uuid': node.uuid, 'device': device})
def set_boot_mode(node, boot_mode):
"""Sets the node to boot using boot_mode for the next boot.

View File

@ -19,6 +19,7 @@ import tempfile
from oslo.config import cfg
from ironic.common import boot_devices
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common.i18n import _LE
@ -53,29 +54,6 @@ 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 _update_ipmi_properties(task):
"""Update ipmi properties to node driver_info
:param task: a task from TaskManager.
"""
node = task.node
info = node.driver_info
# updating ipmi credentials
info['ipmi_address'] = info['ilo_address']
info['ipmi_username'] = info['ilo_username']
info['ipmi_password'] = info['ilo_password']
if 'console_port' in info:
info['ipmi_terminal_port'] = info['console_port']
# saving ipmi credentials to task object
task.node.driver_info = info
def _get_boot_iso_object_name(node):
"""Returns the floppy image name for a given node.
@ -250,7 +228,7 @@ def _reboot_into(task, iso, ramdisk_options):
:raises: IloOperationError, if some operation on iLO failed.
"""
ilo_common.setup_vmedia_for_boot(task, iso, ramdisk_options)
ilo_common.set_boot_device(task.node, 'CDROM')
manager_utils.node_set_boot_device(task, boot_devices.CDROM)
manager_utils.node_power_action(task, states.REBOOT)
@ -464,79 +442,10 @@ class IloPXEDeploy(pxe.PXEDeploy):
:param task: a TaskManager instance containing the node to act on.
:returns: deploy state DEPLOYWAIT.
"""
ilo_common.set_boot_device(task.node, 'NETWORK', False)
manager_utils.node_set_boot_device(task, boot_devices.PXE)
return super(IloPXEDeploy, self).deploy(task)
class IloManagement(ipmitool.IPMIManagement):
# Currently adding support to set_boot_device through iLO. All other
# functionalities (get_sensors_data etc) will be used from IPMI.
# TODO(ramineni):To support other functionalities also using iLO.
def get_properties(self):
return ilo_common.REQUIRED_PROPERTIES
def validate(self, task):
"""Check that 'driver_info' contains ILO and IPMI credentials.
Validates whether the 'driver_info' property of the supplied
task's node contains the required credentials information.
:param task: a task from TaskManager.
:raises: InvalidParameterValue if required IPMI/iLO parameters
are missing.
:raises: MissingParameterValue if a required parameter is missing.
"""
ilo_common.parse_driver_info(task.node)
_update_ipmi_properties(task)
super(IloManagement, self).validate(task)
@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)
def get_sensors_data(self, task):
"""Get sensors data.
:param task: a TaskManager instance.
:raises: FailedToGetSensorData when getting the sensor data fails.
:raises: FailedToParseSensorData when parsing sensor data fails.
:raises: InvalidParameterValue if required ipmi/iLO parameters
are missing.
:raises: MissingParameterValue if a required parameter is missing.
:returns: returns a dict of sensor data group by sensor type.
"""
ilo_common.parse_driver_info(task.node)
_update_ipmi_properties(task)
super(IloManagement, self).get_sensors_data(task)
class IloConsoleInterface(ipmitool.IPMIShellinaboxConsole):
"""A ConsoleInterface that uses ipmitool and shellinabox."""
@ -559,7 +468,7 @@ class IloConsoleInterface(ipmitool.IPMIShellinaboxConsole):
raise exception.MissingParameterValue(_(
"Missing 'console_port' parameter in node's driver_info."))
_update_ipmi_properties(task)
ilo_common.update_ipmi_properties(task)
super(IloConsoleInterface, self).validate(task)
@ -567,7 +476,7 @@ class IloPXEVendorPassthru(pxe.VendorPassthru):
@base.passthru(['POST'], method='pass_deploy_info')
def _continue_deploy(self, task, **kwargs):
ilo_common.set_boot_device(task.node, 'NETWORK', True)
manager_utils.node_set_boot_device(task, boot_devices.PXE, True)
super(IloPXEVendorPassthru, self)._continue_deploy(task, **kwargs)
@ -623,7 +532,7 @@ class VendorPassthru(base.VendorInterface):
return
ilo_common.setup_vmedia_for_boot(task, boot_iso)
ilo_common.set_boot_device(node, 'CDROM')
manager_utils.node_set_boot_device(task, boot_devices.CDROM)
address = kwargs.get('address')
deploy_utils.notify_deploy_complete(address)

View File

@ -0,0 +1,164 @@
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# 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.
"""
iLO Management Interface
"""
from oslo.utils import importutils
from ironic.common import boot_devices
from ironic.common import exception
from ironic.common.i18n import _
from ironic.conductor import task_manager
from ironic.drivers import base
from ironic.drivers.modules.ilo import common as ilo_common
from ironic.drivers.modules import ipmitool
from ironic.openstack.common import log as logging
LOG = logging.getLogger(__name__)
ilo_client = importutils.try_import('proliantutils.ilo.ribcl')
BOOT_DEVICE_MAPPING_TO_ILO = {boot_devices.PXE: 'NETWORK',
boot_devices.DISK: 'HDD',
boot_devices.CDROM: 'CDROM'
}
BOOT_DEVICE_ILO_TO_GENERIC = {v: k
for k, v in BOOT_DEVICE_MAPPING_TO_ILO.items()}
class IloManagement(base.ManagementInterface):
def get_properties(self):
return ilo_common.REQUIRED_PROPERTIES
def validate(self, task):
"""Check that 'driver_info' contains required ILO credentials.
Validates whether the 'driver_info' property of the supplied
task's node contains the required credentials information.
:param task: a task from TaskManager.
:raises: InvalidParameterValue if required iLO parameters
are not valid.
:raises: MissingParameterValue if a required parameter is missing.
"""
ilo_common.parse_driver_info(task.node)
def get_supported_boot_devices(self):
"""Get a list of the supported boot devices.
:returns: A list with the supported boot devices defined
in :mod:`ironic.common.boot_devices`.
"""
return list(BOOT_DEVICE_MAPPING_TO_ILO.keys())
def get_boot_device(self, task):
"""Get the current boot device for a node.
Returns the current boot device of the node.
:param task: a task from TaskManager.
:raises: MissingParameterValue if a required iLO parameter is missing.
:raises: IloOperationError on an error from IloClient library.
:returns: a dictionary containing:
:boot_device:
the boot device, one of the supported devices listed in
:mod:`ironic.common.boot_devices` or None if it is unknown.
:persistent:
Whether the boot device will persist to all future boots or
not, None if it is unknown.
"""
ilo_object = ilo_common.get_ilo_object(task.node)
persistent = False
try:
# Return one time boot device if set, else return
# the persistent boot device
next_boot = ilo_object.get_one_time_boot()
if next_boot == 'Normal':
# One time boot is not set. Check for persistent boot.
persistent = True
next_boot = ilo_object.get_persistent_boot_device()
except ilo_client.IloError as ilo_exception:
operation = _("Get boot device")
raise exception.IloOperationError(operation=operation,
error=ilo_exception)
boot_device = BOOT_DEVICE_ILO_TO_GENERIC.get(next_boot, None)
if boot_device is None:
persistent = None
return {'boot_device': boot_device, 'persistent': persistent}
@task_manager.require_exclusive_lock
def set_boot_device(self, task, device, persistent=False):
"""Set the boot device for a 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 the supported devices
listed in :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 a required parameter is missing.
:raises: IloOperationError on an error from IloClient library.
"""
try:
boot_device = BOOT_DEVICE_MAPPING_TO_ILO[device]
except KeyError:
raise exception.InvalidParameterValue(_(
"Invalid boot device %s specified.") % device)
try:
ilo_object = ilo_common.get_ilo_object(task.node)
if not persistent:
ilo_object.set_one_time_boot(boot_device)
else:
ilo_object.update_persistent_boot([boot_device])
except ilo_client.IloError as ilo_exception:
operation = _("Setting %s as boot device") % device
raise exception.IloOperationError(operation=operation,
error=ilo_exception)
LOG.debug("Node %(uuid)s set to boot from %(device)s.",
{'uuid': task.node.uuid, 'device': device})
def get_sensors_data(self, task):
"""Get sensors data.
:param task: a TaskManager instance.
:raises: FailedToGetSensorData when getting the sensor data fails.
:raises: FailedToParseSensorData when parsing sensor data fails.
:raises: InvalidParameterValue if required ipmi parameters
are missing.
:raises: MissingParameterValue if a required parameter is missing.
:returns: returns a dict of sensor data group by sensor type.
"""
ilo_common.update_ipmi_properties(task)
ipmi_management = ipmitool.IPMIManagement()
return ipmi_management.get_sensors_data(task)

View File

@ -19,11 +19,13 @@ iLO Power Driver
from oslo.config import cfg
from oslo.utils import importutils
from ironic.common import boot_devices
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common.i18n import _LE
from ironic.common import states
from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers import base
from ironic.drivers.modules.ilo import common as ilo_common
from ironic.openstack.common import log as logging
@ -61,7 +63,7 @@ def _attach_boot_iso(task):
if 'ilo_boot_iso' in i_info:
ilo_common.setup_vmedia_for_boot(task, i_info['ilo_boot_iso'])
ilo_common.set_boot_device(task.node, 'CDROM')
manager_utils.node_set_boot_device(task, boot_devices.CDROM)
def _get_power_state(node):

View File

@ -24,6 +24,7 @@ from ironic.common.i18n import _
from ironic.drivers import base
from ironic.drivers.modules import iboot
from ironic.drivers.modules.ilo import deploy as ilo_deploy
from ironic.drivers.modules.ilo import management as ilo_management
from ironic.drivers.modules.ilo import power as ilo_power
from ironic.drivers.modules import ipminative
from ironic.drivers.modules import ipmitool
@ -147,8 +148,7 @@ 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`
:class:`ironic.drivers.modules.ilo.deploy.IloManagement` for image
:class:`ironic.drivers.modules.ilo.deploy.IloPXEDeploy` for image
deployment.
"""
@ -162,7 +162,7 @@ class PXEAndIloDriver(base.BaseDriver):
self.deploy = ilo_deploy.IloPXEDeploy()
self.vendor = ilo_deploy.IloPXEVendorPassthru()
self.console = ilo_deploy.IloConsoleInterface()
self.management = ilo_deploy.IloManagement()
self.management = ilo_management.IloManagement()
class PXEAndSNMPDriver(base.BaseDriver):

View File

@ -155,6 +155,23 @@ class IloCommonMethodsTestCase(db_base.DbTestCase):
ilo_common.get_ilo_license,
self.node)
def test_update_ipmi_properties(self):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
ipmi_info = {
"ipmi_address": "1.2.3.4",
"ipmi_username": "admin",
"ipmi_password": "fake",
"ipmi_terminal_port": 60
}
ilo_info = INFO_DICT
ilo_info['console_port'] = 60
task.node.driver_info = ilo_info
ilo_common.update_ipmi_properties(task)
actual_info = task.node.driver_info
expected_info = dict(INFO_DICT, **ipmi_info)
self.assertEqual(expected_info, actual_info)
def test__get_floppy_image_name(self):
image_name_expected = 'image-' + self.node.uuid
image_name_actual = ilo_common._get_floppy_image_name(self.node)
@ -248,20 +265,6 @@ class IloCommonMethodsTestCase(db_base.DbTestCase):
self.assertRaises(exception.IloOperationError,
ilo_common.attach_vmedia, self.node, 'FLOPPY', 'url')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device(self, get_ilo_object_mock):
ilo_object_mock = get_ilo_object_mock.return_value
ilo_common.set_boot_device(self.node, 'CDROM')
get_ilo_object_mock.assert_called_once_with(self.node)
ilo_object_mock.set_one_time_boot.assert_called_once_with('CDROM')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device_persistent_true(self, get_ilo_object_mock):
ilo_mock = get_ilo_object_mock.return_value
ilo_common.set_boot_device(self.node, 'NETWORK', True)
get_ilo_object_mock.assert_called_once_with(self.node)
ilo_mock.update_persistent_boot.assert_called_once_with(['NETWORK'])
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_mode(self, get_ilo_object_mock):
ilo_object_mock = get_ilo_object_mock.return_value

View File

@ -20,7 +20,7 @@ import tempfile
import mock
from oslo.config import cfg
from ironic.common import exception
from ironic.common import boot_devices
from ironic.common import images
from ironic.common import states
from ironic.common import swift
@ -180,7 +180,7 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
self.assertEqual(expected_info, actual_info)
@mock.patch.object(manager_utils, 'node_power_action')
@mock.patch.object(ilo_common, 'set_boot_device')
@mock.patch.object(manager_utils, 'node_set_boot_device')
@mock.patch.object(ilo_common, 'setup_vmedia_for_boot')
def test__reboot_into(self, setup_vmedia_mock, set_boot_device_mock,
node_power_action_mock):
@ -189,7 +189,8 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
opts = {'a': 'b'}
ilo_deploy._reboot_into(task, 'iso', opts)
setup_vmedia_mock.assert_called_once_with(task, 'iso', opts)
set_boot_device_mock.assert_called_once_with(task.node, 'CDROM')
set_boot_device_mock.assert_called_once_with(task,
boot_devices.CDROM)
node_power_action_mock.assert_called_once_with(task, states.REBOOT)
@ -222,12 +223,11 @@ class IloVirtualMediaIscsiDeployTestCase(db_base.DbTestCase):
@mock.patch.object(ilo_deploy, '_get_single_nic_with_vif_port_id')
@mock.patch.object(iscsi_deploy, 'build_deploy_ramdisk_options')
@mock.patch.object(manager_utils, 'node_power_action')
@mock.patch.object(ilo_common, 'set_boot_device')
@mock.patch.object(iscsi_deploy, 'check_image_size')
@mock.patch.object(iscsi_deploy, 'cache_instance_image')
def test_deploy(self, cache_instance_image_mock, check_image_size_mock,
set_boot_device_mock, node_power_action_mock,
build_opts_mock, get_nic_mock, reboot_into_mock):
node_power_action_mock, build_opts_mock, get_nic_mock,
reboot_into_mock):
deploy_opts = {'a': 'b'}
build_opts_mock.return_value = deploy_opts
get_nic_mock.return_value = '12:34:56:78:90:ab'
@ -328,7 +328,7 @@ class VendorPassthruTestCase(db_base.DbTestCase):
driver='iscsi_ilo', driver_info=INFO_DICT)
@mock.patch.object(deploy_utils, 'notify_deploy_complete')
@mock.patch.object(ilo_common, 'set_boot_device')
@mock.patch.object(manager_utils, 'node_set_boot_device')
@mock.patch.object(ilo_common, 'setup_vmedia_for_boot')
@mock.patch.object(ilo_deploy, '_get_boot_iso')
@mock.patch.object(iscsi_deploy, 'continue_deploy')
@ -351,7 +351,8 @@ class VendorPassthruTestCase(db_base.DbTestCase):
continue_deploy_mock.assert_called_once_with(task, **kwargs)
get_boot_iso_mock.assert_called_once_with(task, 'root-uuid')
setup_vmedia_mock.assert_called_once_with(task, 'boot-iso')
set_boot_device_mock.assert_called_once_with(task.node, 'CDROM')
set_boot_device_mock.assert_called_once_with(task,
boot_devices.CDROM)
self.assertEqual('boot-iso',
task.node.instance_info['ilo_boot_iso'])
notify_deploy_complete_mock.assert_called_once_with('123456')
@ -430,41 +431,16 @@ class IloPXEDeployTestCase(db_base.DbTestCase):
pxe_prepare_mock.assert_called_once_with(task)
@mock.patch.object(pxe.PXEDeploy, 'deploy')
@mock.patch.object(ilo_common, 'set_boot_device')
@mock.patch.object(manager_utils, 'node_set_boot_device')
def test_deploy_boot_mode_exists(self, set_persistent_mock,
pxe_deploy_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.deploy.deploy(task)
set_persistent_mock.assert_called_with(task.node, 'NETWORK', False)
set_persistent_mock.assert_called_with(task, boot_devices.PXE)
pxe_deploy_mock.assert_called_once_with(task)
class IloManagementTestCase(db_base.DbTestCase):
def setUp(self):
super(IloManagementTestCase, self).setUp()
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(db_base.DbTestCase):
def setUp(self):
@ -489,13 +465,14 @@ class IloPXEVendorPassthruTestCase(db_base.DbTestCase):
self.assertEqual({}, driver_routes)
@mock.patch.object(pxe.VendorPassthru, '_continue_deploy')
@mock.patch.object(ilo_common, 'set_boot_device')
def test_vendorpassthru(self, set_persistent_mock,
@mock.patch.object(manager_utils, 'node_set_boot_device')
def test_vendorpassthru(self, set_boot_device_mock,
pxe_vendorpassthru_mock):
kwargs = {'address': '123456'}
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.node.provision_state = states.DEPLOYWAIT
task.driver.vendor._continue_deploy(task, **kwargs)
set_persistent_mock.assert_called_with(task.node, 'NETWORK', True)
set_boot_device_mock.assert_called_with(task, boot_devices.PXE,
True)
pxe_vendorpassthru_mock.assert_called_once_with(task, **kwargs)

View File

@ -0,0 +1,195 @@
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# 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 Management Interface used by iLO modules."""
import mock
from oslo.config import cfg
from oslo.utils import importutils
from ironic.common import boot_devices
from ironic.common import exception
from ironic.conductor import task_manager
from ironic.drivers.modules.ilo import common as ilo_common
from ironic.drivers.modules.ilo import management as ilo_management
from ironic.drivers.modules import ipmitool
from ironic.tests.conductor import utils as mgr_utils
from ironic.tests.db import base as db_base
from ironic.tests.db import utils as db_utils
from ironic.tests.objects import utils as obj_utils
ilo_client = importutils.try_import('proliantutils.ilo.ribcl')
INFO_DICT = db_utils.get_test_ilo_info()
CONF = cfg.CONF
class IloManagementTestCase(db_base.DbTestCase):
def setUp(self):
super(IloManagementTestCase, self).setUp()
mgr_utils.mock_the_extension_manager(driver="fake_ilo")
self.node = obj_utils.create_test_node(self.context,
driver='fake_ilo', driver_info=INFO_DICT)
def test_get_properties(self):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
expected = ilo_common.REQUIRED_PROPERTIES
self.assertEqual(expected, task.driver.management.
get_properties())
@mock.patch.object(ilo_common, 'parse_driver_info')
def test_validate(self, driver_info_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.validate(task)
driver_info_mock.assert_called_once_with(task.node)
def test_get_supported_boot_devices(self):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
expected = [boot_devices.PXE, boot_devices.DISK,
boot_devices.CDROM]
self.assertEqual(sorted(expected), sorted(task.driver.management.
get_supported_boot_devices()))
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_get_boot_device_next_boot(self, get_ilo_object_mock):
ilo_object_mock = get_ilo_object_mock.return_value
ilo_object_mock.get_one_time_boot.return_value = 'CDROM'
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
expected_device = boot_devices.CDROM
expected_response = {'boot_device': expected_device,
'persistent': False}
self.assertEqual(expected_response,
task.driver.management.get_boot_device(task))
ilo_object_mock.get_one_time_boot.assert_called_once_with()
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_get_boot_device_persistent(self, get_ilo_object_mock):
ilo_mock = get_ilo_object_mock.return_value
ilo_mock.get_one_time_boot.return_value = 'Normal'
ilo_mock.get_persistent_boot_device.return_value = 'NETWORK'
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
expected_device = boot_devices.PXE
expected_response = {'boot_device': expected_device,
'persistent': True}
self.assertEqual(expected_response,
task.driver.management.get_boot_device(task))
ilo_mock.get_one_time_boot.assert_called_once_with()
ilo_mock.get_persistent_boot_device.assert_called_once_with()
@mock.patch.object(ilo_management, 'ilo_client')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_get_boot_device_fail(self, get_ilo_object_mock, ilo_mgmt_mock):
ilo_mgmt_mock.IloError = Exception
ilo_mock_object = get_ilo_object_mock.return_value
ilo_mock_object.get_one_time_boot.side_effect = Exception()
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
self.assertRaises(exception.IloOperationError,
task.driver.management.get_boot_device,
task)
ilo_mock_object.get_one_time_boot.assert_called_once_with()
@mock.patch.object(ilo_management, 'ilo_client')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_get_boot_device_persistent_fail(self, get_ilo_object_mock,
ilo_mgmt_mock):
ilo_mgmt_mock.IloError = Exception
ilo_mock_object = get_ilo_object_mock.return_value
ilo_mock_object.get_one_time_boot.return_value = 'Normal'
ilo_mock_object.get_persistent_boot_device.side_effect = Exception()
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
self.assertRaises(exception.IloOperationError,
task.driver.management.get_boot_device,
task)
ilo_mock_object.get_one_time_boot.assert_called_once_with()
ilo_mock_object.get_persistent_boot_device.assert_called_once_with()
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device_ok(self, get_ilo_object_mock):
ilo_object_mock = get_ilo_object_mock.return_value
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.set_boot_device(task, boot_devices.CDROM,
False)
get_ilo_object_mock.assert_called_once_with(task.node)
ilo_object_mock.set_one_time_boot.assert_called_once_with('CDROM')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device_persistent_true(self, get_ilo_object_mock):
ilo_mock = get_ilo_object_mock.return_value
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.set_boot_device(task, boot_devices.PXE,
True)
get_ilo_object_mock.assert_called_once_with(task.node)
ilo_mock.update_persistent_boot.assert_called_once_with(
['NETWORK'])
@mock.patch.object(ilo_management, 'ilo_client')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device_fail(self, get_ilo_object_mock, ilo_mgmt_mock):
ilo_mgmt_mock.IloError = Exception
ilo_mock_object = get_ilo_object_mock.return_value
ilo_mock_object.set_one_time_boot.side_effect = Exception()
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
self.assertRaises(exception.IloOperationError,
task.driver.management.set_boot_device,
task, boot_devices.PXE)
ilo_mock_object.set_one_time_boot.assert_called_once_with('NETWORK')
@mock.patch.object(ilo_management, 'ilo_client')
@mock.patch.object(ilo_common, 'get_ilo_object')
def test_set_boot_device_persistent_fail(self, get_ilo_object_mock,
ilo_mgmt_mock):
ilo_mgmt_mock.IloError = Exception
ilo_mock_object = get_ilo_object_mock.return_value
ilo_mock_object.update_persistent_boot.side_effect = Exception()
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
self.assertRaises(exception.IloOperationError,
task.driver.management.set_boot_device,
task, boot_devices.PXE, True)
ilo_mock_object.update_persistent_boot.assert_called_once_with(
['NETWORK'])
def test_set_boot_device_invalid_device(self):
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')
@mock.patch.object(ilo_common, 'update_ipmi_properties')
@mock.patch.object(ipmitool.IPMIManagement, 'get_sensors_data')
def test_get_sensor_data(self, get_sensors_data_mock, update_ipmi_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.get_sensors_data(task)
update_ipmi_mock.assert_called_once_with(task)
get_sensors_data_mock.assert_called_once_with(task)

View File

@ -19,9 +19,11 @@ import mock
from oslo.config import cfg
from oslo.utils import importutils
from ironic.common import boot_devices
from ironic.common import exception
from ironic.common import states
from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers.modules.ilo import common as ilo_common
from ironic.drivers.modules.ilo import deploy as ilo_deploy
from ironic.drivers.modules.ilo import power as ilo_power
@ -142,7 +144,7 @@ class IloPowerInternalMethodsTestCase(db_base.DbTestCase):
ilo_mock_object.get_host_power_status.assert_called_with()
ilo_mock_object.set_host_power.assert_called_once_with('ON')
@mock.patch.object(ilo_common, 'set_boot_device')
@mock.patch.object(manager_utils, 'node_set_boot_device')
@mock.patch.object(ilo_common, 'setup_vmedia_for_boot')
def test__attach_boot_iso(self, setup_vmedia_mock, set_boot_device_mock,
power_ilo_client_mock, common_ilo_client_mock):
@ -151,7 +153,8 @@ class IloPowerInternalMethodsTestCase(db_base.DbTestCase):
task.node.instance_info['ilo_boot_iso'] = 'boot-iso'
ilo_power._attach_boot_iso(task)
setup_vmedia_mock.assert_called_once_with(task, 'boot-iso')
set_boot_device_mock.assert_called_once_with(task.node, 'CDROM')
set_boot_device_mock.assert_called_once_with(task,
boot_devices.CDROM)
class IloPowerTestCase(db_base.DbTestCase):