示例#1
0
def create_configuration(raid_config):
    """Create a RAID configuration on this server.

    This method creates the given RAID configuration on the
    server based on the input passed.
    :param raid_config: The dictionary containing the requested
        RAID configuration. This data structure should be as follows:
        raid_config = {'logical_disks': [{'raid_level': 1, 'size_gb': 100},
                                         <info-for-logical-disk-2>
                                        ]}
    :raises exception.InvalidInputError, if input is invalid.
    """
    validate(raid_config)

    server = objects.Server()
    logical_disks_sorted = sorted(raid_config['logical_disks'],
                                  cmp=_compare_logical_disks)

    for logical_disk in logical_disks_sorted:

        if 'physical_disks' not in logical_disk:
            # TODO(rameshg87): hpssa module should be capable of finding
            # the suitable controller and physical disks if it not provided
            # by using hints. This is a supported use-case, but not implemented
            # as of now. Will be implemented soon.
            # _find_physical_disks(logical_disk, server)
            msg = ("Mentioning logical_disks without 'controller' and "
                   "'physical_disks' is not supported as of now.")
            raise exception.InvalidInputError(reason=msg)

        controller_id = logical_disk['controller']

        controller = server.get_controller_by_id(controller_id)
        if not controller:
            msg = ("Unable to find controller named '%s'" % controller_id)
            raise exception.InvalidInputError(reason=msg)

        for physical_disk in logical_disk['physical_disks']:
            disk_obj = controller.get_physical_drive_by_id(physical_disk)
            if not disk_obj:
                msg = ("Unable to find physical disk '%(physical_disk)s' "
                       "on '%(controller)s'" % {
                           'physical_disk': physical_disk,
                           'controller': controller_id
                       })
                raise exception.InvalidInputError(reason=msg)

        physical_drive_ids = logical_disk['physical_disks']

        controller.create_logical_drive(logical_disk, physical_drive_ids)
        server.refresh()
示例#2
0
    def push_power_button(self, target_value):
        """Reset the system in hpe exclusive manner.

        :param target_value: The target value to be set.
        :raises: InvalidInputError, if the target value is not
            allowed.
        :raises: SushyError, on an error from iLO.
        """
        if target_value not in mappings.PUSH_POWER_BUTTON_VALUE_MAP_REV:
            msg = ('The parameter "%(parameter)s" value "%(target_value)s" is '
                   'invalid. Valid values are: %(valid_power_values)s' % {
                       'parameter':
                       'target_value',
                       'target_value':
                       target_value,
                       'valid_power_values':
                       (mappings.PUSH_POWER_BUTTON_VALUE_MAP_REV.keys())
                   })
            raise exception.InvalidInputError(msg)

        value = mappings.PUSH_POWER_BUTTON_VALUE_MAP_REV[target_value]
        target_uri = (
            self._get_hpe_push_power_button_action_element().target_uri)

        self._conn.post(target_uri, data={'PushType': value})
    def extract(self):
        """Extracts the raw firmware file from its compact format

        Extracts the raw firmware file from its compact file format (already
        set as attribute in FirmwareImageControllerBase constructor).
        :raises: InvalidInputError, if raw firmware file not found
        :raises: ImageExtractionFailed, for extraction related issues
        :returns: the raw firmware file with the complete path
        :returns: boolean(True) to indicate that a new file got generated
                  after successful extraction.
        """
        target_file = self.fw_file
        common.add_exec_permission_to(target_file)
        # create a temp directory where the extraction will occur
        temp_dir = tempfile.mkdtemp()
        extract_path = os.path.join(temp_dir, self.fw_filename)

        try:
            self._do_extract(target_file, extract_path)
        except exception.ImageExtractionFailed:
            # clean up the partial extracted content, if any,
            # along with temp dir and re-raise the exception
            shutil.rmtree(temp_dir, ignore_errors=True)
            raise

        # creating a new hard link to the core firmware file
        firmware_file_path = _get_firmware_file_in_new_path(extract_path)
        # delete the entire extracted content along with temp dir.
        shutil.rmtree(temp_dir, ignore_errors=True)

        if not firmware_file_path:
            raise exception.InvalidInputError(
                "Raw firmware file not found in: '%s'" % target_file)

        return firmware_file_path, True
示例#4
0
def validate(raid_config):
    """Validates the RAID configuration provided.

    This method validates the RAID configuration provided against
    a JSON schema.

    :param raid_config: The RAID configuration to be validated.
    :raises: InvalidInputError, if validation of the input fails.
    """
    raid_schema_fobj = open(RAID_CONFIG_SCHEMA, 'r')
    raid_config_schema = json.load(raid_schema_fobj)
    try:
        jsonschema.validate(raid_config, raid_config_schema)
    except json_schema_exc.ValidationError as e:
        raise exception.InvalidInputError(e.message)

    for logical_disk in raid_config['logical_disks']:

        # If user has provided 'number_of_physical_disks' or
        # 'physical_disks', validate that they have mentioned at least
        # minimum number of physical disks required for that RAID level.
        raid_level = logical_disk['raid_level']
        min_disks_reqd = constants.RAID_LEVEL_MIN_DISKS[raid_level]

        no_of_disks_specified = None
        if 'number_of_physical_disks' in logical_disk:
            no_of_disks_specified = logical_disk['number_of_physical_disks']
        elif 'physical_disks' in logical_disk:
            no_of_disks_specified = len(logical_disk['physical_disks'])

        if (no_of_disks_specified and no_of_disks_specified < min_disks_reqd):
            msg = ("RAID level %(raid_level)s requires at least %(number)s "
                   "disks." % {
                       'raid_level': raid_level,
                       'number': min_disks_reqd
                   })
            raise exception.InvalidInputError(msg)
