Beispiel #1
0
def _raise_unsupported_error(method=None):
    if method:
        raise exception.UnsupportedDriverExtension(
            _("Unsupported method (%s) passed through to vendor extension.") %
            method)
    raise exception.MissingParameterValue(
        _("Method not specified when calling vendor extension."))
Beispiel #2
0
    def vendor_passthru(self, context, node_id, driver_method, info):
        """RPC method to encapsulate vendor action.

        Synchronously validate driver specific info or get driver status,
        and if successful, start background worker to perform vendor action
        asynchronously.

        :param context: an admin context.
        :param node_id: the id or uuid of a node.
        :param driver_method: the name of the vendor method.
        :param info: vendor method args.
        :raises: InvalidParameterValue if supplied info is not valid.
        :raises: UnsupportedDriverExtension if current driver does not have
                 vendor interface or method is unsupported.
        :raises: NoFreeConductorWorker when there is no free worker to start
                 async task.

        """
        LOG.debug("RPC vendor_passthru called for node %s." % node_id)
        # NOTE(max_lobur): Even though not all vendor_passthru calls may
        # require an exclusive lock, we need to do so to guarantee that the
        # state doesn't unexpectedly change between doing a vendor.validate
        # and vendor.vendor_passthru.
        with task_manager.acquire(context, node_id, shared=False) as task:
            if not getattr(task.driver, 'vendor', None):
                raise exception.UnsupportedDriverExtension(
                    driver=task.node.driver,
                    extension='vendor passthru')

            task.driver.vendor.validate(task, method=driver_method,
                                        **info)
            task.spawn_after(self._spawn_worker,
                             task.driver.vendor.vendor_passthru, task,
                             method=driver_method, **info)
Beispiel #3
0
    def driver_vendor_passthru(self, context, driver_name, driver_method,
                                  info):
        """RPC method which synchronously handles driver-level vendor passthru
        calls. These calls don't require a node UUID and are executed on a
        random conductor with the specified driver.

        :param context: an admin context.
        :param driver_name: name of the driver on which to call the method.
        :param driver_method: name of the vendor method, for use by the driver.
        :param info: user-supplied data to pass through to the driver.
        :raises: InvalidParameterValue if supplied info is not valid.
        :raises: UnsupportedDriverExtension if current driver does not have
                 vendor interface, if the vendor interface does not implement
                 driver-level vendor passthru or if the passthru method is
                 unsupported.
        :raises: DriverNotFound if the supplied driver is not loaded.

        """
        # Any locking in a top-level vendor action will need to be done by the
        # implementation, as there is little we could reasonably lock on here.
        LOG.debug("RPC driver_vendor_passthru for driver %s." % driver_name)
        try:
            driver = self.driver_factory[driver_name].obj
        except KeyError:
            raise exception.DriverNotFound(driver_name=driver_name)

        if not getattr(driver, 'vendor', None):
            raise exception.UnsupportedDriverExtension(
                driver=driver_name,
                extension='vendor interface')

        return driver.vendor.driver_vendor_passthru(context,
                                                    method=driver_method,
                                                    **info)
Beispiel #4
0
 def test_validate_require_managed_boot(self, mock_get_system,
                                        mock_create_ports_if_not_exist,
                                        mock_client):
     CONF.set_override('require_managed_boot', True, group='inspector')
     self.driver.boot.validate_inspection.side_effect = (
         exception.UnsupportedDriverExtension(''))
     self.assertRaises(exception.UnsupportedDriverExtension,
                       self.iface.validate, self.task)
