Пример #1
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_client.IloError as ilo_exception:
        LOG.error(_LE("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
Пример #2
0
def _execute_ilo_clean_step(node, step, *args, **kwargs):
    """Executes a particular clean step.

    :param node: an Ironic node object.
    :param step: a clean step to be executed.
    :param args: The args to be passed to the clean step.
    :param kwargs: The kwargs to be passed to the clean step.
    :raises: NodeCleaningFailure, on failure to execute step.
    """
    ilo_object = ilo_common.get_ilo_object(node)

    try:
        clean_step = getattr(ilo_object, step)
    except AttributeError:
        # The specified clean step is not present in the proliantutils
        # package. Raise exception to update the proliantutils package
        # to newer version.
        raise exception.NodeCleaningFailure(
            _("Clean step '%s' not found. 'proliantutils' package needs to be "
              "updated.") % step)
    try:
        clean_step(*args, **kwargs)
    except ilo_error.IloCommandNotSupportedError:
        # This clean step is not supported on Gen8 and below servers.
        # Log the failure and continue with cleaning.
        LOG.warning("'%(step)s' clean step is not supported on node "
                    "%(uuid)s. Skipping the clean step.",
                    {'step': step, 'uuid': node.uuid})
    except ilo_error.IloError as ilo_exception:
        raise exception.NodeCleaningFailure(_(
            "Clean step %(step)s failed "
            "on node %(node)s with error: %(err)s") %
            {'node': node.uuid, 'step': step, 'err': ilo_exception})
Пример #3
0
    def delete_configuration(self, task):
        """Delete the RAID configuration.

        :param task: a TaskManager instance  containing the node to act on.
        :raises: NodeCleaningFailure, on failure to execute step.
        """
        node = task.node
        LOG.debug("OOB RAID delete_configuration invoked for node %s.",
                  node.uuid)
        driver_internal_info = node.driver_internal_info
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_delete_in_progress'):
                ilo_object.delete_raid_configuration()
                self._prepare_for_read_raid(task, 'delete_raid')
                return states.CLEANWAIT
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = ilo_object.read_raid_configuration()
                if not len(raid_conf['logical_disks']):
                    node.raid_config = {}
                    LOG.debug("Node %(uuid)s raid delete clean step is done.",
                              {'uuid': node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_delete_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                else:
                    # Raid configuration failed
                    msg = ("Unable to delete this logical disks: %s" %
                           raid_conf['logical_disks'])
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_delete_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                    raise exception.NodeCleaningFailure(
                        "Clean step delete_configuration failed "
                        "on node %(node)s with error: %(err)s" %
                        {'node': node.uuid, 'err': msg})
        except ilo_error.IloLogicalDriveNotFoundError:
            LOG.info("No logical drive found to delete on node %(node)s",
                     {'node': node.uuid})
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to delete raid configuration on node %s")
                         % node.uuid)
            self._pop_driver_internal_values(task,
                                             'ilo_raid_delete_in_progress',
                                             'cleaning_reboot',
                                             'skip_current_clean_step')
            node.driver_internal_info = driver_internal_info
            node.save()
            self._set_clean_failed(task, operation, ilo_exception)
Пример #4
0
 def test_get_ilo_object(self, ilo_client_mock):
     self.info['client_timeout'] = 60
     self.info['client_port'] = 443
     ilo_client_mock.return_value = 'ilo_object'
     returned_ilo_object = ilo_common.get_ilo_object(self.node)
     ilo_client_mock.assert_called_with(
         self.info['ilo_address'],
         self.info['ilo_username'],
         self.info['ilo_password'],
         self.info['client_timeout'],
         self.info['client_port'])
     self.assertEqual('ilo_object', returned_ilo_object)
 def test_get_ilo_object(self, ilo_client_mock):
     info = INFO_DICT
     info['client_timeout'] = 60
     info['client_port'] = 443
     ilo_client_mock.IloClient.return_value = 'ilo_object'
     returned_ilo_object = ilo_common.get_ilo_object(self.node)
     ilo_client_mock.IloClient.assert_called_with(
         INFO_DICT['ilo_address'],
         INFO_DICT['ilo_username'],
         INFO_DICT['ilo_password'],
         info['client_timeout'],
         info['client_port'])
     self.assertEqual('ilo_object', returned_ilo_object)
Пример #6
0
 def test_get_ilo_object(self, ilo_client_mock):
     self.info["client_timeout"] = 60
     self.info["client_port"] = 443
     ilo_client_mock.return_value = "ilo_object"
     returned_ilo_object = ilo_common.get_ilo_object(self.node)
     ilo_client_mock.assert_called_with(
         self.info["ilo_address"],
         self.info["ilo_username"],
         self.info["ilo_password"],
         self.info["client_timeout"],
         self.info["client_port"],
     )
     self.assertEqual("ilo_object", returned_ilo_object)
Пример #7
0
 def _test_get_ilo_object(self, ilo_client_mock, isFile_mock, ca_file=None):
     self.info["client_timeout"] = 600
     self.info["client_port"] = 4433
     self.info["ca_file"] = ca_file
     self.node.driver_info = self.info
     ilo_client_mock.return_value = "ilo_object"
     returned_ilo_object = ilo_common.get_ilo_object(self.node)
     ilo_client_mock.assert_called_with(
         self.info["ilo_address"],
         self.info["ilo_username"],
         self.info["ilo_password"],
         self.info["client_timeout"],
         self.info["client_port"],
         cacert=self.info["ca_file"],
     )
     self.assertEqual("ilo_object", returned_ilo_object)
Пример #8
0
 def test_get_ilo_object(self, ilo_client_mock):
     info = INFO_DICT
     info['client_timeout'] = 60
     info['client_port'] = 443
     node = obj_utils.create_test_node(self.context,
                                       driver='ilo',
                                       driver_info=INFO_DICT)
     ilo_client_mock.IloClient.return_value = 'ilo_object'
     returned_ilo_object = ilo_common.get_ilo_object(node)
     ilo_client_mock.IloClient.assert_called_with(
         INFO_DICT['ilo_address'],
         INFO_DICT['ilo_username'],
         INFO_DICT['ilo_password'],
         info['client_timeout'],
         info['client_port'])
     self.assertEqual('ilo_object', returned_ilo_object)
Пример #9
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)
Пример #10
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}
Пример #11
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})
Пример #12
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 ESSENTIAL_PROPERTIES_KEYS:
            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
