xref: /aosp_15_r20/external/bazelbuild-remote-apis/build/bazel/remote/asset/v1/remote_asset.proto (revision ae21b2b400d1606a797985382019aea74177085c)
1// Copyright 2020 The Bazel Authors.
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.
14
15syntax = "proto3";
16
17package build.bazel.remote.asset.v1;
18
19import "build/bazel/remote/execution/v2/remote_execution.proto";
20import "google/api/annotations.proto";
21import "google/protobuf/duration.proto";
22import "google/protobuf/timestamp.proto";
23import "google/rpc/status.proto";
24
25option csharp_namespace = "Build.Bazel.Remote.Asset.v1";
26option go_package = "github.com/bazelbuild/remote-apis/build/bazel/remote/asset/v1;remoteasset";
27option java_multiple_files = true;
28option java_outer_classname = "RemoteAssetProto";
29option java_package = "build.bazel.remote.asset.v1";
30option objc_class_prefix = "RA";
31
32// The Remote Asset API provides a mapping from a URI and Qualifiers to
33// Digests.
34//
35// Multiple URIs may be used to refer to the same content.  For example, the
36// same tarball may exist at multiple mirrors and thus be retrievable from
37// multiple URLs.  When URLs are used, these should refer to actual content as
38// Fetch service implementations may choose to fetch the content directly
39// from the origin.  For example, the HEAD of a git repository's active branch
40// can be referred to as:
41//
42//     uri: https://github.com/bazelbuild/remote-apis.git
43//
44// URNs may be used to strongly identify content, for instance by using the
45// uuid namespace identifier: urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6.
46// This is most applicable to named content that is Push'd, where the URN
47// serves as an agreed-upon key, but carries no other inherent meaning.
48//
49// Service implementations may choose to support only URLs, only URNs for
50// Push'd content, only other URIs for which the server and client agree upon
51// semantics of, or any mixture of the above.
52
53// Qualifiers are used to disambiguate or sub-select content that shares a URI.
54// This may include specifying a particular commit or branch, in the case of
55// URIs referencing a repository; they could also be used to specify a
56// particular subdirectory of a repository or tarball. Qualifiers may also be
57// used to ensure content matches what the client expects, even when there is
58// no ambiguity to be had - for example, a qualifier specifying a checksum
59// value.
60//
61// In cases where the semantics of the request are not immediately clear from
62// the URL and/or qualifiers - e.g. dictated by URL scheme - it is recommended
63// to use an additional qualifier to remove the ambiguity. The `resource_type`
64// qualifier is recommended for this purpose.
65//
66// Qualifiers may be supplied in any order.
67message Qualifier {
68  // The "name" of the qualifier, for example "resource_type".
69  // No separation is made between 'standard' and 'nonstandard'
70  // qualifiers, in accordance with https://tools.ietf.org/html/rfc6648,
71  // however implementers *SHOULD* take care to avoid ambiguity.
72  string name = 1;
73
74  // The "value" of the qualifier. Semantics will be dictated by the name.
75  string value = 2;
76}
77
78// The Fetch service resolves or fetches assets referenced by URI and
79// Qualifiers, returning a Digest for the content in
80// [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
81//
82// As with other services in the Remote Execution API, any call may return an
83// error with a [RetryInfo][google.rpc.RetryInfo] error detail providing
84// information about when the client should retry the request; clients SHOULD
85// respect the information provided.
86service Fetch {
87  // Resolve or fetch referenced assets, making them available to the caller and
88  // other consumers in the [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
89  //
90  // Servers *MAY* fetch content that they do not already have cached, for any
91  // URLs they support.
92  //
93  // Servers *SHOULD* ensure that referenced files are present in the CAS at the
94  // time of the response, and (if supported) that they will remain available
95  // for a reasonable period of time. The lifetimes of the referenced blobs *SHOULD*
96  // be increased if necessary and applicable.
97  // In the event that a client receives a reference to content that is no
98  // longer present, it *MAY* re-issue the request with
99  // `oldest_content_accepted` set to a more recent timestamp than the original
100  // attempt, to induce a re-fetch from origin.
101  //
102  // Servers *MAY* cache fetched content and reuse it for subsequent requests,
103  // subject to `oldest_content_accepted`.
104  //
105  // Servers *MAY* support the complementary [Push][build.bazel.remote.asset.v1.Push]
106  // API and allow content to be directly inserted for use in future fetch
107  // responses.
108  //
109  // Servers *MUST* ensure Fetch'd content matches all the specified
110  // qualifiers except in the case of previously Push'd resources, for which
111  // the server *MAY* trust the pushing client to have set the qualifiers
112  // correctly, without validation.
113  //
114  // Servers not implementing the complementary [Push][build.bazel.remote.asset.v1.Push]
115  // API *MUST* reject requests containing qualifiers it does not support.
116  //
117  // Servers *MAY* transform assets as part of the fetch. For example a
118  // tarball fetched by [FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory]
119  // might be unpacked, or a Git repository
120  // fetched by [FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob]
121  // might be passed through `git-archive`.
122  //
123  // Errors handling the requested assets will be returned as gRPC Status errors
124  // here; errors outside the server's control will be returned inline in the
125  // `status` field of the response (see comment there for details).
126  // The possible RPC errors include:
127  // * `INVALID_ARGUMENT`: One or more arguments were invalid, such as a
128  //   qualifier that is not supported by the server.
129  // * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
130  //   perform the requested operation. The client may retry after a delay.
131  // * `UNAVAILABLE`: Due to a transient condition the operation could not be
132  //   completed. The client should retry.
133  // * `INTERNAL`: An internal error occurred while performing the operation.
134  //   The client should retry.
135  // * `DEADLINE_EXCEEDED`: The fetch could not be completed within the given
136  //   RPC deadline. The client should retry for at least as long as the value
137  //   provided in `timeout` field of the request.
138  //
139  // In the case of unsupported qualifiers, the server *SHOULD* additionally
140  // send a [BadRequest][google.rpc.BadRequest] error detail where, for each
141  // unsupported qualifier, there is a `FieldViolation` with a `field` of
142  // `qualifiers.name` and a `description` of `"{qualifier}" not supported`
143  // indicating the name of the unsupported qualifier.
144  rpc FetchBlob(FetchBlobRequest) returns (FetchBlobResponse) {
145    option (google.api.http) = { post: "/v1/{instance_name=**}/assets:fetchBlob" body: "*" };
146  }
147  rpc FetchDirectory(FetchDirectoryRequest) returns (FetchDirectoryResponse) {
148    option (google.api.http) = { post: "/v1/{instance_name=**}/assets:fetchDirectory" body: "*" };
149  }
150}
151
152// A request message for
153// [Fetch.FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
154message FetchBlobRequest {
155  // The instance of the execution system to operate against. A server may
156  // support multiple instances of the execution system (with their own workers,
157  // storage, caches, etc.). The server MAY require use of this field to select
158  // between them in an implementation-defined fashion, otherwise it can be
159  // omitted.
160  string instance_name = 1;
161
162  // The timeout for the underlying fetch, if content needs to be retrieved from
163  // origin.
164  //
165  // If unset, the server *MAY* apply an implementation-defined timeout.
166  //
167  // If set, and the user-provided timeout exceeds the RPC deadline, the server
168  // *SHOULD* keep the fetch going after the RPC completes, to be made
169  // available for future Fetch calls. The server may also enforce (via clamping
170  // and/or an INVALID_ARGUMENT error) implementation-defined minimum and
171  // maximum timeout values.
172  //
173  // If this timeout is exceeded on an attempt to retrieve content from origin
174  // the client will receive DEADLINE_EXCEEDED in [FetchBlobResponse.status].
175  google.protobuf.Duration timeout = 2;
176
177  // The oldest content the client is willing to accept, as measured from the
178  // time it was Push'd or when the underlying retrieval from origin was
179  // started.
180  // Upon retries of Fetch requests that cannot be completed within a single
181  // RPC, clients *SHOULD* provide the same value for subsequent requests as the
182  // original, to simplify combining the request with the previous attempt.
183  //
184  // If unset, the client *SHOULD* accept content of any age.
185  google.protobuf.Timestamp oldest_content_accepted = 3;
186
187  // The URI(s) of the content to fetch. These may be resources that the server
188  // can directly fetch from origin, in which case multiple URIs *SHOULD*
189  // represent the same content available at different locations (such as an
190  // origin and secondary mirrors). These may also be URIs for content known to
191  // the server through other mechanisms, e.g. pushed via the [Push][build.bazel.remote.asset.v1.Push]
192  // service.
193  //
194  // Clients *MUST* supply at least one URI. Servers *MAY* match any one of the
195  // supplied URIs.
196  repeated string uris = 4;
197
198  // Qualifiers sub-specifying the content to fetch - see comments on
199  // [Qualifier][build.bazel.remote.asset.v1.Qualifier].
200  // The same qualifiers apply to all URIs.
201  //
202  // Specified qualifier names *MUST* be unique.
203  repeated Qualifier qualifiers = 5;
204
205  // The digest function the server must use to compute the digest.
206  //
207  // If unset, the server SHOULD default to SHA256.
208  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 6;
209}
210
211// A response message for
212// [Fetch.FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
213message FetchBlobResponse {
214  // If the status has a code other than `OK`, it indicates that the operation
215  // was unable to be completed for reasons outside the servers' control.
216  // The possible fetch errors include:
217  // * `DEADLINE_EXCEEDED`: The operation could not be completed within the
218  //   specified timeout.
219  // * `NOT_FOUND`: The requested asset was not found at the specified location.
220  // * `PERMISSION_DENIED`: The request was rejected by a remote server, or
221  //   requested an asset from a disallowed origin.
222  // * `ABORTED`: The operation could not be completed, typically due to a
223  //   failed consistency check.
224  // * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
225  //   perform the requested operation. The client may retry after a delay.
226  google.rpc.Status status = 1;
227
228  // The uri from the request that resulted in a successful retrieval, or from
229  // which the error indicated in `status` was obtained.
230  string uri = 2;
231
232  // Any qualifiers known to the server and of interest to clients.
233  repeated Qualifier qualifiers = 3;
234
235  // A minimum timestamp the content is expected to be available through.
236  // Servers *MAY* omit this field, if not known with confidence.
237  google.protobuf.Timestamp expires_at = 4;
238
239  // The result of the fetch, if the status had code `OK`.
240  // The digest of the file's contents, available for download through the CAS.
241  build.bazel.remote.execution.v2.Digest blob_digest = 5;
242
243  // This field SHOULD be set to the digest function that was used by the server
244  // to compute [FetchBlobResponse.blob_digest].
245  // Clients could use this to determine whether the server honors
246  // [FetchBlobRequest.digest_function] that was set in the request.
247  //
248  // If unset, clients SHOULD default to use SHA256 regardless of the requested
249  // [FetchBlobRequest.digest_function].
250  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 6;
251}
252
253// A request message for
254// [Fetch.FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
255message FetchDirectoryRequest {
256  // The instance of the execution system to operate against. A server may
257  // support multiple instances of the execution system (with their own workers,
258  // storage, caches, etc.). The server MAY require use of this field to select
259  // between them in an implementation-defined fashion, otherwise it can be
260  // omitted.
261  string instance_name = 1;
262
263  // The timeout for the underlying fetch, if content needs to be retrieved from
264  // origin. This value is allowed to exceed the RPC deadline, in which case the
265  // server *SHOULD* keep the fetch going after the RPC completes, to be made
266  // available for future Fetch calls.
267  //
268  // If this timeout is exceeded on an attempt to retrieve content from origin
269  // the client will receive DEADLINE_EXCEEDED in [FetchDirectoryResponse.status].
270  google.protobuf.Duration timeout = 2;
271
272  // The oldest content the client is willing to accept, as measured from the
273  // time it was Push'd or when the underlying retrieval from origin was
274  // started.
275  // Upon retries of Fetch requests that cannot be completed within a single
276  // RPC, clients *SHOULD* provide the same value for subsequent requests as the
277  // original, to simplify combining the request with the previous attempt.
278  //
279  // If unset, the client *SHOULD* accept content of any age.
280  google.protobuf.Timestamp oldest_content_accepted = 3;
281
282  // The URI(s) of the content to fetch. These may be resources that the server
283  // can directly fetch from origin, in which case multiple URIs *SHOULD*
284  // represent the same content available at different locations (such as an
285  // origin and secondary mirrors). These may also be URIs for content known to
286  // the server through other mechanisms, e.g. pushed via the [Push][build.bazel.remote.asset.v1.Push]
287  // service.
288  //
289  // Clients *MUST* supply at least one URI. Servers *MAY* match any one of the
290  // supplied URIs.
291  repeated string uris = 4;
292
293  // Qualifiers sub-specifying the content to fetch - see comments on
294  // [Qualifier][build.bazel.remote.asset.v1.Qualifier].
295  // The same qualifiers apply to all URIs.
296  //
297  // Specified qualifier names *MUST* be unique.
298  repeated Qualifier qualifiers = 5;
299
300  // The digest function the server must use to compute the digest.
301  //
302  // If unset, the server SHOULD default to SHA256.
303  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 6;
304}
305
306// A response message for
307// [Fetch.FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
308message FetchDirectoryResponse {
309  // If the status has a code other than `OK`, it indicates that the operation
310  // was unable to be completed for reasons outside the servers' control.
311  // The possible fetch errors include:
312  // * `DEADLINE_EXCEEDED`: The operation could not be completed within the
313  //   specified timeout.
314  // * `NOT_FOUND`: The requested asset was not found at the specified location.
315  // * `PERMISSION_DENIED`: The request was rejected by a remote server, or
316  //   requested an asset from a disallowed origin.
317  // * `ABORTED`: The operation could not be completed, typically due to a
318  //   failed consistency check.
319  // * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
320  //   perform the requested operation. The client may retry after a delay.
321  google.rpc.Status status = 1;
322
323  // The uri from the request that resulted in a successful retrieval, or from
324  // which the error indicated in `status` was obtained.
325  string uri = 2;
326
327  // Any qualifiers known to the server and of interest to clients.
328  repeated Qualifier qualifiers = 3;
329
330  // A minimum timestamp the content is expected to be available through.
331  // Servers *MAY* omit this field, if not known with confidence.
332  google.protobuf.Timestamp expires_at = 4;
333
334  // The result of the fetch, if the status had code `OK`.
335  // the root digest of a directory tree, suitable for fetching via
336  // [ContentAddressableStorage.GetTree].
337  build.bazel.remote.execution.v2.Digest root_directory_digest = 5;
338
339  // This field SHOULD be set to the digest function that was used by the server
340  // to compute [FetchBlobResponse.root_directory_digest].
341  // Clients could use this to determine whether the server honors
342  // [FetchDirectoryRequest.digest_function] that was set in the request.
343  //
344  // If unset, clients SHOULD default to use SHA256 regardless of the requested
345  // [FetchDirectoryRequest.digest_function].
346  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 6;
347}
348
349// The Push service is complementary to the Fetch, and allows for
350// associating contents of URLs to be returned in future Fetch API calls.
351//
352// As with other services in the Remote Execution API, any call may return an
353// error with a [RetryInfo][google.rpc.RetryInfo] error detail providing
354// information about when the client should retry the request; clients SHOULD
355// respect the information provided.
356service Push {
357  // These APIs associate the identifying information of a resource, as
358  // indicated by URI and optionally Qualifiers, with content available in the
359  // CAS. For example, associating a repository url and a commit id with a
360  // Directory Digest.
361  //
362  // Servers *SHOULD* only allow trusted clients to associate content, and *MAY*
363  // only allow certain URIs to be pushed.
364  //
365  // Clients *MUST* ensure associated content is available in CAS prior to
366  // pushing.
367  //
368  // Clients *MUST* ensure the Qualifiers listed correctly match the contents,
369  // and Servers *MAY* trust these values without validation.
370  // Fetch servers *MAY* require exact match of all qualifiers when returning
371  // content previously pushed, or allow fetching content with only a subset of
372  // the qualifiers specified on Push.
373  //
374  // Clients can specify expiration information that the server *SHOULD*
375  // respect. Subsequent requests can be used to alter the expiration time.
376  //
377  // A minimal compliant Fetch implementation may support only Push'd content
378  // and return `NOT_FOUND` for any resource that was not pushed first.
379  // Alternatively, a compliant implementation may choose to not support Push
380  // and only return resources that can be Fetch'd from origin.
381  //
382  // Errors will be returned as gRPC Status errors.
383  // The possible RPC errors include:
384  // * `INVALID_ARGUMENT`: One or more arguments to the RPC were invalid.
385  // * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
386  //   perform the requested operation. The client may retry after a delay.
387  // * `UNAVAILABLE`: Due to a transient condition the operation could not be
388  //   completed. The client should retry.
389  // * `INTERNAL`: An internal error occurred while performing the operation.
390  //   The client should retry.
391  rpc PushBlob(PushBlobRequest) returns (PushBlobResponse) {
392    option (google.api.http) = { post: "/v1/{instance_name=**}/assets:pushBlob" body: "*" };
393  }
394
395  rpc PushDirectory(PushDirectoryRequest) returns (PushDirectoryResponse) {
396    option (google.api.http) = { post: "/v1/{instance_name=**}/assets:pushDirectory" body: "*" };
397  }
398}
399
400// A request message for
401// [Push.PushBlob][build.bazel.remote.asset.v1.Push.PushBlob].
402message PushBlobRequest {
403  // The instance of the execution system to operate against. A server may
404  // support multiple instances of the execution system (with their own workers,
405  // storage, caches, etc.). The server MAY require use of this field to select
406  // between them in an implementation-defined fashion, otherwise it can be
407  // omitted.
408  string instance_name = 1;
409
410  // The URI(s) of the content to associate. If multiple URIs are specified, the
411  // pushed content will be available to fetch by specifying any of them.
412  repeated string uris = 2;
413
414  // Qualifiers sub-specifying the content that is being pushed - see comments
415  // on [Qualifier][build.bazel.remote.asset.v1.Qualifier].
416  // The same qualifiers apply to all URIs.
417  repeated Qualifier qualifiers = 3;
418
419  // A time after which this content should stop being returned via [FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
420  // Servers *MAY* expire content early, e.g. due to storage pressure.
421  google.protobuf.Timestamp expire_at = 4;
422
423  // The blob to associate.
424  build.bazel.remote.execution.v2.Digest blob_digest = 5;
425
426  // Referenced blobs or directories that need to not expire before expiration
427  // of this association, in addition to `blob_digest` itself.
428  // These fields are hints - clients *MAY* omit them, and servers *SHOULD*
429  // respect them, at the risk of increased incidents of Fetch responses
430  // indirectly referencing unavailable blobs.
431  repeated build.bazel.remote.execution.v2.Digest references_blobs = 6;
432  repeated build.bazel.remote.execution.v2.Digest references_directories = 7;
433
434  // The digest function that was used to compute the blob digest.
435  //
436  // If the digest function used is one of MD5, MURMUR3, SHA1, SHA256,
437  // SHA384, SHA512, or VSO, the client MAY leave this field unset. In
438  // that case the server SHOULD infer the digest function using the
439  // length of the action digest hash and the digest functions announced
440  // in the server's capabilities.
441  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 8;
442}
443
444// A response message for
445// [Push.PushBlob][build.bazel.remote.asset.v1.Push.PushBlob].
446message PushBlobResponse { /* empty */ }
447
448// A request message for
449// [Push.PushDirectory][build.bazel.remote.asset.v1.Push.PushDirectory].
450message PushDirectoryRequest {
451  // The instance of the execution system to operate against. A server may
452  // support multiple instances of the execution system (with their own workers,
453  // storage, caches, etc.). The server MAY require use of this field to select
454  // between them in an implementation-defined fashion, otherwise it can be
455  // omitted.
456  string instance_name = 1;
457
458  // The URI(s) of the content to associate. If multiple URIs are specified, the
459  // pushed content will be available to fetch by specifying any of them.
460  repeated string uris = 2;
461
462  // Qualifiers sub-specifying the content that is being pushed - see comments
463  // on [Qualifier][build.bazel.remote.asset.v1.Qualifier].
464  // The same qualifiers apply to all URIs.
465  repeated Qualifier qualifiers = 3;
466
467  // A time after which this content should stop being returned via
468  // [FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
469  // Servers *MAY* expire content early, e.g. due to storage pressure.
470  google.protobuf.Timestamp expire_at = 4;
471
472  // Directory to associate
473  build.bazel.remote.execution.v2.Digest root_directory_digest = 5;
474
475  // Referenced blobs or directories that need to not expire before expiration
476  // of this association, in addition to `root_directory_digest` itself.
477  // These fields are hints - clients *MAY* omit them, and servers *SHOULD*
478  // respect them, at the risk of increased incidents of Fetch responses
479  // indirectly referencing unavailable blobs.
480  repeated build.bazel.remote.execution.v2.Digest references_blobs = 6;
481  repeated build.bazel.remote.execution.v2.Digest references_directories = 7;
482
483  // The digest function that was used to compute blob digests.
484  //
485  // If the digest function used is one of MD5, MURMUR3, SHA1, SHA256,
486  // SHA384, SHA512, or VSO, the client MAY leave this field unset. In
487  // that case the server SHOULD infer the digest function using the
488  // length of the action digest hash and the digest functions announced
489  // in the server's capabilities.
490  build.bazel.remote.execution.v2.DigestFunction.Value digest_function = 8;
491}
492
493// A response message for
494// [Push.PushDirectory][build.bazel.remote.asset.v1.Push.PushDirectory].
495message PushDirectoryResponse { /* empty */ }
496