aboutsummaryrefslogtreecommitdiff
path: root/build/bazel/remote/execution/v2/remote_execution.proto
blob: ca96a34649586bfe854b4e753ff080d7d7e61375 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
// Copyright 2018 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.execution.v2;

import "build/bazel/semver/semver.proto";
import "google/api/annotations.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option csharp_namespace = "Build.Bazel.Remote.Execution.V2";
option go_package = "remoteexecution";
option java_multiple_files = true;
option java_outer_classname = "RemoteExecutionProto";
option java_package = "build.bazel.remote.execution.v2";
option objc_class_prefix = "REX";


// The Remote Execution API is used to execute an
// [Action][build.bazel.remote.execution.v2.Action] on the remote
// workers.
//
// 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 Execution {
  // Execute an action remotely.
  //
  // In order to execute an action, the client must first upload all of the
  // inputs, the
  // [Command][build.bazel.remote.execution.v2.Command] to run, and the
  // [Action][build.bazel.remote.execution.v2.Action] into the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  // It then calls `Execute` with an `action_digest` referring to them. The
  // server will run the action and eventually return the result.
  //
  // The input `Action`'s fields MUST meet the various canonicalization
  // requirements specified in the documentation for their types so that it has
  // the same digest as other logically equivalent `Action`s. The server MAY
  // enforce the requirements and return errors if a non-canonical input is
  // received. It MAY also proceed without verifying some or all of the
  // requirements, such as for performance reasons. If the server does not
  // verify the requirement, then it will treat the `Action` as distinct from
  // another logically equivalent action if they hash differently.
  //
  // Returns a stream of
  // [google.longrunning.Operation][google.longrunning.Operation] messages
  // describing the resulting execution, with eventual `response`
  // [ExecuteResponse][build.bazel.remote.execution.v2.ExecuteResponse]. The
  // `metadata` on the operation is of type
  // [ExecuteOperationMetadata][build.bazel.remote.execution.v2.ExecuteOperationMetadata].
  //
  // If the client remains connected after the first response is returned after
  // the server, then updates are streamed as if the client had called
  // [WaitExecution][build.bazel.remote.execution.v2.Execution.WaitExecution]
  // until the execution completes or the request reaches an error. The
  // operation can also be queried using [Operations
  // API][google.longrunning.Operations.GetOperation].
  //
  // The server NEED NOT implement other methods or functionality of the
  // Operations API.
  //
  // Errors discovered during creation of the `Operation` will be reported
  // as gRPC Status errors, while errors that occurred while running the
  // action will be reported in the `status` field of the `ExecuteResponse`. The
  // server MUST NOT set the `error` field of the `Operation` proto.
  // The possible errors include:
  //
  // * `INVALID_ARGUMENT`: One or more arguments are invalid.
  // * `FAILED_PRECONDITION`: One or more errors occurred in setting up the
  //   action requested, such as a missing input or command or no worker being
  //   available. The client may be able to fix the errors and retry.
  // * `RESOURCE_EXHAUSTED`: There is insufficient quota of some resource to run
  //   the action.
  // * `UNAVAILABLE`: Due to a transient condition, such as all workers being
  //   occupied (and the server does not support a queue), the action could not
  //   be started. The client should retry.
  // * `INTERNAL`: An internal error occurred in the execution engine or the
  //   worker.
  // * `DEADLINE_EXCEEDED`: The execution timed out.
  // * `CANCELLED`: The operation was cancelled by the client. This status is
  //   only possible if the server implements the Operations API CancelOperation
  //   method, and it was called for the current execution.
  //
  // In the case of a missing input or command, the server SHOULD additionally
  // send a [PreconditionFailure][google.rpc.PreconditionFailure] error detail
  // where, for each requested blob not present in the CAS, there is a
  // `Violation` with a `type` of `MISSING` and a `subject` of
  // `"blobs/{hash}/{size}"` indicating the digest of the missing blob.
  rpc Execute(ExecuteRequest) returns (stream google.longrunning.Operation) {
    option (google.api.http) = { post: "/v2/{instance_name=**}/actions:execute" body: "*" };
  }

  // Wait for an execution operation to complete. When the client initially
  // makes the request, the server immediately responds with the current status
  // of the execution. The server will leave the request stream open until the
  // operation completes, and then respond with the completed operation. The
  // server MAY choose to stream additional updates as execution progresses,
  // such as to provide an update as to the state of the execution.
  rpc WaitExecution(WaitExecutionRequest) returns (stream google.longrunning.Operation) {
    option (google.api.http) = { post: "/v2/{name=operations/**}:waitExecution" body: "*" };
  }
}

// The action cache API is used to query whether a given action has already been
// performed and, if so, retrieve its result. Unlike the
// [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage],
// which addresses blobs by their own content, the action cache addresses the
// [ActionResult][build.bazel.remote.execution.v2.ActionResult] by a
// digest of the encoded [Action][build.bazel.remote.execution.v2.Action]
// which produced them.
//
// The lifetime of entries in the action cache is implementation-specific, but
// the server SHOULD assume that more recently used entries are more likely to
// be used again. Additionally, action cache implementations SHOULD ensure that
// any blobs referenced in the
// [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage]
// are still valid when returning a result.
//
// 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 ActionCache {
  // Retrieve a cached execution result.
  //
  // Errors:
  //
  // * `NOT_FOUND`: The requested `ActionResult` is not in the cache.
  rpc GetActionResult(GetActionResultRequest) returns (ActionResult) {
    option (google.api.http) = { get: "/v2/{instance_name=**}/actionResults/{action_digest.hash}/{action_digest.size_bytes}" };
  }

  // Upload a new execution result.
  //
  // In order to allow the server to perform access control based on the type of
  // action, and to assist with client debugging, the client MUST first upload
  // the [Action][build.bazel.remote.execution.v2.Execution] that produced the
  // result, along with its
  // [Command][build.bazel.remote.execution.v2.Command], into the
  // `ContentAddressableStorage`.
  //
  // Errors:
  //
  // * `INVALID_ARGUMENT`: One or more arguments are invalid.
  // * `FAILED_PRECONDITION`: One or more errors occurred in updating the
  //   action result, such as a missing command or action.
  // * `RESOURCE_EXHAUSTED`: There is insufficient storage space to add the
  //   entry to the cache.
  rpc UpdateActionResult(UpdateActionResultRequest) returns (ActionResult) {
    option (google.api.http) = { put: "/v2/{instance_name=**}/actionResults/{action_digest.hash}/{action_digest.size_bytes}" body: "action_result" };
  }
}

