Coverage for /builds/BuildGrid/buildgrid/buildgrid/server/capabilities/instance.py: 100.00%
35 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-10-04 17:48 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-10-04 17:48 +0000
1# Copyright (C) 2018 Bloomberg LP
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# <http://www.apache.org/licenses/LICENSE-2.0>
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14from typing import Optional, Union
16from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import DESCRIPTOR as RE_DESCRIPTOR
17from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import (
18 ActionCacheUpdateCapabilities,
19 CacheCapabilities,
20 ExecutionCapabilities,
21 ServerCapabilities,
22 SymlinkAbsolutePathStrategy,
23)
24from buildgrid._protos.build.bazel.semver.semver_pb2 import SemVer
25from buildgrid.server.actioncache.caches.action_cache_abc import ActionCacheABC
26from buildgrid.server.actioncache.instance import ActionCache
27from buildgrid.server.cas.instance import ContentAddressableStorageInstance
28from buildgrid.server.execution.instance import ExecutionInstance
29from buildgrid.server.servicer import Instance
30from buildgrid.server.settings import HIGH_REAPI_VERSION, LOW_REAPI_VERSION, MAX_REQUEST_SIZE
31from buildgrid.server.utils.digests import get_hash_type
33ActionCacheInstance = Union[ActionCache, ActionCacheABC]
36class CapabilitiesInstance(Instance):
37 SERVICE_NAME = RE_DESCRIPTOR.services_by_name["Capabilities"].full_name
39 def __init__(
40 self,
41 cas_instance: Optional["ContentAddressableStorageInstance"] = None,
42 action_cache_instance: Optional["ActionCacheInstance"] = None,
43 execution_instance: Optional["ExecutionInstance"] = None,
44 ) -> None:
45 self._cas_instance = cas_instance
46 self._action_cache_instance = action_cache_instance
47 self._execution_instance = execution_instance
48 self._high_api_version = _split_semantic_version(HIGH_REAPI_VERSION)
49 self._low_api_version = _split_semantic_version(LOW_REAPI_VERSION)
51 def add_cas_instance(self, cas_instance: "ContentAddressableStorageInstance") -> None:
52 self._cas_instance = cas_instance
54 def add_action_cache_instance(self, action_cache_instance: "ActionCacheInstance") -> None:
55 self._action_cache_instance = action_cache_instance
57 def add_execution_instance(self, execution_instance: "ExecutionInstance") -> None:
58 self._execution_instance = execution_instance
60 def get_capabilities(self) -> ServerCapabilities:
61 # The caching capabilities are VERY hardcoded by the buildgrid server components.
62 # Simply forwarding abilities from remote storage or local components does more
63 # harm than good, as the remote capabilities do not feed into usage by most components.
64 #
65 # The most sane way to override these values would be via server configuration,
66 # not by dynamically fetching the capabilities remotely.
67 #
68 # If we want to properly support this functionality, a large refactor would be needed.
69 return ServerCapabilities(
70 cache_capabilities=CacheCapabilities(
71 digest_functions=[get_hash_type()],
72 max_batch_total_size_bytes=MAX_REQUEST_SIZE,
73 symlink_absolute_path_strategy=SymlinkAbsolutePathStrategy.DISALLOWED,
74 action_cache_update_capabilities=ActionCacheUpdateCapabilities(
75 update_enabled=bool(self._action_cache_instance and self._action_cache_instance.allow_updates)
76 ),
77 ),
78 execution_capabilities=ExecutionCapabilities(
79 exec_enabled=self._execution_instance is not None,
80 digest_function=get_hash_type(),
81 digest_functions=[get_hash_type()],
82 ),
83 low_api_version=self._low_api_version,
84 high_api_version=self._high_api_version,
85 )
88def _split_semantic_version(version_string: str) -> SemVer:
89 major_version, minor_version, patch_version = version_string.split(".")
91 semantic_version = SemVer()
92 semantic_version.major = int(major_version)
93 semantic_version.minor = int(minor_version)
94 semantic_version.patch = int(patch_version)
96 return semantic_version