Example #1
0
def eject_vmedia_devices(task):
    """Ejects virtual media devices.

    This method ejects virtual media floppy and cdrom.

    :param task: a TaskManager instance containing the node to act on.
    :returns: None
    :raises: IloOperationError, if some error was encountered while
        trying to eject virtual media floppy or cdrom.
    """
    ilo_object = get_ilo_object(task.node)
    for device in ('FLOPPY', 'CDROM'):
        try:
            ilo_object.eject_virtual_media(device)
        except ilo_error.IloError as ilo_exception:
            LOG.error(
                _LE("Error while ejecting virtual media %(device)s "
                    "from node %(uuid)s. Error: %(error)s"), {
                        'device': device,
                        'uuid': task.node.uuid,
                        'error': ilo_exception
                    })
            operation = _("Eject virtual media %s") % device.lower()
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
Example #2
0
def clear_certificates(task, cert_file_list=None):
    """Clears any certificates added to the node.

    Clears the certificates added to the node as part of any Ironic
    operation

    :param task: a TaskManager instance containing the node to act on.
    :param cert_file_list: List of certificates to be removed from node.
        If None, all the certificates present on the node will be removed.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if retrieving post state is not
        supported on the server.
    """

    node = task.node
    operation = (_("Clearing certificates from node %(node)s.") % {
        'node': node.uuid
    })

    try:
        ilo_object = get_ilo_object(node)
        ilo_object.remove_tls_certificate(cert_file_list)
    except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
    LOG.info(
        "Cleared TLS certificates from the node %(node)s "
        "successfully from paths %(cpath)s.", {
            'node': node.uuid,
            'cpath': cert_file_list
        })
Example #3
0
def _get_power_state(node):
    """Returns the current power state of the node.

    :param node: The node.
    :returns: power state, one of :mod: `ironic.common.states`.
    :raises: InvalidParameterValue if required iLO credentials are missing.
    :raises: IloOperationError on an error from IloClient library.
    """

    ilo_object = ilo_common.get_ilo_object(node)

    # Check the current power state.
    try:
        power_status = ilo_object.get_host_power_status()

    except ilo_error.IloError as ilo_exception:
        LOG.error(
            "iLO get_power_state failed for node %(node_id)s with "
            "error: %(error)s.", {
                'node_id': node.uuid,
                'error': ilo_exception
            })
        operation = _('iLO get_power_status')
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    if power_status == "ON":
        return states.POWER_ON
    elif power_status == "OFF":
        return states.POWER_OFF
    else:
        return states.ERROR
Example #4
0
def set_boot_mode(node, boot_mode):
    """Sets the node to boot using boot_mode for the next boot.

    :param node: an ironic node object.
    :param boot_mode: Next boot mode.
    :raises: IloOperationError if setting boot mode failed.
    """
    ilo_object = get_ilo_object(node)

    try:
        p_boot_mode = ilo_object.get_pending_boot_mode()
    except ilo_error.IloCommandNotSupportedError:
        p_boot_mode = DEFAULT_BOOT_MODE

    if BOOT_MODE_ILO_TO_GENERIC[p_boot_mode.lower()] == boot_mode:
        LOG.info(_LI("Node %(uuid)s pending boot mode is %(boot_mode)s."), {
            'uuid': node.uuid,
            'boot_mode': boot_mode
        })
        return

    try:
        ilo_object.set_pending_boot_mode(
            BOOT_MODE_GENERIC_TO_ILO[boot_mode].upper())
    except ilo_error.IloError as ilo_exception:
        operation = _("Setting %s as boot mode") % boot_mode
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    LOG.info(_LI("Node %(uuid)s boot mode is set to %(boot_mode)s."), {
        'uuid': node.uuid,
        'boot_mode': boot_mode
    })
Example #5
0
def get_ilo_license(node):
    """Gives the current installed license on the node.

    Given an ironic node object, this method queries the iLO
    for currently installed license and returns it back.

    :param node: an ironic node object.
    :returns: a constant defined in this module which
        refers to the current license installed on the node.
    :raises: InvalidParameterValue on invalid inputs.
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    :raises: IloOperationError if it failed to retrieve the
        installed licenses from the iLO.
    """
    # Get the ilo client object, and then the license from the iLO
    ilo_object = get_ilo_object(node)
    try:
        license_info = ilo_object.get_all_licenses()
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=_('iLO license check'),
                                          error=str(ilo_exception))

    # Check the license to see if the given license exists
    current_license_type = license_info['LICENSE_TYPE']

    if current_license_type.endswith("Advanced"):
        return ADVANCED_LICENSE
    elif current_license_type.endswith("Essentials"):
        return ESSENTIALS_LICENSE
    else:
        return STANDARD_LICENSE