// The CAS (content-addressable storage) is used to store the inputs to and
// outputs from the execution service. Each piece of content is addressed by the
// digest of its binary data.
//
// Most of the binary data stored in the CAS is opaque to the execution engine,
// and is only used as a communication medium. In order to build an
// [Action][build.bazel.remote.execution.v2.Action],
// however, the client will need to also upload the
// [Command][build.bazel.remote.execution.v2.Command] and input root
// [Directory][build.bazel.remote.execution.v2.Directory] for the Action.
// The Command and Directory messages must be marshalled to wire format and then
// uploaded under the hash as with any other piece of content. In practice, the
// input root directory is likely to refer to other Directories in its
// hierarchy, which must also each be uploaded on their own.
//
// For small file uploads the client should group them together and call
// [BatchUpdateBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.BatchUpdateBlobs].
// For large uploads, the client must use the
// [Write method][google.bytestream.ByteStream.Write] of the ByteStream API. The
// `resource_name` is `{instance_name}/uploads/{uuid}/blobs/{hash}/{size}`,
// where `instance_name` is as described in the next paragraph, `uuid` is a
// version 4 UUID generated by the client, and `hash` and `size` are the
// [Digest][build.bazel.remote.execution.v2.Digest] of the blob. The
// `uuid` is used only to avoid collisions when multiple clients try to upload
// the same file (or the same client tries to upload the file multiple times at
// once on different threads), so the client MAY reuse the `uuid` for uploading
// different blobs. The `resource_name` may optionally have a trailing filename
// (or other metadata) for a client to use if it is storing URLs, as in
// `{instance}/uploads/{uuid}/blobs/{hash}/{size}/foo/bar/baz.cc`. Anything
// after the `size` is ignored.
//
// A single server MAY support multiple instances of the execution system, each
// with their own workers, storage, cache, etc. The exact relationship between
// instances is up to the server. If the server does, then the `instance_name`
// is an identifier, possibly containing multiple path segments, used to
// distinguish between the various instances on the server, in a manner defined
// by the server. For servers which do not support multiple instances, then the
// `instance_name` is the empty path and the leading slash is omitted, so that
// the `resource_name` becomes `uploads/{uuid}/blobs/{hash}/{size}`.
// To simplify parsing, a path segment cannot equal any of the following
// keywords: `blobs`, `uploads`, `actions`, `actionResults`, `operations` and
// `capabilities`.
//
// When attempting an upload, if another client has already completed the upload
// (which may occur in the middle of a single upload if another client uploads
// the same blob concurrently), the request will terminate immediately with
// a response whose `committed_size` is the full size of the uploaded file
// (regardless of how much data was transmitted by the client). If the client
// completes the upload but the
// [Digest][build.bazel.remote.execution.v2.Digest] does not match, an
// `INVALID_ARGUMENT` error will be returned. In either case, the client should
// not attempt to retry the upload.
//
// For downloading blobs, the client must use the
// [Read method][google.bytestream.ByteStream.Read] of the ByteStream API, with
// a `resource_name` of `"{instance_name}/blobs/{hash}/{size}"`, where
// `instance_name` is the instance name (see above), and `hash` and `size` are
// the [Digest][build.bazel.remote.execution.v2.Digest] of the blob.
//
// The lifetime of entries in the CAS is implementation specific, but it SHOULD
// be long enough to allow for newly-added and recently looked-up entries to be
// used in subsequent calls (e.g. to
// [Execute][build.bazel.remote.execution.v2.Execution.Execute]).
//
// 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 ContentAddressableStorage {
  // Determine if blobs are present in the CAS.
  //
  // Clients can use this API before uploading blobs to determine which ones are
  // already present in the CAS and do not need to be uploaded again.
  //
  // There are no method-specific errors.
  rpc FindMissingBlobs(FindMissingBlobsRequest) returns (FindMissingBlobsResponse) {
    option (google.api.http) = { post: "/v2/{instance_name=**}/blobs:findMissing" body: "*" };
  }

  // Upload many blobs at once.
  //
  // The server may enforce a limit of the combined total size of blobs
  // to be uploaded using this API. This limit may be obtained using the
  // [Capabilities][build.bazel.remote.execution.v2.Capabilities] API.
  // Requests exceeding the limit should either be split into smaller
  // chunks or uploaded using the
  // [ByteStream API][google.bytestream.ByteStream], as appropriate.
  //
  // This request is equivalent to calling a Bytestream `Write` request
  // on each individual blob, in parallel. The requests may succeed or fail
  // independently.
  //
  // Errors:
  //
  // * `INVALID_ARGUMENT`: The client attempted to upload more than the
  //   server supported limit.
  //
  // Individual requests may return the following errors, additionally:
  //
  // * `RESOURCE_EXHAUSTED`: There is insufficient disk quota to store the blob.
  // * `INVALID_ARGUMENT`: The
  // [Digest][build.bazel.remote.execution.v2.Digest] does not match the
  // provided data.
  rpc BatchUpdateBlobs(BatchUpdateBlobsRequest) returns (BatchUpdateBlobsResponse) {
    option (google.api.http) = { post: "/v2/{instance_name=**}/blobs:batchUpdate" body: "*" };
  }

  // Download many blobs at once.
  //
  // The server may enforce a limit of the combined total size of blobs
  // to be downloaded using this API. This limit may be obtained using the
  // [Capabilities][build.bazel.remote.execution.v2.Capabilities] API.
  // Requests exceeding the limit should either be split into smaller
  // chunks or downloaded using the
  // [ByteStream API][google.bytestream.ByteStream], as appropriate.
  //
  // This request is equivalent to calling a Bytestream `Read` request
  // on each individual blob, in parallel. The requests may succeed or fail
  // independently.
  //
  // Errors:
  //
  // * `INVALID_ARGUMENT`: The client attempted to read more than the
  //   server supported limit.
  //
  // Every error on individual read will be returned in the corresponding digest
  // status.
  rpc BatchReadBlobs(BatchReadBlobsRequest) returns (BatchReadBlobsResponse) {
    option (google.api.http) = { post: "/v2/{instance_name=**}/blobs:batchRead" body: "*" };
  }

  // Fetch the entire directory tree rooted at a node.
  //
  // This request must be targeted at a
  // [Directory][build.bazel.remote.execution.v2.Directory] stored in the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage]
  // (CAS). The server will enumerate the `Directory` tree recursively and
  // return every node descended from the root.
  //
  // The GetTreeRequest.page_token parameter can be used to skip ahead in
  // the stream (e.g. when retrying a partially completed and aborted request),
  // by setting it to a value taken from GetTreeResponse.next_page_token of the
  // last successfully processed GetTreeResponse).
  //
  // The exact traversal order is unspecified and, unless retrieving subsequent
  // pages from an earlier request, is not guaranteed to be stable across
  // multiple invocations of `GetTree`.
  //
  // If part of the tree is missing from the CAS, the server will return the
  // portion present and omit the rest.
  //
  // * `NOT_FOUND`: The requested tree root is not present in the CAS.
  rpc GetTree(GetTreeRequest) returns (stream GetTreeResponse) {
    option (google.api.http) = { get: "/v2/{instance_name=**}/blobs/{root_digest.hash}/{root_digest.size_bytes}:getTree" };
  }
}

