Example #1
0
    def test_expire_old_sessions(self, mock_sushy):
        for num in range(20):
            self.node.driver_info['redfish_username'] = '******' % num
            redfish_utils.get_system(self.node)

        self.assertEqual(mock_sushy.call_count, 20)
        self.assertEqual(len(redfish_utils.SessionCache.sessions), 10)
Example #2
0
 def test_auth_auto(self, mock_sushy):
     redfish_utils.get_system(self.node)
     mock_sushy.assert_called_with(
         self.parsed_driver_info['address'],
         username=self.parsed_driver_info['username'],
         password=self.parsed_driver_info['password'],
         verify=True)
Example #3
0
    def test_disabled_sessions_cache(self, mock_sushy):
        cfg.CONF.set_override('connection_cache_size', 0, 'redfish')
        for num in range(2):
            self.node.driver_info['redfish_username'] = '******' % num
            redfish_utils.get_system(self.node)

        self.assertEqual(mock_sushy.call_count, 2)
        self.assertEqual(len(redfish_utils.SessionCache._sessions), 0)
Example #4
0
    def test_disabled_sessions_cache(self, mock_sushy):
        cfg.CONF.set_override('connection_cache_size', 0, 'redfish')
        for num in range(2):
            self.node.driver_info['redfish_username'] = '******' % num
            redfish_utils.get_system(self.node)

        self.assertEqual(mock_sushy.call_count, 2)
        self.assertEqual(len(redfish_utils.SessionCache._sessions), 0)
Example #5
0
 def test_ensure_basic_session_caching(self, mock_auth, mock_sushy):
     self.node.driver_info['redfish_auth_type'] = 'basic'
     mock_session_or_basic_auth = mock_auth['auto']
     redfish_utils.get_system(self.node)
     mock_sushy.assert_called_with(
         mock.ANY, verify=mock.ANY,
         auth=mock_session_or_basic_auth.return_value,
     )
     self.assertEqual(len(redfish_utils.SessionCache._sessions), 1)
Example #6
0
 def test_ensure_basic_session_caching(self, mock_auth, mock_sushy):
     self.node.driver_info['redfish_auth_type'] = 'basic'
     mock_session_or_basic_auth = mock_auth['auto']
     redfish_utils.get_system(self.node)
     mock_sushy.assert_called_with(
         mock.ANY, verify=mock.ANY,
         auth=mock_session_or_basic_auth.return_value,
     )
     self.assertEqual(len(redfish_utils.SessionCache._sessions), 1)
Example #7
0
 def test_auth_auto(self, mock_auth, mock_sushy):
     redfish_utils.get_system(self.node)
     mock_session_or_basic_auth = mock_auth['auto']
     mock_session_or_basic_auth.assert_called_with(
         username=self.parsed_driver_info['username'],
         password=self.parsed_driver_info['password'])
     mock_sushy.assert_called_with(
         self.parsed_driver_info['address'],
         auth=mock_session_or_basic_auth.return_value,
         verify=True)
Example #8
0
 def test_auth_basic(self, mock_auth, mock_sushy):
     self.node.driver_info['redfish_auth_type'] = 'basic'
     mock_basic_auth = mock_auth['basic']
     redfish_utils.get_system(self.node)
     mock_basic_auth.assert_called_with(
         username=self.parsed_driver_info['username'],
         password=self.parsed_driver_info['password'])
     sushy.Sushy.assert_called_with(mock.ANY,
                                    verify=mock.ANY,
                                    auth=mock_basic_auth.return_value)
Example #9
0
 def test_auth_auto(self, mock_auth, mock_sushy):
     redfish_utils.get_system(self.node)
     mock_session_or_basic_auth = mock_auth['auto']
     mock_session_or_basic_auth.assert_called_with(
         username=self.parsed_driver_info['username'],
         password=self.parsed_driver_info['password']
     )
     mock_sushy.assert_called_with(
         self.parsed_driver_info['address'],
         auth=mock_session_or_basic_auth.return_value,
         verify=True)
Example #10
0
 def test_auth_basic(self, mock_auth, mock_sushy):
     self.node.driver_info['redfish_auth_type'] = 'basic'
     mock_basic_auth = mock_auth['basic']
     redfish_utils.get_system(self.node)
     mock_basic_auth.assert_called_with(
         username=self.parsed_driver_info['username'],
         password=self.parsed_driver_info['password']
     )
     sushy.Sushy.assert_called_with(
         mock.ANY, verify=mock.ANY,
         auth=mock_basic_auth.return_value
     )
Example #11
0
    def clean_up_ramdisk(self, task):
        """Cleans up the boot of ironic ramdisk.

        This method cleans up the environment that was setup for booting the
        deploy ramdisk.

        :param task: A task from TaskManager.
        :returns: None
        """
        d_info = _parse_driver_info(task.node)

        config_via_floppy = d_info.get('config_via_floppy')

        LOG.debug("Cleaning up deploy boot for "
                  "%(node)s", {'node': task.node.uuid})

        managers = redfish_utils.get_system(task.node).managers

        _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_CD)
        image_utils.cleanup_iso_image(task)

        if (config_via_floppy
                and _has_vmedia_device(managers, sushy.VIRTUAL_MEDIA_FLOPPY)):
            _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_FLOPPY)

            image_utils.cleanup_floppy_image(task)