Beispiel #5
0
    def set_secure_boot_state(self, task, state):
        """Set the current secure boot state for the node.

        :param task: A task from TaskManager.
        :param state: A new state as a boolean.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishError or its derivative in case of a driver
            runtime error.
        :raises: UnsupportedDriverExtension if secure boot is
                 not supported by the hardware.
        """
        system = redfish_utils.get_system(task.node)
        try:
            sb = system.secure_boot
        except sushy.exceptions.MissingAttributeError:
            LOG.error(
                'Secure boot has been requested for node %s but its '
                'Redfish BMC does not have a SecureBoot object',
                task.node.uuid)
            raise exception.UnsupportedDriverExtension(
                driver=task.node.driver, extension='set_secure_boot_state')

        if sb.enabled == state:
            LOG.info(
                'Secure boot state for node %(node)s is already '
                '%(value)s', {
                    'node': task.node.uuid,
                    'value': state
                })
            return

        boot_mode = system.boot.get('mode')
        if boot_mode == sushy.BOOT_SOURCE_MODE_BIOS:
            # NOTE(dtantsur): the case of disabling secure boot when boot mode
            # is legacy should be covered by the check above.
            msg = (_("Configuring secure boot requires UEFI for node %s") %
                   task.node.uuid)
            LOG.error(msg)
            raise exception.RedfishError(error=msg)

        try:
            sb.set_enabled(state)
        except sushy.exceptions.SushyError as exc:
            msg = (_('Failed to set secure boot state on node %(node)s to '
                     '%(value)s: %(exc)s') % {
                         'node': task.node.uuid,
                         'value': state,
                         'exc': exc
                     })
            LOG.error(msg)
            raise exception.RedfishError(error=msg)
        else:
            LOG.info(
                'Secure boot state for node %(node)s has been set to '
                '%(value)s', {
                    'node': task.node.uuid,
                    'value': state
                })
Beispiel #6
0
    def factory_reset(self, task):
        """Reset BIOS configuration to factory default on the given node.

        :param task: a TaskManager instance.
        :raises: UnsupportedDriverExtension, if the node's driver doesn't
            support BIOS reset.
        """

        raise exception.UnsupportedDriverExtension(driver=task.node.driver,
                                                   extension='factory_reset')
Beispiel #7
0
    def validate_rescue(self, task):
        """Validate that the node has required properties for rescue.

        :param task: A TaskManager instance with the node being checked
        :raises: MissingParameterValue if node is missing one or more required
            parameters
        :raises: UnsupportedDriverExtension
        """
        raise exception.UnsupportedDriverExtension(driver=task.node.driver,
                                                   extension='validate_rescue')
Beispiel #8
0
 def test_get_console_information_not_supported(self):
     node = self.dbapi.create_node(dbutils.get_test_node())
     with mock.patch.object(rpcapi.ConductorAPI,
                            'get_console_information') as mock_gci:
         mock_gci.side_effect = exception.UnsupportedDriverExtension(
                                extension='console', driver='test-driver')
         ret = self.get_json('/nodes/%s/states/console' % node.uuid,
                             expect_errors=True)
         self.assertEqual(400, ret.status_code)
         mock_gci.assert_called_once_with(mock.ANY, node.uuid, 'test-topic')
Beispiel #9
0
 def test_set_console_mode_console_not_supported(self):
     with mock.patch.object(rpcapi.ConductorAPI, 'set_console_mode') \
             as mock_scm:
         mock_scm.side_effect = exception.UnsupportedDriverExtension(
                                extension='console', driver='test-driver')
         ret = self.put_json('/nodes/%s/states/console' % self.node.uuid,
                             {'enabled': "true"}, expect_errors=True)
         self.assertEqual(400, ret.status_code)
         mock_scm.assert_called_once_with(mock.ANY, self.node.uuid,
                                          True, 'test-topic')
Beispiel #10
0
    def inject_nmi(self, task):
        """Inject NMI, Non Maskable Interrupt.

        Inject NMI (Non Maskable Interrupt) for a node immediately.

        :param task: A TaskManager instance containing the node to act on.
        :raises: UnsupportedDriverExtension
        """
        raise exception.UnsupportedDriverExtension(driver=task.node.driver,
                                                   extension='inject_nmi')