// The Capabilities service may be used by remote execution clients to query
// various server properties, in order to self-configure or return meaningful
// error messages.
//
// The query may include a particular `instance_name`, in which case the values
// returned will pertain to that instance.
service Capabilities {
  // GetCapabilities returns the server capabilities configuration.
  rpc GetCapabilities(GetCapabilitiesRequest) returns (ServerCapabilities) {
    option (google.api.http) = {
      get: "/v2/{instance_name=**}/capabilities"
    };
  }
}

// An `Action` captures all the information about an execution which is required
// to reproduce it.
//
// `Action`s are the core component of the [Execution] service. A single
// `Action` represents a repeatable action that can be performed by the
// execution service. `Action`s can be succinctly identified by the digest of
// their wire format encoding and, once an `Action` has been executed, will be
// cached in the action cache. Future requests can then use the cached result
// rather than needing to run afresh.
//
// When a server completes execution of an
// [Action][build.bazel.remote.execution.v2.Action], it MAY choose to
// cache the [result][build.bazel.remote.execution.v2.ActionResult] in
// the [ActionCache][build.bazel.remote.execution.v2.ActionCache] unless
// `do_not_cache` is `true`. Clients SHOULD expect the server to do so. By
// default, future calls to
// [Execute][build.bazel.remote.execution.v2.Execution.Execute] the same
// `Action` will also serve their results from the cache. Clients must take care
// to understand the caching behaviour. Ideally, all `Action`s will be
// reproducible so that serving a result from cache is always desirable and
// correct.
message Action {
  // The digest of the [Command][build.bazel.remote.execution.v2.Command]
  // to run, which MUST be present in the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  Digest command_digest = 1;

  // The digest of the root
  // [Directory][build.bazel.remote.execution.v2.Directory] for the input
  // files. The files in the directory tree are available in the correct
  // location on the build machine before the command is executed. The root
  // directory, as well as every subdirectory and content blob referred to, MUST
  // be in the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  Digest input_root_digest = 2;

  reserved 3 to 5; // Used for fields moved to [Command][build.bazel.remote.execution.v2.Command].

  // A timeout after which the execution should be killed. If the timeout is
  // absent, then the client is specifying that the execution should continue
  // as long as the server will let it. The server SHOULD impose a timeout if
  // the client does not specify one, however, if the client does specify a
  // timeout that is longer than the server's maximum timeout, the server MUST
  // reject the request.
  //
  // The timeout is a part of the
  // [Action][build.bazel.remote.execution.v2.Action] message, and
  // therefore two `Actions` with different timeouts are different, even if they
  // are otherwise identical. This is because, if they were not, running an
  // `Action` with a lower timeout than is required might result in a cache hit
  // from an execution run with a longer timeout, hiding the fact that the
  // timeout is too short. By encoding it directly in the `Action`, a lower
  // timeout will result in a cache miss and the execution timeout will fail
  // immediately, rather than whenever the cache entry gets evicted.
  google.protobuf.Duration timeout = 6;

  // If true, then the `Action`'s result cannot be cached, and in-flight
  // requests for the same `Action` may not be merged.
  bool do_not_cache = 7;
}

// A `Command` is the actual command executed by a worker running an
// [Action][build.bazel.remote.execution.v2.Action] and specifications of its
// environment.
//
// Except as otherwise required, the environment (such as which system
// libraries or binaries are available, and what filesystems are mounted where)
// is defined by and specific to the implementation of the remote execution API.
message Command {
  // An `EnvironmentVariable` is one variable to set in the running program's
  // environment.
  message EnvironmentVariable {
    // The variable name.
    string name = 1;

    // The variable value.
    string value = 2;
  }

  // The arguments to the command. The first argument must be the path to the
  // executable, which must be either a relative path, in which case it is
  // evaluated with respect to the input root, or an absolute path.
  repeated string arguments = 1;

  // The environment variables to set when running the program. The worker may
  // provide its own default environment variables; these defaults can be
  // overridden using this field. Additional variables can also be specified.
  //
  // In order to ensure that equivalent
  // [Command][build.bazel.remote.execution.v2.Command]s always hash to the same
  // value, the environment variables MUST be lexicographically sorted by name.
  // Sorting of strings is done by code point, equivalently, by the UTF-8 bytes.
  repeated EnvironmentVariable environment_variables = 2;

  // A list of the output files that the client expects to retrieve from the
  // action. Only the listed files, as well as directories listed in
  // `output_directories`, will be returned to the client as output.
  // Other files or directories that may be created during command execution
  // are discarded.
  //
  // The paths are relative to the working directory of the action execution.
  // The paths are specified using a single forward slash (`/`) as a path
  // separator, even if the execution platform natively uses a different
  // separator. The path MUST NOT include a trailing slash, nor a leading slash,
  // being a relative path.
  //
  // In order to ensure consistent hashing of the same Action, the output paths
  // MUST be sorted lexicographically by code point (or, equivalently, by UTF-8
  // bytes).
  //
  // An output file cannot be duplicated, be a parent of another output file, or
  // have the same path as any of the listed output directories.
  //
  // Directories leading up to the output files are created by the worker prior
  // to execution, even if they are not explicitly part of the input root.
  repeated string output_files = 3;

  // A list of the output directories that the client expects to retrieve from
  // the action. Only the listed directories will be returned (an entire
  // directory structure will be returned as a
  // [Tree][build.bazel.remote.execution.v2.Tree] message digest, see
  // [OutputDirectory][build.bazel.remote.execution.v2.OutputDirectory]), as
  // well as files listed in `output_files`. Other files or directories that
  // may be created during command execution are discarded.
  //
  // The paths are relative to the working directory of the action execution.
  // The paths are specified using a single forward slash (`/`) as a path
  // separator, even if the execution platform natively uses a different
  // separator. The path MUST NOT include a trailing slash, nor a leading slash,
  // being a relative path. The special value of empty string is allowed,
  // although not recommended, and can be used to capture the entire working
  // directory tree, including inputs.
  //
  // In order to ensure consistent hashing of the same Action, the output paths
  // MUST be sorted lexicographically by code point (or, equivalently, by UTF-8
  // bytes).
  //
  // An output directory cannot be duplicated or have the same path as any of
  // the listed output files.
  //
  // Directories leading up to the output directories (but not the output
  // directories themselves) are created by the worker prior to execution, even
  // if they are not explicitly part of the input root.
  repeated string output_directories = 4;

  // The platform requirements for the execution environment. The server MAY
  // choose to execute the action on any worker satisfying the requirements, so
  // the client SHOULD ensure that running the action on any such worker will
  // have the same result.
  Platform platform = 5;

  // The working directory, relative to the input root, for the command to run
  // in. It must be a directory which exists in the input tree. If it is left
  // empty, then the action is run in the input root.
  string working_directory = 6;
}