Example #6
0
def get_secure_boot_mode(task):
    """Retrieves current enabled state of UEFI secure boot on the node

    Returns the current enabled state of UEFI secure boot on the node.

    :param task: a task from TaskManager.
    :raises: MissingParameterValue if a required iLO parameter is missing.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if UEFI secure boot is not supported.
    :returns: Boolean value indicating current state of UEFI secure boot
              on the node.
    """

    operation = _("Get secure boot mode for node %s.") % task.node.uuid
    secure_boot_state = False
    ilo_object = get_ilo_object(task.node)

    try:
        current_boot_mode = ilo_object.get_current_boot_mode()
        if current_boot_mode == 'UEFI':
            secure_boot_state = ilo_object.get_secure_boot_mode()

    except ilo_error.IloCommandNotSupportedError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    LOG.debug("Get secure boot mode for node %(node)s returned %(value)s", {
        'value': secure_boot_state,
        'node': task.node.uuid
    })
    return secure_boot_state
Example #7
0
def set_secure_boot_mode(task, flag):
    """Enable or disable UEFI Secure Boot for the next boot

    Enable or disable UEFI Secure Boot for the next boot

    :param task: a task from TaskManager.
    :param flag: Boolean value. True if the secure boot to be
                       enabled in next boot.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if UEFI secure boot is not supported.
    """

    operation = (_("Setting secure boot to %(flag)s for node %(node)s.") % {
        'flag': flag,
        'node': task.node.uuid
    })
    ilo_object = get_ilo_object(task.node)

    try:
        ilo_object.set_secure_boot_mode(flag)
        LOG.debug(operation)

    except ilo_error.IloCommandNotSupportedError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)

    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
Example #8
0
def update_boot_mode(task):
    """Update instance_info with boot mode to be used for deploy.

    This method updates instance_info with boot mode to be used for
    deploy if node properties['capabilities'] do not have boot_mode.
    It sets the boot mode on the node.

    :param task: Task object.
    :raises: IloOperationError if setting boot mode failed.
    """

    node = task.node
    boot_mode = deploy_utils.get_boot_mode_for_deploy(node)

    if boot_mode is not None:
        LOG.debug("Node %(uuid)s boot mode is being set to %(boot_mode)s", {
            'uuid': node.uuid,
            'boot_mode': boot_mode
        })
        set_boot_mode(node, boot_mode)
        return

    LOG.debug("Check pending boot mode for node %s.", node.uuid)
    ilo_object = get_ilo_object(node)

    try:
        boot_mode = ilo_object.get_pending_boot_mode()
    except ilo_error.IloCommandNotSupportedError:
        boot_mode = 'legacy'

    if boot_mode != 'UNKNOWN':
        boot_mode = BOOT_MODE_ILO_TO_GENERIC[boot_mode.lower()]

    if boot_mode == 'UNKNOWN':
        # NOTE(faizan) ILO will return this in remote cases and mostly on
        # the nodes which supports UEFI. Such nodes mostly comes with UEFI
        # as default boot mode. So we will try setting bootmode to UEFI
        # and if it fails then we fall back to BIOS boot mode.
        try:
            boot_mode = 'uefi'
            ilo_object.set_pending_boot_mode(
                BOOT_MODE_GENERIC_TO_ILO[boot_mode].upper())
        except ilo_error.IloError as ilo_exception:
            operation = _("Setting %s as boot mode") % boot_mode
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)

        LOG.debug(
            "Node %(uuid)s boot mode is being set to %(boot_mode)s "
            "as pending boot mode is unknown.", {
                'uuid': node.uuid,
                'boot_mode': boot_mode
            })

    instance_info = node.instance_info
    instance_info['deploy_boot_mode'] = boot_mode
    node.instance_info = instance_info
    node.save()