示例#5
0
def _get_hash_object(hash_algo_name):
    """Create a hash object based on given algorithm.

    :param hash_algo_name: name of the hashing algorithm.
    :raises: InvalidInputError, on unsupported or invalid input.
    :returns: a hash object based on the given named algorithm.
    """
    algorithms = (hashlib.algorithms_guaranteed if six.PY3
                  else hashlib.algorithms)
    if hash_algo_name not in algorithms:
        msg = ("Unsupported/Invalid hash name '%s' provided."
               % hash_algo_name)
        raise exception.InvalidInputError(msg)

    return getattr(hashlib, hash_algo_name)()
示例#6
0
def validate(raid_config):
    """Validates the RAID configuration provided.

    This method validates the RAID configuration provided against
    a JSON schema.

    :param raid_config: The RAID configuration to be validated.
    :raises: InvalidInputError, if validation of the input fails.
    """
    raid_schema_fobj = open(RAID_CONFIG_SCHEMA, 'r')
    raid_config_schema = json.load(raid_schema_fobj)
    try:
        jsonschema.validate(raid_config, raid_config_schema)
    except json_schema_exc.ValidationError as e:
        raise exception.InvalidInputError(e.message)
    def wrapper(self, filename, component_type):
        """Wrapper around ``update_firmware`` call.

        :param filename: location of the raw firmware file.
        :param component_type: Type of component to be applied to.
        """
        component_type = component_type and component_type.lower()
        if (component_type not in SUPPORTED_FIRMWARE_UPDATE_COMPONENTS):
            msg = ("Got invalid component type for firmware update: "
                   "``update_firmware`` is not supported on %(component)s" % {
                       'component': component_type
                   })
            LOG.error(self._(msg))  # noqa
            raise exception.InvalidInputError(msg)

        return func(self, filename, component_type)
示例#8
0
    def enable_secure_boot(self, secure_boot_enable):
        """Enable/Disable secure boot on the server.

        Caller needs to reset the server after issuing this command
        to bring this into effect.
        :param secure_boot_enable: True, if secure boot needs to be
               enabled for next boot, else False.
        :raises: InvalidInputError, if the validation of the input fails
        :raises: SushyError, on an error from iLO.
        """
        if not isinstance(secure_boot_enable, bool):
            msg = ('The parameter "%(parameter)s" value "%(value)s" is '
                   'invalid. Valid values are: True/False.' % {
                       'parameter': 'secure_boot_enable',
                       'value': secure_boot_enable
                   })
            raise exception.InvalidInputError(msg)

        self._conn.patch(self.path,
                         data={'SecureBootEnable': secure_boot_enable})
示例#9
0
    def reset_keys(self, target_value):
        """Resets the secure boot keys.

        :param target_value: The target value to be set.
        :raises: InvalidInputError, if the target value is not
            allowed.
        :raises: SushyError, on an error from iLO.
        """
        valid_keys_resets = self.get_allowed_reset_keys_values()
        if target_value not in valid_keys_resets:
            msg = ('The parameter "%(parameter)s" value "%(target_value)s" is '
                   'invalid. Valid values are: %(valid_keys_reset_values)s' % {
                       'parameter': 'target_value',
                       'target_value': target_value,
                       'valid_keys_reset_values': valid_keys_resets
                   })
            raise exception.InvalidInputError(msg)

        value = mappings.SECUREBOOT_RESET_KEYS_MAP_REV[target_value]
        target_uri = (self._get_reset_keys_action_element().target_uri)

        self._conn.post(target_uri, data={'ResetKeysType': value})
def get_fw_extractor(fw_file):
    """Gets the firmware extractor object fine-tuned for specified type

    :param fw_file: compact firmware file to be extracted from
    :raises: InvalidInputError, for unsupported file types
    :returns: FirmwareImageExtractor object
    """
    fw_img_extractor = FirmwareImageExtractor(fw_file)
    extension = fw_img_extractor.fw_file_ext.lower()

    if extension == '.scexe':
        # assign _do_extract attribute to refer to _extract_scexe_file
        fw_img_extractor._do_extract = types.MethodType(
            _extract_scexe_file, fw_img_extractor)
    elif extension == '.rpm':
        # assign _do_extract attribute to refer to _extract_rpm_file
        fw_img_extractor._do_extract = types.MethodType(
            _extract_rpm_file, fw_img_extractor)
    elif extension in RAW_FIRMWARE_EXTNS:
        # Note(deray): Assigning ``extract`` attribute to return
        #     1. the firmware file itself
        #     2. boolean (False) to indicate firmware file is not extracted
        def dummy_extract(self):
            """Dummy (no-op) extract method

            :returns: the same firmware file with the complete path
            :returns: boolean(False) to indicate that a new file is not
                      generated.
            """
            return fw_img_extractor.fw_file, False

        fw_img_extractor.extract = types.MethodType(dummy_extract,
                                                    fw_img_extractor)
    else:
        raise exception.InvalidInputError(
            'Unexpected compact firmware file type: %s' % fw_file)

    return fw_img_extractor
