| // Copyright 2024 The Bazel Authors. 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. |
| // |
| // This file contains the protocol buffer representation of a list of supported |
| // flags for Bazel commands. |
| syntax = "proto3"; |
| |
| package bazel_output_service; |
| |
| import "google/protobuf/any.proto"; |
| import "google/rpc/status.proto"; |
| |
| option java_package = "com.google.devtools.build.lib.remote"; |
| option java_outer_classname = "BazelOutputServiceProto"; |
| option go_package = "bazeloutputservice"; |
| |
| // The Bazel Output Service may be used by users of the Remote Execution API to |
| // construct a directory on the local system that contains all output files of a |
| // build. |
| // |
| // Primitive implementations of this API may simply download files from the |
| // Content Addressable Storage (CAS) and store them at their designated |
| // location. Complex implementations may use a pseudo file system (e.g., FUSE) |
| // to support deduplication, lazy loading and snapshotting. |
| // |
| // Details: |
| // https://github.com/bazelbuild/proposals/blob/master/designs/2021-02-09-remote-output-service.md |
| // https://groups.google.com/g/remote-execution-apis/c/qOSWWwBLPzo |
| // https://groups.google.com/g/bazel-dev/c/lKzENsNd1Do |
| // https://docs.google.com/document/d/1W6Tqq8cndssnDI0yzFSoj95oezRKcIhU57nwLHaN1qk/edit |
| service BazelOutputService { |
| // Clean all data associated with a single output path, so that the |
| // next invocation of StartBuild() yields an empty output path. This |
| // MAY be implemented in a way that's faster than removing all of the |
| // files from the file system manually. |
| rpc Clean(CleanRequest) returns (CleanResponse); |
| |
| // Signal that a new build is about to start. |
| // |
| // Bazel uses this call to obtain a directory where outputs of the build may |
| // be stored, called the output path. Based on the parameters provided, server |
| // may provide an empty output path, or one that has contents from a previous |
| // build of the same workspace. |
| // |
| // In case the output path contains data from a previous build, server is |
| // responsible for calling ContentAddressableStorage.FindMissingBlobs() for |
| // all of the objects that are stored remotely. This ensures that these |
| // objects don't disappear from the Content Addressable Storage while the |
| // build is running. Any files that are absent MUST be removed from the output |
| // path and reported through InitialOutputPathContents.modified_path_prefixes, |
| // unless the field has been omitted because it would have been too large. |
| rpc StartBuild(StartBuildRequest) returns (StartBuildResponse); |
| |
| // Stage build artifacts at the given paths with digests that are known to the |
| // Content Addressable Storage. The file contents MAY be lazily downloaded |
| // when they're accessed in the future, and are not guaranteed to have already |
| // been downloaded upon return. |
| rpc StageArtifacts(StageArtifactsRequest) returns (StageArtifactsResponse); |
| |
| // Notify the server that a set of paths are not expected to be modified |
| // further by Bazel or a local build action within the current build. |
| // |
| // For each of these paths, the server MAY decide to store a dirty bit, |
| // initially unset. Subsequent modifications to the contents, or deletion of, |
| // the file stored at that path, cause the dirty bit to be set. If the server |
| // chooses to implement the dirty bit, any paths with the dirty bit set MUST |
| // be reported back to Bazel in the next |
| // InitialOutputPathContents.modified_path_prefixes for the same workspace. |
| // |
| // As an alternative to tracking modifications via a dirty bit, a server MAY |
| // choose to freeze finalized paths, preventing further modifications to the |
| // files stored there. |
| rpc FinalizeArtifacts(FinalizeArtifactsRequest) |
| returns (FinalizeArtifactsResponse); |
| |
| // Signal that a build has been completed. |
| rpc FinalizeBuild(FinalizeBuildRequest) returns (FinalizeBuildResponse); |
| |
| // Obtain the status of one or more files, directories or symbolic |
| // links that are stored in the output path. |
| rpc BatchStat(BatchStatRequest) returns (BatchStatResponse); |
| } |
| |
| message CleanRequest { |
| // The workspace identifier that was provided to |
| // StartBuildRequest.output_base_id whose data needs to be removed. |
| string output_base_id = 1; |
| } |
| |
| message CleanResponse { |
| // Intentionally empty for future extensibility. |
| } |
| |
| message StartBuildRequest { |
| // The version of the protocol Bazel currently uses. The service MUST return |
| // an error if it doesn't recognize the version. |
| // |
| // A future Bazel version may introduce incompatible changes and increment |
| // this version number. The incompatible change will be first made in the |
| // development tree for the next major Bazel release, and the new version thus |
| // introduced should be considered unstable until that major Bazel release |
| // occurs. At that time, the new version becomes stable, and the old one is |
| // immediately retired. |
| // |
| // In particular, version 1 must not be considered stable until Bazel 8.0.0 is |
| // released. |
| // |
| // Current version: 1 (experimental). |
| int32 version = 1; |
| |
| // A client-chosen value for the output service to uniquely identify the |
| // workspace the build is being started. This value must be set to ensure that |
| // the remote output service is capable of managing builds for distinct |
| // workspaces concurrently. |
| // |
| // Bazel sets this value to the MD5 sum of the absolute path of the output |
| // base. |
| // |
| // Starting a build finalizes any previous build with the same output_base_id |
| // that has not been finalized yet as if a FinalizeBuildRequest had been sent |
| // with build_successful set to false. |
| string output_base_id = 2; |
| |
| // A client-chosen value that uniquely identifies this build. This value must |
| // be provided to most other methods to ensure that operations are targeted |
| // against the right output path. If the server receives a subsequent request |
| // with a non-matching build_id, it SHOULD send back an error response. |
| // |
| // Bazel sets this value to --invocation_id. |
| string build_id = 3; |
| |
| // Additional arguments to pass depending on how Bazel communicate with the |
| // Content Addressable Storage. |
| // |
| // In case of a REv2 CAS, the type is |
| // [StartBuildArgs][bazel_output_service_rev2.StartBuildArgs]. |
| google.protobuf.Any args = 4; |
| |
| // The absolute path at which the remote output service exposes its output |
| // paths, as seen from the perspective of the client. |
| // |
| // This value needs to be provided by the client, because file system |
| // namespace virtualization may cause this directory to appear at a location |
| // that differs from the one used by the service. |
| // |
| // The purpose of this field is to ensure that the remote output service is |
| // capable of expanding symbolic links containing absolute paths. |
| // |
| // If this is not set, or an empty string, the service must determine where to |
| // expose its output path and return an absolute path in |
| // StartBuildResponse.output_path_suffix. |
| string output_path_prefix = 5; |
| |
| // A map of paths on the system that will become symbolic links pointing to |
| // locations inside the output path. Similar to output_path_prefix, this |
| // option is used to ensure the remote output service is capable of expanding |
| // symbolic links. |
| // |
| // Map keys are absolute paths, while map values are paths that are |
| // relative to the output path. |
| map<string, string> output_path_aliases = 6; |
| } |
| |
| message StartBuildResponse { |
| // If set, the contents of the output path are almost entirely identical on |
| // the results of a previous build. This information may be used by Bazel to |
| // prevent unnecessary scanning of the file system. |
| // |
| // The server MUST leave this field unset in case the contents of the output |
| // path are empty, not based on a previous build, if no tracking of this |
| // information is performed, or if the number of changes made to the output |
| // path is too large to be expressed. |
| InitialOutputPathContents initial_output_path_contents = 1; |
| |
| // A path that the client must append to StartBuildRequest.output_path_prefix |
| // to obtain the full path at which outputs of the build are stored. |
| // |
| // Bazel replaces bazel-out/ with a symlink targeting this path. |
| string output_path_suffix = 2; |
| } |
| |
| message InitialOutputPathContents { |
| // The identifier of a previously finalized build whose results are stored in |
| // the output path. |
| string build_id = 1; |
| |
| // Output path prefixes that have been deleted or modified since they were |
| // finalized. Any path exactly matching or starting with one of these prefixes |
| // may be assumed to have been modified or deleted. |
| // |
| // In the interest of performance, the server SHOULD only include path |
| // prefixes that contain at least one of the paths that were finalized by the |
| // previous build. |
| repeated string modified_path_prefixes = 2; |
| } |
| |
| message StageArtifactsRequest { |
| message Artifact { |
| // path is relative to StartBuildResponse.output_path. |
| string path = 1; |
| // Describe how to stage the artifact. |
| // |
| // The concrete type of the locator depending on the CAS Bazel connects to. |
| // In case of a REv2 CAS, the type is |
| // [FileArtifactLocator][bazel_output_service_rev2.FileArtifactLocator]. |
| google.protobuf.Any locator = 2; |
| } |
| |
| // The identifier of the build. Server uses this to determine which output |
| // path needs to be modified. |
| string build_id = 1; |
| |
| repeated Artifact artifacts = 2; |
| } |
| |
| message StageArtifactsResponse { |
| message Response { |
| // If the status has a code other than `OK`, it indicates that the artifact |
| // could not be staged. |
| // |
| // Errors: |
| // * `NOT_FOUND`: The requested Artifact is not in the CAS. |
| google.rpc.Status status = 1; |
| } |
| |
| // The response for each of the requested artifacts, using the same order as |
| // requested. This means that this list has the same length as |
| // StageArtifactsRequest.artifacts. |
| repeated Response responses = 1; |
| } |
| |
| message FinalizeArtifactsRequest { |
| message Artifact { |
| // path is relative to StartBuildResponse.output_path. |
| string path = 1; |
| // Expected digest for this path. This allows server to detect if the path |
| // has been changed after Bazel finished creating the path and the |
| // corresponding FinalizeArtifactsRequest is processed. |
| // |
| // The concrete type of the locator depending on the CAS Bazel connects to. |
| // In case of a REv2 CAS, the type is |
| // [FileArtifactLocator][bazel_output_service_rev2.FileArtifactLocator]. |
| google.protobuf.Any locator = 2; |
| } |
| |
| // The identifier of the build. Server uses this to determine which output |
| // path needs to be modified. |
| string build_id = 1; |
| |
| repeated Artifact artifacts = 2; |
| } |
| |
| message FinalizeArtifactsResponse { |
| // Intentionally empty for future extensibility. |
| } |
| |
| message FinalizeBuildRequest { |
| // The identifier of the build that should be finalized. |
| string build_id = 1; |
| |
| // Whether the build completed successfully. The remote output service MAY, |
| // for example, use this option to apply different retention policies that |
| // take the outcome of the build into account. |
| bool build_successful = 2; |
| } |
| |
| message FinalizeBuildResponse { |
| // Intentionally empty for future extensibility. |
| } |
| |
| message BatchStatRequest { |
| // The identifier of the build. The remote output service uses this to |
| // determine which output path needs to be inspected. |
| string build_id = 1; |
| |
| // Paths whose status is to be obtained. The server MUST canonicalize each |
| // path using lstat semantics, i.e., all components except the last must be |
| // resolved if they are symlinks. If a symlink pointing to a location outside |
| // of the output path is encountered at any point during the canonicalization |
| // process, the server MAY use the information in |
| // StartBuildRequest.output_path_aliases map to continue the canonicalization. |
| // |
| // Refer to Stat.type for how to handle a situation where canonicalization |
| // fails due to a symlink pointing to a location outside of the output path. |
| // |
| // Path is relative to StartBuildResponse.output_path. |
| repeated string paths = 2; |
| } |
| |
| message BatchStatResponse { |
| message StatResponse { |
| // The status of the path. If the path does not exist, this field MUST be |
| // unset. |
| Stat stat = 1; |
| } |
| |
| message Stat { |
| message File { |
| // The digest of the file. |
| // |
| // The server MAY leave this field unset if it is unable to compute the |
| // digest. |
| // |
| // The concrete type of the digest depending on the CAS Bazel connects to. |
| // In case of a REv2 CAS, the type is |
| // [FileArtifactLocator][bazel_output_service_rev2.FileArtifactLocator]. |
| google.protobuf.Any locator = 1; |
| } |
| |
| message Symlink { |
| // The target of the symbolic link. |
| string target = 1; |
| } |
| |
| message Directory {} |
| |
| // If the path cannot be canonicalized, the server MUST NOT set any of the |
| // type fields. |
| // |
| // If the path resolves to a special file, the server MUST NOT set any of |
| // the type fields. |
| oneof type { |
| // The path resolves to a regular file. |
| File file = 1; |
| |
| // The path resolves to a symbolic link. |
| Symlink symlink = 2; |
| |
| // The path resolves to a directory. |
| Directory directory = 3; |
| } |
| } |
| |
| // The status response for each of the requested paths, using the same |
| // order as requested. This means that this list has the same length |
| // as BatchStatRequest.paths. |
| repeated StatResponse responses = 1; |
| } |