def test_validate_aws_lambda_schema(): deployment_pb = _get_test_lambda_deployment_pb() assert validate_deployment_pb(deployment_pb) is None deployment_pb_with_bad_memory_size = _get_test_lambda_deployment_pb() deployment_pb_with_bad_memory_size.spec.aws_lambda_operator_config.timeout = 1000 deployment_pb_with_bad_memory_size.spec.aws_lambda_operator_config.memory_size = 129 errors = validate_deployment_pb(deployment_pb_with_bad_memory_size) aws_spec_fail_msg = errors['spec'][0]['aws_lambda_operator_config'][0] assert 'AWS Lambda memory' in aws_spec_fail_msg['memory_size'][0] assert 'max value is 900' in aws_spec_fail_msg['timeout'][0]
def apply(self, deployment_info, wait): if isinstance(deployment_info, dict): deployment_pb = deployment_dict_to_pb(deployment_info) elif isinstance(deployment_info, str): deployment_pb = deployment_yaml_string_to_pb(deployment_info) elif isinstance(deployment_info, Deployment): deployment_pb = deployment_info else: raise YataiDeploymentException( 'Unexpected argument type, expect deployment info to be str in yaml ' 'format or a dict or a deployment protobuf obj, instead got: {}' .format(str(type(deployment_info)))) validation_errors = validate_deployment_pb(deployment_pb) if validation_errors: raise YataiDeploymentException( f'Failed to validate deployment {deployment_pb.name}: ' f'{validation_errors}') apply_result = self.yatai_service.ApplyDeployment( ApplyDeploymentRequest(deployment=deployment_pb)) if apply_result.status.status_code != status_pb2.Status.OK: error_code, error_message = status_pb_to_error_code_and_message( apply_result.status) raise YataiDeploymentException(f'{error_code}:{error_message}') if wait: self._wait_deployment_action_complete(deployment_pb.name, deployment_pb.namespace) return self.get(namespace=deployment_pb.namespace, name=deployment_pb.name)
def test_validate_deployment_pb_schema(): deployment_pb = _get_test_sagemaker_deployment_pb() assert validate_deployment_pb(deployment_pb) is None deployment_pb_with_empty_name = _get_test_sagemaker_deployment_pb() deployment_pb_with_empty_name.name = '' errors = validate_deployment_pb(deployment_pb_with_empty_name) assert errors == {'name': ['required field']} deployment_pb_with_invalid_service_version = _get_test_sagemaker_deployment_pb( ) deployment_pb_with_invalid_service_version.spec.bento_version = 'latest' errors = validate_deployment_pb(deployment_pb_with_invalid_service_version) assert errors['spec'][0]['bento_version'] == [ 'Must use specific "bento_version" in deployment, using "latest" is an ' 'anti-pattern.' ]
def create(self, deployment_info, wait): from bentoml.yatai.validator import validate_deployment_pb if isinstance(deployment_info, dict): deployment_pb = deployment_dict_to_pb(deployment_info) elif isinstance(deployment_info, str): deployment_pb = deployment_yaml_string_to_pb(deployment_info) elif isinstance(deployment_info, Deployment): deployment_pb = deployment_info else: raise YataiDeploymentException( 'Unexpected argument type, expect deployment info to be str in yaml ' 'format or a dict or a deployment protobuf obj, instead got: {}'.format( str(type(deployment_info)) ) ) validation_errors = validate_deployment_pb(deployment_pb) if validation_errors: raise YataiDeploymentException( f'Failed to validate deployment {deployment_pb.name}: ' f'{validation_errors}' ) # Make sure there is no active deployment with the same deployment name get_deployment_pb = self.yatai_service.GetDeployment( GetDeploymentRequest( deployment_name=deployment_pb.name, namespace=deployment_pb.namespace ) ) if get_deployment_pb.status.status_code != status_pb2.Status.NOT_FOUND: raise BentoMLException( f'Deployment "{deployment_pb.name}" already existed, use Update or ' f'Apply for updating existing deployment, delete the deployment, ' f'or use a different deployment name' ) apply_result = self.yatai_service.ApplyDeployment( ApplyDeploymentRequest(deployment=deployment_pb) ) if apply_result.status.status_code != status_pb2.Status.OK: error_code, error_message = status_pb_to_error_code_and_message( apply_result.status ) raise YataiDeploymentException(f'{error_code}:{error_message}') if wait: self._wait_deployment_action_complete( deployment_pb.name, deployment_pb.namespace ) return self.get(namespace=deployment_pb.namespace, name=deployment_pb.name)
def ApplyDeployment(self, request, context=None): try: # apply default namespace if not set request.deployment.namespace = (request.deployment.namespace or self.default_namespace) validation_errors = validate_deployment_pb(request.deployment) if validation_errors: raise InvalidArgument( 'Failed to validate deployment. {errors}'.format( errors=validation_errors)) previous_deployment = self.deployment_store.get( request.deployment.name, request.deployment.namespace) if not previous_deployment: request.deployment.created_at.GetCurrentTime() request.deployment.last_updated_at.GetCurrentTime() self.deployment_store.insert_or_update(request.deployment) # find deployment operator based on deployment spec operator = get_deployment_operator(self, request.deployment) # deploying to target platform if previous_deployment: response = operator.update(request.deployment, previous_deployment) else: response = operator.add(request.deployment) if response.status.status_code == status_pb2.Status.OK: # update deployment state if response and response.deployment: self.deployment_store.insert_or_update(response.deployment) else: raise BentoMLException( "DeploymentOperator Internal Error: failed to add or update " "deployment metadata to database") logger.info( "ApplyDeployment (%s, namespace %s) succeeded", request.deployment.name, request.deployment.namespace, ) else: if not previous_deployment: # When failed to create the deployment, delete it from active # deployments records self.deployment_store.delete(request.deployment.name, request.deployment.namespace) logger.debug( "ApplyDeployment (%s, namespace %s) failed: %s", request.deployment.name, request.deployment.namespace, response.status.error_message, ) return response except BentoMLException as e: logger.error("RPC ERROR ApplyDeployment: %s", e) return ApplyDeploymentResponse(status=e.status_proto) except Exception as e: logger.error("URPC ERROR ApplyDeployment: %s", e) return ApplyDeploymentResponse(status=Status.INTERNAL(str(e)))