| // 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 |
| // assist Bazel in constructing the output tree: a directory on the local system |
| // containing all output files produced by 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 an output tree, so that the next invocation |
| // of StartBuild() yields an empty output tree. This MAY be implemented in a |
| // way that's faster than removing the contents 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 tree. Based on the parameters provided, the |
| // server may provide an empty output tree, or one containing the result of |
| // a previous build of the same workspace. |
| // |
| // In case the output tree 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 during the |
| // build. Objects that are no longer available MUST be removed from the output |
| // tree 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. Any subsequent modification, deletion or recreation of |
| // that path causes the dirty bit to be set. If the server chooses to store |
| // the dirty bit, any paths with the dirty bit set MUST be reported back in |
| // the next InitialOutputPathContents.modified_path_prefixes. |
| // |
| // As an alternative to tracking modifications via a dirty bit, a server MAY |
| // choose to freeze finalized paths, preventing them from being modified |
| // until the next StartBuildRequest or CleanRequest. |
| 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 |
| // stored in the output tree. |
| 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 that uniquely identifies the workspace where a build |
| // is being started. Each workspace corresponds to a separately managed output |
| // tree. This value MAY be used by the server to manage multiple output trees |
| // 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 tree. 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 communicates 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 server exposes its output tree, 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 different locations |
| // as seen by the client and the server. |
| // |
| // In addition, this field is used to ensure the server is capable of |
| // expanding symbolic links containing absolute paths into the output tree. |
| // |
| // If unset or empty, the server must determine where to expose its output |
| // tree 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 tree. Similar to output_path_prefix, this |
| // option is used to ensure the server is capable of expanding additional |
| // symbolic links. |
| // |
| // Map keys are absolute paths, while map values are paths that are |
| // relative to the output tree. |
| map<string, string> output_path_aliases = 6; |
| } |
| |
| message StartBuildResponse { |
| // If set, the contents of the output tree 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 modification tracking |
| // is performed. It MAY leave it unset 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 the output tree is available. |
| // |
| // 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 tree. |
| string build_id = 1; |
| |
| // Path prefixes relative to StartBuildResponse.output_path that have been |
| // modified, deleted or recreated since they were finalized. Any path exactly |
| // matching or starting with one of these prefixes MUST be assumed by Bazel to |
| // have been modified or deleted. Any other path MAY be assumed by Bazel to |
| // have remained unchanged since it was last finalized. |
| // |
| // In the interest of performance, the server SHOULD only include path |
| // prefixes that contain at least one of the paths that were previously |
| // finalized. |
| repeated string modified_path_prefixes = 2; |
| } |
| |
| message StageArtifactsRequest { |
| message Artifact { |
| // Path 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 relative to StartBuildResponse.output_path. |
| string path = 1; |
| // Expected digest for this path. This allows the server to detect changes |
| // the path has been changed after the client 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 server 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 server uses this to determine which output |
| // tree 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 tree 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 tree. |
| // |
| // 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 file digest. |
| // |
| // 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; |
| } |