Example #9
0
    def set_iscsi_boot_target(self, task):
        """Set iSCSI details of the system in UEFI boot mode.

        The initiator is set with the target details like
        IQN, LUN, IP, Port etc.
        :param task: a task from TaskManager.
        :raises: MissingParameterValue if a required parameter is missing.
        :raises: IloCommandNotSupportedInBiosError if system in BIOS boot mode.
        :raises: IloError on an error from iLO.
        """
        # Getting target info
        node = task.node
        macs = [port['address'] for port in task.ports]
        boot_volume = node.driver_internal_info.get('boot_from_volume')
        volume = volume_target.VolumeTarget.get_by_uuid(
            task.context, boot_volume)
        properties = volume.properties
        username = properties.get('auth_username')
        password = properties.get('auth_password')
        try:
            portal = properties['target_portal']
            iqn = properties['target_iqn']
            lun = properties['target_lun']
            host, port = portal.split(':')
        except KeyError as e:
            raise exception.MissingParameterValue(
                _('Failed to get iSCSI target info for node '
                  '%(node)s. Error: %(error)s') % {
                      'node': task.node.uuid,
                      'error': e
                  })
        ilo_object = ilo_common.get_ilo_object(task.node)
        try:
            auth_method = 'CHAP' if username else None
            ilo_object.set_iscsi_info(iqn,
                                      lun,
                                      host,
                                      port,
                                      auth_method=auth_method,
                                      username=username,
                                      password=password,
                                      macs=macs)
        except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
            operation = (_("Setting of target IQN %(target_iqn)s for node "
                           "%(node)s") % {
                               'target_iqn': iqn,
                               'node': node.uuid
                           })
            raise exception.IloOperationNotSupported(operation=operation,
                                                     error=ilo_exception)
        except ilo_error.IloError as ilo_exception:
            operation = (_("Setting of target IQN %(target_iqn)s for node "
                           "%(node)s") % {
                               'target_iqn': iqn,
                               'node': node.uuid
                           })
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
Example #10
0
def _set_power_state(task, target_state):
    """Turns the server power on/off or do a reboot.

    :param task: a TaskManager instance containing the node to act on.
    :param target_state: target state of the node.
    :raises: InvalidParameterValue if an invalid power state was specified.
    :raises: IloOperationError on an error from IloClient library.
    :raises: PowerStateFailure if the power couldn't be set to target_state.
    """

    node = task.node
    ilo_object = ilo_common.get_ilo_object(node)

    # Trigger the operation based on the target state.
    try:
        if target_state == states.POWER_OFF:
            ilo_object.hold_pwr_btn()
        elif target_state == states.POWER_ON:
            _attach_boot_iso(task)
            ilo_object.set_host_power('ON')
        elif target_state == states.REBOOT:
            _attach_boot_iso(task)
            ilo_object.reset_server()
            target_state = states.POWER_ON
        else:
            msg = _("_set_power_state called with invalid power state "
                    "'%s'") % target_state
            raise exception.InvalidParameterValue(msg)

    except ilo_client.IloError as ilo_exception:
        LOG.error(
            _LE("iLO set_power_state failed to set state to %(tstate)s "
                " for node %(node_id)s with error: %(error)s"), {
                    'tstate': target_state,
                    'node_id': node.uuid,
                    'error': ilo_exception
                })
        operation = _('iLO set_power_state')
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    # Wait till the state change gets reflected.
    state = _wait_for_state_change(node, target_state)

    if state != target_state:
        timeout = (CONF.ilo.power_wait) * (CONF.ilo.power_retry)
        LOG.error(
            _LE("iLO failed to change state to %(tstate)s "
                "within %(timeout)s sec"), {
                    'tstate': target_state,
                    'timeout': timeout
                })
        raise exception.PowerStateFailure(pstate=target_state)
Example #11
0
def setup_uefi_https(task, iso, persistent=False):
    """Sets up system to boot from UEFIHTTP boot device.

    Sets the one-time/persistent boot device to UEFIHTTP based
    on the argument supplied.

    :param task: a TaskManager instance containing the node to act on.
    :param iso: ISO URL to be set to boot from.
    :param persistent: Indicates whether the system should be set to boot
        from the given device one-time or each time.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if retrieving post state is not
        supported on the server.
    """
    node = task.node
    ilo_object = get_ilo_object(node)
    scheme = urlparse.urlparse(iso).scheme.lower()

    operation = (_("Setting up node %(node)s to boot from URL %(iso)s.") % {
        'iso': iso,
        'node': node.uuid
    })

    if scheme != 'https':
        msg = (_('Error setting up node %(node)s to boot from '
                 'URL %(iso)s. A secure URL is expected that is exposed '
                 'over HTTPS.') % {
                     'node': node.uuid,
                     'iso': iso
                 })
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=msg)

    try:
        ilo_object.set_http_boot_url(iso)
        LOG.info(
            "Set the node %(node)s to boot from URL %(iso)s "
            "successfully.", {
                'node': node.uuid,
                'iso': iso
            })
        if not persistent:
            ilo_object.set_one_time_boot('UEFIHTTP')
        else:
            ilo_object.update_persistent_boot(['UEFIHTTP'])

    except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
Example #12
0
def get_current_boot_mode(node):
    """Get the current boot mode for a node.

    :param node: an ironic node object.
    :raises: IloOperationError if failed to fetch boot mode.
    :raises: IloOperationNotSupported if node does not support getting pending
             boot mode.
    """
    ilo_object = get_ilo_object(node)
    operation = _("Get current boot mode")
    try:
        c_boot_mode = ilo_object.get_current_boot_mode()
        return BOOT_MODE_ILO_TO_GENERIC[c_boot_mode.lower()]
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
Example #13
0
def attach_vmedia(node, device, url):
    """Attaches the given url as virtual media on the node.

    :param node: an ironic node object.
    :param device: the virtual media device to attach
    :param url: the http/https url to attach as the virtual media device
    :raises: IloOperationError if insert virtual media failed.
    """
    ilo_object = get_ilo_object(node)

    try:
        ilo_object.insert_virtual_media(url, device=device)
        ilo_object.set_vm_status(device=device, boot_option='CONNECT',
                write_protect='YES')
    except ilo_client.IloError as ilo_exception:
        operation = _("Inserting virtual media %s") % device
        raise exception.IloOperationError(operation=operation,
                error=ilo_exception)

    LOG.info(_LI("Attached virtual media %s successfully."), device)