示例#11
0
def create_configuration(raid_config):
    """Create a RAID configuration on this server.

    This method creates the given RAID configuration on the
    server based on the input passed.
    :param raid_config: The dictionary containing the requested
        RAID configuration. This data structure should be as follows:
        raid_config = {'logical_disks': [{'raid_level': 1, 'size_gb': 100},
                                         <info-for-logical-disk-2>
                                        ]}
    :returns: the current raid configuration. This is same as raid_config
        with some extra properties like root_device_hint, volume_name,
        controller, physical_disks, etc filled for each logical disk
        after its creation.
    :raises exception.InvalidInputError, if input is invalid.
    :raises exception.HPSSAOperationError, if all the controllers are in HBA
        mode.
    """
    server = objects.Server()

    select_controllers = lambda x: not x.properties.get(
        'HBA Mode Enabled', False)
    _select_controllers_by(server, select_controllers, 'RAID enabled')

    validate(raid_config)

    # Make sure we create the large disks first.  This is avoid the
    # situation that we avoid giving large disks to smaller requests.
    # For example, consider this:
    #   - two logical disks - LD1(50), LD(100)
    #   - have 4 physical disks - PD1(50), PD2(50), PD3(100), PD4(100)
    #
    # In this case, for RAID1 configuration, if we were to consider
    # LD1 first and allocate PD3 and PD4 for it, then allocation would
    # fail. So follow a particular order for allocation.
    #
    # Also make sure we create the MAX logical_disks the last to make sure
    # we allot only the remaining space available.
    logical_disks_sorted = (
        sorted(
            (x for x in raid_config['logical_disks'] if x['size_gb'] != "MAX"),
            reverse=True,
            key=lambda x: x['size_gb']) +
        [x for x in raid_config['logical_disks'] if x['size_gb'] == "MAX"])

    if any(logical_disk['share_physical_disks']
           for logical_disk in logical_disks_sorted
           if 'share_physical_disks' in logical_disk):
        logical_disks_sorted = _sort_shared_logical_disks(logical_disks_sorted)

    # We figure out the new disk created by recording the wwns
    # before and after the create, and then figuring out the
    # newly found wwn from it.
    wwns_before_create = set([x.wwn for x in server.get_logical_drives()])

    for logical_disk in logical_disks_sorted:

        if 'physical_disks' not in logical_disk:
            disk_allocator.allocate_disks(logical_disk, server, raid_config)

        controller_id = logical_disk['controller']

        controller = server.get_controller_by_id(controller_id)
        if not controller:
            msg = (
                "Unable to find controller named '%(controller)s'."
                " The available controllers are '%(ctrl_list)s'." % {
                    'controller': controller_id,
                    'ctrl_list': ', '.join([c.id for c in server.controllers])
                })
            raise exception.InvalidInputError(reason=msg)

        if 'physical_disks' in logical_disk:
            for physical_disk in logical_disk['physical_disks']:
                disk_obj = controller.get_physical_drive_by_id(physical_disk)
                if not disk_obj:
                    msg = ("Unable to find physical disk '%(physical_disk)s' "
                           "on '%(controller)s'" % {
                               'physical_disk': physical_disk,
                               'controller': controller_id
                           })
                    raise exception.InvalidInputError(msg)

        controller.create_logical_drive(logical_disk)

        # Now find the new logical drive created.
        server.refresh()
        wwns_after_create = set([x.wwn for x in server.get_logical_drives()])

        new_wwn = wwns_after_create - wwns_before_create

        if not new_wwn:
            reason = ("Newly created logical disk with raid_level "
                      "'%(raid_level)s' and size %(size_gb)s GB not "
                      "found." % {
                          'raid_level': logical_disk['raid_level'],
                          'size_gb': logical_disk['size_gb']
                      })
            raise exception.HPSSAOperationError(reason=reason)

        new_logical_disk = server.get_logical_drive_by_wwn(new_wwn.pop())
        new_log_drive_properties = new_logical_disk.get_logical_drive_dict()
        logical_disk.update(new_log_drive_properties)

        wwns_before_create = wwns_after_create.copy()

    _update_physical_disk_details(raid_config, server)
    return raid_config
 def raising_invalid_input_error_exc_with(msg, **kwargs):
     raise exception.InvalidInputError(msg, **kwargs)