Merge "Add vendor_passthru method for virtual media"
This commit is contained in:
commit
a08da8551a
@ -81,4 +81,5 @@ class IDRACHardware(generic.GenericHardware):
|
||||
def supported_vendor_interfaces(self):
|
||||
"""List of supported vendor interfaces."""
|
||||
return [vendor_passthru.DracWSManVendorPassthru,
|
||||
vendor_passthru.DracVendorPassthru, noop.NoVendor]
|
||||
vendor_passthru.DracVendorPassthru,
|
||||
vendor_passthru.DracRedfishVendorPassthru, noop.NoVendor]
|
||||
|
@ -24,6 +24,7 @@ from ironic.drivers import base
|
||||
from ironic.drivers.modules.drac import bios as drac_bios
|
||||
from ironic.drivers.modules.drac import common as drac_common
|
||||
from ironic.drivers.modules.drac import job as drac_job
|
||||
from ironic.drivers.modules.redfish import vendor as redfish_vendor
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -190,3 +191,10 @@ class DracVendorPassthru(DracWSManVendorPassthru):
|
||||
LOG.warning("Vendor passthru interface 'idrac' is deprecated and may "
|
||||
"be removed in a future release. Use 'idrac-wsman' "
|
||||
"instead.")
|
||||
|
||||
|
||||
class DracRedfishVendorPassthru(redfish_vendor.RedfishVendorPassthru):
|
||||
"""iDRAC Redfish interface for vendor_passthru.
|
||||
|
||||
Use the Redfish implementation for vendor passthru.
|
||||
"""
|
||||
|
@ -183,7 +183,7 @@ def _insert_vmedia(task, boot_url, boot_device):
|
||||
_('No suitable virtual media device found'))
|
||||
|
||||
|
||||
def _eject_vmedia(task, boot_device=None):
|
||||
def eject_vmedia(task, boot_device=None):
|
||||
"""Eject virtual CDs and DVDs
|
||||
|
||||
:param task: A task from TaskManager.
|
||||
@ -430,7 +430,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
floppy_ref = image_utils.prepare_floppy_image(
|
||||
task, params=ramdisk_params)
|
||||
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
_insert_vmedia(
|
||||
task, floppy_ref, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
|
||||
@ -447,7 +447,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
iso_ref = image_utils.prepare_deploy_iso(task, ramdisk_params,
|
||||
mode, d_info)
|
||||
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
_insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
|
||||
|
||||
boot_mode_utils.sync_boot_mode(task)
|
||||
@ -474,12 +474,12 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
LOG.debug("Cleaning up deploy boot for "
|
||||
"%(node)s", {'node': task.node.uuid})
|
||||
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
image_utils.cleanup_iso_image(task)
|
||||
|
||||
if (config_via_floppy
|
||||
and _has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY)):
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
|
||||
image_utils.cleanup_floppy_image(task)
|
||||
|
||||
@ -533,7 +533,7 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
|
||||
deploy_info = _parse_deploy_info(node)
|
||||
iso_ref = image_utils.prepare_boot_iso(task, deploy_info, **params)
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
_insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD)
|
||||
|
||||
boot_mode_utils.sync_boot_mode(task)
|
||||
@ -556,11 +556,11 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
||||
LOG.debug("Cleaning up instance boot for "
|
||||
"%(node)s", {'node': task.node.uuid})
|
||||
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
d_info = task.node.driver_info
|
||||
config_via_floppy = d_info.get('config_via_floppy')
|
||||
if config_via_floppy:
|
||||
_eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY)
|
||||
|
||||
image_utils.cleanup_iso_image(task)
|
||||
|
||||
|
92
ironic/drivers/modules/redfish/vendor.py
Normal file
92
ironic/drivers/modules/redfish/vendor.py
Normal file
@ -0,0 +1,92 @@
|
||||
# Copyright 2015 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.
|
||||
"""
|
||||
Vendor Interface for Redfish drivers and its supporting methods.
|
||||
"""
|
||||
|
||||
from ironic_lib import metrics_utils
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules.redfish import boot as redfish_boot
|
||||
from ironic.drivers.modules.redfish import utils as redfish_utils
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
|
||||
class RedfishVendorPassthru(base.VendorInterface):
|
||||
"""Vendor-specific interfaces for Redfish drivers."""
|
||||
|
||||
def get_properties(self):
|
||||
return {}
|
||||
|
||||
@METRICS.timer('RedfishVendorPassthru.validate')
|
||||
def validate(self, task, method, **kwargs):
|
||||
"""Validate vendor-specific actions.
|
||||
|
||||
Checks if a valid vendor passthru method was passed and validates
|
||||
the parameters for the vendor passthru method.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:param method: method to be validated.
|
||||
:param kwargs: kwargs containing the vendor passthru method's
|
||||
parameters.
|
||||
:raises: InvalidParameterValue, if any of the parameters have invalid
|
||||
value.
|
||||
"""
|
||||
if method == 'eject_vmedia':
|
||||
self._validate_eject_vmedia(task, kwargs)
|
||||
return
|
||||
super(RedfishVendorPassthru, self).validate(task, method, **kwargs)
|
||||
|
||||
def _validate_eject_vmedia(self, task, kwargs):
|
||||
"""Verify that the boot_device input is valid."""
|
||||
|
||||
# If a boot device is provided check that it's valid.
|
||||
# It is OK to eject if already ejected
|
||||
boot_device = kwargs.get('boot_device')
|
||||
|
||||
if not boot_device:
|
||||
return
|
||||
|
||||
system = redfish_utils.get_system(task.node)
|
||||
|
||||
for manager in system.managers:
|
||||
for v_media in manager.virtual_media.get_members():
|
||||
if boot_device not in v_media.media_types:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Boot device %s is not a valid value ") % boot_device)
|
||||
|
||||
@METRICS.timer('RedfishVendorPassthru.eject_vmedia')
|
||||
@base.passthru(['POST'],
|
||||
description=_("Eject a virtual media device. If no device "
|
||||
"is provided than all attached devices will "
|
||||
"be ejected. "
|
||||
"Optional arguments: "
|
||||
"'boot_device' - the boot device to eject, "
|
||||
"either 'cd', 'dvd', 'usb', or 'floppy'"))
|
||||
# @task_manager.require_exclusive_lock
|
||||
def eject_vmedia(self, task, **kwargs):
|
||||
"""Eject a virtual media device.
|
||||
|
||||
:param task: A TaskManager object.
|
||||
:param kwargs: The arguments sent with vendor passthru. The optional
|
||||
kwargs are::
|
||||
'boot_device': the boot device to eject
|
||||
"""
|
||||
|
||||
# If boot_device not provided all vmedia devices will be ejected
|
||||
boot_device = kwargs.get('boot_device')
|
||||
redfish_boot.eject_vmedia(task, boot_device)
|
@ -24,6 +24,7 @@ from ironic.drivers.modules.redfish import boot as redfish_boot
|
||||
from ironic.drivers.modules.redfish import inspect as redfish_inspect
|
||||
from ironic.drivers.modules.redfish import management as redfish_mgmt
|
||||
from ironic.drivers.modules.redfish import power as redfish_power
|
||||
from ironic.drivers.modules.redfish import vendor as redfish_vendor
|
||||
|
||||
|
||||
class RedfishHardware(generic.GenericHardware):
|
||||
@ -57,3 +58,8 @@ class RedfishHardware(generic.GenericHardware):
|
||||
# vendors support.
|
||||
return [ipxe.iPXEBoot, pxe.PXEBoot,
|
||||
redfish_boot.RedfishVirtualMediaBoot]
|
||||
|
||||
@property
|
||||
def supported_vendor_interfaces(self):
|
||||
"""List of supported vendor interfaces."""
|
||||
return [redfish_vendor.RedfishVendorPassthru, noop.NoVendor]
|
||||
|
@ -326,7 +326,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device',
|
||||
autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_deploy_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
|
||||
@ -371,7 +371,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.manager_utils, 'node_set_boot_device',
|
||||
autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_deploy_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
|
||||
@ -417,7 +417,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(image_utils, 'prepare_floppy_image', autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_deploy_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_has_vmedia_device', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot.manager_utils, 'node_power_action',
|
||||
@ -482,7 +482,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task)
|
||||
|
||||
@mock.patch.object(redfish_boot, '_has_vmedia_device', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||
@mock.patch.object(image_utils, 'cleanup_floppy_image', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_driver_info', autospec=True)
|
||||
@ -517,7 +517,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
|
||||
'clean_up_instance', autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_deploy_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
|
||||
@ -569,7 +569,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
|
||||
'clean_up_instance', autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_deploy_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
|
||||
@ -617,7 +617,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
|
||||
'clean_up_instance', autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_deploy_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
|
||||
@ -663,7 +663,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot,
|
||||
'clean_up_instance', autospec=True)
|
||||
@mock.patch.object(image_utils, 'prepare_boot_iso', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_insert_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, '_parse_deploy_info', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
|
||||
@ -700,7 +700,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
|
||||
mock_boot_mode_utils.sync_boot_mode.assert_called_once_with(task)
|
||||
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'manager_utils', autospec=True)
|
||||
def _test_prepare_instance_local_boot(
|
||||
@ -733,7 +733,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
self.node.save()
|
||||
self._test_prepare_instance_local_boot()
|
||||
|
||||
@mock.patch.object(redfish_boot, '_eject_vmedia', autospec=True)
|
||||
@mock.patch.object(redfish_boot, 'eject_vmedia', autospec=True)
|
||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||
def _test_clean_up_instance(self, mock_cleanup_iso_image,
|
||||
mock__eject_vmedia):
|
||||
@ -832,7 +832,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
task, 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test__eject_vmedia_everything(self, mock_redfish_utils):
|
||||
def test_eject_vmedia_everything(self, mock_redfish_utils):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
@ -851,13 +851,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
redfish_boot._eject_vmedia(task)
|
||||
redfish_boot.eject_vmedia(task)
|
||||
|
||||
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||
mock_vmedia_floppy.eject_media.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test__eject_vmedia_specific(self, mock_redfish_utils):
|
||||
def test_eject_vmedia_specific(self, mock_redfish_utils):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
@ -876,13 +876,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
redfish_boot._eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
redfish_boot.eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||
|
||||
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test__eject_vmedia_not_inserted(self, mock_redfish_utils):
|
||||
def test_eject_vmedia_not_inserted(self, mock_redfish_utils):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
@ -901,13 +901,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
redfish_boot._eject_vmedia(task)
|
||||
redfish_boot.eject_vmedia(task)
|
||||
|
||||
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test__eject_vmedia_unknown(self, mock_redfish_utils):
|
||||
def test_eject_vmedia_unknown(self, mock_redfish_utils):
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
@ -923,6 +923,6 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
redfish_boot._eject_vmedia(task)
|
||||
redfish_boot.eject_vmedia(task)
|
||||
|
||||
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||
|
116
ironic/tests/unit/drivers/modules/redfish/test_vendor.py
Normal file
116
ironic/tests/unit/drivers/modules/redfish/test_vendor.py
Normal file
@ -0,0 +1,116 @@
|
||||
# Copyright 2018 DMTF. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from oslo_utils import importutils
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.drivers.modules.redfish import boot as redfish_boot
|
||||
from ironic.drivers.modules.redfish import vendor as redfish_vendor
|
||||
from ironic.tests.unit.db import base as db_base
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
from ironic.tests.unit.objects import utils as obj_utils
|
||||
|
||||
sushy = importutils.try_import('sushy')
|
||||
|
||||
INFO_DICT = db_utils.get_test_redfish_info()
|
||||
|
||||
|
||||
class RedfishVendorPassthruTestCase(db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RedfishVendorPassthruTestCase, self).setUp()
|
||||
self.config(enabled_bios_interfaces=['redfish'],
|
||||
enabled_hardware_types=['redfish'],
|
||||
enabled_power_interfaces=['redfish'],
|
||||
enabled_boot_interfaces=['redfish-virtual-media'],
|
||||
enabled_management_interfaces=['redfish'],
|
||||
enabled_vendor_interfaces=['redfish'])
|
||||
self.node = obj_utils.create_test_node(
|
||||
self.context, driver='redfish', driver_info=INFO_DICT)
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test_eject_vmedia_all(self, mock_redfish_utils):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
|
||||
mock_vmedia_cd = mock.MagicMock(
|
||||
inserted=True,
|
||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||
mock_vmedia_floppy = mock.MagicMock(
|
||||
inserted=True,
|
||||
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||
|
||||
mock_manager = mock.MagicMock()
|
||||
|
||||
mock_manager.virtual_media.get_members.return_value = [
|
||||
mock_vmedia_cd, mock_vmedia_floppy]
|
||||
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
task.driver.vendor.eject_vmedia(task)
|
||||
|
||||
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||
mock_vmedia_floppy.eject_media.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||
def test_eject_vmedia_cd(self, mock_redfish_utils):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
|
||||
mock_vmedia_cd = mock.MagicMock(
|
||||
inserted=True,
|
||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||
mock_vmedia_floppy = mock.MagicMock(
|
||||
inserted=True,
|
||||
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||
|
||||
mock_manager = mock.MagicMock()
|
||||
|
||||
mock_manager.virtual_media.get_members.return_value = [
|
||||
mock_vmedia_cd, mock_vmedia_floppy]
|
||||
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
task.driver.vendor.eject_vmedia(task,
|
||||
boot_device=sushy.VIRTUAL_MEDIA_CD)
|
||||
|
||||
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||
mock_vmedia_floppy.eject_media.assert_not_called()
|
||||
|
||||
@mock.patch.object(redfish_vendor, 'redfish_utils', autospec=True)
|
||||
def test_eject_vmedia_invalid_dev(self, mock_redfish_utils):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
|
||||
mock_vmedia_cd = mock.MagicMock(
|
||||
inserted=True,
|
||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||
|
||||
mock_manager = mock.MagicMock()
|
||||
|
||||
mock_manager.virtual_media.get_members.return_value = [
|
||||
mock_vmedia_cd]
|
||||
|
||||
mock_redfish_utils.get_system.return_value.managers = [
|
||||
mock_manager]
|
||||
|
||||
kwargs = {'boot_device': 'foo'}
|
||||
self.assertRaises(
|
||||
exception.InvalidParameterValue,
|
||||
task.driver.vendor.validate, task, 'eject_vmedia', **kwargs)
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Provides a new vendor passthru method for Redfish to eject a virtual_media
|
||||
device. A specific device can be given (either ``cd``, ``dvd``,
|
||||
``floppy``, or ``usb``), or if no device is provided then all attached
|
||||
devices will be ejected.
|
@ -162,9 +162,11 @@ ironic.hardware.interfaces.vendor =
|
||||
ibmc = ironic.drivers.modules.ibmc.vendor:IBMCVendor
|
||||
idrac = ironic.drivers.modules.drac.vendor_passthru:DracVendorPassthru
|
||||
idrac-wsman = ironic.drivers.modules.drac.vendor_passthru:DracWSManVendorPassthru
|
||||
idrac-redfish = ironic.drivers.modules.drac.vendor_passthru:DracRedfishVendorPassthru
|
||||
ilo = ironic.drivers.modules.ilo.vendor:VendorPassthru
|
||||
ipmitool = ironic.drivers.modules.ipmitool:VendorPassthru
|
||||
no-vendor = ironic.drivers.modules.noop:NoVendor
|
||||
redfish = ironic.drivers.modules.redfish.vendor:RedfishVendorPassthru
|
||||
|
||||
ironic.hardware.types =
|
||||
fake-hardware = ironic.drivers.fake_hardware:FakeHardware
|
||||
|
Loading…
Reference in New Issue
Block a user