Example #14
0
    def clear_iscsi_boot_target(self, task):
        """Unset iSCSI details of the system in UEFI boot mode.

        :param task: a task from TaskManager.
        :raises: IloCommandNotSupportedInBiosError if system in BIOS boot mode.
        :raises: IloError on an error from iLO.
        """
        ilo_object = ilo_common.get_ilo_object(task.node)
        try:
            ilo_object.unset_iscsi_info()
        except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
            operation = (_("Unsetting of iSCSI target for node %(node)s")
                         % {'node': task.node.uuid})
            raise exception.IloOperationNotSupported(operation=operation,
                                                     error=ilo_exception)
        except ilo_error.IloError as ilo_exception:
            operation = (_("Unsetting of iSCSI target for node %(node)s")
                         % {'node': task.node.uuid})
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
Example #15
0
    def get_boot_device(self, task):
        """Get the current boot device for a node.

        Returns the current boot device of the node.

        :param task: a task from TaskManager.
        :raises: MissingParameterValue if a required iLO parameter is missing.
        :raises: IloOperationError on an error from IloClient library.
        :returns: a dictionary containing:

            :boot_device:
                the boot device, one of the supported devices listed in
                :mod:`ironic.common.boot_devices` or None if it is unknown.
            :persistent:
                Whether the boot device will persist to all future boots or
                not, None if it is unknown.

        """
        ilo_object = ilo_common.get_ilo_object(task.node)
        persistent = False

        try:
            # Return one time boot device if set, else return
            # the persistent boot device
            next_boot = ilo_object.get_one_time_boot()
            if next_boot == 'Normal':
                # One time boot is not set. Check for persistent boot.
                persistent = True
                next_boot = ilo_object.get_persistent_boot_device()

        except ilo_error.IloError as ilo_exception:
            operation = _("Get boot device")
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)

        boot_device = BOOT_DEVICE_ILO_TO_GENERIC.get(next_boot, None)

        if boot_device is None:
            persistent = None

        return {'boot_device': boot_device, 'persistent': persistent}
Example #16
0
def get_server_post_state(node):
    """Get the current state of system POST.

    :param node: an ironic node object.
    :returns: POST state of the server. The valida states are:-
        null, Unknown, Reset, PowerOff, InPost, InPostDiscoveryComplete
        and FinishedPost.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if retrieving post state is not
        supported on the server.
    """
    ilo_object = get_ilo_object(node)
    operation = _("Get server post state for node %s.") % node.uuid
    try:
        return ilo_object.get_host_post_state()
    except ilo_error.IloCommandNotSupportedError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
Example #17
0
def set_boot_device(node, device, persistent=False):
    """Sets the node to boot from a device for the next boot.

    :param node: an ironic node object.
    :param device: the device to boot from
    :raises: IloOperationError if setting boot device failed.
    """
    ilo_object = get_ilo_object(node)

    try:
        if not persistent:
            ilo_object.set_one_time_boot(device)
        else:
            ilo_object.update_persistent_boot([device])
    except ilo_client.IloError as ilo_exception:
        operation = _("Setting %s as boot device") % device
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    LOG.debug("Node %(uuid)s set to boot from %(device)s.",
             {'uuid': node.uuid, 'device': device})