// A `Platform` is a set of requirements, such as hardware, operating system, or
// compiler toolchain, for an
// [Action][build.bazel.remote.execution.v2.Action]'s execution
// environment. A `Platform` is represented as a series of key-value pairs
// representing the properties that are required of the platform.
message Platform {
  // A single property for the environment. The server is responsible for
  // specifying the property `name`s that it accepts. If an unknown `name` is
  // provided in the requirements for an
  // [Action][build.bazel.remote.execution.v2.Action], the server SHOULD
  // reject the execution request. If permitted by the server, the same `name`
  // may occur multiple times.
  //
  // The server is also responsible for specifying the interpretation of
  // property `value`s. For instance, a property describing how much RAM must be
  // available may be interpreted as allowing a worker with 16GB to fulfill a
  // request for 8GB, while a property describing the OS environment on which
  // the action must be performed may require an exact match with the worker's
  // OS.
  //
  // The server MAY use the `value` of one or more properties to determine how
  // it sets up the execution environment, such as by making specific system
  // files available to the worker.
  message Property {
    // The property name.
    string name = 1;

    // The property value.
    string value = 2;
  }

  // The properties that make up this platform. In order to ensure that
  // equivalent `Platform`s always hash to the same value, the properties MUST
  // be lexicographically sorted by name, and then by value. Sorting of strings
  // is done by code point, equivalently, by the UTF-8 bytes.
  repeated Property properties = 1;
}

// A `Directory` represents a directory node in a file tree, containing zero or
// more children [FileNodes][build.bazel.remote.execution.v2.FileNode],
// [DirectoryNodes][build.bazel.remote.execution.v2.DirectoryNode] and
// [SymlinkNodes][build.bazel.remote.execution.v2.SymlinkNode].
// Each `Node` contains its name in the directory, either the digest of its
// content (either a file blob or a `Directory` proto) or a symlink target, as
// well as possibly some metadata about the file or directory.
//
// In order to ensure that two equivalent directory trees hash to the same
// value, the following restrictions MUST be obeyed when constructing a
// a `Directory`:
//
// * Every child in the directory must have a path of exactly one segment.
//   Multiple levels of directory hierarchy may not be collapsed.
// * Each child in the directory must have a unique path segment (file name).
//   Note that while the API itself is case-sensitive, the environment where
//   the Action is executed may or may not be case-sensitive. That is, it is
//   legal to call the API with a Directory that has both "Foo" and "foo" as
//   children, but the Action may be rejected by the remote system upon
//   execution.
// * The files, directories and symlinks in the directory must each be sorted
//   in lexicographical order by path. The path strings must be sorted by code
//   point, equivalently, by UTF-8 bytes.
//
// A `Directory` that obeys the restrictions is said to be in canonical form.
//
// As an example, the following could be used for a file named `bar` and a
// directory named `foo` with an executable file named `baz` (hashes shortened
// for readability):
//
// ```json
// // (Directory proto)
// {
//   files: [
//     {
//       name: "bar",
//       digest: {
//         hash: "4a73bc9d03...",
//         size: 65534
//       }
//     }
//   ],
//   directories: [
//     {
//       name: "foo",
//       digest: {
//         hash: "4cf2eda940...",
//         size: 43
//       }
//     }
//   ]
// }
//
// // (Directory proto with hash "4cf2eda940..." and size 43)
// {
//   files: [
//     {
//       name: "baz",
//       digest: {
//         hash: "b2c941073e...",
//         size: 1294,
//       },
//       is_executable: true
//     }
//   ]
// }
// ```
message Directory {
  // The files in the directory.
  repeated FileNode files = 1;

  // The subdirectories in the directory.
  repeated DirectoryNode directories = 2;

  // The symlinks in the directory.
  repeated SymlinkNode symlinks = 3;
}

// A `FileNode` represents a single file and associated metadata.
message FileNode {
  // The name of the file.
  string name = 1;

  // The digest of the file's content.
  Digest digest = 2;

  reserved 3; // Reserved to ensure wire-compatibility with `OutputFile`.

  // True if file is executable, false otherwise.
  bool is_executable = 4;
}

// A `DirectoryNode` represents a child of a
// [Directory][build.bazel.remote.execution.v2.Directory] which is itself
// a `Directory` and its associated metadata.
message DirectoryNode {
  // The name of the directory.
  string name = 1;

  // The digest of the
  // [Directory][build.bazel.remote.execution.v2.Directory] object
  // represented. See [Digest][build.bazel.remote.execution.v2.Digest]
  // for information about how to take the digest of a proto message.
  Digest digest = 2;
}

// A `SymlinkNode` represents a symbolic link.
message SymlinkNode {
  // The name of the symlink.
  string name = 1;

  // The target path of the symlink. The path separator is a forward slash `/`.
  // The target path can be relative to the parent directory of the symlink or
  // it can be an absolute path starting with `/`. Support for absolute paths
  // can be checked using the [Capabilities][build.bazel.remote.execution.v2.Capabilities]
  // API. The canonical form forbids the substrings `/./` and `//` in the target
  // path. `..` components are allowed anywhere in the target path.
  string target = 2;
}

