Example #1
0
def validate_job_queue(node):
    """Validates the job queue on the node.

    It raises an exception if an unfinished configuration job exists.

    :param node: an ironic node object.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        unfinished_jobs = client.list_jobs(only_unfinished=True)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            _LE('DRAC driver failed to get the list of unfinished jobs '
                'for node %(node_uuid)s. Reason: %(error)s.'), {
                    'node_uuid': node.uuid,
                    'error': exc
                })
        raise exception.DracOperationError(error=exc)

    if unfinished_jobs:
        msg = _('Unfinished config jobs found: %(jobs)r. Make sure they are '
                'completed before retrying.') % {
                    'jobs': unfinished_jobs
                }
        raise exception.DracOperationError(error=msg)
Example #2
0
def _get_next_persistent_boot_mode(node):
    client = drac_common.get_drac_client(node)

    try:
        boot_modes = client.list_boot_modes()
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            'DRAC driver failed to get next persistent boot mode for '
            'node %(node_uuid)s. Reason: %(error)s', {
                'node_uuid': node.uuid,
                'error': exc
            })
        raise exception.DracOperationError(error=exc)

    next_persistent_boot_mode = None
    for mode in boot_modes:
        if mode.is_next and mode.id != _NON_PERSISTENT_BOOT_MODE:
            next_persistent_boot_mode = mode.id
            break

    if not next_persistent_boot_mode:
        message = _('List of boot modes, %(list_boot_modes)s, does not '
                    'contain a persistent mode') % {
                        'list_boot_modes': boot_modes
                    }
        LOG.error(
            'DRAC driver failed to get next persistent boot mode for '
            'node %(node_uuid)s. Reason: %(message)s', {
                'node_uuid': node.uuid,
                'message': message
            })
        raise exception.DracOperationError(error=message)

    return next_persistent_boot_mode
Example #3
0
def _calculate_volume_props(logical_disk, physical_disks, free_space_mb):
    selected_disks = [
        disk for disk in physical_disks
        if disk.id in logical_disk['physical_disks']
    ]

    spans_count = _calculate_spans(logical_disk['raid_level'],
                                   len(selected_disks))

    if len(selected_disks) % spans_count != 0:
        error_msg = _('invalid number of physical disks was provided')
        raise exception.DracOperationError(error=error_msg)

    disks_per_span = len(selected_disks) / spans_count

    # Best practice is to not pass span_length and span_depth when creating a
    # RAID10.  The iDRAC will dynamically calculate these values using maximum
    # values obtained from the RAID controller.
    logical_disk['span_depth'] = None
    logical_disk['span_length'] = None
    if logical_disk['raid_level'] != '1+0':
        logical_disk['span_depth'] = spans_count
        logical_disk['span_length'] = disks_per_span

    max_volume_size_mb = _max_volume_size_mb(logical_disk['raid_level'],
                                             selected_disks,
                                             free_space_mb,
                                             spans_count=spans_count)

    if logical_disk['size_mb'] == 'MAX':
        if max_volume_size_mb == 0:
            error_msg = _("size set to 'MAX' but could not allocate physical "
                          "disk space")
            raise exception.DracOperationError(error=error_msg)

        logical_disk['size_mb'] = max_volume_size_mb
    elif max_volume_size_mb < logical_disk['size_mb']:
        if max_volume_size_mb == 0:
            error_msg = _('not enough physical disk space for the logical '
                          'disk')
            raise exception.DracOperationError(error=error_msg)

    disk_usage = _volume_usage_per_disk_mb(logical_disk,
                                           selected_disks,
                                           spans_count=spans_count)

    for disk in selected_disks:
        if free_space_mb[disk] < disk_usage:
            error_msg = _('not enough free space on physical disks for the '
                          'logical disk')
            raise exception.DracOperationError(error=error_msg)
        else:
            free_space_mb[disk] -= disk_usage

    if 'controller' not in logical_disk:
        logical_disk['controller'] = selected_disks[0].controller
Example #4
0
def _calculate_volume_props(logical_disk, physical_disks, free_space_mb):
    selected_disks = [
        disk for disk in physical_disks
        if disk.id in logical_disk['physical_disks']
    ]

    spans_count = _calculate_spans(logical_disk['raid_level'],
                                   len(selected_disks))

    if len(selected_disks) % spans_count != 0:
        error_msg = _('invalid number of physical disks was provided')
        raise exception.DracOperationError(error=error_msg)

    disks_per_span = len(selected_disks) / spans_count

    logical_disk['span_depth'] = spans_count
    logical_disk['span_length'] = disks_per_span

    max_volume_size_mb = _max_volume_size_mb(logical_disk['raid_level'],
                                             selected_disks,
                                             free_space_mb,
                                             spans_count=spans_count)

    if logical_disk['size_mb'] == 'MAX':
        if max_volume_size_mb == 0:
            error_msg = _("size set to 'MAX' but could not allocate physical "
                          "disk space")
            raise exception.DracOperationError(error=error_msg)

        logical_disk['size_mb'] = max_volume_size_mb
    elif max_volume_size_mb < logical_disk['size_mb']:
        if max_volume_size_mb == 0:
            error_msg = _('not enough physical disk space for the logical '
                          'disk')
            raise exception.DracOperationError(error=error_msg)

    disk_usage = _volume_usage_per_disk_mb(logical_disk,
                                           selected_disks,
                                           spans_count=spans_count)

    for disk in selected_disks:
        if free_space_mb[disk] < disk_usage:
            error_msg = _('not enough free space on physical disks for the '
                          'logical disk')
            raise exception.DracOperationError(error=error_msg)
        else:
            free_space_mb[disk] -= disk_usage

    if 'controller' not in logical_disk:
        logical_disk['controller'] = selected_disks[0].controller
Example #5
0
def _get_boot_device(node, drac_boot_devices=None):
    client = drac_common.get_drac_client(node)

    try:
        boot_modes = client.list_boot_modes()
        next_boot_modes = [mode.id for mode in boot_modes if mode.is_next]
        if NON_PERSISTENT_BOOT_MODE in next_boot_modes:
            next_boot_mode = NON_PERSISTENT_BOOT_MODE
        else:
            next_boot_mode = next_boot_modes[0]

        if drac_boot_devices is None:
            drac_boot_devices = client.list_boot_devices()
        drac_boot_device = drac_boot_devices[next_boot_mode][0]

        boot_device = next(key for (key, value) in _BOOT_DEVICES_MAP.items()
                           if value in drac_boot_device.id)
        return {
            'boot_device': boot_device,
            'persistent': next_boot_mode == PERSISTENT_BOOT_MODE
        }
    except (drac_exceptions.BaseClientException, IndexError) as exc:
        LOG.error(
            'DRAC driver failed to get next boot mode for '
            'node %(node_uuid)s. Reason: %(error)s.', {
                'node_uuid': node.uuid,
                'error': exc
            })
        raise exception.DracOperationError(error=exc)
Example #6
0
def set_config(task, **kwargs):
    """Sets the pending_value parameter for each of the values passed in.

    :param task: a TaskManager instance containing the node to act on.
    :param kwargs: a dictionary of {'AttributeName': 'NewValue'}
    :raises: DracOperationError on an error from python-dracclient.
    :returns: A dictionary containing the commit_required key with a boolean
              value indicating whether commit_bios_config() needs to be called
              to make the changes.
    """
    node = task.node
    drac_job.validate_job_queue(node)

    client = drac_common.get_drac_client(node)
    if 'http_method' in kwargs:
        del kwargs['http_method']

    try:
        return client.set_bios_settings(kwargs)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            _LE('DRAC driver failed to set the BIOS settings for node '
                '%(node_uuid)s. Reason: %(error)s.'), {
                    'node_uuid': node.uuid,
                    'error': exc
                })
        raise exception.DracOperationError(error=exc)
Example #7
0
def commit_config(node, raid_controller, reboot=False, realtime=False):
    """Apply all pending changes on a RAID controller.

    :param node: an ironic node object.
    :param raid_controller: id of the RAID controller.
    :param reboot: indicates whether a reboot job should be automatically
                   created with the config job. (optional, defaults to False)
    :param realtime: indicates RAID controller supports realtime.
                     (optional, defaults to False)
    :returns: id of the created job
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.commit_pending_raid_changes(
            raid_controller=raid_controller, reboot=reboot, realtime=realtime)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            'DRAC driver failed to commit pending RAID config for'
            ' controller %(raid_controller_fqdd)s on node '
            '%(node_uuid)s. Reason: %(error)s.', {
                'raid_controller_fqdd': raid_controller,
                'node_uuid': node.uuid,
                'error': exc
            })
        raise exception.DracOperationError(error=exc)