Example #18
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 the supported devices
                       listed in :mod:`ironic.common.boot_devices`.
        :param persistent: Boolean value. True if the boot device will
                           persist to all future boots, False if not.
                           Default: False.
        :raises: InvalidParameterValue if an invalid boot device is
                 specified.
        :raises: MissingParameterValue if a required parameter is missing.
        :raises: IloOperationError on an error from IloClient library.
        """

        try:
            boot_device = BOOT_DEVICE_MAPPING_TO_ILO[device]
        except KeyError:
            raise exception.InvalidParameterValue(
                _("Invalid boot device %s specified.") % device)
        try:
            ilo_object = ilo_common.get_ilo_object(task.node)

            if not persistent:
                ilo_object.set_one_time_boot(boot_device)
            else:
                ilo_object.update_persistent_boot([boot_device])

        except ilo_error.IloError as ilo_exception:
            operation = _("Setting %s as boot device") % device
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)

        LOG.debug("Node %(uuid)s set to boot from %(device)s.", {
            'uuid': task.node.uuid,
            'device': device
        })
Example #19
0
    def get_supported_boot_modes(self, task):
        """Get a list of the supported boot devices.

        :param task: a task from TaskManager.
        :raises: IloOperationError if any exception happens in proliantutils
        :returns: A list with the supported boot devices defined
                  in :mod:`ironic.common.boot_devices`.
        """
        node = task.node
        ilo_object = ilo_common.get_ilo_object(node)
        try:
            modes = ilo_object.get_supported_boot_mode()
            if modes == ilo_common.SUPPORTED_BOOT_MODE_LEGACY_BIOS_ONLY:
                return [boot_modes.LEGACY_BIOS]
            elif modes == ilo_common.SUPPORTED_BOOT_MODE_UEFI_ONLY:
                return [boot_modes.UEFI]
            elif modes == ilo_common.SUPPORTED_BOOT_MODE_LEGACY_BIOS_AND_UEFI:
                return [boot_modes.UEFI, boot_modes.LEGACY_BIOS]
        except ilo_error.IloError as ilo_exception:
            operation = _("Get supported boot modes")
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
Example #20
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: IloCommandNotSupportedError if system does not support
            NMI injection.
        :raises: IloError on an error from iLO.
        :returns: None
        """
        node = task.node
        ilo_object = ilo_common.get_ilo_object(node)
        try:
            operation = (_("Injecting NMI for node %(node)s")
                         % {'node': node.uuid})
            ilo_object.inject_nmi()
        except ilo_error.IloCommandNotSupportedError as ilo_exception:
            raise exception.IloOperationNotSupported(operation=operation,
                                                     error=ilo_exception)
        except ilo_error.IloError as ilo_exception:
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
Example #21
0
def _extract_fw_from_file(node, target_file):
    """Extracts firmware image file.

    Extracts the firmware image file thru proliantutils and uploads it to the
    conductor webserver, if needed.
    :param node: an Ironic node object.
    :param target_file: firmware file to be extracted from
    :returns: tuple of:
                a) wrapper object of raw firmware image location
                b) a boolean, depending upon whether the raw firmware file was
                   already in raw format(same file remains, no need to extract)
                   or compact format (thereby extracted and hence different
                   file). If uploaded then, then also its a different file.
    :raises: ImageUploadFailed, if upload to web server fails.
    :raises: SwiftOperationError, if upload to Swift fails.
    :raises: IloOperationError, on failure to process firmware file.
    """
    ilo_object = ilo_common.get_ilo_object(node)

    try:
        # Note(deray): Based upon different iLO firmwares, the firmware file
        # which needs to be updated has to be either an http/https or a simple
        # file location. If it has to be a http/https location, then conductor
        # will take care of uploading the firmware file to web server or
        # swift (providing a temp url).
        fw_image_location, to_upload, is_extracted = (
            proliantutils_utils.process_firmware_image(target_file,
                                                       ilo_object))
    except (proliantutils_error.InvalidInputError,
            proliantutils_error.ImageExtractionFailed) as proliantutils_exc:
        operation = _("Firmware file extracting as part of manual cleaning")
        raise exception.IloOperationError(operation=operation,
                                          error=proliantutils_exc)

    is_different_file = is_extracted
    fw_image_filename = os.path.basename(fw_image_location)
    fw_image_location_obj = FirmwareImageLocation(fw_image_location,
                                                  fw_image_filename)
    if to_upload:
        is_different_file = True
        try:
            if CONF.ilo.use_web_server_for_images:
                # upload firmware image file to conductor webserver
                LOG.debug(
                    "For firmware update on node %(node)s, hosting "
                    "firmware file %(firmware_image)s on web server ...", {
                        'firmware_image': fw_image_location,
                        'node': node.uuid
                    })
                fw_image_uploaded_url = ilo_common.copy_image_to_web_server(
                    fw_image_location, fw_image_filename)

                fw_image_location_obj.fw_image_location = fw_image_uploaded_url
                fw_image_location_obj.remove = types.MethodType(
                    _remove_webserver_based_me, fw_image_location_obj)
            else:
                # upload firmware image file to swift
                LOG.debug(
                    "For firmware update on node %(node)s, hosting "
                    "firmware file %(firmware_image)s on swift ...", {
                        'firmware_image': fw_image_location,
                        'node': node.uuid
                    })
                fw_image_uploaded_url = ilo_common.copy_image_to_swift(
                    fw_image_location, fw_image_filename)

                fw_image_location_obj.fw_image_location = fw_image_uploaded_url
                fw_image_location_obj.remove = types.MethodType(
                    _remove_swift_based_me, fw_image_location_obj)
        finally:
            if is_extracted:
                # Note(deray): remove the file `fw_image_location` irrespective
                # of status of uploading (success or failure) and only if
                # extracted (and not passed as in plain binary format). If the
                # file is passed in binary format, then the invoking method
                # takes care of handling the deletion of the file.
                ilo_common.remove_single_or_list_of_files(fw_image_location)

        LOG.debug(
            "For firmware update on node %(node)s, hosting firmware "
            "file: %(fw_image_location)s ... done. Hosted firmware "
            "file: %(fw_image_uploaded_url)s", {
                'fw_image_location': fw_image_location,
                'node': node.uuid,
                'fw_image_uploaded_url': fw_image_uploaded_url
            })
    else:
        fw_image_location_obj.remove = types.MethodType(
            _remove_file_based_me, fw_image_location_obj)

    return fw_image_location_obj, is_different_file