Example #12
0
    def get_boot_device(self, task):
        """Get the current boot device for a node.

        :param task: a task from TaskManager.
        :raises: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :raises: RedfishConnectionError when it fails to connect to Redfish
        :raises: RedfishError on an error from the Sushy library
        :returns: a dictionary containing:

            :boot_device:
                the boot device, one of :mod:`ironic.common.boot_devices` or
                None if it is unknown.
            :persistent:
                Boolean value or None, True if the boot device persists,
                False otherwise. None if it's unknown.


        """
        system = redfish_utils.get_system(task.node)
        return {
            'boot_device':
            BOOT_DEVICE_MAP.get(system.boot.get('target')),
            'persistent':
            BOOT_DEVICE_PERSISTENT_MAP.get(system.boot.get('enabled'))
        }
Example #13
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)
            raise exception.RedfishError(error=error_msg)
Example #14
0
    def set_power_state(self, task, power_state, timeout=None):
        """Set the power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param power_state: Any power state from :mod:`ironic.common.states`.
        :param timeout: Time to wait for the node to reach the requested state.
        :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)

        if (power_state in (states.POWER_ON, states.SOFT_REBOOT, states.REBOOT)
                and isinstance(task.driver.management,
                               redfish_mgmt.RedfishManagement)):
            task.driver.management.restore_boot_device(task, system)

        try:
            _set_power_state(task, system, power_state, timeout=timeout)
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Setting power state to %(state)s failed for node '
                           '%(node)s. Error: %(error)s') % {
                               'node': task.node.uuid,
                               'state': power_state,
                               'error': e
                           })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #15
0
    def clean_up_instance(self, task):
        """Cleans up the boot of instance.

        This method cleans up the environment that was setup for booting
        the instance.

        :param task: A task from TaskManager.
        :returns: None
        """
        LOG.debug("Cleaning up instance boot for "
                  "%(node)s", {'node': task.node.uuid})

        managers = redfish_utils.get_system(task.node).managers

        _eject_vmedia(task, managers, 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, managers, sushy.VIRTUAL_MEDIA_FLOPPY)

        boot_option = deploy_utils.get_boot_option(task.node)
        if (boot_option == 'ramdisk'
                and task.node.instance_info.get('configdrive')):
            _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_USBSTICK)
            image_utils.cleanup_disk_image(task, prefix='configdrive')

        image_utils.cleanup_iso_image(task)
Example #16
0
    def set_power_state(self, task, power_state, timeout=None):
        """Set the power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param power_state: Any power state from :mod:`ironic.common.states`.
        :param timeout: Time to wait for the node to reach the requested state.
        :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.reset_system(SET_POWER_STATE_MAP.get(power_state))
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish set power state failed for node '
                           '%(node)s. Error: %(error)s') % {
                               'node': task.node.uuid,
                               'error': e
                           })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        target_state = TARGET_STATE_MAP.get(power_state, power_state)
        cond_utils.node_wait_for_power_state(task,
                                             target_state,
                                             timeout=timeout)
Example #17
0
File: boot.py Project: LZMWL/ironic
    def _eject_vmedia(task, boot_device=None):
        """Eject virtual CDs and DVDs

        :param task: A task from TaskManager.
        :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
            `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY` or `None` to
            eject everything (default).
        :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
            found on the node.
        """
        system = redfish_utils.get_system(task.node)

        for manager in system.managers:
            for v_media in manager.virtual_media.get_members():
                if boot_device and boot_device not in v_media.media_types:
                    continue

                inserted = v_media.inserted

                if inserted:
                    v_media.eject_media()

                LOG.info(
                    "Boot media is%(already)s ejected from "
                    "%(boot_device)s for node %(node)s"
                    "", {
                        'node': task.node.uuid,
                        'already': '' if inserted else ' already',
                        'boot_device': v_media.name
                    })
Example #18
0
 def test_get_system(self, mock_sushy):
     fake_conn = mock_sushy.return_value
     fake_system = fake_conn.get_system.return_value
     response = redfish_utils.get_system(self.node)
     self.assertEqual(fake_system, response)
     fake_conn.get_system.assert_called_once_with(
         '/redfish/v1/Systems/FAKESYSTEM')
Example #19
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
        """

        node_id = task.node.id
        system = redfish_utils.get_system(task.node)
        attributes = system.bios.attributes
        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)
Example #20
0
    def reboot(self, task, timeout=None):
        """Perform a hard reboot of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param timeout: Time to wait for the node to become powered on.
        :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)
        current_power_state = GET_POWER_STATE_MAP.get(system.power_state)

        try:
            if current_power_state == states.POWER_ON:
                system.reset_system(SET_POWER_STATE_MAP.get(states.REBOOT))
            else:
                system.reset_system(SET_POWER_STATE_MAP.get(states.POWER_ON))
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish reboot failed for node %(node)s. '
                           'Error: %(error)s') % {'node': task.node.uuid,
                                                  'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        cond_utils.node_wait_for_power_state(task, states.POWER_ON,
                                             timeout=timeout)