Example #8
0
def _set_power_state(node, power_state):
    """Turns the server power on/off or do a reboot.

    :param node: an ironic node object.
    :param power_state: a power state from :mod:`ironic.common.states`.
    :raises: InvalidParameterValue if required DRAC credentials are missing.
    :raises: DracOperationError on an error from python-dracclient
    """

    # NOTE(ifarkas): DRAC interface doesn't allow changing the boot device
    #                multiple times in a row without a reboot. This is
    #                because a change need to be committed via a
    #                configuration job, and further configuration jobs
    #                cannot be created until the previous one is processed
    #                at the next boot. As a workaround, it is saved to
    #                driver_internal_info during set_boot_device and committing
    #                it here.
    _commit_boot_list_change(node)

    client = drac_common.get_drac_client(node)
    target_power_state = REVERSE_POWER_STATES[power_state]

    try:
        client.set_power_state(target_power_state)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            'DRAC driver failed to set power state for node '
            '%(node_uuid)s to %(power_state)s. '
            'Reason: %(error)s.', {
                'node_uuid': node.uuid,
                'power_state': power_state,
                'error': exc
            })
        raise exception.DracOperationError(error=exc)
Example #9
0
def clear_foreign_config(node, raid_controller):
    """Free up the foreign drives.

    :param node: an ironic node object.
    :param raid_controller: id of the RAID controller.
    :returns: a dictionary containing
              - The is_commit_required needed key with a
              boolean value indicating whether a config job must be created
              for the values to be applied.
              - The is_reboot_required key with a RebootRequired enumerated
              value indicating whether the server must be rebooted to
              clear foreign configuration.
    :raises: DracOperationError on an error from python-dracclient.
    """
    try:

        drac_job.validate_job_queue(node)

        client = drac_common.get_drac_client(node)
        return client.clear_foreign_config(raid_controller)
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to free foreign driver '
                  'on %(raid_controller_fqdd)s '
                  'for node %(node_uuid)s. '
                  'Reason: %(error)s.',
                  {'raid_controller_fqdd': raid_controller,
                   'node_uuid': node.uuid,
                   'error': exc})
        raise exception.DracOperationError(error=exc)