// A content digest. A digest for a given blob consists of the size of the blob
// and its hash. The hash algorithm to use is defined by the server, but servers
// SHOULD use SHA-256.
//
// The size is considered to be an integral part of the digest and cannot be
// separated. That is, even if the `hash` field is correctly specified but
// `size_bytes` is not, the server MUST reject the request.
//
// The reason for including the size in the digest is as follows: in a great
// many cases, the server needs to know the size of the blob it is about to work
// with prior to starting an operation with it, such as flattening Merkle tree
// structures or streaming it to a worker. Technically, the server could
// implement a separate metadata store, but this results in a significantly more
// complicated implementation as opposed to having the client specify the size
// up-front (or storing the size along with the digest in every message where
// digests are embedded). This does mean that the API leaks some implementation
// details of (what we consider to be) a reasonable server implementation, but
// we consider this to be a worthwhile tradeoff.
//
// When a `Digest` is used to refer to a proto message, it always refers to the
// message in binary encoded form. To ensure consistent hashing, clients and
// servers MUST ensure that they serialize messages according to the following
// rules, even if there are alternate valid encodings for the same message:
//
// * Fields are serialized in tag order.
// * There are no unknown fields.
// * There are no duplicate fields.
// * Fields are serialized according to the default semantics for their type.
//
// Most protocol buffer implementations will always follow these rules when
// serializing, but care should be taken to avoid shortcuts. For instance,
// concatenating two messages to merge them may produce duplicate fields.
message Digest {
  // The hash. In the case of SHA-256, it will always be a lowercase hex string
  // exactly 64 characters long.
  string hash = 1;

  // The size of the blob, in bytes.
  int64 size_bytes = 2;
}

// ExecutedActionMetadata contains details about a completed execution.
message ExecutedActionMetadata {
  // The name of the worker which ran the execution.
  string worker = 1;

  // When was the action added to the queue.
  google.protobuf.Timestamp queued_timestamp = 2;

  // When the worker received the action.
  google.protobuf.Timestamp worker_start_timestamp = 3;

  // When the worker completed the action, including all stages.
  google.protobuf.Timestamp worker_completed_timestamp = 4;

  // When the worker started fetching action inputs.
  google.protobuf.Timestamp input_fetch_start_timestamp = 5;

  // When the worker finished fetching action inputs.
  google.protobuf.Timestamp input_fetch_completed_timestamp = 6;

  // When the worker started executing the action command.
  google.protobuf.Timestamp execution_start_timestamp = 7;

  // When the worker completed executing the action command.
  google.protobuf.Timestamp execution_completed_timestamp = 8;

  // When the worker started uploading action outputs.
  google.protobuf.Timestamp output_upload_start_timestamp = 9;

  // When the worker finished uploading action outputs.
  google.protobuf.Timestamp output_upload_completed_timestamp = 10;
}

// An ActionResult represents the result of an
// [Action][build.bazel.remote.execution.v2.Action] being run.
message ActionResult {
  reserved 1; // Reserved for use as the resource name.

  // The output files of the action. For each output file requested in the
  // `output_files` field of the Action, if the corresponding file existed after
  // the action completed, a single entry will be present either in this field,
  // or in the output_file_symlinks field, if the file was a symbolic link to
  // another file.
  //
  // If the action does not produce the requested output, or produces a
  // directory where a regular file is expected or vice versa, then that output
  // will be omitted from the list. The server is free to arrange the output
  // list as desired; clients MUST NOT assume that the output list is sorted.
  repeated OutputFile output_files = 2;

  // The output files of the action that are symbolic links to other files. Those
  // may be links to other output files, or input files, or even absolute paths
  // outside of the working directory, if the server supports
  // [SymlinkAbsolutePathStrategy.ALLOWED][build.bazel.remote.execution.v2.CacheCapabilities.SymlinkAbsolutePathStrategy].
  // For each output file requested in the `output_files` field of the Action,
  // if the corresponding file existed after
  // the action completed, a single entry will be present either in this field,
  // or in the `output_files` field, if the file was not a symbolic link.
  //
  // If the action does not produce the requested output, or produces a
  // directory where a regular file is expected or vice versa, then that output
  // will be omitted from the list. The server is free to arrange the output
  // list as desired; clients MUST NOT assume that the output list is sorted.
  repeated OutputSymlink output_file_symlinks = 10;

  // The output directories of the action. For each output directory requested
  // in the `output_directories` field of the Action, if the corresponding
  // directory existed after the action completed, a single entry will be
  // present in the output list, which will contain the digest of a
  // [Tree][build.bazel.remote.execution.v2.Tree] message containing the
  // directory tree, and the path equal exactly to the corresponding Action
  // output_directories member.
  //
  // As an example, suppose the Action had an output directory `a/b/dir` and the
  // execution produced the following contents in `a/b/dir`: a file named `bar`
  // and a directory named `foo` with an executable file named `baz`. Then,
  // output_directory will contain (hashes shortened for readability):
  //
  // ```json
  // // OutputDirectory proto:
  // {
  //   path: "a/b/dir"
  //   tree_digest: {
  //     hash: "4a73bc9d03...",
  //     size: 55
  //   }
  // }
  // // Tree proto with hash "4a73bc9d03..." and size 55:
  // {
  //   root: {
  //     files: [
  //       {
  //         name: "bar",
  //         digest: {
  //           hash: "4a73bc9d03...",
  //           size: 65534
  //         }
  //       }
  //     ],
  //     directories: [
  //       {
  //         name: "foo",
  //         digest: {
  //           hash: "4cf2eda940...",
  //           size: 43
  //         }
  //       }
  //     ]
  //   }
  //   children : {
  //     // (Directory proto with hash "4cf2eda940..." and size 43)
  //     files: [
  //       {
  //         name: "baz",
  //         digest: {
  //           hash: "b2c941073e...",
  //           size: 1294,
  //         },
  //         is_executable: true
  //       }
  //     ]
  //   }
  // }
  // ```
  repeated OutputDirectory output_directories = 3;

  // The output directories of the action that are symbolic links to other
  // directories. Those may be links to other output directories, or input
  // directories, or even absolute paths outside of the working directory,
  // if the server supports
  // [SymlinkAbsolutePathStrategy.ALLOWED][build.bazel.remote.execution.v2.CacheCapabilities.SymlinkAbsolutePathStrategy].
  // For each output directory requested in the `output_directories` field of
  // the Action, if the directory file existed after
  // the action completed, a single entry will be present either in this field,
  // or in the `output_directories` field, if the directory was not a symbolic link.
  //
  // If the action does not produce the requested output, or produces a
  // file where a directory is expected or vice versa, then that output
  // will be omitted from the list. The server is free to arrange the output
  // list as desired; clients MUST NOT assume that the output list is sorted.
  repeated OutputSymlink output_directory_symlinks = 11;

  // The exit code of the command.
  int32 exit_code = 4;

  // The standard output buffer of the action. The server will determine, based
  // on the size of the buffer, whether to return it in raw form or to return
  // a digest in `stdout_digest` that points to the buffer. If neither is set,
  // then the buffer is empty. The client SHOULD NOT assume it will get one of
  // the raw buffer or a digest on any given request and should be prepared to
  // handle either.
  bytes stdout_raw = 5;

  // The digest for a blob containing the standard output of the action, which
  // can be retrieved from the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  // See `stdout_raw` for when this will be set.
  Digest stdout_digest = 6;

  // The standard error buffer of the action. The server will determine, based
  // on the size of the buffer, whether to return it in raw form or to return
  // a digest in `stderr_digest` that points to the buffer. If neither is set,
  // then the buffer is empty. The client SHOULD NOT assume it will get one of
  // the raw buffer or a digest on any given request and should be prepared to
  // handle either.
  bytes stderr_raw = 7;

  // The digest for a blob containing the standard error of the action, which
  // can be retrieved from the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  // See `stderr_raw` for when this will be set.
  Digest stderr_digest = 8;

  // The details of the execution that originally produced this result.
  ExecutedActionMetadata execution_metadata = 9;
}

