|  | // 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; | 
|  | } |