bots.proto 14 KB

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