// An `OutputFile` is similar to a
// [FileNode][build.bazel.remote.execution.v2.FileNode], but it is used as an
// output in an `ActionResult`. It allows a full file path rather than
// only a name.
//
// `OutputFile` is binary-compatible with `FileNode`.
message OutputFile {
  // The full path of the file relative to the working directory, including the
  // filename. The path separator is a forward slash `/`. Since this is a
  // relative path, it MUST NOT begin with a leading forward slash.
  string path = 1;

  // The digest of the file's content.
  Digest digest = 2;

  reserved 3; // Used for a removed field in an earlier version of the API.

  // True if file is executable, false otherwise.
  bool is_executable = 4;
}

// A `Tree` contains all the
// [Directory][build.bazel.remote.execution.v2.Directory] protos in a
// single directory Merkle tree, compressed into one message.
message Tree {
  // The root directory in the tree.
  Directory root = 1;

  // All the child directories: the directories referred to by the root and,
  // recursively, all its children. In order to reconstruct the directory tree,
  // the client must take the digests of each of the child directories and then
  // build up a tree starting from the `root`.
  repeated Directory children = 2;
}

// An `OutputDirectory` is the output in an `ActionResult` corresponding to a
// directory's full contents rather than a single file.
message OutputDirectory {
  // The full path of the directory relative to the working directory. The path
  // separator is a forward slash `/`. Since this is a relative path, it MUST
  // NOT begin with a leading forward slash. The empty string value is allowed,
  // and it denotes the entire working directory.
  string path = 1;

  reserved 2; // Used for a removed field in an earlier version of the API.

  // The digest of the encoded
  // [Tree][build.bazel.remote.execution.v2.Tree] proto containing the
  // directory's contents.
  Digest tree_digest = 3;
}

// An `OutputSymlink` is similar to a
// [Symlink][build.bazel.remote.execution.v2.SymlinkNode], but it is used as an
// output in an `ActionResult`.
//
// `OutputSymlink` is binary-compatible with `SymlinkNode`.
message OutputSymlink {
  // The full path of the symlink relative to the working directory, including the
  // filename. The path separator is a forward slash `/`. Since this is a
  // relative path, it MUST NOT begin with a leading forward slash.
  string path = 1;

  // The target path of the symlink. The path separator is a forward slash `/`.
  // The target path can be relative to the parent directory of the symlink or
  // it can be an absolute path starting with `/`. Support for absolute paths
  // can be checked using the [Capabilities][build.bazel.remote.execution.v2.Capabilities]
  // API. The canonical form forbids the substrings `/./` and `//` in the target
  // path. `..` components are allowed anywhere in the target path.
  string target = 2;
}

// An `ExecutionPolicy` can be used to control the scheduling of the action.
message ExecutionPolicy {
  // The priority (relative importance) of this action. Generally, a lower value
  // means that the action should be run sooner than actions having a greater
  // priority value, but the interpretation of a given value is server-
  // dependent. A priority of 0 means the *default* priority. Priorities may be
  // positive or negative, and such actions should run later or sooner than
  // actions having the default priority, respectively. The particular semantics
  // of this field is up to the server. In particular, every server will have
  // their own supported range of priorities, and will decide how these map into
  // scheduling policy.
  int32 priority = 1;
}

// A `ResultsCachePolicy` is used for fine-grained control over how action
// outputs are stored in the CAS and Action Cache.
message ResultsCachePolicy {
  // The priority (relative importance) of this content in the overall cache.
  // Generally, a lower value means a longer retention time or other advantage,
  // but the interpretation of a given value is server-dependent. A priority of
  // 0 means a *default* value, decided by the server.
  //
  // The particular semantics of this field is up to the server. In particular,
  // every server will have their own supported range of priorities, and will
  // decide how these map into retention/eviction policy.
  int32 priority = 1;
}

// A request message for
// [Execution.Execute][build.bazel.remote.execution.v2.Execution.Execute].
message ExecuteRequest {
  // 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;

  // If true, the action will be executed even if its result is already
  // present in the [ActionCache][build.bazel.remote.execution.v2.ActionCache].
  // The execution is still allowed to be merged with other in-flight executions
  // of the same action, however - semantically, the service MUST only guarantee
  // that the results of an execution with this field set were not visible
  // before the corresponding execution request was sent.
  // Note that actions from execution requests setting this field set are still
  // eligible to be entered into the action cache upon completion, and services
  // SHOULD overwrite any existing entries that may exist. This allows
  // skip_cache_lookup requests to be used as a mechanism for replacing action
  // cache entries that reference outputs no longer available or that are
  // poisoned in any way.
  // If false, the result may be served from the action cache.
  bool skip_cache_lookup = 3;

  reserved 2, 4, 5; // Used for removed fields in an earlier version of the API.

  // The digest of the [Action][build.bazel.remote.execution.v2.Action] to
  // execute.
  Digest action_digest = 6;

  // An optional policy for execution of the action.
  // The server will have a default policy if this is not provided.
  ExecutionPolicy execution_policy = 7;

  // An optional policy for the results of this execution in the remote cache.
  // The server will have a default policy if this is not provided.
  // This may be applied to both the ActionResult and the associated blobs.
  ResultsCachePolicy results_cache_policy = 8;
}