Example #10
0
def _is_raid_controller(node, raid_controller_fqdd, raid_controllers=None):
    """Find out if object's fqdd is for a raid controller or not

    :param node: an ironic node object
    :param raid_controller_fqdd: The object's fqdd we are testing to see
                                 if it is a raid controller or not.
    :param raid_controllers: A list of RAIDControllers used to check for
                             the presence of BOSS cards.  If None, the
                             iDRAC will be queried for the list of
                             controllers.
    :returns: boolean, True if the device is a RAID controller,
              False if not.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.is_raid_controller(raid_controller_fqdd,
                                         raid_controllers)
    except drac_exceptions.BaseClientException as exc:
        LOG.error('Unable to determine if controller %(raid_controller_fqdd)s '
                  'on node %(node_uuid)s is a RAID controller. '
                  'Reason: %(error)s. ',
                  {'raid_controller_fqdd': raid_controller_fqdd,
                   'node_uuid': node.uuid, 'error': exc})

        raise exception.DracOperationError(error=exc)
Example #11
0
def delete_virtual_disk(node, virtual_disk):
    """Delete a single virtual disk on a RAID controller.

    The deleted virtual disk will be in pending state. The DRAC card will do
    the actual configuration once the changes are applied by calling the
    ``commit_config`` method.

    :param node: an ironic node object.
    :param virtual_disk: id of the virtual disk.
    :returns: a dictionary containing the commit_needed key with a boolean
              value indicating whether a config job must be created for the
              values to be applied.
    :raises: DracOperationError on an error from python-dracclient.
    """
    drac_job.validate_job_queue(node)

    client = drac_common.get_drac_client(node)

    try:
        return client.delete_virtual_disk(virtual_disk)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            _LE('DRAC driver failed to delete virtual disk '
                '%(virtual_disk_fqdd)s for node %(node_uuid)s. '
                'Reason: %(error)s.'), {
                    'virtual_disk_fqdd': virtual_disk,
                    'node_uuid': node.uuid,
                    'error': exc
                })
        raise exception.DracOperationError(error=exc)
Example #12
0
    def test_list_unfinished_jobs_fail(self, mock_get_drac_client):
        mock_client = mock.Mock()
        mock_get_drac_client.return_value = mock_client
        exc = exception.DracOperationError('boom')
        mock_client.list_jobs.side_effect = exc

        self.assertRaises(exception.DracOperationError,
                          drac_job.list_unfinished_jobs, self.node)
Example #13
0
    def test_get_job_fail(self, mock_get_drac_client):
        mock_client = mock.Mock()
        mock_get_drac_client.return_value = mock_client
        exc = exception.DracOperationError('boom')
        mock_client.get_job.side_effect = exc

        self.assertRaises(exception.DracOperationError, drac_job.get_job,
                          self.node, 'foo')
Example #14
0
def _raid_level_overhead(raid_level, spans_count=1):
    try:
        raid_level_info = RAID_LEVELS[raid_level]
    except KeyError:
        reason = (_('RAID level %(raid_level)s is not supported by the '
                    'driver. Supported RAID levels: %(supported_raid_levels)s')
                  % {'raid_level': raid_level,
                     'supported_raid_levels': list(RAID_LEVELS)})
        raise exception.DracOperationError(error=reason)

    if raid_level_info['type'] == 'spanned':
        if spans_count <= 1:
            reason = _('Spanned RAID volumes cannot contain a single span')
            raise exception.DracOperationError(error=reason)

        span_type = raid_level_info['span_type']
        raid_level_info = RAID_LEVELS[span_type]

    return raid_level_info['overhead'] * spans_count
Example #15
0
    def test_list_unfinished_jobs_fail(self, mock_get_drac_client):
        mock_client = mock.Mock()
        mock_get_drac_client.return_value = mock_client
        exc = exception.DracOperationError('boom')
        mock_client.list_jobs.side_effect = exc

        with task_manager.acquire(self.context, self.node.uuid,
                                  shared=False) as task:
            self.assertRaises(exception.DracOperationError,
                              task.driver.vendor.list_unfinished_jobs, task)
Example #16
0
def set_boot_device(node, device, persistent=False):
    """Set the boot device for a node.

    Set the boot device to use on next boot of the node.

    :param node: an ironic node object.
    :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: DracOperationError on an error from python-dracclient.
    """

    drac_job.validate_job_queue(node)

    client = drac_common.get_drac_client(node)

    try:
        drac_boot_devices = client.list_boot_devices()

        current_boot_device = _get_boot_device(node, drac_boot_devices)
        # If we are already booting from the right device, do nothing.
        if current_boot_device == {
                'boot_device': device,
                'persistent': persistent
        }:
            LOG.debug('DRAC already set to boot from %s', device)
            return

        drac_boot_device = next(
            drac_device.id
            for drac_device in drac_boot_devices[PERSISTENT_BOOT_MODE]
            if _BOOT_DEVICES_MAP[device] in drac_device.id)

        if persistent:
            boot_list = PERSISTENT_BOOT_MODE
        else:
            boot_list = NON_PERSISTENT_BOOT_MODE

        client.change_boot_device_order(boot_list, drac_boot_device)
        client.commit_pending_bios_changes()
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            'DRAC driver failed to change boot device order for '
            'node %(node_uuid)s. Reason: %(error)s.', {
                'node_uuid': node.uuid,
                'error': exc
            })
        raise exception.DracOperationError(error=exc)
Example #17
0
def validate_job_queue(node):
    """Validates the job queue on the node.

    It raises an exception if an unfinished configuration job exists.

    :param node: an ironic node object.
    :raises: DracOperationError on an error from python-dracclient.
    """

    unfinished_jobs = list_unfinished_jobs(node)
    if unfinished_jobs:
        msg = _('Unfinished config jobs found: %(jobs)r. Make sure they are '
                'completed before retrying.') % {'jobs': unfinished_jobs}
        raise exception.DracOperationError(error=msg)
    def test_set_boot_device_with_invalid_job_queue(
            self, mock_validate_job_queue, mock_get_drac_client):
        mock_client = mock.Mock()
        mock_get_drac_client.return_value = mock_client
        mock_validate_job_queue.side_effect = exception.DracOperationError(
            'boom')

        self.assertRaises(exception.DracOperationError,
                          drac_mgmt.set_boot_device, self.node,
                          ironic.common.boot_devices.PXE, persistent=True)

        self.assertEqual(0, mock_client.change_boot_device_order.call_count)
        self.assertEqual(0, mock_client.set_bios_settings.call_count)
        self.assertEqual(0, mock_client.commit_pending_bios_changes.call_count)
Example #19
0
def list_raid_controllers(node):
    """List the RAID controllers of the node.

    :param node: an ironic node object.
    :returns: a list of RAIDController objects from dracclient.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.list_raid_controllers()
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to get the list of RAID controllers '
                  'for node %(node_uuid)s. Reason: %(error)s.',
                  {'node_uuid': node.uuid, 'error': exc})
        raise exception.DracOperationError(error=exc)