Beispiel #11
0
    def set_console_mode(self, context, node_id, enabled):
        """Enable/Disable the console.

        Validate driver specific information synchronously, and then
        spawn a background worker to set console mode asynchronously.

        :param context: request context.
        :param node_id: node id or uuid.
        :param enabled: Boolean value; whether the console is enabled or
                        disabled.
        :raises: UnsupportedDriverExtension if the node's driver doesn't
                 support console.
        :raises: InvalidParameterValue when the wrong driver info is specified.
        :raises: NoFreeConductorWorker when there is no free worker to start
                 async task
        """
        LOG.debug(
            _('RPC set_console_mode called for node %(node)s with '
              'enabled %(enabled)s') % {
                  'node': node_id,
                  'enabled': enabled
              })

        task = task_manager.TaskManager(context, node_id, shared=False)
        node = task.node

        try:
            if not getattr(task.driver, 'console', None):
                exc = exception.UnsupportedDriverExtension(driver=node.driver,
                                                           extension='console')
                node.last_error = exc.format_message()
                node.save(context)
                raise exc

            task.driver.console.validate(task, node)

            if enabled == node.console_enabled:
                op = _('enabled') if enabled else _('disabled')
                LOG.info(
                    _("No console action was triggered because the "
                      "console is already %s") % op)
            else:
                node.last_error = None
                node.save(context)

                # Start the requested action in the background.
                thread = self._spawn_worker(self._set_console_mode, task,
                                            enabled)
                # Release node lock at the end.
                thread.link(lambda t: task.release_resources())

        except Exception:
            with excutils.save_and_reraise_exception():
                # Release node lock if error occurred.
                task.release_resources()
Beispiel #12
0
    def validate_inspection(self, task):
        """Validate that the node has required properties for inspection.

        :param task: A TaskManager instance with the node being checked
        :raises: UnsupportedDriverExtension
        """
        try:
            self._validate_common(task)
        except exception.MissingParameterValue:
            # Fall back to non-managed in-band inspection
            raise exception.UnsupportedDriverExtension(driver=task.node.driver,
                                                       extension='inspection')
Beispiel #13
0
 def test_prepare_ramdisk_conflicting_boot_modes_set_unsupported(
         self, set_boot_mode_mock):
     self.node.provision_state = states.DEPLOYING
     properties = self.node.properties
     properties['capabilities'] = 'boot_mode:uefi'
     self.node.properties = properties
     self.node.save()
     set_boot_mode_mock.side_effect = exception.UnsupportedDriverExtension(
         extension='management', driver='test-driver')
     self.assertRaises(exception.UnsupportedDriverExtension,
                       self._test_prepare_ramdisk,
                       uefi=True,
                       node_boot_mode=boot_modes.LEGACY_BIOS)
Beispiel #14
0
 def test_unmanaged_ok(self, mock_client):
     self.driver.boot.validate_inspection.side_effect = (
         exception.UnsupportedDriverExtension(''))
     mock_introspect = mock_client.return_value.start_introspection
     self.assertEqual(states.INSPECTWAIT,
                      self.iface.inspect_hardware(self.task))
     mock_introspect.assert_called_once_with(self.node.uuid)
     self.assertFalse(self.driver.boot.prepare_ramdisk.called)
     self.assertFalse(self.driver.network.add_inspection_network.called)
     self.assertFalse(self.driver.power.reboot.called)
     self.assertFalse(self.driver.network.remove_inspection_network.called)
     self.assertFalse(self.driver.boot.clean_up_ramdisk.called)
     self.assertFalse(self.driver.power.set_power_state.called)
Beispiel #15
0
 def test_raid_logical_disk_properties_iface_not_supported(
         self, disk_prop_mock):
     driver._RAID_PROPERTIES = {}
     self.register_fake_conductors()
     disk_prop_mock.side_effect = exception.UnsupportedDriverExtension(
         extension='raid', driver='fake-hardware')
     path = '/drivers/%s/raid/logical_disk_properties' % self.hw1
     ret = self.get_json(path,
                         headers={api_base.Version.string: "1.12"},
                         expect_errors=True)
     self.assertEqual(http_client.NOT_FOUND, ret.status_code)
     self.assertTrue(ret.json['error_message'])
     disk_prop_mock.assert_called_once_with(mock.ANY, mock.ANY, self.hw1,
                                            topic=mock.ANY)
