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