Example #22
0
    def inspect_hardware(self, task):
        """Inspect hardware to get the hardware properties.

        Inspects hardware to get the essential and additional hardware
        properties. It fails if any of the essential properties
        are not received from the node.  It doesn't fail if node fails
        to return any capabilities as the capabilities differ from hardware
        to hardware mostly.

        :param task: a TaskManager instance.
        :raises: HardwareInspectionFailure if essential properties
                 could not be retrieved successfully.
        :raises: IloOperationError if system fails to get power state.
        :returns: The resulting state of inspection.

        """
        power_turned_on = False
        ilo_object = ilo_common.get_ilo_object(task.node)
        try:
            state = task.driver.power.get_power_state(task)
        except exception.IloOperationError as ilo_exception:
            operation = (_("Inspecting hardware (get_power_state) on %s")
                         % task.node.uuid)
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
        if state != states.POWER_ON:
            LOG.info("The node %s is not powered on. Powering on the "
                     "node for inspection.", task.node.uuid)
            conductor_utils.node_power_action(task, states.POWER_ON)
            power_turned_on = True

        # get the essential properties and update the node properties
        # with it.

        inspected_properties = {}
        result = _get_essential_properties(task.node, ilo_object)

        # A temporary hook for OOB inspection to not to update 'local_gb'
        # for hardware if the storage is a "Direct Attached Storage" or
        # "Dynamic Smart Array Controllers" and the operator has manually
        # updated the local_gb in node properties prior to node inspection.
        # This will be removed once we have inband inspection support for
        # ilo drivers.
        current_local_gb = task.node.properties.get('local_gb')
        properties = result['properties']
        if current_local_gb:
            if properties['local_gb'] == 0 and current_local_gb > 0:
                properties['local_gb'] = current_local_gb
                LOG.warning('Could not discover size of disk on the node '
                            '%s. Value of `properties/local_gb` of the '
                            'node is not overwritten.', task.node.uuid)

        for known_property in self.ESSENTIAL_PROPERTIES:
            inspected_properties[known_property] = properties[known_property]
        node_properties = task.node.properties
        node_properties.update(inspected_properties)
        task.node.properties = node_properties

        # Inspect the hardware for additional hardware capabilities.
        # Since additional hardware capabilities may not apply to all the
        # hardwares, the method inspect_hardware() doesn't raise an error
        # for these capabilities.
        capabilities = _get_capabilities(task.node, ilo_object)
        if capabilities:
            valid_cap = _create_supported_capabilities_dict(capabilities)
            capabilities = utils.get_updated_capabilities(
                task.node.properties.get('capabilities'), valid_cap)
            if capabilities:
                node_properties['capabilities'] = capabilities
                task.node.properties = node_properties

        task.node.save()

        # Create ports for the nics detected.
        _create_ports_if_not_exist(task, result['macs'])

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

        LOG.info("Node %s inspected.", task.node.uuid)
        if power_turned_on:
            conductor_utils.node_power_action(task, states.POWER_OFF)
            LOG.info("The node %s was powered on for inspection. "
                     "Powered off the node as inspection completed.",
                     task.node.uuid)
        return states.MANAGEABLE
Example #23
0
    def inspect_hardware(self, task):
        """Inspect hardware to get the hardware properties.

        Inspects hardware to get the essential and additional hardware
        properties. It fails if any of the essential properties
        are not received from the node.  It doesn't fail if node fails
        to return any capabilities as the capabilities differ from hardware
        to hardware mostly.

        :param task: a TaskManager instance.
        :raises: HardwareInspectionFailure if essential properties
                 could not be retrieved successfully.
        :raises: IloOperationError if system fails to get power state.
        :returns: The resulting state of inspection.

        """
        power_turned_on = False
        ilo_object = ilo_common.get_ilo_object(task.node)
        try:
            state = task.driver.power.get_power_state(task)
        except exception.IloOperationError as ilo_exception:
            operation = (_("Inspecting hardware (get_power_state) on %s") %
                         task.node.uuid)
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
        if state != states.POWER_ON:
            LOG.info(
                _LI("The node %s is not powered on. Powering on the "
                    "node for inspection."), task.node.uuid)
            conductor_utils.node_power_action(task, states.POWER_ON)
            power_turned_on = True

        # get the essential properties and update the node properties
        # with it.

        inspected_properties = {}
        result = _get_essential_properties(task.node, ilo_object)
        properties = result['properties']
        for known_property in self.ESSENTIAL_PROPERTIES:
            inspected_properties[known_property] = properties[known_property]
        node_properties = task.node.properties
        node_properties.update(inspected_properties)
        task.node.properties = node_properties

        # Inspect the hardware for additional hardware capabilities.
        # Since additional hardware capabilities may not apply to all the
        # hardwares, the method inspect_hardware() doesn't raise an error
        # for these capabilities.
        capabilities = _get_capabilities(task.node, ilo_object)
        if capabilities:
            valid_cap = _create_supported_capabilities_dict(capabilities)
            capabilities = utils.get_updated_capabilities(
                task.node.properties.get('capabilities'), valid_cap)
            if capabilities:
                node_properties['capabilities'] = capabilities
                task.node.properties = node_properties

        task.node.save()

        # Create ports for the nics detected.
        _create_ports_if_not_exist(task.node, result['macs'])

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

        LOG.info(_LI("Node %s inspected."), task.node.uuid)
        if power_turned_on:
            conductor_utils.node_power_action(task, states.POWER_OFF)
            LOG.info(
                _LI("The node %s was powered on for inspection. "
                    "Powered off the node as inspection completed."),
                task.node.uuid)
        return states.MANAGEABLE