Example #20
0
def _calculate_spans(raid_level, disks_count):
    """Calculates number of spans for a RAID level given a physical disk count

    :param raid_level: RAID level of the virtual disk.
    :param disk_count: number of physical disks used for the virtual disk.
    :returns: number of spans.
    """
    if raid_level in ['0', '1', '5', '6']:
        return 1
    elif raid_level in ['5+0', '6+0']:
        return 2
    elif raid_level in ['1+0']:
        return disks_count >> 1
    else:
        reason = (_('Cannot calculate spans for RAID level "%s"') % raid_level)
        raise exception.DracOperationError(error=reason)
Example #21
0
    def clear_job_queue(self, task):
        """Clear the job queue.

        :param task: a TaskManager instance containing the node to act on.
        :returns: None if it is completed.
        :raises: DracOperationError on an error from python-dracclient.
        """
        try:
            node = task.node

            client = drac_common.get_drac_client(node)
            client.delete_jobs(job_ids=[_CLEAR_JOB_IDS])
        except drac_exceptions.BaseClientException as exc:
            LOG.error('DRAC driver failed to clear the job queue for node '
                      '%(node_uuid)s. Reason: %(error)s.',
                      {'node_uuid': node.uuid, 'error': exc})
            raise exception.DracOperationError(error=exc)
