def _get_api_volume_by_name(self, volume_name, pool_id): logger.info("Getting volume {} in pool {}".format( volume_name, pool_id)) if not pool_id: pools = self._get_pools() else: pools = [Munch({"id": pool_id})] for pool in pools: volume_candidates = [] try: volume_candidates.extend( self.client.get_volumes_by_pool(pool.id)) except (exceptions.NotFound, exceptions.InternalServerError) as ex: if ERROR_CODE_RESOURCE_NOT_EXISTS or INCORRECT_ID in str( ex.message).upper(): raise array_errors.PoolDoesNotExist( pool.id, self.identifier) else: raise ex for volume in volume_candidates: logger.info("Checking volume: {}".format(volume.name)) if volume.name == volume_name: logger.debug("Found volume: {}".format(volume)) volume.flashcopy = self.get_flashcopies_by_volume( volume.id) return volume return None
def _create_cli_volume(self, name, size_in_bytes, space_efficiency, pool): logger.info( "creating volume with name : {}. size : {} . in pool : {} with parameters : {}" .format(name, size_in_bytes, pool, space_efficiency)) try: size = self._convert_size_bytes(size_in_bytes) cli_kwargs = build_kwargs_from_parameters(space_efficiency, pool, name, size) self.client.svctask.mkvolume(**cli_kwargs) cli_volume = self._get_cli_volume(name) logger.info("finished creating cli volume : {}".format( cli_volume.name)) return cli_volume except (svc_errors.CommandExecutionError, CLIFailureError) as ex: if not is_warning_message(ex.my_message): logger.error(msg="Cannot create volume {0}, " "Reason is: {1}".format(name, ex)) if OBJ_ALREADY_EXIST in ex.my_message: raise array_errors.VolumeAlreadyExists(name, self.endpoint) if NAME_NOT_EXIST_OR_MEET_RULES in ex.my_message: raise array_errors.PoolDoesNotExist(pool, self.endpoint) if (POOL_NOT_MATCH_VOL_CAPABILITIES in ex.my_message or NOT_REDUCTION_POOL in ex.my_message): raise array_errors.PoolDoesNotMatchCapabilities( pool, space_efficiency, ex) if NOT_ENOUGH_EXTENTS_IN_POOL_CREATE in ex.my_message: raise array_errors.NotEnoughSpaceInPool(id_or_name=pool) if any(msg_id in ex.my_message for msg_id in (NON_ASCII_CHARS, INVALID_NAME, TOO_MANY_CHARS)): raise array_errors.IllegalObjectName(ex.my_message) raise ex except Exception as ex: logger.exception(ex) raise ex
def create_volume(self, name, size_in_bytes, capabilities, pool): logger.info( "creating volume with name : {}. size : {} . in pool : {} with capabilities : {}" .format(name, size_in_bytes, pool, capabilities)) size_in_blocks = self._convert_size_bytes_to_blocks(size_in_bytes) try: cli_volume = self.client.cmd.vol_create( vol=name, size_blocks=size_in_blocks, pool=pool).as_single_element logger.info("finished creating cli volume : {}".format(cli_volume)) return self._generate_volume_response(cli_volume) except xcli_errors.IllegalNameForObjectError as ex: logger.exception(ex) raise controller_errors.IllegalObjectName(ex.status) except xcli_errors.VolumeExistsError as ex: logger.exception(ex) raise controller_errors.VolumeAlreadyExists(name, self.endpoint) except xcli_errors.PoolDoesNotExistError as ex: logger.exception(ex) raise controller_errors.PoolDoesNotExist(pool, self.endpoint) except xcli_errors.OperationForbiddenForUserCategoryError as ex: logger.exception(ex) raise controller_errors.PermissionDeniedError( "create vol : {0}".format(name)) except xcli_errors.CommandFailedRuntimeError as ex: logger.exception(ex) if NO_ALLOCATION_SPACE_ERROR in ex.status: raise controller_errors.NotEnoughSpaceInPool(pool=pool)
def get_volume(self, name, volume_context=None, volume_prefix=""): logger.debug("Getting volume {} under context {}".format( name, volume_context)) if not volume_context: logger.error( "volume_context is not specified, can not get volumes from storage." ) raise array_errors.VolumeNotFoundError(name) volume_candidates = [] if config.CONTEXT_POOL in volume_context: try: volume_candidates = self.client.get_volumes_by_pool( volume_context[config.CONTEXT_POOL]) except exceptions.NotFound as ex: if ERROR_CODE_RESOURCE_NOT_EXISTS in str(ex.message).upper(): raise array_errors.PoolDoesNotExist( volume_context[config.CONTEXT_POOL], self.identifier) else: raise ex for vol in volume_candidates: if vol.name == shorten_volume_name(name, volume_prefix): logger.debug("Found volume: {}".format(vol)) return self._generate_volume_response(vol) raise array_errors.VolumeNotFoundError(name)
def _create_cli_volume(self, name, size_in_bytes, capabilities, pool): logger.info("creating volume with name : {}. size : {} . in pool : {} " "with capabilities : {}".format(name, size_in_bytes, pool, capabilities)) try: size = self._convert_size_bytes(size_in_bytes) cli_kwargs = build_kwargs_from_capabilities( capabilities, pool, name, size) self.client.svctask.mkvolume(**cli_kwargs) vol = self._get_cli_volume(name) logger.info("finished creating cli volume : {}".format(vol.name)) return vol except (svc_errors.CommandExecutionError, CLIFailureError) as ex: if not is_warning_message(ex.my_message): logger.error(msg="Cannot create volume {0}, " "Reason is: {1}".format(name, ex)) if OBJ_ALREADY_EXIST in ex.my_message: raise controller_errors.VolumeAlreadyExists( name, self.endpoint) if NAME_NOT_MEET in ex.my_message: raise controller_errors.PoolDoesNotExist( pool, self.endpoint) if (POOL_NOT_MATCH_VOL_CAPABILITIES in ex.my_message or NOT_REDUCTION_POOL in ex.my_message): raise controller_errors.PoolDoesNotMatchCapabilities( pool, capabilities, ex) if NOT_ENOUGH_EXTENTS_IN_POOL_CREATE in ex.my_message: raise controller_errors.NotEnoughSpaceInPool(pool=pool) raise ex except Exception as ex: logger.exception(ex) raise ex
def create_volume(self, name, size_in_bytes, capabilities, pool_id, volume_prefix=""): logger.info("Creating volume with name: {}, size: {}, in pool: {}, " "with capabilities: {}".format(name, size_in_bytes, pool_id, capabilities)) try: cli_kwargs = {} cli_kwargs.update({ 'name': name, 'capacity_in_bytes': size_in_bytes, 'pool_id': pool_id, 'tp': self.get_se_capability_value(capabilities), }) logger.debug("Start to create volume with parameters: {}".format( cli_kwargs)) try: # get the volume before creating again, to make sure it is not existing, # because volume name is not unique in ds8k. volume = self.get_volume( name, volume_context={config.CONTEXT_POOL: pool_id}, volume_prefix=volume_prefix) logger.info("Found volume {}".format(name)) return volume except array_errors.VolumeNotFoundError: volume = self.client.create_volume(**cli_kwargs) logger.info("finished creating volume {}".format(name)) return self._generate_volume_response( self.client.get_volume(volume.id)) except (exceptions.NotFound, exceptions.InternalServerError) as ex: if ERROR_CODE_RESOURCE_NOT_EXISTS or INCORRECT_ID in str( ex.message).upper(): raise array_errors.PoolDoesNotExist(pool_id, self.identifier) else: logger.error( "Failed to create volume {} on array {}, reason is: {}". format(name, self.identifier, ex.details)) raise array_errors.VolumeCreationError(name) except exceptions.ClientException as ex: logger.error( "Failed to create volume {} on array {}, reason is: {}".format( name, self.identifier, ex.details)) raise array_errors.VolumeCreationError(name)
def _create_api_volume(self, name, size_in_bytes, space_efficiency, pool_id): logger.info( "Creating volume with name: {}, size: {}, in pool: {}, with parameters: {}" .format(name, size_in_bytes, pool_id, space_efficiency)) try: cli_kwargs = {} cli_kwargs.update({ 'name': name, 'capacity_in_bytes': size_in_bytes, 'pool_id': pool_id, 'tp': get_array_space_efficiency(space_efficiency), }) logger.debug("Start to create volume with parameters: {}".format( cli_kwargs)) # get the volume before creating again, to make sure it is not existing, # because volume name is not unique in ds8k. api_volume = self._get_api_volume_by_name(name, pool_id=pool_id) logger.info("Found volume {}".format(name)) if api_volume is not None: raise array_errors.VolumeAlreadyExists(name, self.identifier) api_volume = self.client.create_volume(**cli_kwargs) logger.info("finished creating volume {}".format(name)) return self.client.get_volume(api_volume.id) except (exceptions.NotFound, exceptions.InternalServerError) as ex: if ERROR_CODE_RESOURCE_NOT_EXISTS or INCORRECT_ID in str( ex.message).upper(): raise array_errors.PoolDoesNotExist(pool_id, self.identifier) logger.error( "Failed to create volume {} on array {}, reason is: {}".format( name, self.identifier, ex.details)) raise array_errors.VolumeCreationError(name) except (exceptions.ClientError, exceptions.ClientException) as ex: if ERROR_CODE_CREATE_VOLUME_NOT_ENOUGH_EXTENTS in str( ex.message).upper(): raise array_errors.NotEnoughSpaceInPool(id_or_name=pool_id) logger.error( "Failed to create volume {} on array {}, reason is: {}".format( name, self.identifier, ex.details)) raise array_errors.VolumeCreationError(name)
def _get_api_volume_by_name(self, volume_name, pool_id): logger.info("Getting volume {} in pool {}".format(volume_name, pool_id)) if pool_id is None: logger.error( "pool_id is not specified, can not get volumes from storage." ) raise array_errors.PoolParameterIsMissing(self.array_type) try: volume_candidates = [] volume_candidates.extend(self.client.get_volumes_by_pool(pool_id)) except exceptions.ClientException as ex: error_message = str(ex.message).upper() if ERROR_CODE_RESOURCE_NOT_EXISTS in error_message or INCORRECT_ID in error_message: raise array_errors.PoolDoesNotExist(pool_id, self.identifier) raise ex return self._get_api_volume_from_volumes(volume_candidates, volume_name)
def test_create_volume_with_create_volume_with_pool_does_not_exist_exception( self): self.create_volume_returns_error( return_code=grpc.StatusCode.INVALID_ARGUMENT, err=array_errors.PoolDoesNotExist("pool1", "endpoint"))