Example #24
0
    def inspect_hardware(self, task):
        """Inspect hardware to get the hardware properties.

        Inspects hardware to get the essential and additional hardware
        properties. It fails if any of the essential properties
        are not received from the node.  It doesn't fail if node fails
        to return any capabilities as the capabilities differ from hardware
        to hardware mostly.

        :param task: a TaskManager instance.
        :raises: HardwareInspectionFailure if essential properties
                 could not be retrieved successfully.
        :raises: IloOperationError if system fails to get power state.
        :returns: The resulting state of inspection.

        """
        power_turned_on = False
        ilo_object = ilo_common.get_ilo_object(task.node)
        try:
            state = task.driver.power.get_power_state(task)
        except exception.IloOperationError as ilo_exception:
            operation = (_("Inspecting hardware (get_power_state) on %s") %
                         task.node.uuid)
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)
        if state != states.POWER_ON:
            LOG.info(
                "The node %s is not powered on. Powering on the "
                "node for inspection.", task.node.uuid)
            conductor_utils.node_power_action(task, states.POWER_ON)
            power_turned_on = True

        # get the essential properties and update the node properties
        # with it.

        inspected_properties = {}
        result = _get_essential_properties(task.node, ilo_object)

        # A temporary hook for OOB inspection to not to update 'local_gb'
        # for hardware if the storage is a "Direct Attached Storage" or
        # "Dynamic Smart Array Controllers" and the operator has manually
        # updated the local_gb in node properties prior to node inspection.
        # This will be removed once we have inband inspection support for
        # ilo drivers.
        current_local_gb = task.node.properties.get('local_gb')
        properties = result['properties']
        if current_local_gb:
            if properties['local_gb'] == 0 and current_local_gb > 0:
                properties['local_gb'] = current_local_gb
                LOG.warning(
                    'Could not discover size of disk on the node '
                    '%s. Value of `properties/local_gb` of the '
                    'node is not overwritten.', task.node.uuid)

        for known_property in self.ESSENTIAL_PROPERTIES:
            inspected_properties[known_property] = properties[known_property]
        node_properties = task.node.properties
        node_properties.update(inspected_properties)
        task.node.properties = node_properties

        # Inspect the hardware for additional hardware capabilities.
        # Since additional hardware capabilities may not apply to all the
        # hardwares, the method inspect_hardware() doesn't raise an error
        # for these capabilities.
        capabilities = _get_capabilities(task.node, ilo_object)
        model = None
        if capabilities:
            model = capabilities.get('server_model')
            valid_cap = _create_supported_capabilities_dict(capabilities)
            capabilities = utils.get_updated_capabilities(
                task.node.properties.get('capabilities'), valid_cap)
            if capabilities:
                node_properties['capabilities'] = capabilities
                task.node.properties = node_properties

        # RIBCL(Gen8) protocol cannot determine if a NIC
        # is physically connected with cable or not when the server
        # is not provisioned. RIS(Gen9) can detect the same for few NIC
        # adapters but not for all. However it is possible to determine
        # the same using Redfish(Gen10) protocol. Hence proliantutils
        # returns ALL MACs for Gen8 and Gen9 while it returns
        # only active MACs for Gen10. A warning is being added
        # for the user so that he knows that he needs to remove the
        # ironic ports created for inactive ports for Gen8 and Gen9.
        servers = ['Gen8', 'Gen9']
        if model is not None and any(serv in model for serv in servers):
            LOG.warning(
                'iLO cannot determine if the NICs are physically '
                'connected or not for ProLiant Gen8 and Gen9 servers. '
                'Hence returns all the MACs present on the server. '
                'Please remove the ironic ports created for inactive '
                'NICs manually for the node %(node)s',
                {"node": task.node.uuid})
        task.node.save()

        # Create ports for the nics detected.
        inspect_utils.create_ports_if_not_exist(task, result['macs'])

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

        LOG.info("Node %s inspected.", task.node.uuid)
        if power_turned_on:
            conductor_utils.node_power_action(task, states.POWER_OFF)
            LOG.info(
                "The node %s was powered on for inspection. "
                "Powered off the node as inspection completed.",
                task.node.uuid)
        return states.MANAGEABLE