Example #22
0
def abandon_config(task):
    """Abandons uncommitted changes added by set_config

    :param task: a TaskManager instance containing the node to act on.
    :raises: DracOperationError on an error from python-dracclient.
    """
    node = task.node
    client = drac_common.get_drac_client(node)

    try:
        client.abandon_pending_bios_changes()
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to delete the pending BIOS '
                  'settings for node %(node_uuid)s. Reason: %(error)s.',
                  {'node_uuid': node.uuid,
                   'error': exc})
        raise exception.DracOperationError(error=exc)
Example #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: DracOperationError on an error from python-dracclient
        """
        node = task.node
        node_id = node.id
        node_uuid = node.uuid

        client = drac_common.get_drac_client(node)

        try:
            kwsettings = client.list_bios_settings()
        except drac_exceptions.BaseClientException as exc:
            LOG.error(
                'DRAC driver failed to get the BIOS settings for node '
                '%(node_uuid)s. Reason: %(error)s.', {
                    'node_uuid': node.uuid,
                    'error': exc
                })
            raise exception.DracOperationError(error=exc)

        # convert dracclient BIOS settings into ironic settings list
        settings = [{
            "name": name,
            "value": attrib.current_value
        } for name, attrib in kwsettings.items()]

        # Store them in the database table
        LOG.debug('Caching BIOS settings for node %(node_uuid)s',
                  {'node_uuid': 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 #24
0
def list_unfinished_jobs(node):
    """List unfinished config jobs of the node.

    :param node: an ironic node object.
    :returns: a list of Job objects from dracclient.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.list_jobs(only_unfinished=True)
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to get the list of unfinished jobs '
                  'for node %(node_uuid)s. Reason: %(error)s.',
                  {'node_uuid': node.uuid,
                   'error': exc})
        raise exception.DracOperationError(error=exc)
