Exemplo n.º 1
0
 def get(self, namespace, name):
     namespace = (
         namespace if namespace else config().get('deployment', 'default_namespace')
     )
     return self.yatai_service.GetDeployment(
         GetDeploymentRequest(deployment_name=name, namespace=namespace)
     )
Exemplo n.º 2
0
def get_deployment(namespace, name, yatai_service=None):
    if yatai_service is None:
        from bentoml.yatai import get_yatai_service

        yatai_service = get_yatai_service()
    return yatai_service.GetDeployment(
        GetDeploymentRequest(deployment_name=name, namespace=namespace))
Exemplo n.º 3
0
 def get(name, output):
     track_cli('deploy-get')
     result = get_yatai_service().GetDeployment(
         GetDeploymentRequest(deployment_name=name))
     if result.status.status_code != Status.OK:
         _echo(
             'Failed to get deployment {name}. code: {error_code}, message: {error_message}'
             .format(
                 name=name,
                 error_code=Status.Code.Name(result.status.status_code),
                 error_message=result.status.error_message,
             ),
             CLI_COLOR_ERROR,
         )
     else:
         display_deployment_info(result.deployment, output)
Exemplo n.º 4
0
    def create(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_schema(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)
Exemplo n.º 5
0
    def describe(name, output, namespace):
        track_cli('deploy-describe')
        yatai_service = get_yatai_service()

        result = yatai_service.DescribeDeployment(
            DescribeDeploymentRequest(deployment_name=name,
                                      namespace=namespace))
        if result.status.status_code != Status.OK:
            _echo(
                'Failed to describe deployment {name}. code: {error_code}, message: '
                '{error_message}'.format(
                    name=name,
                    error_code=Status.Code.Name(result.status.status_code),
                    error_message=result.status.error_message,
                ),
                CLI_COLOR_ERROR,
            )
        else:
            get_response = yatai_service.GetDeployment(
                GetDeploymentRequest(deployment_name=name,
                                     namespace=namespace))
            deployment_pb = get_response.deployment
            deployment_pb.state.CopyFrom(result.state)
            display_deployment_info(deployment_pb, output)
Exemplo n.º 6
0
def create_deployment(
    deployment_name,
    namespace,
    bento_name,
    bento_version,
    platform,
    operator_spec,
    labels=None,
    annotations=None,
    yatai_service=None,
):
    if yatai_service is None:
        from bentoml.yatai import get_yatai_service

        yatai_service = get_yatai_service()

    # Make sure there is no active deployment with the same deployment name
    get_deployment_pb = yatai_service.GetDeployment(
        GetDeploymentRequest(deployment_name=deployment_name,
                             namespace=namespace))
    if get_deployment_pb.status.status_code == status_pb2.Status.OK:
        raise YataiDeploymentException(
            'Deployment "{name}" already existed, use Update or Apply for updating '
            'existing deployment, delete the deployment, or use a different deployment '
            'name'.format(name=deployment_name))
    if get_deployment_pb.status.status_code != status_pb2.Status.NOT_FOUND:
        raise YataiDeploymentException(
            'Failed accesing YataiService deployment store. {error_code}:'
            '{error_message}'.format(
                error_code=Status.Name(get_deployment_pb.status.status_code),
                error_message=get_deployment_pb.status.error_message,
            ))

    deployment_dict = {
        "name": deployment_name,
        "namespace": namespace
        or config().get('deployment', 'default_namespace'),
        "labels": labels,
        "annotations": annotations,
        "spec": {
            "bento_name": bento_name,
            "bento_version": bento_version,
            "operator": platform,
        },
    }

    operator = platform.replace('-', '_').upper()
    try:
        operator_value = DeploymentSpec.DeploymentOperator.Value(operator)
    except ValueError:
        return ApplyDeploymentResponse(status=Status.INVALID_ARGUMENT(
            'Invalid platform "{}"'.format(platform)))
    if operator_value == DeploymentSpec.AWS_SAGEMAKER:
        deployment_dict['spec']['sagemaker_operator_config'] = {
            'region':
            operator_spec.get('region')
            or config().get('aws', 'default_region'),
            'instance_count':
            operator_spec.get('instance_count'),
            'instance_type':
            operator_spec.get('instance_type'),
            'api_name':
            operator_spec.get('api_name', ''),
        }
        if operator_spec.get('num_of_gunicorn_workers_per_instance'):
            deployment_dict['spec']['sagemaker_operator_config'][
                'num_of_gunicorn_workers_per_instance'] = operator_spec.get(
                    'num_of_gunicorn_workers_per_instance')
    elif operator_value == DeploymentSpec.AWS_LAMBDA:
        deployment_dict['spec']['aws_lambda_operator_config'] = {
            'region':
            operator_spec.get('region')
            or config().get('aws', 'default_region')
        }
        for field in ['api_name', 'memory_size', 'timeout']:
            if operator_spec.get(field):
                deployment_dict['spec']['aws_lambda_operator_config'][
                    field] = operator_spec[field]
    elif operator_value == DeploymentSpec.KUBERNETES:
        deployment_dict['spec']['kubernetes_operator_config'] = {
            'kube_namespace': operator_spec.get('kube_namespace', ''),
            'replicas': operator_spec.get('replicas', 0),
            'service_name': operator_spec.get('service_name', ''),
            'service_type': operator_spec.get('service_type', ''),
        }
    else:
        raise YataiDeploymentException(
            'Platform "{}" is not supported in the current version of '
            'BentoML'.format(platform))

    apply_response = apply_deployment(deployment_dict, yatai_service)

    if apply_response.status.status_code == status_pb2.Status.OK:
        describe_response = describe_deployment(deployment_name, namespace,
                                                yatai_service)
        if describe_response.status.status_code == status_pb2.Status.OK:
            deployment_state = describe_response.state
            apply_response.deployment.state.CopyFrom(deployment_state)
            return apply_response

    return apply_response
Exemplo n.º 7
0
 def get(self, namespace, name):
     return self.yatai_service.GetDeployment(
         GetDeploymentRequest(deployment_name=name, namespace=namespace)
     )
Exemplo n.º 8
0
def create_deployment(
    deployment_name,
    namespace,
    bento_name,
    bento_version,
    platform,
    operator_spec,
    labels=None,
    annotations=None,
    yatai_service=None,
):
    if yatai_service is None:
        from bentoml.yatai import get_yatai_service

        yatai_service = get_yatai_service()

    try:
        # Make sure there is no active deployment with the same deployment name
        get_deployment_pb = yatai_service.GetDeployment(
            GetDeploymentRequest(deployment_name=deployment_name, namespace=namespace)
        )
        if get_deployment_pb.status.status_code == status_pb2.Status.OK:
            raise BentoMLDeploymentException(
                'Deployment "{name}" already existed, use Update or Apply for updating'
                'existing deployment, or create the deployment with a different name or'
                'under a different deployment namespace'.format(name=deployment_name)
            )
        if get_deployment_pb.status.status_code != status_pb2.Status.NOT_FOUND:
            raise BentoMLDeploymentException(
                'Failed accesing YataiService deployment store. {error_code}:'
                '{error_message}'.format(
                    error_code=Status.Name(get_deployment_pb.status.status_code),
                    error_message=get_deployment_pb.status.error_message,
                )
            )

        deployment_dict = {
            "name": deployment_name,
            "namespace": namespace or config().get('deployment', 'default_namespace'),
            "labels": labels,
            "annotations": annotations,
            "spec": {
                "bento_name": bento_name,
                "bento_version": bento_version,
                "operator": platform,
            },
        }

        operator = platform.replace('-', '_').upper()
        try:
            operator_value = DeploymentSpec.DeploymentOperator.Value(operator)
        except ValueError:
            return ApplyDeploymentResponse(
                status=Status.INVALID_ARGUMENT('Invalid platform "{}"'.format(platform))
            )
        if operator_value == DeploymentSpec.AWS_SAGEMAKER:
            deployment_dict['spec']['sagemaker_operator_config'] = {
                'region': operator_spec.get('region')
                or config().get('aws', 'default_region'),
                'instance_count': operator_spec.get('instance_count')
                or config().getint('sagemaker', 'default_instance_count'),
                'instance_type': operator_spec.get('instance_type')
                or config().get('sagemaker', 'default_instance_type'),
                'api_name': operator_spec.get('api_name', ''),
            }
        elif operator_value == DeploymentSpec.AWS_LAMBDA:
            deployment_dict['spec']['aws_lambda_operator_config'] = {
                'region': operator_spec.get('region')
                or config().get('aws', 'default_region')
            }
            if operator_spec.get('api_name'):
                deployment_dict['spec']['aws_lambda_operator_config'][
                    'api_name'
                ] = operator_spec['api_name']
        elif operator_value == DeploymentSpec.GCP_FCUNTION:
            deployment_dict['spec']['gcp_function_operatorConfig'] = {
                'region': operator_spec.get('region')
                or config().get('google-cloud', 'default_region')
            }
            if operator_spec.get('api_name'):
                deployment_dict['spec']['gcp_function_operator_config'][
                    'api_name'
                ] = operator_spec['api_name']
        elif operator_value == DeploymentSpec.KUBERNETES:
            deployment_dict['spec']['kubernetes_operator_config'] = {
                'kube_namespace': operator_spec.get('kube_namespace', ''),
                'replicas': operator_spec.get('replicas', 0),
                'service_name': operator_spec.get('service_name', ''),
                'service_type': operator_spec.get('service_type', ''),
            }
        else:
            raise BentoMLDeploymentException(
                'Platform "{}" is not supported in the current version of '
                'BentoML'.format(platform)
            )

        return apply_deployment(deployment_dict, yatai_service)
    except BentoMLException as error:
        return ApplyDeploymentResponse(status=Status.INTERNAL(str(error)))
Exemplo n.º 9
0
    def create(
        name,
        bento,
        platform,
        output,
        namespace,
        labels,
        annotations,
        region,
        instance_type,
        instance_count,
        api_name,
        kube_namespace,
        replicas,
        service_name,
        service_type,
        wait,
    ):
        # converting platform parameter to DeploymentOperator name in proto
        # e.g. 'aws-lambda' to 'AWS_LAMBDA'
        platform = platform.replace('-', '_').upper()
        operator = DeploymentSpec.DeploymentOperator.Value(platform)

        track_cli('deploy-create', platform)

        yatai_service = get_yatai_service()

        # Make sure there is no active deployment with the same deployment name
        get_deployment = yatai_service.GetDeployment(
            GetDeploymentRequest(deployment_name=name, namespace=namespace))
        if get_deployment.status.status_code != Status.NOT_FOUND:
            raise BentoMLDeploymentException(
                'Deployment {name} already existed, please use update or apply command'
                ' instead'.format(name=name))

        if operator == DeploymentSpec.AWS_SAGEMAKER:
            if not api_name:
                raise click.BadParameter(
                    'api-name is required for Sagemaker deployment')

            sagemaker_operator_config = DeploymentSpec.SageMakerOperatorConfig(
                region=region or config().get('aws', 'default_region'),
                instance_count=instance_count
                or config().getint('sagemaker', 'instance_count'),
                instance_type=instance_type
                or config().get('sagemaker', 'instance_type'),
                api_name=api_name,
            )
            spec = DeploymentSpec(
                sagemaker_operator_config=sagemaker_operator_config)
        elif operator == DeploymentSpec.AWS_LAMBDA:
            aws_lambda_operator_config = DeploymentSpec.AwsLambdaOperatorConfig(
                region=region or config().get('aws', 'default_region'))
            if api_name:
                aws_lambda_operator_config.api_name = api_name
            spec = DeploymentSpec(
                aws_lambda_operator_config=aws_lambda_operator_config)
        elif operator == DeploymentSpec.GCP_FUNCTION:
            gcp_function_operator_config = DeploymentSpec.GcpFunctionOperatorConfig(
                region=region
                or config().get('google-cloud', 'default_region'))
            if api_name:
                gcp_function_operator_config.api_name = api_name
            spec = DeploymentSpec(
                gcp_function_operator_config=gcp_function_operator_config)
        elif operator == DeploymentSpec.KUBERNETES:
            kubernetes_operator_config = DeploymentSpec.KubernetesOperatorConfig(
                kube_namespace=kube_namespace,
                replicas=replicas,
                service_name=service_name,
                service_type=service_type,
            )
            spec = DeploymentSpec(
                kubernetes_operator_config=kubernetes_operator_config)
        else:
            raise BentoMLDeploymentException(
                'Custom deployment is not supported in the current version of BentoML'
            )

        bento_name, bento_version = bento.split(':')
        spec.bento_name = bento_name
        spec.bento_version = bento_version
        spec.operator = operator

        result = yatai_service.ApplyDeployment(
            ApplyDeploymentRequest(deployment=Deployment(
                namespace=namespace,
                name=name,
                annotations=parse_key_value_pairs(annotations),
                labels=parse_key_value_pairs(labels),
                spec=spec,
            )))
        if result.status.status_code != Status.OK:
            _echo(
                'Failed to create deployment {name}. {error_code}: '
                '{error_message}'.format(
                    name=name,
                    error_code=Status.Code.Name(result.status.status_code),
                    error_message=result.status.error_message,
                ),
                CLI_COLOR_ERROR,
            )
        else:
            if wait:
                result_state = get_state_after_await_action_complete(
                    yatai_service=yatai_service,
                    name=name,
                    namespace=namespace,
                    message='Creating deployment ',
                )
                result.deployment.state.CopyFrom(result_state.state)

            _echo('Successfully created deployment {}'.format(name),
                  CLI_COLOR_SUCCESS)
            display_deployment_info(result.deployment, output)