// A `LogFile` is a log stored in the CAS.
message LogFile {
  // The digest of the log contents.
  Digest digest = 1;

  // This is a hint as to the purpose of the log, and is set to true if the log
  // is human-readable text that can be usefully displayed to a user, and false
  // otherwise. For instance, if a command-line client wishes to print the
  // server logs to the terminal for a failed action, this allows it to avoid
  // displaying a binary file.
  bool human_readable = 2;
}

// The response message for
// [Execution.Execute][build.bazel.remote.execution.v2.Execution.Execute],
// which will be contained in the [response
// field][google.longrunning.Operation.response] of the
// [Operation][google.longrunning.Operation].
message ExecuteResponse {
  // The result of the action.
  ActionResult result = 1;

  // True if the result was served from cache, false if it was executed.
  bool cached_result = 2;

  // If the status has a code other than `OK`, it indicates that the action did
  // not finish execution. For example, if the operation times out during
  // execution, the status will have a `DEADLINE_EXCEEDED` code. Servers MUST
  // use this field for errors in execution, rather than the error field on the
  // `Operation` object.
  //
  // If the status code is other than `OK`, then the result MUST NOT be cached.
  // For an error status, the `result` field is optional; the server may
  // populate the output-, stdout-, and stderr-related fields if it has any
  // information available, such as the stdout and stderr of a timed-out action.
  google.rpc.Status status = 3;

  // An optional list of additional log outputs the server wishes to provide. A
  // server can use this to return execution-specific logs however it wishes.
  // This is intended primarily to make it easier for users to debug issues that
  // may be outside of the actual job execution, such as by identifying the
  // worker executing the action or by providing logs from the worker's setup
  // phase. The keys SHOULD be human readable so that a client can display them
  // to a user.
  map<string, LogFile> server_logs = 4;

  // Freeform informational message with details on the execution of the action
  // that may be displayed to the user upon failure or when requested explicitly.
  string message = 5;
}

// Metadata about an ongoing
// [execution][build.bazel.remote.execution.v2.Execution.Execute], which
// will be contained in the [metadata
// field][google.longrunning.Operation.response] of the
// [Operation][google.longrunning.Operation].
message ExecuteOperationMetadata {
  // The current stage of execution.
  enum Stage {
    UNKNOWN = 0;

    // Checking the result against the cache.
    CACHE_CHECK = 1;

    // Currently idle, awaiting a free machine to execute.
    QUEUED = 2;

    // Currently being executed by a worker.
    EXECUTING = 3;

    // Finished execution.
    COMPLETED = 4;
  }

  Stage stage = 1;

  // The digest of the [Action][build.bazel.remote.execution.v2.Action]
  // being executed.
  Digest action_digest = 2;

  // If set, the client can use this name with
  // [ByteStream.Read][google.bytestream.ByteStream.Read] to stream the
  // standard output.
  string stdout_stream_name = 3;

  // If set, the client can use this name with
  // [ByteStream.Read][google.bytestream.ByteStream.Read] to stream the
  // standard error.
  string stderr_stream_name = 4;
}

// A request message for
// [WaitExecution][build.bazel.remote.execution.v2.Execution.WaitExecution].
message WaitExecutionRequest {
  // The name of the [Operation][google.longrunning.Operation]
  // returned by [Execute][build.bazel.remote.execution.v2.Execution.Execute].
  string name = 1;
}

// A request message for
// [ActionCache.GetActionResult][build.bazel.remote.execution.v2.ActionCache.GetActionResult].
message GetActionResultRequest {
  // 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 digest of the [Action][build.bazel.remote.execution.v2.Action]
  // whose result is requested.
  Digest action_digest = 2;
}

// A request message for
// [ActionCache.UpdateActionResult][build.bazel.remote.execution.v2.ActionCache.UpdateActionResult].
message UpdateActionResultRequest {
  // 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 digest of the [Action][build.bazel.remote.execution.v2.Action]
  // whose result is being uploaded.
  Digest action_digest = 2;

  // The [ActionResult][build.bazel.remote.execution.v2.ActionResult]
  // to store in the cache.
  ActionResult action_result = 3;

  // An optional policy for the results of this execution in the remote cache.
  // The server will have a default policy if this is not provided.
  // This may be applied to both the ActionResult and the associated blobs.
  ResultsCachePolicy results_cache_policy = 4;
}

// A request message for
// [ContentAddressableStorage.FindMissingBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.FindMissingBlobs].
message FindMissingBlobsRequest {
  // 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;

  // A list of the blobs to check.
  repeated Digest blob_digests = 2;
}

// A response message for
// [ContentAddressableStorage.FindMissingBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.FindMissingBlobs].
message FindMissingBlobsResponse {
  // A list of the blobs requested *not* present in the storage.
  repeated Digest missing_blob_digests = 2;
}

// A request message for
// [ContentAddressableStorage.BatchUpdateBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.BatchUpdateBlobs].
message BatchUpdateBlobsRequest {
  // A request corresponding to a single blob that the client wants to upload.
  message Request {
    // The digest of the blob. This MUST be the digest of `data`.
    Digest digest = 1;

    // The raw binary data.
    bytes data = 2;
  }

  // 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 individual upload requests.
  repeated Request requests = 2;
}

// A response message for
// [ContentAddressableStorage.BatchUpdateBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.BatchUpdateBlobs].
message BatchUpdateBlobsResponse {
  // A response corresponding to a single blob that the client tried to upload.
  message Response {
    // The blob digest to which this response corresponds.
    Digest digest = 1;

    // The result of attempting to upload that blob.
    google.rpc.Status status = 2;
  }

  // The responses to the requests.
  repeated Response responses = 1;
}

// A request message for
// [ContentAddressableStorage.BatchReadBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.BatchReadBlobs].
message BatchReadBlobsRequest {
  // 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 individual blob digests.
  repeated Digest digests = 2;
}