Beispiel #16
0
 def test_require_managed_boot(self, mock_client):
     CONF.set_override('require_managed_boot', True, group='inspector')
     self.driver.boot.validate_inspection.side_effect = (
         exception.UnsupportedDriverExtension(''))
     mock_introspect = mock_client.return_value.start_introspection
     self.assertRaises(exception.UnsupportedDriverExtension,
                       self.iface.inspect_hardware, self.task)
     self.assertFalse(mock_introspect.called)
     self.assertFalse(self.driver.boot.prepare_ramdisk.called)
     self.assertFalse(self.driver.network.add_inspection_network.called)
     self.assertFalse(self.driver.power.reboot.called)
     self.assertFalse(self.driver.network.remove_inspection_network.called)
     self.assertFalse(self.driver.boot.clean_up_ramdisk.called)
     self.assertFalse(self.driver.power.set_power_state.called)
Beispiel #17
0
    def set_secure_boot_state(self, task, state):
        """Set the current secure boot state for the node.

        :param task: A task from TaskManager.
        :param state: A new state as a boolean.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: IloOperationError on an error from IloClient library.
        :raises: UnsupportedDriverExtension if secure boot is
                 not supported by the hardware
        """
        try:
            ilo_common.set_secure_boot_mode(task, state)
        except ilo_error.IloOperationNotSupported:
            raise exception.UnsupportedDriverExtension(
                driver=task.node.driver, extension='set_secure_boot_state')
Beispiel #18
0
 def test_unmanaged_error(self, mock_acquire, mock_client):
     mock_acquire.return_value.__enter__.return_value = self.task
     self.driver.boot.validate_inspection.side_effect = (
         exception.UnsupportedDriverExtension(''))
     mock_introspect = mock_client.return_value.start_introspection
     mock_introspect.side_effect = RuntimeError('boom')
     self.iface.inspect_hardware(self.task)
     mock_introspect.assert_called_once_with(self.node.uuid)
     self.assertIn('boom', self.task.node.last_error)
     self.task.process_event.assert_called_once_with('fail')
     self.assertFalse(self.driver.boot.prepare_ramdisk.called)
     self.assertFalse(self.driver.network.add_inspection_network.called)
     self.assertFalse(self.driver.network.remove_inspection_network.called)
     self.assertFalse(self.driver.boot.clean_up_ramdisk.called)
     self.assertFalse(self.driver.power.set_power_state.called)
Beispiel #19
0
    def driver_vendor_passthru(self, context, method, **kwargs):
        """Handle top-level (ie, no node is specified) vendor actions. These
        allow a vendor interface to expose additional cross-node API
        functionality.

        VendorInterface subclasses are explicitly not required to implement
        this in order to maintain backwards compatibility with existing
        drivers.

        :param context: a context for this action.
        :param method: an arbitrary string describing the action to be taken.
        :param kwargs: arbitrary parameters to the passthru method.
        """
        raise exception.UnsupportedDriverExtension(
            _('Vendor interface does not support driver vendor_passthru '
              'method: %s') % method)