Example #25
0
def get_job(node, job_id):
    """Get the details of a Lifecycle job of the node.

    :param node: an ironic node object.
    :param job_id: ID of the Lifecycle job.
    :returns: a Job object from dracclient.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.get_job(job_id)
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to get the job %(job_id)s '
                  'for node %(node_uuid)s. Reason: %(error)s.',
                  {'node_uuid': node.uuid,
                   'error': exc})
        raise exception.DracOperationError(error=exc)
Example #26
0
def wait_for_job_completion(node, retries=CONF.drac.config_job_max_retries):
    """Wait for job to complete

    It will wait for the job to complete for 20 minutes and raises timeout
    if job never complete within given interval of time.
    :param node: an ironic node object.
    :param retries: no of retries to make conductor wait.
    :raises: DracOperationError on exception raised from python-dracclient
    or a timeout while waiting for job completion.
    """
    if not list_unfinished_jobs(node):
        return
    err_msg = _('There are unfinished jobs in the job '
                'queue on node %(node_uuid)s.') % {
                    'node_uuid': node.uuid
                }
    LOG.warning(err_msg)
    raise exception.DracOperationError(error=err_msg)
Example #27
0
def _set_power_state(node, target_state):
    """Turns the server power on/off or do a reboot.

    :param node: an ironic node object.
    :param target_state: target state of the node.
    :raises: DracClientError if the client received unexpected response.
    :raises: InvalidParameterValue if an invalid power state was specified.
    """

    client = drac_common.get_wsman_client(node)
    options = pywsman.ClientOptions()
    options.add_selector('CreationClassName', 'DCIM_ComputerSystem')
    options.add_selector('Name', 'srv:system')
    options.add_property('RequestedState', REVERSE_POWER_STATES[target_state])

    try:
        root = client.wsman_invoke(resource_uris.DCIM_ComputerSystem, options,
                                   'RequestStateChange')
    except exception.DracClientError as exc:
        with excutils.save_and_reraise_exception():
            LOG.error(
                _LE('DRAC driver failed to set power state for node '
                    '%(node_uuid)s to %(target_power_state)s. '
                    'Reason: %(error)s.'), {
                        'node_uuid': node.uuid,
                        'target_power_state': target_state,
                        'error': exc
                    })

    return_value = drac_common.find_xml(root, 'ReturnValue',
                                        resource_uris.DCIM_ComputerSystem).text
    if return_value != drac_common.RET_SUCCESS:
        message = drac_common.find_xml(root, 'Message',
                                       resource_uris.DCIM_ComputerSystem).text
        LOG.error(
            _LE('DRAC driver failed to set power state for node '
                '%(node_uuid)s to %(target_power_state)s. '
                'Reason: %(error)s.'), {
                    'node_uuid': node.uuid,
                    'target_power_state': target_state,
                    'error': message
                })
        raise exception.DracOperationError(operation='set_power_state',
                                           error=message)
Example #28
0
def abandon_config(node, raid_controller):
    """Deletes all pending changes on a RAID controller.

    :param node: an ironic node object.
    :param raid_controller: id of the RAID controller.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        client.abandon_pending_raid_changes(raid_controller)
    except drac_exceptions.BaseClientException as exc:
        LOG.error('DRAC driver failed to delete pending RAID config '
                  'for controller %(raid_controller_fqdd)s on node '
                  '%(node_uuid)s. Reason: %(error)s.',
                  {'raid_controller_fqdd': raid_controller,
                   'node_uuid': node.uuid,
                   'error': exc})
        raise exception.DracOperationError(error=exc)
Example #29
0
def list_physical_disks(node):
    """List the physical disks of the node.

    :param node: an ironic node object.
    :returns: a list of PhysicalDisk objects from dracclient.
    :raises: DracOperationError on an error from python-dracclient.
    """
    client = drac_common.get_drac_client(node)

    try:
        return client.list_physical_disks()
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            _LE('DRAC driver failed to get the list of physical disks '
                'for node %(node_uuid)s. Reason: %(error)s.'), {
                    'node_uuid': node.uuid,
                    'error': exc
                })
        raise exception.DracOperationError(error=exc)
Example #30
0
def create_virtual_disk(node,
                        raid_controller,
                        physical_disks,
                        raid_level,
                        size_mb,
                        disk_name=None,
                        span_length=None,
                        span_depth=None):
    """Create a single virtual disk on a RAID controller.

    The created virtual disk will be in pending state. The DRAC card will do
    the actual configuration once the changes are applied by calling the
    ``commit_config`` method.

    :param node: an ironic node object.
    :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_mb: 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)
    :returns: a dictionary containing the commit_needed key with a boolean
              value indicating whether a config job must be created for the
              values to be applied.
    :raises: DracOperationError on an error from python-dracclient.
    """
    drac_job.validate_job_queue(node)

    client = drac_common.get_drac_client(node)

    try:
        return client.create_virtual_disk(raid_controller, physical_disks,
                                          raid_level, size_mb, disk_name,
                                          span_length, span_depth)
    except drac_exceptions.BaseClientException as exc:
        LOG.error(
            _LE('DRAC driver failed to create virtual disk for node '
                '%(node_uuid)s. Reason: %(error)s.'), {
                    'node_uuid': node.uuid,
                    'error': exc
                })
        raise exception.DracOperationError(error=exc)