Пример #13
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)', {"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
Пример #14
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]

    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, 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, is_final_state=True,
                timeout=rem_timeout)
    else:
        time_consumed = _wait_for_state_change(
            node, target_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})
Пример #15
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)

        # 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(_LW('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(_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
Пример #16
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
Пример #17
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 ESSENTIAL_PROPERTIES_KEYS:
            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 = _update_capabilities(task.node, 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
Пример #18
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)

        # 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(
                    _LW('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(_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
Пример #19
0
    def delete_configuration(self, task):
        """Delete the RAID configuration.

        :param task: a TaskManager instance  containing the node to act on.
        :raises: NodeCleaningFailure, on failure to execute clean step.
        :raises: InstanceDeployFailure, on failure to execute deploy step.
        """
        node = task.node
        LOG.debug("OOB RAID delete_configuration invoked for node %s.",
                  node.uuid)
        driver_internal_info = node.driver_internal_info
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_delete_in_progress'):
                ilo_object.delete_raid_configuration()
                self._prepare_for_read_raid(task, 'delete_raid')
                return deploy_utils.get_async_step_return_state(node)
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = ilo_object.read_raid_configuration()
                fields = ['ilo_raid_delete_in_progress']
                if node.clean_step:
                    fields.append('skip_current_clean_step')
                else:
                    fields.append('skip_current_deploy_step')
                self._pop_driver_internal_values(task, *fields)
                if not len(raid_conf['logical_disks']):
                    node.raid_config = {}
                    LOG.debug("Node %(uuid)s raid delete clean step is done.",
                              {'uuid': node.uuid})
                else:
                    # Raid configuration failed
                    err_msg = (_("Step delete_configuration failed "
                                 "on node %(node)s with error: "
                                 "Unable to delete these logical disks: "
                                 "%(disks)s") % {
                                     'node': node.uuid,
                                     'disks': raid_conf['logical_disks']
                                 })
                    if node.clean_step:
                        raise exception.NodeCleaningFailure(err_msg)
                    else:
                        raise exception.InstanceDeployFailure(reason=err_msg)
        except ilo_error.IloLogicalDriveNotFoundError:
            LOG.info("No logical drive found to delete on node %(node)s",
                     {'node': node.uuid})
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to delete raid configuration on node %s") %
                         node.uuid)
            self._pop_driver_internal_values(task,
                                             'ilo_raid_delete_in_progress',
                                             'skip_current_clean_step')
            fields = ['ilo_raid_delete_in_progress']
            if node.clean_step:
                fields.append('skip_current_clean_step')
            else:
                fields.append('skip_current_deploy_step')
            self._pop_driver_internal_values(task, *fields)
            self._set_step_failed(task, operation, ilo_exception)