Example #21
0
    def reboot(self, task, timeout=None):
        """Perform a hard reboot of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param timeout: Time to wait for the node to become powered on.
        :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)
        current_power_state = GET_POWER_STATE_MAP.get(system.power_state)

        try:
            if current_power_state == states.POWER_ON:
                next_state = states.POWER_OFF
                _set_power_state(task, system, next_state, timeout=timeout)

            next_state = states.POWER_ON
            _set_power_state(task, system, next_state, timeout=timeout)
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Reboot failed for node %(node)s when setting '
                           'power state to %(state)s. Error: %(error)s') % {
                               'node': task.node.uuid,
                               'state': next_state,
                               'error': e
                           })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #22
0
 def test_get_system(self, mock_sushy):
     fake_conn = mock_sushy.return_value
     fake_system = fake_conn.get_system.return_value
     response = redfish_utils.get_system(self.node)
     self.assertEqual(fake_system, response)
     fake_conn.get_system.assert_called_once_with(
         '/redfish/v1/Systems/FAKESYSTEM')
Example #23
0
def get_physical_disks(node):
    """Get the physical drives of the node.

    :param node: an ironic node object.
    :returns: a list of Drive objects from sushy
    :raises: RedfishConnectionError when it fails to connect to Redfish
    :raises: RedfishError if there is an error getting the drives via Redfish
    """
    system = redfish_utils.get_system(node)

    disks = []
    disk_to_controller = {}
    try:
        collection = system.storage
        for storage in collection.get_members():
            disks.extend(storage.drives)
            controller = (storage.storage_controllers[0]
                          if storage.storage_controllers else None)
            for drive in storage.drives:
                disk_to_controller[drive] = controller
    except sushy.exceptions.SushyError as exc:
        error_msg = _('Cannot get the list of physical disks for node '
                      '%(node_uuid)s. Reason: %(error)s.' %
                      {'node_uuid': node.uuid, 'error': exc})
        LOG.error(error_msg)
        raise exception.RedfishError(error=exc)
    return disks, disk_to_controller
Example #24
0
    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
                       :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 on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :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_source(
                BOOT_DEVICE_MAP_REV[device],
                enabled=BOOT_DEVICE_PERSISTENT_MAP_REV[persistent])
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish set boot device failed for node '
                           '%(node)s. Error: %(error)s') %
                         {'node': task.node.uuid, 'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #25
0
    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
                       :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 on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :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_source(
                BOOT_DEVICE_MAP_REV[device],
                enabled=BOOT_DEVICE_PERSISTENT_MAP_REV[persistent])
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish set boot device failed for node '
                           '%(node)s. Error: %(error)s') % {
                               'node': task.node.uuid,
                               'error': e
                           })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #26
0
    def apply_configuration(self, task, settings):
        """Apply the BIOS settings to the node.

        :param task: a TaskManager instance containing the node to act on.
        :param settings: a list of BIOS settings to be updated.
        :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:
            bios = system.bios
        except sushy.exceptions.MissingAttributeError:
            error_msg = (_('Redfish BIOS factory reset failed for node '
                           '%s, because BIOS settings are not supported.') %
                         task.node.uuid)
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        # Convert Ironic BIOS settings to Redfish BIOS attributes
        attributes = {s['name']: s['value'] for s in settings}

        info = task.node.driver_internal_info
        reboot_requested = info.get('post_config_reboot_requested')

        if not reboot_requested:
            # Step 1: Apply settings and issue a reboot
            LOG.debug('Apply BIOS configuration for node %(node_uuid)s: '
                      '%(settings)r', {'node_uuid': task.node.uuid,
                                       'settings': settings})

            if bios.supported_apply_times and (
                    sushy.APPLY_TIME_ON_RESET in bios.supported_apply_times):
                apply_time = sushy.APPLY_TIME_ON_RESET
            else:
                apply_time = None

            try:
                bios.set_attributes(attributes, apply_time=apply_time)
            except sushy.exceptions.SushyError as e:
                error_msg = (_('Redfish BIOS apply configuration failed for '
                               'node %(node)s. Error: %(error)s') %
                             {'node': task.node.uuid, 'error': e})
                LOG.error(error_msg)
                raise exception.RedfishError(error=error_msg)

            self.post_configuration(task, settings)
            self._set_reboot_requested(task, attributes)
            return deploy_utils.get_async_step_return_state(task.node)
        else:
            # Step 2: Verify requested BIOS settings applied
            requested_attrs = info.get('requested_bios_attrs')
            current_attrs = bios.attributes
            LOG.debug('Verify BIOS configuration for node %(node_uuid)s: '
                      '%(attrs)r', {'node_uuid': task.node.uuid,
                                    'attrs': requested_attrs})
            self._clear_reboot_requested(task)
            self._check_bios_attrs(task, current_attrs, requested_attrs)
