167 lines
5.4 KiB
Python
167 lines
5.4 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Wraps a Cloud Run revision message with convenience methods."""
|
|
|
|
from googlecloudsdk.api_lib.run import container_resource
|
|
from googlecloudsdk.api_lib.run import k8s_object
|
|
|
|
# Label names as to be stored in k8s object metadata
|
|
SERVICE_LABEL = 'serving.knative.dev/service'
|
|
WORKER_POOL_LABEL = 'run.googleapis.com/workerPool'
|
|
# Used to force a new revision, and also to tie a particular request for changes
|
|
# to a particular created revision.
|
|
NONCE_LABEL = 'client.knative.dev/nonce'
|
|
MIN_SCALE_ANNOTATION = 'autoscaling.knative.dev/minScale'
|
|
MAX_SCALE_ANNOTATION = 'autoscaling.knative.dev/maxScale'
|
|
# gcloud-disable-gdu-domain
|
|
SESSION_AFFINITY_ANNOTATION = 'run.googleapis.com/sessionAffinity'
|
|
# gcloud-disable-gdu-domain
|
|
MESH_ANNOTATION = 'run.googleapis.com/mesh'
|
|
# gcloud-disable-gdu-domain
|
|
BASE_IMAGES_ANNOTATION = 'run.googleapis.com/base-images'
|
|
# gcloud-disable-gdu-domain
|
|
IDENTITY_ANNOTATION = 'run.googleapis.com/identity'
|
|
# gcloud-disable-gdu-domain
|
|
IDENTITY_CERTIFICATE_ENABLED_ANNOTATION = (
|
|
'run.googleapis.com/identity-certificate-enabled'
|
|
)
|
|
# gcloud-disable-gdu-domain
|
|
IDENTITY_TYPE_ANNOTATION = 'run.googleapis.com/identity-type'
|
|
# gcloud-disable-gdu-domain
|
|
MESH_DATAPLANE_ANNOTATION = 'run.googleapis.com/mesh-dataplane'
|
|
# gcloud-disable-gdu-domain
|
|
BASE_IMAGE_UPDATE_RUNTIME_CLASS_NAME = (
|
|
'run.googleapis.com/linux-base-image-update'
|
|
)
|
|
# gcloud-disable-gdu-domain
|
|
GPU_ZONAL_REDUNDANCY_DISABLED_ANNOTATION = (
|
|
'run.googleapis.com/gpu-zonal-redundancy-disabled'
|
|
)
|
|
# gcloud-disable-gdu-domain
|
|
SOURCES_ANNOTATION = (
|
|
'run.googleapis.com/sources'
|
|
)
|
|
# If true, overflow scaling capabilities are enabled for this revision.
|
|
OVERFLOW_SCALING_ANNOTATION = 'run.googleapis.com/overflow-scaling'
|
|
# Annotation to set the CPU utilization target for scaling.
|
|
CPU_UTILIZATION_ANNOTATION = 'run.googleapis.com/scaling-cpu-target'
|
|
# Annotation to set the concurrency utilization target for scaling.
|
|
CONCURRENCY_UTILIZATION_ANNOTATION = 'run.googleapis.com/scaling-concurrency-target'
|
|
|
|
|
|
class Revision(container_resource.ContainerResource):
|
|
"""Wraps a Cloud Run Revision message, making fields more convenient."""
|
|
|
|
API_CATEGORY = 'serving.knative.dev'
|
|
KIND = 'Revision'
|
|
READY_CONDITION = 'Ready'
|
|
_ACTIVE_CONDITION = 'Active'
|
|
TERMINAL_CONDITIONS = frozenset([
|
|
READY_CONDITION,
|
|
])
|
|
|
|
@property
|
|
def gcs_location(self):
|
|
return self._m.status.gcs.location
|
|
|
|
@property
|
|
def service_name(self):
|
|
return self.labels[SERVICE_LABEL] if SERVICE_LABEL in self.labels else None
|
|
|
|
@property
|
|
def worker_pool_name(self):
|
|
return (
|
|
self.labels[WORKER_POOL_LABEL]
|
|
if WORKER_POOL_LABEL in self.labels
|
|
else None
|
|
)
|
|
|
|
@property
|
|
def serving_state(self):
|
|
return self.spec.servingState
|
|
|
|
@property
|
|
def active(self):
|
|
cond = self.conditions
|
|
if self._ACTIVE_CONDITION in cond:
|
|
return cond[self._ACTIVE_CONDITION]['status']
|
|
return None
|
|
|
|
@property
|
|
def concurrency(self):
|
|
"""The concurrency number in the revisionTemplate.
|
|
|
|
0: Multiple concurrency, max unspecified.
|
|
1: Single concurrency
|
|
n>1: Allow n simultaneous requests per instance.
|
|
"""
|
|
return self.spec.containerConcurrency
|
|
|
|
@concurrency.setter
|
|
def concurrency(self, value):
|
|
# Clear the old, deperecated string field
|
|
try:
|
|
self.spec.concurrencyModel = None
|
|
except AttributeError:
|
|
# This field only exists in the v1alpha1 spec, if we're working with a
|
|
# different version, this is safe to ignore
|
|
pass
|
|
self.spec.containerConcurrency = value
|
|
|
|
@property
|
|
def timeout(self):
|
|
"""The timeout number in the revisionTemplate.
|
|
|
|
The lib can accept either a duration format like '1m20s' or integer like
|
|
'80' to set the timeout. The returned object is an integer value, which
|
|
assumes second the unit, e.g., 80.
|
|
"""
|
|
return self.spec.timeoutSeconds
|
|
|
|
@timeout.setter
|
|
def timeout(self, value):
|
|
self.spec.timeoutSeconds = value
|
|
|
|
@property
|
|
def service_account(self):
|
|
"""The service account in the revisionTemplate."""
|
|
return self.spec.serviceAccountName
|
|
|
|
@service_account.setter
|
|
def service_account(self, value):
|
|
self.spec.serviceAccountName = value
|
|
|
|
@property
|
|
def image_digest(self):
|
|
"""The URL of the image, by digest. Stable when tags are not."""
|
|
return self.status.imageDigest
|
|
|
|
def _EnsureNodeSelector(self):
|
|
if self.spec.nodeSelector is None:
|
|
self.spec.nodeSelector = k8s_object.InitializedInstance(
|
|
self._messages.RevisionSpec.NodeSelectorValue
|
|
)
|
|
|
|
@property
|
|
def node_selector(self):
|
|
"""The node selector as a dictionary { accelerator_type: value}."""
|
|
self._EnsureNodeSelector()
|
|
return k8s_object.KeyValueListAsDictionaryWrapper(
|
|
self.spec.nodeSelector.additionalProperties,
|
|
self._messages.RevisionSpec.NodeSelectorValue.AdditionalProperty,
|
|
key_field='key',
|
|
value_field='value',
|
|
)
|