aboutsummaryrefslogtreecommitdiff
path: root/google/devtools/remoteworkers/v1test2/bots.proto
blob: fbad1bf4f4a19e94c250a122735b36b7b862f822 (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
// Copyright 2018 Google LLC
//
// 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 google.devtools.remoteworkers.v1test2;

import "google/api/annotations.proto";
import "google/devtools/remoteworkers/v1test2/worker.proto";
import "google/protobuf/any.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option csharp_namespace = "Google.DevTools.RemoteWorkers.V1Test2";
option go_package = "google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2;remoteworkers";
option java_multiple_files = true;
option java_outer_classname = "RemoteWorkersBots";
option java_package = "com.google.devtools.remoteworkers.v1test2";
option objc_class_prefix = "RW";

// Design doc: https://goo.gl/oojM5H
//
// Loosely speaking, the Bots interface monitors a collection of workers (think
// of them as "computers" for a moment). This collection is known as a "farm,"
// and its purpose is to perform work on behalf of a client.
//
// Each worker runs a small program known as a "bot" that allows it to be
// controlled by the server. This interface contains only methods that are
// called by the bots themselves; admin functionality is out of scope for this
// interface.
//
// More precisely, we use the term "worker" to refer to the physical "thing"
// running the bot. We use the term "worker," and not "machine" or "computer,"
// since a worker may consist of more than one machine - e.g., a computer with
// multiple attached devices, or even a cluster of computers, with only one of
// them running the bot. Conversely, a single machine may host several bots, in
// which case each bot has a "worker" corresponding to the slice of the machine
// being managed by that bot.
//
// The main resource in the Bots interface is not, surprisingly, a Bot - it is a
// BotSession, which represents a period of time in which a bot is in continuous
// contact with the server (see the BotSession message for more information).
// The parent of a bot session can be thought of as an instance of a farm. That
// is, one endpoint may be able to manage many farms for many users. For
// example, for a farm managed through GCP, the parent resource will typically
// take the form "projects/{project_id}". This is referred to below as "the farm
// resource."
service Bots {
  // CreateBotSession is called when the bot first joins the farm, and
  // establishes a session ID to ensure that multiple machines do not register
  // using the same name accidentally.
  rpc CreateBotSession(CreateBotSessionRequest) returns (BotSession) {
    option (google.api.http) = {
      post: "/v1test2/{parent=**}/botSessions"
      body: "bot_session"
    };
  }

  // UpdateBotSession must be called periodically by the bot (on a schedule
  // determined by the server) to let the server know about its status, and to
  // pick up new lease requests from the server.
  rpc UpdateBotSession(UpdateBotSessionRequest) returns (BotSession) {
    option (google.api.http) = {
      patch: "/v1test2/{name=**/botSessions/*}"
      body: "bot_session"
    };
  }

  // PostBotEventTemp may be called by the bot to indicate that some exceptional
  // event has occurred. This method is subject to change or removal in future
  // revisions of this API; we may simply want to replace it with StackDriver or
  // some other common interface.
  rpc PostBotEventTemp(PostBotEventTempRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1test2/{name=**/botSessions/*}:postEvent"
      body: "*"
    };
  }
}

// A bot session represents the state of a bot while in continuous contact with
// the server for a period of time. The session includes information about the
// worker - that is, the *worker* (the physical or virtual hardware) is
// considered to be a property of the bot (the software agent running on that
// hardware), which is the reverse of real life, but more natural from the point
// of the view of this API, which communicates solely with the bot and not
// directly with the underlying worker.
message BotSession {
  // The bot session name, as selected by the server. Output only during a call
  // to CreateBotSession.
  string name = 1;

  // A unique bot ID within the farm used to persistently identify this bot over
  // time (i.e., over multiple sessions). This ID must be unique within a
  // farm. Typically, the bot ID will be the same as the name of the primary
  // device in the worker (e.g., what you'd get from typing `uname -n` on *nix),
  // but this is not required since a single device may allow multiple bots to
  // run on it, each with access to different resources. What is important is
  // that this ID is meaningful to humans, who might need to hunt a physical
  // machine down to fix it.
  //
  // When CreateBotSession is successfully called with a bot_id, all prior
  // sessions with the same ID are invalidated. If a bot attempts to update an
  // invalid session, the server must reject that request, and may also
  // quarantine the other bot with the same bot IDs (ie, stop sending it new
  // leases and alert an admin).
  string bot_id = 2;

  // The status of the bot. This must be populated in every call to
  // UpdateBotSession.
  BotStatus status = 3;

  // A description of the worker hosting this bot. The Worker message is used
  // here in the Status context (see Worker for more information).  If multiple
  // bots are running on the worker, this field should only describe the
  // resources accessible from this bot.
  //
  // During the call to CreateBotSession, the server may make arbitrary changes
  // to the worker's `server_properties` field (see that field for more
  // information). Otherwise, this field is input-only.
  Worker worker = 4;

  // A list of all leases that are a part of this session. See the Lease message
  // for details.
  repeated Lease leases = 5;

  // The time at which this bot session will expire, unless the bot calls
  // UpdateBotSession again. Output only.
  google.protobuf.Timestamp expire_time = 6;

  // The version of the bot code currently running. The server may use this
  // information to issue an admin action to tell the bot to update itself.
  string version = 7;
}

// A Lease is a lease that the scheduler has assigned to this bot. If the bot
// notices (by UpdateBotSession) that it has any leases in the PENDING state, it
// should call UpdateBotSession to put the leases into the ACTIVE state and
// start executing their assignments.
//
// All fields in this message are output-only, *except* the `state` and `status`
// fields. Note that repeated fields can only be updated as a unit, so on every
// update the bot must provide an update for *all* the leases the server expects
// it to report on.
//
// The scheduler *should* ensure that all leases scheduled to a bot can actually
// be accepted, but race conditions may occur. In such cases, the bot should
// attempt to accept the leases in the order they are listed by the server, to
// allow the server to control priorities.
//
// The server will remove COMPLETED leases from time to time, after which the
// bot shouldn't report on them any more (the server will ignore superfluous
// COMPLETED records).
message Lease {
  // A short string uniquely identifing the lease within this bot session.
  string id = 7;

  // The actual work to be performed, if any. May be omitted by the server if
  // the lease is not in the `PENDING` state. The message must be meaningful to
  // the bot. Output only (must only be set by the server).
  google.protobuf.Any payload = 8;

  // Any result the bot wishes to provide about the lease. Must not be changed
  // after the first call with the lease in the `COMPLETED` or `CANCELLED`
  // state. Input only (must only be set by the bot, will not be echoed by the
  // server).
  google.protobuf.Any result = 9;

  // The state of the lease. See LeaseState for more information.
  LeaseState state = 2;

  // The final status of the lease (should be populated by the bot if the state
  // is completed). This is the status of the lease, not of any task represented
  // by the lease. For example, if the bot could not accept the lease because it
  // asked for some resource the bot didn't have, this status will be
  // FAILED_PRECONDITION. But if the assignment in the lease didn't execute
  // correctly, this field will be `OK` while the failure of the assignment must
  // communicated via the `result` field.
  google.rpc.Status status = 3;

  // The requirements that are being claimed by this lease. This field may be
  // omitted by the server if the lease is not pending.
  Worker requirements = 4;

  // The time at which this lease expires. The server *may* extend this over
  // time, but due to race conditions, the bot is not *required* to respect any
  // expiry date except the first one.
  google.protobuf.Timestamp expire_time = 5;

  // DEPRECATED. The assignment should be provided to the bot via the `payload`
  // field. Clients that wish to use a simple name (such as a queue of work
  // provided elsewhere) should define a custom message type and encode it into
  // `payload`.
  string assignment = 1 [deprecated = true];

  // DEPRECATED. Use `payload` instead.
  google.protobuf.Any inline_assignment = 6 [deprecated = true];
}

// AdminTemp is a prelimiary set of administration tasks. It's called "Temp"
// because we do not yet know the best way to represent admin tasks; it's
// possible that this will be entirely replaced in later versions of this API.
// If this message proves to be sufficient, it will be renamed in the alpha or
// beta release of this API.
//
// This message (suitably marshalled into a protobuf.Any) can be used as the
// inline_assignment field in a lease; the lease assignment field should simply
// be `"admin"` in these cases.
//
// This message is heavily based on Swarming administration tasks from the LUCI
// project (http://github.com/luci/luci-py/appengine/swarming).
message AdminTemp {
  // Possible administration actions.
  enum Command {
    // Illegal value.
    UNSPECIFIED = 0;

    // Download and run a new version of the bot. `arg` will be a resource
    // accessible via `ByteStream.Read` to obtain the new bot code.
    BOT_UPDATE = 1;

    // Restart the bot without downloading a new version. `arg` will be a
    // message to log.
    BOT_RESTART = 2;

    // Shut down the bot. `arg` will be a task resource name (similar to those
    // in tasks.proto) that the bot can use to tell the server that it is
    // terminating.
    BOT_TERMINATE = 3;

    // Restart the host computer. `arg` will be a message to log.
    HOST_RESTART = 4;
  }

  // The admin action; see `Command` for legal values.
  Command command = 1;

  // The argument to the admin action; see `Command` for semantics.
  string arg = 2;
}

// Request message for CreateBotSession.
message CreateBotSessionRequest {
  // The farm resource.
  string parent = 1;

  // The bot session to create. Server-assigned fields like name must be unset.
  BotSession bot_session = 2;
}

// Request message for UpdateBotSession.
message UpdateBotSessionRequest {
  // The bot session name. Must match bot_session.name.
  string name = 1;

  // The bot session resource to update.
  BotSession bot_session = 2;

  // The fields on the bot that should be updated. See the BotSession resource
  // for which fields are updatable by which caller.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for PostBotEventTemp
message PostBotEventTempRequest {
  // Types of bot events.
  enum Type {
    // Illegal value.
    UNSPECIFIED = 0;

    // Interesting but harmless event.
    INFO = 1;

    // Error condition.
    ERROR = 2;
  }

  // The bot session name.
  string name = 1;

  // The type of bot event.
  Type type = 2;

  // A human-readable message.
  string msg = 3;
}

// A coarse description of the status of the bot that the server uses to
// determine whether to assign the bot new leases.
enum BotStatus {
  // Default value; do not use.
  BOT_STATUS_UNSPECIFIED = 0;

  // The bot is healthy, and will accept leases as normal.
  OK = 1;

  // The bot is unhealthy and will not accept new leases. For example, the bot
  // may have detected that available disk space is too low. This situation may
  // resolve itself, but will typically require human intervention.
  UNHEALTHY = 2;

  // The bot has been asked to reboot the host. The bot will not accept new
  // leases; once all leases are complete, this session will no longer be
  // updated but the bot will be expected to establish a new session after the
  // reboot completes.
  HOST_REBOOTING = 3;

  // The bot has been asked to shut down. As with HOST_REBOOTING, once all
  // leases are completed, the session will no longer be updated and the bot
  // will not be expected to establish a new session.
  //
  // Bots are typically only asked to shut down if its host computer will be
  // modified in some way, such as deleting a VM.
  BOT_TERMINATING = 4;
}

// The state of the lease. All leases start in the PENDING state. A bot can
// change PENDING to ACTIVE or (in the case of an error) COMPLETED, or from
// ACTIVE to COMPLETED. The server can change PENDING or ACTIVE to CANCELLED if
// it wants the bot to release its resources - for example, if the bot needs to
// be quarantined (it's producing bad output) or a cell needs to be drained.
enum LeaseState {
  // Default value; do not use.
  LEASE_STATE_UNSPECIFIED = 0;

  // Pending: the server expects the bot to accept this lease. This may only be
  // set by the server.
  PENDING = 1;

  // Active: the bot has accepted this lease. This may only be set by the bot.
  ACTIVE = 2;

  // Completed: the bot is no longer leased. This may only be set by the bot,
  // and the status field must be populated iff the state is COMPLETED.
  COMPLETED = 4;

  // Cancelled: The bot should immediately release all resources associated with
  // the lease. This may only be set by the server.
  CANCELLED = 5;
}