Example #27
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
                })
Example #28
0
    def set_indicator_state(self, task, component, indicator, state):
        """Set indicator on the hardware component to the desired state.

        :param task: A task from TaskManager.
        :param component: The hardware component, one of
            :mod:`ironic.common.components`.
        :param indicator: Indicator ID (as reported by
            `get_supported_indicators`).
        :param state: Desired state of the indicator, one of
            :mod:`ironic.common.indicator_states`.
        :raises: InvalidParameterValue if an invalid component, indicator
                 or state is specified.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishError on an error from the Sushy library
        """
        system = redfish_utils.get_system(task.node)

        try:
            if (component == components.SYSTEM
                    and indicator == system.uuid):
                system.set_indicator_led(INDICATOR_MAP_REV[state])
                return

            elif (component == components.CHASSIS
                    and system.chassis):
                for chassis in system.chassis:
                    if chassis.uuid == indicator:
                        chassis.set_indicator_led(
                            INDICATOR_MAP_REV[state])
                        return

            elif (component == components.DISK
                  and system.simple_storage
                  and system.simple_storage.drives):
                for drive in system.simple_storage.drives:
                    if drive.uuid == indicator:
                        drive.set_indicator_led(
                            INDICATOR_MAP_REV[state])
                        return

        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish set %(component)s indicator %(indicator)s '
                           'state %(state)s failed for node %(node)s. Error: '
                           '%(error)s') % {'component': component,
                                           'indicator': indicator,
                                           'state': state,
                                           'node': task.node.uuid,
                                           'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        raise exception.MissingParameterValue(_(
            "Unknown indicator %(indicator)s for component %(component)s of "
            "node %(uuid)s") % {'indicator': indicator,
                                'component': component,
                                'uuid': task.node.uuid})
Example #29
0
    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 parameters
                 are missing.
        :raises: MissingParameterValue if a required parameter is missing.
        :returns: returns a dict of sensor data grouped by sensor type.
        """
        node = task.node

        sensors = collections.defaultdict(dict)

        system = redfish_utils.get_system(node)

        for chassis in system.chassis:
            try:
                sensors['Fan'].update(self._get_sensors_fan(chassis))

            except sushy.exceptions.SushyError as exc:
                LOG.debug("Failed reading fan information for node "
                          "%(node)s: %(error)s", {'node': node.uuid,
                                                  'error': exc})

            try:
                sensors['Temperature'].update(
                    self._get_sensors_temperatures(chassis))

            except sushy.exceptions.SushyError as exc:
                LOG.debug("Failed reading temperature information for node "
                          "%(node)s: %(error)s", {'node': node.uuid,
                                                  'error': exc})

            try:
                sensors['Power'].update(self._get_sensors_power(chassis))

            except sushy.exceptions.SushyError as exc:
                LOG.debug("Failed reading power information for node "
                          "%(node)s: %(error)s", {'node': node.uuid,
                                                  'error': exc})

        try:
            sensors['Drive'].update(self._get_sensors_drive(system))

        except sushy.exceptions.SushyError as exc:
            LOG.debug("Failed reading drive information for node "
                      "%(node)s: %(error)s", {'node': node.uuid,
                                              'error': exc})

        LOG.debug("Gathered sensor data: %(sensors)s", {'sensors': sensors})

        return sensors
Example #30
0
    def get_power_state(self, task):
        """Get the current power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: a power state. One of :mod:`ironic.common.states`.
        :raises: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :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)
        return GET_POWER_STATE_MAP.get(system.power_state)