Пример #20
0
    def create_configuration(self, task, create_root_volume=True,
                             create_nonroot_volumes=True):
        """Create a RAID configuration on a bare metal using agent ramdisk.

        This method creates a RAID configuration on the given node.

        :param task: a TaskManager instance.
        :param create_root_volume: If True, a root volume is created
            during RAID configuration. Otherwise, no root volume is
            created. Default is True.
        :param create_nonroot_volumes: If True, non-root volumes are
            created. If False, no non-root volumes are created. Default
            is True.
        :raises: MissingParameterValue, if node.target_raid_config is missing
            or was found to be empty after skipping root volume and/or non-root
            volumes.
        :raises: NodeCleaningFailure, on failure to execute step.
        """
        node = task.node
        target_raid_config = raid.filter_target_raid_config(
            node, create_root_volume=create_root_volume,
            create_nonroot_volumes=create_nonroot_volumes)
        driver_internal_info = node.driver_internal_info
        driver_internal_info['target_raid_config'] = target_raid_config
        LOG.debug("Calling OOB RAID create_configuration for node %(node)s "
                  "with the following target RAID configuration: %(target)s",
                  {'node': node.uuid, 'target': target_raid_config})
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_create_in_progress'):
                ilo_object.create_raid_configuration(target_raid_config)
                self._prepare_for_read_raid(task, 'create_raid')
                return states.CLEANWAIT
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = (
                    ilo_object.read_raid_configuration(
                        raid_config=target_raid_config))
                if len(raid_conf['logical_disks']):
                    raid.update_raid_info(node, raid_conf)
                    LOG.debug("Node %(uuid)s raid create clean step is done.",
                              {'uuid': node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                else:
                    # Raid configuration failed
                    msg = "Unable to create raid"
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                    raise exception.NodeCleaningFailure(
                        "Clean step create_configuration failed "
                        "on node %(node)s with error: %(err)s" %
                        {'node': node.uuid, 'err': msg})
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to create raid configuration on node %s")
                         % node.uuid)
            self._pop_driver_internal_values(task,
                                             'ilo_raid_create_in_progress',
                                             'cleaning_reboot',
                                             'skip_current_clean_step')
            node.driver_internal_info = driver_internal_info
            node.save()
            self._set_clean_failed(task, operation, ilo_exception)
Пример #21
0
    def create_configuration(self, task, create_root_volume=True,
                             create_nonroot_volumes=True):
        """Create a RAID configuration on a bare metal using agent ramdisk.

        This method creates a RAID configuration on the given node.

        :param task: a TaskManager instance.
        :param create_root_volume: If True, a root volume is created
            during RAID configuration. Otherwise, no root volume is
            created. Default is True.
        :param create_nonroot_volumes: If True, non-root volumes are
            created. If False, no non-root volumes are created. Default
            is True.
        :raises: MissingParameterValue, if node.target_raid_config is missing
            or was found to be empty after skipping root volume and/or non-root
            volumes.
        :raises: NodeCleaningFailure, on failure to execute step.
        """
        node = task.node
        target_raid_config = raid.filter_target_raid_config(
            node, create_root_volume=create_root_volume,
            create_nonroot_volumes=create_nonroot_volumes)
        driver_internal_info = node.driver_internal_info
        driver_internal_info['target_raid_config'] = target_raid_config
        node.driver_internal_info = driver_internal_info
        node.save()
        LOG.debug("Calling OOB RAID create_configuration for node %(node)s "
                  "with the following target RAID configuration: %(target)s",
                  {'node': node.uuid, 'target': target_raid_config})
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_create_in_progress'):
                ilo_object.create_raid_configuration(target_raid_config)
                self._prepare_for_read_raid(task, 'create_raid')
                return states.CLEANWAIT
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = (
                    ilo_object.read_raid_configuration(
                        raid_config=target_raid_config))
                if len(raid_conf['logical_disks']):
                    raid.update_raid_info(node, raid_conf)
                    LOG.debug("Node %(uuid)s raid create clean step is done.",
                              {'uuid': node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'skip_current_clean_step')
                else:
                    # Raid configuration failed
                    msg = "Unable to create raid"
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'skip_current_clean_step')
                    raise exception.NodeCleaningFailure(
                        "Clean step create_configuration failed "
                        "on node %(node)s with error: %(err)s" %
                        {'node': node.uuid, 'err': msg})
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to create raid configuration on node %s")
                         % node.uuid)
            self._pop_driver_internal_values(task,
                                             'ilo_raid_create_in_progress',
                                             'skip_current_clean_step')
            self._set_clean_failed(task, operation, ilo_exception)