// A response message for
// [ContentAddressableStorage.BatchReadBlobs][build.bazel.remote.execution.v2.ContentAddressableStorage.BatchReadBlobs].
message BatchReadBlobsResponse {
  // A response corresponding to a single blob that the client tried to download.
  message Response {
    // The digest to which this response corresponds.
    Digest digest = 1;

    // The raw binary data.
    bytes data = 2;

    // The result of attempting to download that blob.
    google.rpc.Status status = 3;
  }

  // The responses to the requests.
  repeated Response responses = 1;
}

// A request message for
// [ContentAddressableStorage.GetTree][build.bazel.remote.execution.v2.ContentAddressableStorage.GetTree].
message GetTreeRequest {
  // 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 digest of the root, which must be an encoded
  // [Directory][build.bazel.remote.execution.v2.Directory] message
  // stored in the
  // [ContentAddressableStorage][build.bazel.remote.execution.v2.ContentAddressableStorage].
  Digest root_digest = 2;

  // A maximum page size to request. If present, the server will request no more
  // than this many items. Regardless of whether a page size is specified, the
  // server may place its own limit on the number of items to be returned and
  // require the client to retrieve more items using a subsequent request.
  int32 page_size = 3;

  // A page token, which must be a value received in a previous
  // [GetTreeResponse][build.bazel.remote.execution.v2.GetTreeResponse].
  // If present, the server will use it to return the following page of results.
  string page_token = 4;
}

// A response message for
// [ContentAddressableStorage.GetTree][build.bazel.remote.execution.v2.ContentAddressableStorage.GetTree].
message GetTreeResponse {
  // The directories descended from the requested root.
  repeated Directory directories = 1;

  // If present, signifies that there are more results which the client can
  // retrieve by passing this as the page_token in a subsequent
  // [request][build.bazel.remote.execution.v2.GetTreeRequest].
  // If empty, signifies that this is the last page of results.
  string next_page_token = 2;
}

// A request message for
// [Capabilities.GetCapabilities][build.bazel.remote.execution.v2.Capabilities.GetCapabilities].
message GetCapabilitiesRequest {
  // 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;
}

// A response message for
// [Capabilities.GetCapabilities][build.bazel.remote.execution.v2.Capabilities.GetCapabilities].
message ServerCapabilities {
  // Capabilities of the remote cache system.
  CacheCapabilities cache_capabilities = 1;

  // Capabilities of the remote execution system.
  ExecutionCapabilities execution_capabilities = 2;

  // Earliest RE API version supported, including deprecated versions.
  build.bazel.semver.SemVer deprecated_api_version = 3;

  // Earliest non-deprecated RE API version supported.
  build.bazel.semver.SemVer low_api_version = 4;

  // Latest RE API version supported.
  build.bazel.semver.SemVer high_api_version = 5;
}

// The digest function used for converting values into keys for CAS and Action
// Cache.
enum DigestFunction {
  // It is an error for the server to return this value.
  UNKNOWN = 0;

  // The Sha-256 digest function.
  SHA256 = 1;

  // The Sha-1 digest function.
  SHA1 = 2;

  // The MD5 digest function.
  MD5 = 3;
}

// Describes the server/instance capabilities for updating the action cache.
message ActionCacheUpdateCapabilities {
  bool update_enabled = 1;
}

// Allowed values for priority in
// [ResultsCachePolicy][google.devtools.remoteexecution.v2.ResultsCachePolicy]
// Used for querying both cache and execution valid priority ranges.
message PriorityCapabilities {
  // Supported range of priorities, including boundaries.
  message PriorityRange {
    int32 min_priority = 1;
    int32 max_priority = 2;
  }
  repeated PriorityRange priorities = 1;
}

// Capabilities of the remote cache system.
message CacheCapabilities {
  // Describes how the server treats absolute symlink targets.
  enum SymlinkAbsolutePathStrategy {
    UNKNOWN = 0;

    // Server will return an `INVALID_ARGUMENT` on input symlinks with absolute
    // targets.
    // If an action tries to create an output symlink with an absolute target, a
    // `FAILED_PRECONDITION` will be returned.
    DISALLOWED = 1;

    // Server will allow symlink targets to escape the input root tree, possibly
    // resulting in non-hermetic builds.
    ALLOWED = 2;
  }

  // All the digest functions supported by the remote cache.
  // Remote cache may support multiple digest functions simultaneously.
  repeated DigestFunction digest_function = 1;

  // Capabilities for updating the action cache.
  ActionCacheUpdateCapabilities action_cache_update_capabilities = 2;

  // Supported cache priority range for both CAS and ActionCache.
  PriorityCapabilities cache_priority_capabilities = 3;

  // Maximum total size of blobs to be uploaded/downloaded using
  // batch methods. A value of 0 means no limit is set, although
  // in practice there will always be a message size limitation
  // of the protocol in use, e.g. GRPC.
  int64 max_batch_total_size_bytes = 4;

  // Whether absolute symlink targets are supported.
  SymlinkAbsolutePathStrategy symlink_absolute_path_strategy = 5;
}

// Capabilities of the remote execution system.
message ExecutionCapabilities {
  // Remote execution may only support a single digest function.
  DigestFunction digest_function = 1;

  // Whether remote execution is enabled for the particular server/instance.
  bool exec_enabled = 2;

  // Supported execution priority range.
  PriorityCapabilities execution_priority_capabilities = 3;
}

// Details for the tool used to call the API.
message ToolDetails {
  // Name of the tool, e.g. bazel.
  string tool_name = 1;

  // Version of the tool used for the request, e.g. 5.0.3.
  string tool_version = 2;
}

// An optional Metadata to attach to any RPC request to tell the server about an
// external context of the request. The server may use this for logging or other
// purposes. To use it, the client attaches the header to the call using the
// canonical proto serialization:
//
// * name: `build.bazel.remote.execution.v2.requestmetadata-bin`
// * contents: the base64 encoded binary `RequestMetadata` message.
message RequestMetadata {
  // The details for the tool invoking the requests.
  ToolDetails tool_details = 1;

  // An identifier that ties multiple requests to the same action.
  // For example, multiple requests to the CAS, Action Cache, and Execution
  // API are used in order to compile foo.cc.
  string action_id = 2;

  // An identifier that ties multiple actions together to a final result.
  // For example, multiple actions are required to build and run foo_test.
  string tool_invocation_id = 3;

  // An identifier to tie multiple tool invocations together. For example,
  // runs of foo_test, bar_test and baz_test on a post-submit of a given patch.
  string correlated_invocations_id = 4;
}