Example #31
0
    def get_power_state(self, task):
        """Get the current power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: a power state. One of :mod:`ironic.common.states`.
        :raises: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :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)
        return GET_POWER_STATE_MAP.get(system.power_state)
Example #32
0
def eject_vmedia(task, boot_device=None):
    """Eject virtual CDs and DVDs

    :param task: A task from TaskManager.
    :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
        `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY` or `None` to
        eject everything (default).
    :raises: InvalidParameterValue, if no suitable virtual CD or DVD is
        found on the node.
    """
    system = redfish_utils.get_system(task.node)
    _eject_vmedia(task, system.managers, boot_device=boot_device)
Example #33
0
def create_virtual_disk(task, raid_controller, physical_disks, raid_level,
                        size_bytes, disk_name=None, span_length=None,
                        span_depth=None, error_handler=None):
    """Create a single virtual disk on a RAID controller.

    :param task: TaskManager object containing the node.
    :param raid_controller: id of the RAID controller.
    :param physical_disks: ids of the physical disks.
    :param raid_level: RAID level of the virtual disk.
    :param size_bytes: size of the virtual disk.
    :param disk_name: name of the virtual disk. (optional)
    :param span_depth: Number of spans in virtual disk. (optional)
    :param span_length: Number of disks per span. (optional)
    :param error_handler: function to call if volume create fails. (optional)
    :returns: Newly created Volume resource or TaskMonitor if async task.
    :raises: RedfishConnectionError when it fails to connect to Redfish.
    :raises: RedfishError if there is an error creating the virtual disk.
    """
    node = task.node
    system = redfish_utils.get_system(node)
    storage = _get_storage_controller(node, system, physical_disks)
    if not storage:
        reason = _('No storage controller found for node %(node_uuid)s' %
                   {'node_uuid': node.uuid})
        raise exception.RedfishError(error=reason)
    volume_collection = storage.volumes

    apply_time = None
    apply_time_support = volume_collection.operation_apply_time_support
    if apply_time_support and apply_time_support.mapped_supported_values:
        supported_values = apply_time_support.mapped_supported_values
        if sushy.APPLY_TIME_IMMEDIATE in supported_values:
            apply_time = sushy.APPLY_TIME_IMMEDIATE
        elif sushy.APPLY_TIME_ON_RESET in supported_values:
            apply_time = sushy.APPLY_TIME_ON_RESET
    payload = _construct_volume_payload(
        node, storage, raid_controller, physical_disks, raid_level, size_bytes,
        disk_name=disk_name, span_length=span_length, span_depth=span_depth)

    try:
        return volume_collection.create(payload, apply_time=apply_time)
    except sushy.exceptions.SushyError as exc:
        msg = ('Redfish driver failed to create virtual disk for node '
               '%(node_uuid)s. Reason: %(error)s.')
        if error_handler:
            try:
                return error_handler(task, exc, volume_collection, payload)
            except sushy.exceptions.SushyError as exc:
                LOG.error(msg, {'node_uuid': node.uuid, 'error': exc})
                raise exception.RedfishError(error=exc)
        LOG.error(msg, {'node_uuid': node.uuid, 'error': exc})
        raise exception.RedfishError(error=exc)
Example #34
0
    def clear_job_queue(self, task):
        """Clear iDRAC job queue.

        :param task: a TaskManager instance containing the node to act
                     on.
        :raises: RedfishError on an error.
        """
        system = redfish_utils.get_system(task.node)
        for manager in system.managers:
            try:
                oem_manager = manager.get_oem_extension('Dell')
            except sushy.exceptions.OEMExtensionNotFoundError as e:
                error_msg = (_("Search for Sushy OEM extension Python package "
                               "'sushy-oem-idrac' failed for node %(node)s. "
                               "Ensure it is installed. Error: %(error)s") % {
                                   'node': task.node.uuid,
                                   'error': e
                               })
                LOG.error(error_msg)
                raise exception.RedfishError(error=error_msg)
            try:
                oem_manager.job_service.delete_jobs(job_ids=['JID_CLEARALL'])
            except sushy.exceptions.SushyError as e:
                error_msg = (
                    'Failed to clear iDRAC job queue with system '
                    '%(system)s manager %(manager)s for node '
                    '%(node)s. Will try next manager, if available. '
                    'Error: %(error)s' % {
                        'system':
                        system.uuid if system.uuid else system.identity,
                        'manager':
                        manager.uuid if manager.uuid else manager.identity,
                        'node': task.node.uuid,
                        'error': e
                    })
                LOG.debug(error_msg)
                continue
            LOG.info('Cleared iDRAC job queue for node %(node)s',
                     {'node': task.node.uuid})
            break
        else:
            error_msg = (
                _('iDRAC Redfish clear job queue failed for node '
                  '%(node)s, because system %(system)s has no '
                  'manager%(no_manager)s.') %
                {
                    'node': task.node.uuid,
                    'system': system.uuid if system.uuid else system.identity,
                    'no_manager': '' if not system.managers else ' which could'
                })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #35
0
File: boot.py Project: LZMWL/ironic
    def _has_vmedia_device(task, boot_device):
        """Indicate if device exists at any of the managers

        :param task: A task from TaskManager.
        :param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
            `VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`.
        """
        system = redfish_utils.get_system(task.node)

        for manager in system.managers:
            for v_media in manager.virtual_media.get_members():
                if boot_device in v_media.media_types:
                    return True
Example #36
0
    def reset_idrac(self, task):
        """Reset the iDRAC.

        :param task: a TaskManager instance containing the node to act
                     on.
        :raises: RedfishError on an error.
        """
        system = redfish_utils.get_system(task.node)
        for manager in system.managers:
            try:
                oem_manager = manager.get_oem_extension('Dell')
            except sushy.exceptions.OEMExtensionNotFoundError as e:
                error_msg = (_("Search for Sushy OEM extension Python package "
                               "'sushy-oem-idrac' failed for node %(node)s. "
                               "Ensure it is installed. Error: %(error)s") % {
                                   'node': task.node.uuid,
                                   'error': e
                               })
                LOG.error(error_msg)
                raise exception.RedfishError(error=error_msg)
            try:
                oem_manager.reset_idrac()
            except sushy.exceptions.SushyError as e:
                error_msg = (
                    'Failed to reset iDRAC with system %(system)s '
                    'manager %(manager)s for node %(node)s. Will try '
                    'next manager, if available. Error: %(error)s' % {
                        'system':
                        system.uuid if system.uuid else system.identity,
                        'manager':
                        manager.uuid if manager.uuid else manager.identity,
                        'node': task.node.uuid,
                        'error': e
                    })
                LOG.debug(error_msg)
                continue
            redfish_utils.wait_until_get_system_ready(task.node)
            LOG.info('Reset iDRAC for node %(node)s', {'node': task.node.uuid})
            break
        else:
            error_msg = (
                _('iDRAC Redfish reset iDRAC failed for node '
                  '%(node)s, because system %(system)s has no '
                  'manager%(no_manager)s.') %
                {
                    'node': task.node.uuid,
                    'system': system.uuid if system.uuid else system.identity,
                    'no_manager': '' if not system.managers else ' which could'
                })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #37
0
    def detect_vendor(self, task):
        """Detects and returns the hardware vendor.

        Uses the System's Manufacturer field.

        :param task: A task from TaskManager.
        :raises: InvalidParameterValue if an invalid component, indicator
            or state is specified.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishError on driver-specific problems.
        :returns: String representing the BMC reported Vendor or
                  Manufacturer, otherwise returns None.
        """
        return redfish_utils.get_system(task.node).manufacturer
Example #38
0
    def get_indicator_state(self, task, component, indicator):
        """Get current state of the indicator of the hardware component.

        :param task: A task from TaskManager.
        :param component: The hardware component, one of
            :mod:`ironic.common.components`.
        :param indicator: Indicator ID (as reported by
            `get_supported_indicators`).
        :raises: MissingParameterValue if a required parameter is missing
        :raises: RedfishError on an error from the Sushy library
        :returns: Current state of the indicator, one of
            :mod:`ironic.common.indicator_states`.
        """
        system = redfish_utils.get_system(task.node)

        try:
            if (component == components.SYSTEM and indicator == system.uuid):
                return INDICATOR_MAP[system.indicator_led]

            if (component == components.CHASSIS and system.chassis):
                for chassis in system.chassis:
                    if chassis.uuid == indicator:
                        return INDICATOR_MAP[chassis.indicator_led]

            if (component == components.DISK and system.simple_storage
                    and system.simple_storage.drives):
                for drive in system.simple_storage.drives:
                    if drive.uuid == indicator:
                        return INDICATOR_MAP[drive.indicator_led]

        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish get %(component)s indicator %(indicator)s '
                           'state failed for node %(node)s. Error: '
                           '%(error)s') % {
                               'component': component,
                               'indicator': indicator,
                               'node': task.node.uuid,
                               'error': e
                           })
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        raise exception.MissingParameterValue(
            _("Unknown indicator %(indicator)s for component %(component)s of "
              "node %(uuid)s") % {
                  'indicator': indicator,
                  'component': component,
                  'uuid': task.node.uuid
              })
Example #39
0
    def get_boot_mode(self, task):
        """Get the current boot mode for a node.

        Provides the current boot mode of the node.

        :param task: A task from TaskManager.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: DriverOperationError or its  derivative in case
                 of driver runtime error.
        :returns: The boot mode, one of :mod:`ironic.common.boot_mode` or
                  None if it is unknown.
        """
        system = redfish_utils.get_system(task.node)

        return BOOT_MODE_MAP.get(system.boot.get('mode'))
Example #40
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)

        boot_device = system.boot.get('target')
        if not boot_device:
            error_msg = (_('Cannot change boot mode on node %(node)s '
                           'because its boot device is not set.') %
                         {'node': task.node.uuid})
            LOG.error(error_msg)
            raise exception.RedfishError(error_msg)

        boot_override = system.boot.get('enabled')
        if not boot_override:
            error_msg = (_('Cannot change boot mode on node %(node)s '
                           'because its boot source override is not set.') %
                         {'node': task.node.uuid})
            LOG.error(error_msg)
            raise exception.RedfishError(error_msg)

        try:
            system.set_system_boot_source(
                boot_device,
                enabled=boot_override,
                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)
            raise exception.RedfishError(error=error_msg)
Example #41
0
    def apply_configuration(self, task, settings):
        """Apply the BIOS settings to the node.

        :param task: a TaskManager instance containing the node to act on.
        :param settings: a list of BIOS settings to be updated.
        :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)
        bios = system.bios
        # Convert Ironic BIOS settings to Redfish BIOS attributes
        attributes = {s['name']: s['value'] for s in settings}

        info = task.node.driver_internal_info
        reboot_requested = info.get('post_config_reboot_requested')

        if not reboot_requested:
            # Step 1: Apply settings and issue a reboot
            LOG.debug('Apply BIOS configuration for node %(node_uuid)s: '
                      '%(settings)r', {'node_uuid': task.node.uuid,
                                       'settings': settings})
            try:
                bios.set_attributes(attributes)
            except sushy.exceptions.SushyError as e:
                error_msg = (_('Redfish BIOS apply configuration failed for '
                               'node %(node)s. Error: %(error)s') %
                             {'node': task.node.uuid, 'error': e})
                LOG.error(error_msg)
                raise exception.RedfishError(error=error_msg)

            self.post_configuration(task, settings)
            self._set_reboot_requested(task, attributes)
            return states.CLEANWAIT
        else:
            # Step 2: Verify requested BIOS settings applied
            requested_attrs = info.get('requested_bios_attrs')
            current_attrs = bios.attributes
            LOG.debug('Verify BIOS configuration for node %(node_uuid)s: '
                      '%(attrs)r', {'node_uuid': task.node.uuid,
                                    'attrs': requested_attrs})
            self._clear_reboot_requested(task)
            self._check_bios_attrs(task, current_attrs, requested_attrs)