Пример #22
0
    def erase_devices(self, task, **kwargs):
        """Erase all the drives on the node.

        This method performs out-of-band sanitize disk erase on all the
        supported physical drives in the node. This erase cannot be performed
        on logical drives.

        :param task: a TaskManager instance.
        :raises: InvalidParameterValue, if any of the arguments are invalid.
        :raises: IloError on an error from iLO.
        """
        erase_pattern = kwargs.get('erase_pattern', {
            'hdd': 'overwrite',
            'ssd': 'block'
        })
        node = task.node
        self._validate_erase_pattern(erase_pattern, node)
        driver_internal_info = node.driver_internal_info
        LOG.debug("Calling out-of-band sanitize disk erase for node %(node)s",
                  {'node': node.uuid})
        try:
            ilo_object = ilo_common.get_ilo_object(node)
            disk_types = ilo_object.get_available_disk_types()
            LOG.info(
                "Disk type detected are: %(disk_types)s. Sanitize disk "
                "erase are now exercised for one after another disk type "
                "for node %(node)s.", {
                    'disk_types': disk_types,
                    'node': node.uuid
                })

            if disk_types:
                # First disk-erase will execute for HDD's and after reboot only
                # try for SSD, since both share same redfish api and would be
                # overwritten.
                if not driver_internal_info.get(
                        'ilo_disk_erase_hdd_check') and ('HDD' in disk_types):
                    ilo_object.do_disk_erase('HDD', erase_pattern.get('hdd'))
                    self._set_driver_internal_value(
                        task, True, 'cleaning_reboot',
                        'ilo_disk_erase_hdd_check')
                    self._set_driver_internal_value(task, False,
                                                    'skip_current_clean_step')
                    deploy_opts = deploy_utils.build_agent_options(task.node)
                    task.driver.boot.prepare_ramdisk(task, deploy_opts)
                    manager_utils.node_power_action(task, states.REBOOT)
                    return states.CLEANWAIT

                if not driver_internal_info.get(
                        'ilo_disk_erase_ssd_check') and ('SSD' in disk_types):
                    ilo_object.do_disk_erase('SSD', erase_pattern.get('ssd'))
                    self._set_driver_internal_value(
                        task, True, 'ilo_disk_erase_hdd_check',
                        'ilo_disk_erase_ssd_check', 'cleaning_reboot')
                    self._set_driver_internal_value(task, False,
                                                    'skip_current_clean_step')
                    deploy_opts = deploy_utils.build_agent_options(task.node)
                    task.driver.boot.prepare_ramdisk(task, deploy_opts)
                    manager_utils.node_power_action(task, states.REBOOT)
                    return states.CLEANWAIT

                # It will wait until disk erase will complete
                if self._wait_for_disk_erase_status(task.node):
                    LOG.info(
                        "For node %(uuid)s erase_devices clean "
                        "step is done.", {'uuid': task.node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_disk_erase_hdd_check',
                        'ilo_disk_erase_ssd_check')
            else:
                LOG.info(
                    "No drive found to perform out-of-band sanitize "
                    "disk erase for node %(node)s", {'node': node.uuid})
        except ilo_error.IloError as ilo_exception:
            self._pop_driver_internal_values(task, 'ilo_disk_erase_hdd_check',
                                             'ilo_disk_erase_ssd_check',
                                             'cleaning_reboot',
                                             'skip_current_clean_step')
            self._set_clean_failed(task, ilo_exception)
Пример #23
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
Пример #24
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})