Beispiel #20
0
    def vendor_passthru(self, context, node_id, driver_method, info):
        """RPC method to encapsulate vendor action.

        Synchronously validate driver specific info or get driver status,
        and if successful, start background worker to perform vendor action
        asynchronously.

        :param context: an admin context.
        :param node_id: the id or uuid of a node.
        :param driver_method: the name of the vendor method.
        :param info: vendor method args.
        :raises: InvalidParameterValue if supplied info is not valid.
        :raises: UnsupportedDriverExtension if current driver does not have
                 vendor interface or method is unsupported.
        :raises: NoFreeConductorWorker when there is no free worker to start
                 async task.

        """
        LOG.debug(_("RPC vendor_passthru called for node %s.") % node_id)
        # NOTE(max_lobur): Even though not all vendor_passthru calls may
        # require an exclusive lock, we need to do so to guarantee that the
        # state doesn't unexpectedly change between doing a vendor.validate
        # and vendor.vendor_passthru.
        task = task_manager.TaskManager(context, node_id, shared=False)

        try:
            if not getattr(task.driver, 'vendor', None):
                raise exception.UnsupportedDriverExtension(
                    driver=task.node.driver, extension='vendor passthru')

            task.driver.vendor.validate(task,
                                        task.node,
                                        method=driver_method,
                                        **info)
            # Start requested action in the background.
            thread = self._spawn_worker(task.driver.vendor.vendor_passthru,
                                        task,
                                        task.node,
                                        method=driver_method,
                                        **info)
            # Release node lock at the end of async action.
            thread.link(lambda t: task.release_resources())
        except Exception:
            with excutils.save_and_reraise_exception():
                # Release node lock if error occurred.
                task.release_resources()
Beispiel #21
0
    def get_secure_boot_state(self, task):
        """Get the current secure boot state for the node.

        :param task: A task from TaskManager.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishError or its derivative in case of a driver
            runtime error.
        :raises: UnsupportedDriverExtension if secure boot is
                 not supported by the hardware.
        :returns: Boolean
        """
        system = redfish_utils.get_system(task.node)
        try:
            return system.secure_boot.enabled
        except sushy.exceptions.MissingAttributeError:
            raise exception.UnsupportedDriverExtension(
                driver=task.node.driver, extension='get_secure_boot_state')
Beispiel #22
0
    def test_vendor_passthru_no_such_method(self):
        ndict = dbutils.get_test_node()
        self.dbapi.create_node(ndict)
        uuid = ndict['uuid']
        info = {'foo': 'bar'}

        with mock.patch.object(
                rpcapi.ConductorAPI, 'vendor_passthru') as mock_vendor:
            mock_vendor.side_effect = exception.UnsupportedDriverExtension(
                                        {'driver': ndict['driver'],
                                         'node': uuid,
                                         'extension': 'test'})
            response = self.post_json('/nodes/%s/vendor_passthru/test' % uuid,
                                      info, expect_errors=True)
            mock_vendor.assert_called_once_with(
                    mock.ANY, uuid, 'test', info, 'test-topic')
            self.assertEqual(400, response.status_code)
Beispiel #23
0
    def cache_bios_settings(self, task):
        """Store or update the current BIOS settings for the node.

        Get the current BIOS settings and store them in the bios_settings
        database table.

        :param task: a TaskManager instance containing the node to act on.
        :raises: RedfishConnectionError when it fails to connect to Redfish
        :raises: RedfishError on an error from the Sushy library
        :raises: UnsupportedDriverExtension if the system does not support BIOS
            settings
        """

        node_id = task.node.id
        system = redfish_utils.get_system(task.node)
        try:
            attributes = system.bios.attributes
        except sushy.exceptions.MissingAttributeError:
            error_msg = _('Cannot fetch BIOS attributes for node %s, '
                          'BIOS settings are not supported.') % task.node.uuid
            LOG.error(error_msg)
            raise exception.UnsupportedDriverExtension(error_msg)

        settings = []
        # Convert Redfish BIOS attributes to Ironic BIOS settings
        if attributes:
            settings = [{'name': k, 'value': v} for k, v in attributes.items()]

        LOG.debug('Cache BIOS settings for node %(node_uuid)s',
                  {'node_uuid': task.node.uuid})

        create_list, update_list, delete_list, nochange_list = (
            objects.BIOSSettingList.sync_node_setting(
                task.context, node_id, settings))

        if create_list:
            objects.BIOSSettingList.create(
                task.context, node_id, create_list)
        if update_list:
            objects.BIOSSettingList.save(
                task.context, node_id, update_list)
        if delete_list:
            delete_names = [d['name'] for d in delete_list]
            objects.BIOSSettingList.delete(
                task.context, node_id, delete_names)