Example #25
0
def add_certificates(task, cert_file_list=None):
    """Adds certificates to the node.

    Adds certificates to the node based on the driver info
    provided.

    :param task: a TaskManager instance containing the node to act on.
    :param cert_file_list: List of certificates to be added to the node.
        If None, certificates from path configured in 'webserver_verify_ca'
        will be added to the node.
    :raises: IloOperationError on an error from IloClient library.
    :raises: IloOperationNotSupported if retrieving post state is not
        supported on the server.
    :raises: InvalidParameterValue, if any of the required parameters are
            invalid.
    """

    node = task.node
    ilo_object = get_ilo_object(node)
    d_info = node.driver_info

    export_certs = d_info.get('ilo_add_certificates', True)

    if export_certs is None:
        export_certs = True
    else:
        try:
            export_certs = strutils.bool_from_string(export_certs, strict=True)
        except ValueError:
            raise exception.InvalidParameterValue(
                _('Invalid value type set in driver_info/'
                  'ilo_add_certificates on node %(node)s. '
                  'The value should be a Boolean '
                  ' not "%(value)s"') % {
                      'value': export_certs,
                      'node': node.uuid
                  })

    if not export_certs:
        LOG.info(
            "Adding of certificates to the node %(node)s is not "
            "requested. Assuming required certificates are available "
            "on the node.", {'node': node.uuid})
        return

    cfl = _get_certificate_file_list(cert_file_list)

    if not cfl:
        LOG.debug(
            "Not adding any certificate to the node %(node)s "
            "as no certificates are provided", {'node': node.uuid})
        return

    try:
        # NOTE(vmud213): Add the certificates to the node which are
        # eventually being used for TLS verification by the node before
        # downloading the deploy/instance images during HTTPS boot from
        # URL.
        operation = (_("Add certificates to %(node)s from paths "
                       "%(cpath)s.") % {
                           'cpath': cfl,
                           'node': node.uuid
                       })

        ilo_object.add_tls_certificate(cfl)

        LOG.info(
            "Successfully added certificates to the node %(node)s from "
            "paths %(cpath)s.", {
                'cpath': cfl,
                'node': node.uuid
            })
    except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
        raise exception.IloOperationNotSupported(operation=operation,
                                                 error=ilo_exception)
    except ilo_error.IloError as ilo_exception:
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)
Example #26
0
def _set_power_state(task, target_state, timeout=None):
    """Turns the server power on/off or do a reboot.

    :param task: a TaskManager instance containing the node to act on.
    :param target_state: target state of the node.
    :param timeout: timeout (in seconds) positive integer (> 0) for any
      power state. ``None`` indicates default timeout.
    :raises: InvalidParameterValue if an invalid power state was specified.
    :raises: IloOperationError on an error from IloClient library.
    :raises: PowerStateFailure if the power couldn't be set to target_state.
    """
    node = task.node
    ilo_object = ilo_common.get_ilo_object(node)

    # Check if its soft power operation
    soft_power_op = target_state in [states.SOFT_POWER_OFF, states.SOFT_REBOOT]

    requested_state = target_state
    if target_state == states.SOFT_REBOOT:
        if _get_power_state(node) == states.POWER_OFF:
            target_state = states.POWER_ON

    # Trigger the operation based on the target state.
    try:
        if target_state == states.POWER_OFF:
            ilo_object.hold_pwr_btn()
        elif target_state == states.POWER_ON:
            _attach_boot_iso_if_needed(task)
            ilo_object.set_host_power('ON')
        elif target_state == states.REBOOT:
            _attach_boot_iso_if_needed(task)
            ilo_object.reset_server()
            target_state = states.POWER_ON
        elif target_state in (states.SOFT_POWER_OFF, states.SOFT_REBOOT):
            ilo_object.press_pwr_btn()
        else:
            msg = _("_set_power_state called with invalid power state "
                    "'%s'") % target_state
            raise exception.InvalidParameterValue(msg)

    except ilo_error.IloError as ilo_exception:
        LOG.error(
            "iLO set_power_state failed to set state to %(tstate)s "
            " for node %(node_id)s with error: %(error)s", {
                'tstate': target_state,
                'node_id': node.uuid,
                'error': ilo_exception
            })
        operation = _('iLO set_power_state')
        raise exception.IloOperationError(operation=operation,
                                          error=ilo_exception)

    # Wait till the soft power state change gets reflected.
    time_consumed = 0
    if soft_power_op:
        # For soft power-off, bare metal reaches final state with one
        # power operation. In case of soft reboot it takes two; soft
        # power-off followed by power-on. Also, for soft reboot we
        # need to ensure timeout does not expire during power-off
        # and power-on operation.
        is_final_state = target_state in (states.SOFT_POWER_OFF,
                                          states.POWER_ON)
        time_consumed = _wait_for_state_change(node,
                                               target_state,
                                               requested_state,
                                               is_final_state=is_final_state,
                                               timeout=timeout)
        if target_state == states.SOFT_REBOOT:
            _attach_boot_iso_if_needed(task)
            try:
                ilo_object.set_host_power('ON')
            except ilo_error.IloError as ilo_exception:
                operation = (_('Powering on failed after soft power off for '
                               'node %s') % node.uuid)
                raise exception.IloOperationError(operation=operation,
                                                  error=ilo_exception)
            # Re-calculate timeout available for power-on operation
            rem_timeout = timeout - time_consumed
            time_consumed += _wait_for_state_change(node,
                                                    states.SOFT_REBOOT,
                                                    requested_state,
                                                    is_final_state=True,
                                                    timeout=rem_timeout)
    else:
        time_consumed = _wait_for_state_change(node,
                                               target_state,
                                               requested_state,
                                               is_final_state=True,
                                               timeout=timeout)
    LOG.info(
        "The node %(node_id)s operation of '%(state)s' "
        "is completed in %(time_consumed)s seconds.", {
            'node_id': node.uuid,
            'state': target_state,
            'time_consumed': time_consumed
        })