blob: 4d9be8175a98858a194385c76ddcc1f14e6028d8 [file] [log] [blame]
// Copyright 2020 The Bazel Authors.
//
// 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.
syntax = "proto3";
package build.bazel.remote.asset.v1;
import "build/bazel/remote/execution/v2/remote_execution.proto";
import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";
option csharp_namespace = "Build.Bazel.Remote.Asset.v1";
option go_package = "github.com/bazelbuild/remote-apis/build/bazel/remote/asset/v1;remoteasset";
option java_multiple_files = true;
option java_outer_classname = "RemoteAssetProto";
option java_package = "build.bazel.remote.asset.v1";
option objc_class_prefix = "RA";
// The Remote Asset API provides a mapping from a URI and Qualifiers to
// Digests.
//
// Multiple URIs may be used to refer to the same content. For example, the
// same tarball may exist at multiple mirrors and thus be retrievable from
// multiple URLs. When URLs are used, these should refer to actual content as
// Fetch service implementations may choose to fetch the content directly
// from the origin. For example, the HEAD of a git repository's active branch
// can be referred to as:
//
// uri: https://github.com/bazelbuild/remote-apis.git
//
// URNs may be used to strongly identify content, for instance by using the
// uuid namespace identifier: urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6.
// This is most applicable to named content that is Push'd, where the URN
// serves as an agreed-upon key, but carries no other inherent meaning.
//
// Service implementations may choose to support only URLs, only URNs for
// Push'd content, only other URIs for which the server and client agree upon
// semantics of, or any mixture of the above.
// Qualifiers are used to disambiguate or sub-select content that shares a URI.
// This may include specifying a particular commit or branch, in the case of
// URIs referencing a repository; they could also be used to specify a
// particular subdirectory of a repository or tarball. Qualifiers may also be
// used to ensure content matches what the client expects, even when there is
// no ambiguity to be had - for example, a qualifier specifying a checksum
// value.
//
// In cases where the semantics of the request are not immediately clear from
// the URL and/or qualifiers - e.g. dictated by URL scheme - it is recommended
// to use an additional qualifier to remove the ambiguity. The `resource_type`
// qualifier is recommended for this purpose.
//
// Qualifiers may be supplied in any order.
message Qualifier {
// The "name" of the qualifier, for example "resource_type".
// No separation is made between 'standard' and 'nonstandard'
// qualifiers, in accordance with https://tools.ietf.org/html/rfc6648,
// however implementers *SHOULD* take care to avoid ambiguity.
string name = 1;
// The "value" of the qualifier. Semantics will be dictated by the name.
string value = 2;
}
// The Fetch service resolves or fetches assets referenced by URI and
// Qualifiers, returning a Digest for the content in
// [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
//
// As with other services in the Remote Execution API, any call may return an
// error with a [RetryInfo][google.rpc.RetryInfo] error detail providing
// information about when the client should retry the request; clients SHOULD
// respect the information provided.
service Fetch {
// Resolve or fetch referenced assets, making them available to the caller and
// other consumers in the [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
//
// Servers *MAY* fetch content that they do not already have cached, for any
// URLs they support.
//
// Servers *SHOULD* ensure that referenced files are present in the CAS at the
// time of the response, and (if supported) that they will remain available
// for a reasonable period of time. The lifetimes of the referenced blobs *SHOULD*
// be increased if necessary and applicable.
// In the event that a client receives a reference to content that is no
// longer present, it *MAY* re-issue the request with
// `oldest_content_accepted` set to a more recent timestamp than the original
// attempt, to induce a re-fetch from origin.
//
// Servers *MAY* cache fetched content and reuse it for subsequent requests,
// subject to `oldest_content_accepted`.
//
// Servers *MAY* support the complementary [Push][build.bazel.remote.asset.v1.Push]
// API and allow content to be directly inserted for use in future fetch
// responses.
//
// Servers *MUST* ensure Fetch'd content matches all the specified
// qualifiers except in the case of previously Push'd resources, for which
// the server *MAY* trust the pushing client to have set the qualifiers
// correctly, without validation.
//
// Servers not implementing the complementary [Push][build.bazel.remote.asset.v1.Push]
// API *MUST* reject requests containing qualifiers it does not support.
//
// Servers *MAY* transform assets as part of the fetch. For example a
// tarball fetched by [FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory]
// might be unpacked, or a Git repository
// fetched by [FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob]
// might be passed through `git-archive`.
//
// Errors handling the requested assets will be returned as gRPC Status errors
// here; errors outside the server's control will be returned inline in the
// `status` field of the response (see comment there for details).
// The possible RPC errors include:
// * `INVALID_ARGUMENT`: One or more arguments were invalid, such as a
// qualifier that is not supported by the server.
// * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
// perform the requested operation. The client may retry after a delay.
// * `UNAVAILABLE`: Due to a transient condition the operation could not be
// completed. The client should retry.
// * `INTERNAL`: An internal error occurred while performing the operation.
// The client should retry.
// * `DEADLINE_EXCEEDED`: The fetch could not be completed within the given
// RPC deadline. The client should retry for at least as long as the value
// provided in `timeout` field of the request.
//
// In the case of unsupported qualifiers, the server *SHOULD* additionally
// send a [BadRequest][google.rpc.BadRequest] error detail where, for each
// unsupported qualifier, there is a `FieldViolation` with a `field` of
// `qualifiers.name` and a `description` of `"{qualifier}" not supported`
// indicating the name of the unsupported qualifier.
rpc FetchBlob(FetchBlobRequest) returns (FetchBlobResponse) {
option (google.api.http) = { post: "/v1/{instance_name=**}/assets:fetchBlob" body: "*" };
}
rpc FetchDirectory(FetchDirectoryRequest) returns (FetchDirectoryResponse) {
option (google.api.http) = { post: "/v1/{instance_name=**}/assets:fetchDirectory" body: "*" };
}
}
// A request message for
// [Fetch.FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
message FetchBlobRequest {
// The instance of the execution system to operate against. A server may
// support multiple instances of the execution system (with their own workers,
// storage, caches, etc.). The server MAY require use of this field to select
// between them in an implementation-defined fashion, otherwise it can be
// omitted.
string instance_name = 1;
// The timeout for the underlying fetch, if content needs to be retrieved from
// origin.
//
// If unset, the server *MAY* apply an implementation-defined timeout.
//
// If set, and the user-provided timeout exceeds the RPC deadline, the server
// *SHOULD* keep the fetch going after the RPC completes, to be made
// available for future Fetch calls. The server may also enforce (via clamping
// and/or an INVALID_ARGUMENT error) implementation-defined minimum and
// maximum timeout values.
//
// If this timeout is exceeded on an attempt to retrieve content from origin
// the client will receive DEADLINE_EXCEEDED in [FetchBlobResponse.status].
google.protobuf.Duration timeout = 2;
// The oldest content the client is willing to accept, as measured from the
// time it was Push'd or when the underlying retrieval from origin was
// started.
// Upon retries of Fetch requests that cannot be completed within a single
// RPC, clients *SHOULD* provide the same value for subsequent requests as the
// original, to simplify combining the request with the previous attempt.
//
// If unset, the client *SHOULD* accept content of any age.
google.protobuf.Timestamp oldest_content_accepted = 3;
// The URI(s) of the content to fetch. These may be resources that the server
// can directly fetch from origin, in which case multiple URIs *SHOULD*
// represent the same content available at different locations (such as an
// origin and secondary mirrors). These may also be URIs for content known to
// the server through other mechanisms, e.g. pushed via the [Push][build.bazel.remote.asset.v1.Push]
// service.
//
// Clients *MUST* supply at least one URI. Servers *MAY* match any one of the
// supplied URIs.
repeated string uris = 4;
// Qualifiers sub-specifying the content to fetch - see comments on
// [Qualifier][build.bazel.remote.asset.v1.Qualifier].
// The same qualifiers apply to all URIs.
//
// Specified qualifier names *MUST* be unique.
repeated Qualifier qualifiers = 5;
}
// A response message for
// [Fetch.FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
message FetchBlobResponse {
// If the status has a code other than `OK`, it indicates that the operation
// was unable to be completed for reasons outside the servers' control.
// The possible fetch errors include:
// * `DEADLINE_EXCEEDED`: The operation could not be completed within the
// specified timeout.
// * `NOT_FOUND`: The requested asset was not found at the specified location.
// * `PERMISSION_DENIED`: The request was rejected by a remote server, or
// requested an asset from a disallowed origin.
// * `ABORTED`: The operation could not be completed, typically due to a
// failed consistency check.
google.rpc.Status status = 1;
// The uri from the request that resulted in a successful retrieval, or from
// which the error indicated in `status` was obtained.
string uri = 2;
// Any qualifiers known to the server and of interest to clients.
repeated Qualifier qualifiers = 3;
// A minimum timestamp the content is expected to be available through.
// Servers *MAY* omit this field, if not known with confidence.
google.protobuf.Timestamp expires_at = 4;
// The result of the fetch, if the status had code `OK`.
// The digest of the file's contents, available for download through the CAS.
build.bazel.remote.execution.v2.Digest blob_digest = 5;
}
// A request message for
// [Fetch.FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
message FetchDirectoryRequest {
// The instance of the execution system to operate against. A server may
// support multiple instances of the execution system (with their own workers,
// storage, caches, etc.). The server MAY require use of this field to select
// between them in an implementation-defined fashion, otherwise it can be
// omitted.
string instance_name = 1;
// The timeout for the underlying fetch, if content needs to be retrieved from
// origin. This value is allowed to exceed the RPC deadline, in which case the
// server *SHOULD* keep the fetch going after the RPC completes, to be made
// available for future Fetch calls.
//
// If this timeout is exceeded on an attempt to retrieve content from origin
// the client will receive DEADLINE_EXCEEDED in [FetchDirectoryResponse.status].
google.protobuf.Duration timeout = 2;
// The oldest content the client is willing to accept, as measured from the
// time it was Push'd or when the underlying retrieval from origin was
// started.
// Upon retries of Fetch requests that cannot be completed within a single
// RPC, clients *SHOULD* provide the same value for subsequent requests as the
// original, to simplify combining the request with the previous attempt.
//
// If unset, the client *SHOULD* accept content of any age.
google.protobuf.Timestamp oldest_content_accepted = 3;
// The URI(s) of the content to fetch. These may be resources that the server
// can directly fetch from origin, in which case multiple URIs *SHOULD*
// represent the same content available at different locations (such as an
// origin and secondary mirrors). These may also be URIs for content known to
// the server through other mechanisms, e.g. pushed via the [Push][build.bazel.remote.asset.v1.Push]
// service.
//
// Clients *MUST* supply at least one URI. Servers *MAY* match any one of the
// supplied URIs.
repeated string uris = 4;
// Qualifiers sub-specifying the content to fetch - see comments on
// [Qualifier][build.bazel.remote.asset.v1.Qualifier].
// The same qualifiers apply to all URIs.
//
// Specified qualifier names *MUST* be unique.
repeated Qualifier qualifiers = 5;
}
// A response message for
// [Fetch.FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
message FetchDirectoryResponse {
// If the status has a code other than `OK`, it indicates that the operation
// was unable to be completed for reasons outside the servers' control.
// The possible fetch errors include:
// * `DEADLINE_EXCEEDED`: The operation could not be completed within the
// specified timeout.
// * `NOT_FOUND`: The requested asset was not found at the specified location.
// * `PERMISSION_DENIED`: The request was rejected by a remote server, or
// requested an asset from a disallowed origin.
// * `ABORTED`: The operation could not be completed, typically due to a
// failed consistency check.
google.rpc.Status status = 1;
// The uri from the request that resulted in a successful retrieval, or from
// which the error indicated in `status` was obtained.
string uri = 2;
// Any qualifiers known to the server and of interest to clients.
repeated Qualifier qualifiers = 3;
// A minimum timestamp the content is expected to be available through.
// Servers *MAY* omit this field, if not known with confidence.
google.protobuf.Timestamp expires_at = 4;
// The result of the fetch, if the status had code `OK`.
// the root digest of a directory tree, suitable for fetching via
// [ContentAddressableStorage.GetTree].
build.bazel.remote.execution.v2.Digest root_directory_digest = 5;
}
// The Push service is complementary to the Fetch, and allows for
// associating contents of URLs to be returned in future Fetch API calls.
//
// As with other services in the Remote Execution API, any call may return an
// error with a [RetryInfo][google.rpc.RetryInfo] error detail providing
// information about when the client should retry the request; clients SHOULD
// respect the information provided.
service Push {
// These APIs associate the identifying information of a resource, as
// indicated by URI and optionally Qualifiers, with content available in the
// CAS. For example, associating a repository url and a commit id with a
// Directory Digest.
//
// Servers *SHOULD* only allow trusted clients to associate content, and *MAY*
// only allow certain URIs to be pushed.
//
// Clients *MUST* ensure associated content is available in CAS prior to
// pushing.
//
// Clients *MUST* ensure the Qualifiers listed correctly match the contents,
// and Servers *MAY* trust these values without validation.
// Fetch servers *MAY* require exact match of all qualifiers when returning
// content previously pushed, or allow fetching content with only a subset of
// the qualifiers specified on Push.
//
// Clients can specify expiration information that the server *SHOULD*
// respect. Subsequent requests can be used to alter the expiration time.
//
// A minimal compliant Fetch implementation may support only Push'd content
// and return `NOT_FOUND` for any resource that was not pushed first.
// Alternatively, a compliant implementation may choose to not support Push
// and only return resources that can be Fetch'd from origin.
//
// Errors will be returned as gRPC Status errors.
// The possible RPC errors include:
// * `INVALID_ARGUMENT`: One or more arguments to the RPC were invalid.
// * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to
// perform the requested operation. The client may retry after a delay.
// * `UNAVAILABLE`: Due to a transient condition the operation could not be
// completed. The client should retry.
// * `INTERNAL`: An internal error occurred while performing the operation.
// The client should retry.
rpc PushBlob(PushBlobRequest) returns (PushBlobResponse) {
option (google.api.http) = { post: "/v1/{instance_name=**}/assets:pushBlob" body: "*" };
}
rpc PushDirectory(PushDirectoryRequest) returns (PushDirectoryResponse) {
option (google.api.http) = { post: "/v1/{instance_name=**}/assets:pushDirectory" body: "*" };
}
}
// A request message for
// [Push.PushBlob][build.bazel.remote.asset.v1.Push.PushBlob].
message PushBlobRequest {
// The instance of the execution system to operate against. A server may
// support multiple instances of the execution system (with their own workers,
// storage, caches, etc.). The server MAY require use of this field to select
// between them in an implementation-defined fashion, otherwise it can be
// omitted.
string instance_name = 1;
// The URI(s) of the content to associate. If multiple URIs are specified, the
// pushed content will be available to fetch by specifying any of them.
repeated string uris = 2;
// Qualifiers sub-specifying the content that is being pushed - see comments
// on [Qualifier][build.bazel.remote.asset.v1.Qualifier].
// The same qualifiers apply to all URIs.
repeated Qualifier qualifiers = 3;
// A time after which this content should stop being returned via [FetchBlob][build.bazel.remote.asset.v1.Fetch.FetchBlob].
// Servers *MAY* expire content early, e.g. due to storage pressure.
google.protobuf.Timestamp expire_at = 4;
// The blob to associate.
build.bazel.remote.execution.v2.Digest blob_digest = 5;
// Referenced blobs or directories that need to not expire before expiration
// of this association, in addition to `blob_digest` itself.
// These fields are hints - clients *MAY* omit them, and servers *SHOULD*
// respect them, at the risk of increased incidents of Fetch responses
// indirectly referencing unavailable blobs.
repeated build.bazel.remote.execution.v2.Digest references_blobs = 6;
repeated build.bazel.remote.execution.v2.Digest references_directories = 7;
}
// A response message for
// [Push.PushBlob][build.bazel.remote.asset.v1.Push.PushBlob].
message PushBlobResponse { /* empty */ }
// A request message for
// [Push.PushDirectory][build.bazel.remote.asset.v1.Push.PushDirectory].
message PushDirectoryRequest {
// The instance of the execution system to operate against. A server may
// support multiple instances of the execution system (with their own workers,
// storage, caches, etc.). The server MAY require use of this field to select
// between them in an implementation-defined fashion, otherwise it can be
// omitted.
string instance_name = 1;
// The URI(s) of the content to associate. If multiple URIs are specified, the
// pushed content will be available to fetch by specifying any of them.
repeated string uris = 2;
// Qualifiers sub-specifying the content that is being pushed - see comments
// on [Qualifier][build.bazel.remote.asset.v1.Qualifier].
// The same qualifiers apply to all URIs.
repeated Qualifier qualifiers = 3;
// A time after which this content should stop being returned via
// [FetchDirectory][build.bazel.remote.asset.v1.Fetch.FetchDirectory].
// Servers *MAY* expire content early, e.g. due to storage pressure.
google.protobuf.Timestamp expire_at = 4;
// Directory to associate
build.bazel.remote.execution.v2.Digest root_directory_digest = 5;
// Referenced blobs or directories that need to not expire before expiration
// of this association, in addition to `root_directory_digest` itself.
// These fields are hints - clients *MAY* omit them, and servers *SHOULD*
// respect them, at the risk of increased incidents of Fetch responses
// indirectly referencing unavailable blobs.
repeated build.bazel.remote.execution.v2.Digest references_blobs = 6;
repeated build.bazel.remote.execution.v2.Digest references_directories = 7;
}
// A response message for
// [Push.PushDirectory][build.bazel.remote.asset.v1.Push.PushDirectory].
message PushDirectoryResponse { /* empty */ }