• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5syntax = "proto3";
6
7package chromiumos.test.api;
8
9option go_package = "go.chromium.org/chromiumos/config/go/test/api";
10
11import "chromiumos/config/api/device_config_id.proto";
12
13import "chromiumos/longrunning/operations.proto";
14
15// Provides network based access to a device under test for remote
16// command execution and device state/identity retrieval.
17service DutService {
18  // ExecCommand runs a command on a DUT.
19  //
20  // The working directory is /.
21  // A tty is not spawned for the command.
22  // The user and group is root.
23  // All signals have their default dispositions and are not masked.
24  // The umask is set to 0.
25  //
26  // The environment contains:
27  //
28  //   TERM=dumb
29  //   PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
30  //   LANG=en_US.UTF-8
31  //   USER=root
32  //   HOME=/root
33  //
34  // The environment MAY also contain SSH client variables.
35  // The environment SHALL NOT contain variables not mentioned above.
36  //
37  // If the stream is interrupted, the implementation MAY attempt to
38  // stop the command by sending SIGINT, SIGHUP, SIGTERM, or SIGKILL.
39  rpc ExecCommand(ExecCommandRequest)
40      returns (stream ExecCommandResponse);
41
42  // FetchCrashes gets a stream of all crash reports currently on the DUT.
43  //
44  // The stream returned may split up a crash over multiple
45  // `FetchCrashesResponse` protos. See the definition of that proto for
46  // details.
47  //
48  // This call is read-only: it doesn't delete the crashes that it reads.
49  rpc FetchCrashes(FetchCrashesRequest) returns (stream FetchCrashesResponse);
50
51  // Restart simply reboots a DUT and returns when done.
52  //
53  // This is necessary as we need to refresh our connection to the DUT at
54  // restart, and this allows a signaling to the server that the connection
55  // will be severed.
56  rpc Restart(RestartRequest)
57      returns (longrunning.Operation) {
58    option (longrunning.operation_info) = {
59      response_type: "RestartResponse",
60      metadata_type: "RestartMetadata"
61    };
62  }
63
64  // Scans the live device to determine device config identifiers.
65  //
66  // The returned scan config can then be used to reverse lookup
67  // the actual DeviceConfigId values and corresponding configs.
68  rpc DetectDeviceConfigId(DetectDeviceConfigIdRequest)
69      returns (stream DetectDeviceConfigIdResponse);
70
71  // Fetch a file or dir from the device.
72  //
73  // The files will be returned via a tar'd bytestream.
74  rpc FetchFile(FetchFileRequest)
75    returns (stream File);
76
77  // Downloads files from GS to the DUT
78  //
79  // The files downloaded may be decompressed in this layer to save cycles (and
80  // space) in the DUT. This utilizes the cacheForDUT endpoint to download the
81  // files.
82  rpc Cache(CacheRequest)
83      returns (longrunning.Operation) {
84    option (longrunning.operation_info) = {
85      response_type: "CacheResponse",
86      metadata_type: "CacheMetadata"
87    };
88  }
89
90
91  // Used to reestablish connection to DUT in case of drops.
92  //
93  // This is needed in case the connection to the DUT is lost and we need to
94  // keep the connection. Previously this was done by the service, but as we try
95  // to accomplish true microservice functionality (i.e.: no side-effects) we
96  // removed it and gave the option for the user to reconnect if needed with
97  // whichever algorithm they prefer.
98  rpc ForceReconnect(ForceReconnectRequest)
99      returns (longrunning.Operation) {
100    option (longrunning.operation_info) = {
101      response_type: "ForceReconnectResponse",
102      metadata_type: "ForceReconnectMetadata"
103    };
104  }
105
106}
107
108
109message ExecCommandRequest {
110  // name is the resource name for the DUT.
111  // The DUT name is passed to the RTD when the RTD is started.
112  // It is not specified whether the name is the DUT hostname.
113  string name = 1;
114  // command is the command to run.
115  // If this contains no slashes, it is resolved using PATH.
116  // If this starts with /, it is used as an absolute path to the
117  // program to run.
118  // Otherwise, this is treated as a path relative to the working
119  // directory.
120  string command = 2;
121  // args are the arguments to pass to the command. The arguments
122  // are not quoted in any way, so passing shell variables and
123  // arguments containing spaces could fail.
124  repeated string args = 3;
125  // stdin is passed to the command as the program's stdin.
126  // The stream does not support seeking.
127  // An empty bytes is not treated specially; if the command reads
128  // from stdin, it will receive zero bytes.
129  bytes stdin = 4;
130  // stdout indicates how to handle the command's stdout.
131  Output stdout = 5;
132  // stderr indicates how to handle the command's stderr.
133  Output stderr = 6;
134}
135message ExecCommandResponse {
136  message ExitInfo {
137    // status provides information about how the command process
138    // terminated.
139    //
140    // If the command failed to start, status is set to an arbitrary
141    // non-zero value.
142    //
143    // If signaled is set, status is set to the signal that caused
144    // the command to terminate.
145    //
146    // Otherwise, status is set to the exit status of the process.
147    // Exit statuses outside of 0 to 255 inclusive are not supported;
148    // they will be mapped to an arbitrary non-zero value.
149    //
150    // status is zero if and only if the process was successfully
151    // started and exited with a zero status.
152    int32 status = 1;
153    // signaled indicates whether the command exited due to a signal.
154    // If set, status contains the signal.
155    bool signaled = 2;
156    // started indicates whether the command was started.
157    bool started = 3;
158    // error_message provides a human readable explanation for some errors.
159    // This MUST NOT be inspected by programs.
160    string error_message = 4;
161  }
162  // exit_info contains exit information.
163  // This is set when the command has exited or failed to start.
164  // This is set on the last message in the response stream.
165  ExitInfo exit_info = 1;
166  // stdout contains the shell command's stdout output since the last
167  // response in the stream.
168  // The implementation MAY batch or delay output to later
169  // responses in the stream.
170  bytes stdout = 2;
171  // stderr contains the shell command's stderr output since the last
172  // response in the stream.
173  // The implementation MAY batch or delay output to later
174  // responses in the stream.
175  bytes stderr = 3;
176}
177
178// Output enumeration for ExecCommandRequest.
179enum Output {
180  // OUTPUT_PIPE means to collect output and return it.
181  OUTPUT_PIPE = 0;
182  // OUTPUT_STDOUT is a special value for stderr which means to merge stderr
183  // into stdout.
184  OUTPUT_STDOUT = 1;
185}
186
187
188// Fetch files from remote host into local /var/tmp/remotefiles
189message FetchFileRequest {
190  string file = 1;
191}
192
193// Byte stream of the requested file.
194message File {
195  bytes file = 1;
196}
197
198message FetchCrashesRequest {
199    // If true, fetch the core file.
200    // For uploads to the crash server, that should generally be false.
201    // If the crash file is likely to be used for manual debugging (e.g. on
202    // a manually-invoked test suite run), this might be true.
203    // Coredumps can be extremely large (even gigabytes), so if resource usage
204    // is a concern, this should probably be false.
205    bool fetch_core = 2;
206
207    // dut is no longer necessary since this service is run on a per-dut basis.
208    // Reserving field in order to keep wire compatible with old proto.
209    reserved 1;
210}
211
212// When this response is streamed, the first proto with a given crash ID will
213// always contain the CrashInfo.
214// Files and core dumps (if present) may be streamed. If they are,
215// subsequent protos with the same crash ID will follow, each containing a chunk
216// of file/coredump. To reassemble these, concatenate the bytes received from
217// each subsequent proto with a matching crash_id (concatenate blobs that have
218// matching crash_ids and keys).
219// Additional crashes may be reported in the same stream with a new crash ID.
220message FetchCrashesResponse {
221    // Crash id. unique only within responses to a single FetchCrashes request.
222    // Used to assemble multiple streamed |FetchCrashesResponse| protos into a
223    // single crash report.
224    int64 crash_id = 1;
225    oneof data {
226      // Full details of crash report.
227      CrashInfo crash = 2;
228      // Misc file (e.g. minidump, large binary log, etc)
229      CrashBlob blob = 3;
230      // Coredump. Present if fetch_core was true in FetchCrashesRequest and
231      // the crash has a coredump. (kernel warnings, for example, do not have
232      // one).
233      bytes core = 4;
234    }
235}
236
237// The data in this proto matches the metadata from crash-reporter's meta files.
238// Sender::CreateCrashFormData puts this data into crash upload POST requests.
239// (See src/platform2/crash-reporter/crash_sender_util.cc.)
240// The names in this proto MUST match the names that crash-reporter uses so
241// that, when crashes are uploaded to the crash server, they are interpreted
242// as they are when crash-reporter uploads them.
243// Similarly, when this proto is converted into a POST request to send to the
244// crash server, the names must not be altered.
245message CrashInfo {
246    // Name of executable that crashed (e.g. "chrome")
247    string exec_name = 1;
248    // Product name (e.g. "Chrome_ChromeOS" or "ChromeOS")
249    string prod = 2;
250    // Product version (e.g. "12345.0.0")
251    string ver = 3;
252    // Crash signature (may not be populated for all crashes)
253    string sig = 4;
254    // The name of the integration test that was running when this crash
255    // happened, if any.
256    string in_progress_integration_test = 5;
257    // The name of the collector (e.g. chrome_collector, arc_collector)
258    string collector = 6;
259    // Additional key-value pairs of metadata (e.g. "crash_loop_mode = true").
260    // These should be included in any POSTs to the crash server in a standard
261    // POST form, as seen in CreateCrashFormData.
262    // (despite the fact that this message is a subfield, it should be a flat
263    // structure in any POSTs).
264    repeated CrashMetadata fields = 7;
265}
266
267// Arbitrary text-only key-value pair corresponding to the key-value pairs in
268// crash report metadata files.
269message CrashMetadata {
270    // This value is a UTF8, human-readable, description of the data.
271    string key = 1;
272    // The value will be a human-readable string (e.g. "12345.0.0"), which must
273    // be valid UTF-8.
274    string text = 2;
275};
276
277// Arbitrary non-UTF8 key-value pair from crash report metadata files.
278message CrashBlob {
279    // This value is a UTF8, human-readable, description of the data.
280    // This should be passed as the 'name' to the crash server.
281    // For instance, upload_file_fake_payload
282    string key = 1;
283    // The value is a blob (e.g. a file from sysfs or a minidump), which need
284    // not be valid UTF-8, and may be large.
285    bytes blob = 2;
286    // The basename of the file. Must be specified as the filename in data
287    // uploaded to the crash server.
288    // e.g. foo_binary.20201027.102345.0.dmp
289    string filename = 3;
290};
291
292message RestartRequest {
293  // args are the arguments to pass to the reboot command.
294  repeated string args = 1;
295
296  message ReconnectRetry {
297    int32 times = 1;
298    int64 interval_ms = 2;
299  }
300
301  ReconnectRetry retry = 2;
302};
303
304message RestartResponse {
305  // output represents the stdout for the reboot. Useful if the verbose flag is
306  // used.
307  string output = 1;
308
309}
310
311message RestartMetadata {
312}
313
314message CacheRequest {
315  // Where to place the file in the DUT:
316  // * Local DUT File
317  // * Pipe to command
318  message LocalFile {
319    string path = 1;
320  }
321
322  message Pipe {
323    string commands = 1;
324  }
325
326  oneof destination {
327    LocalFile file = 1;
328    Pipe pipe = 2;
329  }
330
331  // A file downloaded may be one of:
332  //  * A regular file
333  //  * A tar'd directory from which we fetch one file (source_file)
334  //  * A zipped file
335  message GSFile {
336    string source_path = 1;
337  }
338
339  message GSZipFile {
340    string source_path = 1;
341  }
342
343  message GSTARFile {
344    string source_path = 1;
345    string source_file = 2;
346  }
347
348  message Retry {
349    int32 times = 1;
350    int64 interval_ms = 2;
351  }
352
353  oneof source {
354    GSFile gs_file = 3;
355    GSZipFile gs_zip_file = 4;
356    GSTARFile gs_tar_file = 5;
357  }
358
359  Retry retry = 6;
360}
361
362message CacheResponse {
363  message Success {
364  }
365
366  message Failure {
367    string error_message = 1;
368  }
369
370  oneof result {
371    Success success = 1;
372    Failure failure = 2;
373  }
374}
375
376message CacheMetadata {
377}
378
379message ForceReconnectRequest {
380}
381
382message ForceReconnectResponse {
383  message Success {
384  }
385
386  message Failure {
387    string error_message = 1;
388  }
389
390  oneof result {
391    Success success = 1;
392    Failure failure = 2;
393  }
394}
395
396message ForceReconnectMetadata {
397}
398
399message DetectDeviceConfigIdRequest {
400};
401
402message DetectDeviceConfigIdResponse {
403  oneof result {
404    Success success = 1;
405    Failure failure = 2;
406  }
407
408  message Success {
409    chromiumos.config.api.DeviceConfigId.ScanConfig detected_scan_config = 1;
410  }
411
412  message Failure {
413    string error_message = 1;
414  }
415}
416