Beispiel #24
0
def _set_boot_mode_on_bm(task, ironic_boot_mode, fail_if_unsupported=False):
    try:
        manager_utils.node_set_boot_mode(task, ironic_boot_mode)

    except exception.UnsupportedDriverExtension as ex:
        if fail_if_unsupported:
            msg = (_("Baremetal node %(uuid)s boot mode is not set "
                     "to boot mode %(boot_mode)s: %(error)s") % {
                         'uuid': task.node.uuid,
                         'boot_mode': ironic_boot_mode,
                         'error': ex
                     })
            LOG.error(msg)
            raise exception.UnsupportedDriverExtension(msg)

        msg_tmpl = _("Baremetal node %(uuid)s boot mode is not set "
                     "to boot mode %(boot_mode)s. Assuming "
                     "baremetal node is already in %(boot_mode)s or "
                     "driver set boot mode via some other "
                     "mechanism: %(error)s")

        LOG.debug(msg_tmpl, {
            'uuid': task.node.uuid,
            'boot_mode': ironic_boot_mode,
            'error': ex
        })

    except exception.InvalidParameterValue as ex:
        msg = (_("Node %(uuid)s boot mode is not set. "
                 "Attempt to set %(ironic_boot_mode)s boot mode "
                 "on the baremetal node failed with error %(error)s") % {
                     'uuid': task.node.uuid,
                     'ironic_boot_mode': ironic_boot_mode,
                     'error': ex
                 })
        LOG.error(msg)
        raise exception.InvalidParameterValue(msg)

    else:
        LOG.info(
            "Baremetal node boot mode is set to boot "
            "mode %(boot_mode)s", {
                'uuid': task.node.uuid,
                'boot_mode': ironic_boot_mode
            })
Beispiel #25
0
def get_secure_boot_mode(node):
    """Get the current secure boot mode.

    :param node: An ironic node object.
    :raises: UnsupportedDriverExtension if secure boot is not present.
    :raises: IRMCOperationError if the operation fails.
    """
    driver_info = parse_driver_info(node)

    try:
        return elcm.get_secure_boot_mode(driver_info)
    except elcm.SecureBootConfigNotFound:
        raise exception.UnsupportedDriverExtension(
            driver=node.driver, extension='get_secure_boot_state')
    except scci.SCCIError as irmc_exception:
        LOG.error("Failed to get secure boot for node %s", node.uuid)
        raise exception.IRMCOperationError(
            operation=_("getting secure boot mode"), error=irmc_exception)
Beispiel #26
0
    def set_boot_mode(self, task, mode):
        """Set the boot mode for a node.

        Set the boot mode to use on next reboot of the node.

        :param task: A task from TaskManager.
        :param mode: The boot mode, one of
                     :mod:`ironic.common.boot_modes`.
        :raises: InvalidParameterValue if an invalid boot mode is
                 specified.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishConnectionError when it fails to connect to Redfish
        :raises: RedfishError on an error from the Sushy library
        """
        system = redfish_utils.get_system(task.node)

        try:
            system.set_system_boot_options(mode=BOOT_MODE_MAP_REV[mode])

        except sushy.exceptions.SushyError as e:
            error_msg = (_('Setting boot mode to %(mode)s '
                           'failed for node %(node)s. '
                           'Error: %(error)s') % {
                               'node': task.node.uuid,
                               'mode': mode,
                               'error': e
                           })
            LOG.error(error_msg)

            # NOTE(sbaker): Some systems such as HPE Gen9 do not support
            # getting or setting the boot mode. When setting failed and the
            # mode attribute is missing from the boot field, raising
            # UnsupportedDriverExtension will allow the deploy to continue.
            if system.boot.get('mode') is None:
                LOG.info(
                    _('Attempt to set boot mode on node %(node)s '
                      'failed to set boot mode as the node does not '
                      'appear to support overriding the boot mode. '
                      'Possibly partial Redfish implementation?'),
                    {'node': task.node.uuid})
                raise exception.UnsupportedDriverExtension(
                    driver=task.node.driver, extension='set_boot_mode')
            raise exception.RedfishError(error=error_msg)
