xref: /aosp_15_r20/external/googleapis/google/devtools/remoteworkers/v1test2/bots.proto (revision d5c09012810ac0c9f33fe448fb6da8260d444cc9)
1// Copyright 2019 Google LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16syntax = "proto3";
17
18package google.devtools.remoteworkers.v1test2;
19
20import "google/api/annotations.proto";
21import "google/api/client.proto";
22import "google/api/field_behavior.proto";
23import "google/api/resource.proto";
24import "google/devtools/remoteworkers/v1test2/worker.proto";
25import "google/protobuf/any.proto";
26import "google/protobuf/field_mask.proto";
27import "google/protobuf/timestamp.proto";
28import "google/rpc/status.proto";
29
30option csharp_namespace = "Google.DevTools.RemoteWorkers.V1Test2";
31option go_package = "google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2;remoteworkers";
32option java_multiple_files = true;
33option java_outer_classname = "RemoteWorkersBots";
34option java_package = "com.google.devtools.remoteworkers.v1test2";
35option php_namespace = "Google\\Cloud\\Remoteworkers\\V1test2";
36option objc_class_prefix = "RW";
37
38// Design doc: https://goo.gl/oojM5H
39//
40// Loosely speaking, the Bots interface monitors a collection of workers (think
41// of them as "computers" for a moment). This collection is known as a "farm,"
42// and its purpose is to perform work on behalf of a client.
43//
44// Each worker runs a small program known as a "bot" that allows it to be
45// controlled by the server. This interface contains only methods that are
46// called by the bots themselves; admin functionality is out of scope for this
47// interface.
48//
49// More precisely, we use the term "worker" to refer to the physical "thing"
50// running the bot. We use the term "worker," and not "machine" or "computer,"
51// since a worker may consist of more than one machine - e.g., a computer with
52// multiple attached devices, or even a cluster of computers, with only one of
53// them running the bot. Conversely, a single machine may host several bots, in
54// which case each bot has a "worker" corresponding to the slice of the machine
55// being managed by that bot.
56//
57// The main resource in the Bots interface is not, surprisingly, a Bot - it is a
58// BotSession, which represents a period of time in which a bot is in continuous
59// contact with the server (see the BotSession message for more information).
60// The parent of a bot session can be thought of as an instance of a farm. That
61// is, one endpoint may be able to manage many farms for many users. For
62// example, for a farm managed through GCP, the parent resource will typically
63// take the form "projects/{project_id}". This is referred to below as "the farm
64// resource."
65service Bots {
66  option (google.api.default_host) = "remoteworkers.googleapis.com";
67
68  // CreateBotSession is called when the bot first joins the farm, and
69  // establishes a session ID to ensure that multiple machines do not register
70  // using the same name accidentally.
71  rpc CreateBotSession(CreateBotSessionRequest) returns (BotSession) {
72    option (google.api.http) = {
73      post: "/v1test2/{parent=**}/botSessions"
74      body: "bot_session"
75    };
76    option (google.api.method_signature) = "parent,bot_session";
77  }
78
79  // UpdateBotSession must be called periodically by the bot (on a schedule
80  // determined by the server) to let the server know about its status, and to
81  // pick up new lease requests from the server.
82  rpc UpdateBotSession(UpdateBotSessionRequest) returns (BotSession) {
83    option (google.api.http) = {
84      patch: "/v1test2/{name=**/botSessions/*}"
85      body: "bot_session"
86    };
87    option (google.api.method_signature) = "name,bot_session,update_mask";
88  }
89}
90
91// A bot session represents the state of a bot while in continuous contact with
92// the server for a period of time. The session includes information about the
93// worker - that is, the *worker* (the physical or virtual hardware) is
94// considered to be a property of the bot (the software agent running on that
95// hardware), which is the reverse of real life, but more natural from the point
96// of the view of this API, which communicates solely with the bot and not
97// directly with the underlying worker.
98message BotSession {
99  option (google.api.resource) = {
100    type: "remoteworkers.googleapis.com/BotSession"
101    pattern: "{unknown_path}/botSessions/{bot_session}"
102  };
103
104  // The bot session name, as selected by the server. Output only during a call
105  // to CreateBotSession.
106  string name = 1;
107
108  // A unique bot ID within the farm used to persistently identify this bot over
109  // time (i.e., over multiple sessions). This ID must be unique within a
110  // farm. Typically, the bot ID will be the same as the name of the primary
111  // device in the worker (e.g., what you'd get from typing `uname -n` on *nix),
112  // but this is not required since a single device may allow multiple bots to
113  // run on it, each with access to different resources. What is important is
114  // that this ID is meaningful to humans, who might need to hunt a physical
115  // machine down to fix it.
116  //
117  // When CreateBotSession is successfully called with a bot_id, all prior
118  // sessions with the same ID are invalidated. If a bot attempts to update an
119  // invalid session, the server must reject that request, and may also
120  // quarantine the other bot with the same bot IDs (ie, stop sending it new
121  // leases and alert an admin).
122  string bot_id = 2;
123
124  // The status of the bot. This must be populated in every call to
125  // UpdateBotSession.
126  BotStatus status = 3;
127
128  // A description of the worker hosting this bot. The Worker message is used
129  // here in the Status context (see Worker for more information).  If multiple
130  // bots are running on the worker, this field should only describe the
131  // resources accessible from this bot.
132  //
133  // During the call to CreateBotSession, the server may make arbitrary changes
134  // to the worker's `server_properties` field (see that field for more
135  // information). Otherwise, this field is input-only.
136  Worker worker = 4;
137
138  // A list of all leases that are a part of this session. See the Lease message
139  // for details.
140  repeated Lease leases = 5;
141
142  // The time at which this bot session will expire, unless the bot calls
143  // UpdateBotSession again. Output only.
144  google.protobuf.Timestamp expire_time = 6;
145
146  // The version of the bot code currently running. The server may use this
147  // information to issue an admin action to tell the bot to update itself.
148  string version = 7;
149}
150
151// A Lease is a lease that the scheduler has assigned to this bot. If the bot
152// notices (by UpdateBotSession) that it has any leases in the PENDING state, it
153// should call UpdateBotSession to put the leases into the ACTIVE state and
154// start executing their assignments.
155//
156// All fields in this message are output-only, *except* the `state` and `status`
157// fields. Note that repeated fields can only be updated as a unit, so on every
158// update the bot must provide an update for *all* the leases the server expects
159// it to report on.
160//
161// The scheduler *should* ensure that all leases scheduled to a bot can actually
162// be accepted, but race conditions may occur. In such cases, the bot should
163// attempt to accept the leases in the order they are listed by the server, to
164// allow the server to control priorities.
165//
166// The server will remove COMPLETED leases from time to time, after which the
167// bot shouldn't report on them any more (the server will ignore superfluous
168// COMPLETED records).
169message Lease {
170  // A short string uniquely identifing the lease within this bot session.
171  string id = 7;
172
173  // The actual work to be performed, if any. May be omitted by the server if
174  // the lease is not in the `PENDING` state. The message must be meaningful to
175  // the bot. Output only (must only be set by the server).
176  google.protobuf.Any payload = 8;
177
178  // Any result the bot wishes to provide about the lease. Must not be changed
179  // after the first call with the lease in the `COMPLETED` or `CANCELLED`
180  // state. Input only (must only be set by the bot, will not be echoed by the
181  // server).
182  google.protobuf.Any result = 9;
183
184  // The state of the lease. See LeaseState for more information.
185  LeaseState state = 2;
186
187  // The final status of the lease (should be populated by the bot if the state
188  // is completed). This is the status of the lease, not of any task represented
189  // by the lease. For example, if the bot could not accept the lease because it
190  // asked for some resource the bot didn't have, this status will be
191  // FAILED_PRECONDITION. But if the assignment in the lease didn't execute
192  // correctly, this field will be `OK` while the failure of the assignment must
193  // communicated via the `result` field.
194  google.rpc.Status status = 3;
195
196  // The requirements that are being claimed by this lease. This field may be
197  // omitted by the server if the lease is not pending.
198  Worker requirements = 4;
199
200  // The time at which this lease expires. The server *may* extend this over
201  // time, but due to race conditions, the bot is not *required* to respect any
202  // expiry date except the first one.
203  google.protobuf.Timestamp expire_time = 5;
204
205  // DEPRECATED. The assignment should be provided to the bot via the `payload`
206  // field. Clients that wish to use a simple name (such as a queue of work
207  // provided elsewhere) should define a custom message type and encode it into
208  // `payload`.
209  string assignment = 1 [deprecated = true];
210
211  // DEPRECATED. Use `payload` instead.
212  google.protobuf.Any inline_assignment = 6 [deprecated = true];
213}
214
215// AdminTemp is a prelimiary set of administration tasks. It's called "Temp"
216// because we do not yet know the best way to represent admin tasks; it's
217// possible that this will be entirely replaced in later versions of this API.
218// If this message proves to be sufficient, it will be renamed in the alpha or
219// beta release of this API.
220//
221// This message (suitably marshalled into a protobuf.Any) can be used as the
222// inline_assignment field in a lease; the lease assignment field should simply
223// be `"admin"` in these cases.
224//
225// This message is heavily based on Swarming administration tasks from the LUCI
226// project (http://github.com/luci/luci-py/appengine/swarming).
227message AdminTemp {
228  // Possible administration actions.
229  enum Command {
230    // Illegal value.
231    UNSPECIFIED = 0;
232
233    // Download and run a new version of the bot. `arg` will be a resource
234    // accessible via `ByteStream.Read` to obtain the new bot code.
235    BOT_UPDATE = 1;
236
237    // Restart the bot without downloading a new version. `arg` will be a
238    // message to log.
239    BOT_RESTART = 2;
240
241    // Shut down the bot. `arg` will be a task resource name (similar to those
242    // in tasks.proto) that the bot can use to tell the server that it is
243    // terminating.
244    BOT_TERMINATE = 3;
245
246    // Restart the host computer. `arg` will be a message to log.
247    HOST_RESTART = 4;
248  }
249
250  // The admin action; see `Command` for legal values.
251  Command command = 1;
252
253  // The argument to the admin action; see `Command` for semantics.
254  string arg = 2;
255}
256
257// A coarse description of the status of the bot that the server uses to
258// determine whether to assign the bot new leases.
259enum BotStatus {
260  // Default value; do not use.
261  BOT_STATUS_UNSPECIFIED = 0;
262
263  // The bot is healthy, and will accept leases as normal.
264  OK = 1;
265
266  // The bot is unhealthy and will not accept new leases. For example, the bot
267  // may have detected that available disk space is too low. This situation may
268  // resolve itself, but will typically require human intervention.
269  UNHEALTHY = 2;
270
271  // The bot has been asked to reboot the host. The bot will not accept new
272  // leases; once all leases are complete, this session will no longer be
273  // updated but the bot will be expected to establish a new session after the
274  // reboot completes.
275  HOST_REBOOTING = 3;
276
277  // The bot has been asked to shut down. As with HOST_REBOOTING, once all
278  // leases are completed, the session will no longer be updated and the bot
279  // will not be expected to establish a new session.
280  //
281  // Bots are typically only asked to shut down if its host computer will be
282  // modified in some way, such as deleting a VM.
283  BOT_TERMINATING = 4;
284
285  // The bot is initializing and is not ready to accept leases.
286  INITIALIZING = 5;
287}
288
289// The state of the lease. All leases start in the PENDING state. A bot can
290// change PENDING to ACTIVE or (in the case of an error) COMPLETED, or from
291// ACTIVE to COMPLETED. The server can change PENDING or ACTIVE to CANCELLED if
292// it wants the bot to release its resources - for example, if the bot needs to
293// be quarantined (it's producing bad output) or a cell needs to be drained.
294enum LeaseState {
295  // Default value; do not use.
296  LEASE_STATE_UNSPECIFIED = 0;
297
298  // Pending: the server expects the bot to accept this lease. This may only be
299  // set by the server.
300  PENDING = 1;
301
302  // Active: the bot has accepted this lease. This may only be set by the bot.
303  ACTIVE = 2;
304
305  // Completed: the bot is no longer leased. This may only be set by the bot,
306  // and the status field must be populated iff the state is COMPLETED.
307  COMPLETED = 4;
308
309  // Cancelled: The bot should immediately release all resources associated with
310  // the lease. This may only be set by the server.
311  CANCELLED = 5;
312}
313
314// Request message for CreateBotSession.
315message CreateBotSessionRequest {
316  // Required. The farm resource.
317  string parent = 1 [(google.api.field_behavior) = REQUIRED];
318
319  // Required. The bot session to create. Server-assigned fields like name must
320  // be unset.
321  BotSession bot_session = 2 [(google.api.field_behavior) = REQUIRED];
322}
323
324// Request message for UpdateBotSession.
325message UpdateBotSessionRequest {
326  // Required. The bot session name. Must match bot_session.name.
327  string name = 1 [
328    (google.api.field_behavior) = REQUIRED,
329    (google.api.resource_reference) = {
330      type: "remoteworkers.googleapis.com/BotSession"
331    }
332  ];
333
334  // Required. The bot session resource to update.
335  BotSession bot_session = 2 [(google.api.field_behavior) = REQUIRED];
336
337  // Required. The fields on the bot that should be updated. See the BotSession
338  // resource for which fields are updatable by which caller.
339  google.protobuf.FieldMask update_mask = 3
340      [(google.api.field_behavior) = REQUIRED];
341}
342