Example #42
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: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :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.reset_system(sushy.RESET_NMI)
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish inject NMI failed for node %(node)s. '
                           'Error: %(error)s') % {'node': task.node.uuid,
                                                  'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)
Example #43
0
    def factory_reset(self, task):
        """Reset the BIOS settings of the node to the factory default.

        :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
        """
        system = redfish_utils.get_system(task.node)
        bios = system.bios
        LOG.debug('Factory reset BIOS settings for node %(node_uuid)s',
                  {'node_uuid': task.node.uuid})
        try:
            bios.reset_bios()
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish BIOS factory reset failed for node '
                           '%(node)s. Error: %(error)s') %
                         {'node': task.node.uuid, 'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        self.post_reset(task)
        self._set_cleaning_reboot(task)
Example #44
0
    def set_power_state(self, task, power_state, timeout=None):
        """Set the power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param power_state: Any power state from :mod:`ironic.common.states`.
        :param timeout: Time to wait for the node to reach the requested state.
        :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.reset_system(SET_POWER_STATE_MAP.get(power_state))
        except sushy.exceptions.SushyError as e:
            error_msg = (_('Redfish set power state failed for node '
                           '%(node)s. Error: %(error)s') %
                         {'node': task.node.uuid, 'error': e})
            LOG.error(error_msg)
            raise exception.RedfishError(error=error_msg)

        target_state = TARGET_STATE_MAP.get(power_state, power_state)
        cond_utils.node_wait_for_power_state(task, target_state,
                                             timeout=timeout)
Example #45
0
    def get_boot_device(self, task):
        """Get the current boot device for a node.

        :param task: a task from TaskManager.
        :raises: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        :raises: RedfishConnectionError when it fails to connect to Redfish
        :raises: RedfishError on an error from the Sushy library
        :returns: a dictionary containing:

            :boot_device:
                the boot device, one of :mod:`ironic.common.boot_devices` or
                None if it is unknown.
            :persistent:
                Boolean value or None, True if the boot device persists,
                False otherwise. None if it's unknown.


        """
        system = redfish_utils.get_system(task.node)
        return {'boot_device': BOOT_DEVICE_MAP.get(system.boot.get('target')),
                'persistent': BOOT_DEVICE_PERSISTENT_MAP.get(
                    system.boot.get('enabled'))}
Example #46
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
        """

        node_id = task.node.id
        system = redfish_utils.get_system(task.node)
        attributes = system.bios.attributes
        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)