Beispiel #27
0
    def validate_vendor_action(self, context, node_id, driver_method, info):
        """Validate driver specific info or get driver status."""

        LOG.debug(
            _("RPC validate_vendor_action called for node %s.") % node_id)
        with task_manager.acquire(context, node_id, shared=True) as task:
            try:
                if getattr(task.driver, 'vendor', None):
                    return task.driver.vendor.validate(task,
                                                       task.node,
                                                       method=driver_method,
                                                       **info)
                else:
                    raise exception.UnsupportedDriverExtension(
                        driver=task.node.driver, extension='vendor passthru')
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    task.node.last_error = \
                        _("Failed to validate vendor info. Error: %s") % e
                    task.node.save(context)
Beispiel #28
0
    def _reset_keys(self, task, reset_type):
        system = redfish_utils.get_system(task.node)
        try:
            sb = system.secure_boot
        except sushy.exceptions.MissingAttributeError:
            LOG.error(
                'Resetting secure boot keys has been requested for node '
                '%s but its Redfish BMC does not have a SecureBoot '
                'object', task.node.uuid)
            raise exception.UnsupportedDriverExtension(driver=task.node.driver,
                                                       extension='reset_keys')

        try:
            sb.reset_keys(reset_type)
        except sushy.exceptions.SushyError as exc:
            msg = (_('Failed to reset secure boot keys on node %(node)s: '
                     '%(exc)s') % {
                         'node': task.node.uuid,
                         'exc': exc
                     })
            LOG.error(msg)
            raise exception.RedfishError(error=msg)
Beispiel #29
0
    def set_console_mode(self, context, node_id, enabled):
        """Enable/Disable the console.

        Validate driver specific information synchronously, and then
        spawn a background worker to set console mode asynchronously.

        :param context: request context.
        :param node_id: node id or uuid.
        :param enabled: Boolean value; whether the console is enabled or
                        disabled.
        :raises: UnsupportedDriverExtension if the node's driver doesn't
                 support console.
        :raises: InvalidParameterValue when the wrong driver info is specified.
        :raises: NoFreeConductorWorker when there is no free worker to start
                 async task
        """
        LOG.debug('RPC set_console_mode called for node %(node)s with '
                  'enabled %(enabled)s' % {'node': node_id,
                                           'enabled': enabled})

        with task_manager.acquire(context, node_id, shared=False) as task:
            node = task.node
            if not getattr(task.driver, 'console', None):
                raise exception.UnsupportedDriverExtension(driver=node.driver,
                                                           extension='console')

            task.driver.console.validate(task)

            if enabled == node.console_enabled:
                op = _('enabled') if enabled else _('disabled')
                LOG.info(_("No console action was triggered because the "
                           "console is already %s") % op)
                task.release_resources()
            else:
                node.last_error = None
                node.save(context)
                task.spawn_after(self._spawn_worker,
                                 self._set_console_mode, task, enabled)
Beispiel #30
0
    def get_console_information(self, context, node_id):
        """Get connection information about the console.

        :param context: request context.
        :param node_id: node id or uuid.
        :raises: UnsupportedDriverExtension if the node's driver doesn't
                 support console.
        :raises: NodeConsoleNotEnabled if the console is not enabled.
        :raises: InvalidParameterValue when the wrong driver info is specified.
        """
        LOG.debug('RPC get_console_information called for node %s' % node_id)

        with task_manager.acquire(context, node_id, shared=True) as task:
            node = task.node

            if not getattr(task.driver, 'console', None):
                raise exception.UnsupportedDriverExtension(driver=node.driver,
                                                           extension='console')
            if not node.console_enabled:
                raise exception.NodeConsoleNotEnabled(node=node_id)

            task.driver.console.validate(task)
            return task.driver.console.get_console(task)