Example #47
0
    def inspect_hardware(self, task):
        """Inspect hardware to get the hardware properties.

        Inspects hardware to get the essential properties.
        It fails if any of the essential properties
        are not received from the node.

        :param task: a TaskManager instance.
        :raises: HardwareInspectionFailure if essential properties
                 could not be retrieved successfully.
        :returns: The resulting state of inspection.

        """
        system = redfish_utils.get_system(task.node)

        # get the essential properties and update the node properties
        # with it.
        inspected_properties = task.node.properties

        if system.memory_summary and system.memory_summary.size_gib:
            inspected_properties['memory_mb'] = str(
                system.memory_summary.size_gib * units.Ki)

        if system.processors and system.processors.summary:
            cpus, arch = system.processors.summary
            if cpus:
                inspected_properties['cpus'] = cpus

            if arch:
                try:
                    inspected_properties['cpu_arch'] = CPU_ARCH_MAP[arch]

                except KeyError:
                    LOG.warning("Unknown CPU arch %(arch)s discovered "
                                "for node %(node)s", {'node': task.node.uuid,
                                                      'arch': arch})

        simple_storage_size = 0

        try:
            LOG.debug("Attempting to discover system simple storage size for "
                      "node %(node)s", {'node': task.node.uuid})
            if (system.simple_storage and
                    system.simple_storage.disks_sizes_bytes):
                simple_storage_size = [
                    size for size in system.simple_storage.disks_sizes_bytes
                    if size >= 4 * units.Gi
                ] or [0]

                simple_storage_size = simple_storage_size[0]

        except sushy.exceptions.SushyError as ex:
            LOG.debug("No simple storage information discovered "
                      "for node %(node)s: %(err)s", {'node': task.node.uuid,
                                                     'err': ex})

        storage_size = 0

        try:
            LOG.debug("Attempting to discover system storage volume size for "
                      "node %(node)s", {'node': task.node.uuid})
            if system.storage and system.storage.volumes_sizes_bytes:
                storage_size = [
                    size for size in system.storage.volumes_sizes_bytes
                    if size >= 4 * units.Gi
                ] or [0]

                storage_size = storage_size[0]

        except sushy.exceptions.SushyError as ex:
            LOG.debug("No storage volume information discovered "
                      "for node %(node)s: %(err)s", {'node': task.node.uuid,
                                                     'err': ex})

        try:
            if not storage_size:
                LOG.debug("Attempting to discover system storage drive size "
                          "for node %(node)s", {'node': task.node.uuid})
                if system.storage and system.storage.drives_sizes_bytes:
                    storage_size = [
                        size for size in system.storage.drives_sizes_bytes
                        if size >= 4 * units.Gi
                    ] or [0]

                    storage_size = storage_size[0]

        except sushy.exceptions.SushyError as ex:
            LOG.debug("No storage drive information discovered "
                      "for node %(node)s: %(err)s", {'node': task.node.uuid,
                                                     'err': ex})

        # NOTE(etingof): pick the smallest disk larger than 4G among available
        if simple_storage_size and storage_size:
            local_gb = min(simple_storage_size, storage_size)

        else:
            local_gb = max(simple_storage_size, storage_size)

        # Note(deray): Convert the received size to GiB and reduce the
        # value by 1 GB as consumers like Ironic requires the ``local_gb``
        # to be returned 1 less than actual size.
        local_gb = max(0, int(local_gb / units.Gi - 1))

        # TODO(etingof): should we respect root device hints here?

        if local_gb:
            inspected_properties['local_gb'] = str(local_gb)
        else:
            LOG.warning("Could not provide a valid storage size configured "
                        "for node %(node)s. Assuming this is a disk-less node",
                        {'node': task.node.uuid})
            inspected_properties['local_gb'] = '0'

        if system.boot.mode:
            if not drivers_utils.get_node_capability(task.node, 'boot_mode'):
                capabilities = utils.get_updated_capabilities(
                    inspected_properties.get('capabilities', ''),
                    {'boot_mode': BOOT_MODE_MAP[system.boot.mode]})

                inspected_properties['capabilities'] = capabilities

        valid_keys = self.ESSENTIAL_PROPERTIES
        missing_keys = valid_keys - set(inspected_properties)
        if missing_keys:
            error = (_('Failed to discover the following properties: '
                       '%(missing_keys)s on node %(node)s'),
                     {'missing_keys': ', '.join(missing_keys),
                      'node': task.node.uuid})
            raise exception.HardwareInspectionFailure(error=error)

        task.node.properties = inspected_properties
        task.node.save()

        LOG.debug("Node properties for %(node)s are updated as "
                  "%(properties)s", {'properties': inspected_properties,
                                     'node': task.node.uuid})

        if (system.ethernet_interfaces and
                system.ethernet_interfaces.summary):
            macs = system.ethernet_interfaces.summary

            # Create ports for the discovered NICs being in 'enabled' state
            enabled_macs = {nic_mac: nic_state
                            for nic_mac, nic_state in macs.items()
                            if nic_state == sushy.STATE_ENABLED}
            if enabled_macs:
                inspect_utils.create_ports_if_not_exist(
                    task, enabled_macs, get_mac_address=lambda x: x[0])
            else:
                LOG.warning("Not attempting to create any port as no NICs "
                            "were discovered in 'enabled' state for node "
                            "%(node)s: %(mac_data)s",
                            {'mac_data': macs, 'node': task.node.uuid})
        else:
            LOG.warning("No NIC information discovered "
                        "for node %(node)s", {'node': task.node.uuid})

        return states.MANAGEABLE
Example #48
0
 def test_ensure_session_reuse(self, mock_sushy):
     redfish_utils.get_system(self.node)
     redfish_utils.get_system(self.node)
     self.assertEqual(1, mock_sushy.call_count)
Example #49
0
 def test_ensure_new_session_address(self, mock_sushy):
     self.node.driver_info['redfish_address'] = 'http://bmc.foo'
     redfish_utils.get_system(self.node)
     self.node.driver_info['redfish_address'] = 'http://bmc.bar'
     redfish_utils.get_system(self.node)
     self.assertEqual(2, mock_sushy.call_count)
Example #50
0
 def test_ensure_new_session_username(self, mock_sushy):
     self.node.driver_info['redfish_username'] = '******'
     redfish_utils.get_system(self.node)
     self.node.driver_info['redfish_username'] = '******'
     redfish_utils.get_system(self.node)
     self.assertEqual(2, mock_sushy.call_count)