Documentation
¶
Overview ¶
Package botapi implements core Bot API handlers.
Handlers related to RBE are in the "rbe" package for now.
Index ¶
- type BotAPIServer
- func (srv *BotAPIServer) BotCode(c *router.Context)
- func (srv *BotAPIServer) Claim(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) Event(ctx context.Context, body *EventRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) Handshake(ctx context.Context, body *HandshakeRequest, _ *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) IDToken(ctx context.Context, body *TokenRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) OAuthToken(ctx context.Context, body *TokenRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) Poll(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) TaskError(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
- func (srv *BotAPIServer) TaskUpdate(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
- type BotGroupCfg
- type BotRBEParams
- type EventRequest
- type EventResponse
- type HandshakeRequest
- type HandshakeResponse
- type TokenRequest
- type TokenResponse
- type UnimplementedRequest
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BotAPIServer ¶
type BotAPIServer struct {
// contains filtered or unexported fields
}
BotAPIServer implements core Bot API handlers.
Handlers are implement in individual Go files. They are all installed into the server router in main.go.
func NewBotAPIServer ¶
func NewBotAPIServer(cfg *cfg.Provider, secret *hmactoken.Secret, project, version string) *BotAPIServer
NewBotAPIServer constructs a new BotAPIServer.
func (*BotAPIServer) BotCode ¶
func (srv *BotAPIServer) BotCode(c *router.Context)
BotCode serves the bot archive blob or an HTTP redirect to it.
Used to bootstrap bots and by the self-updating bots.
Uses optional "Version" route parameter. Its value is either a concrete bot archive digest to fetch, or an empty string (in which case the handler will serve a redirect to the current stable bot version).
Attempts are made to utilize GAE's edge cache by setting the corresponding headers.
func (*BotAPIServer) Claim ¶
func (srv *BotAPIServer) Claim(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
Claim implements the handler that claims pending tasks.
TODO: Doc, implement.
func (*BotAPIServer) Event ¶
func (srv *BotAPIServer) Event(ctx context.Context, body *EventRequest, r *botsrv.Request) (botsrv.Response, error)
Event implements the handler that logs events sent by the bot.
func (*BotAPIServer) Handshake ¶
func (srv *BotAPIServer) Handshake(ctx context.Context, body *HandshakeRequest, _ *botsrv.Request) (botsrv.Response, error)
Handshake implements the bot handshake handler.
It is the first ever request sent by the bot. It registers the bot in the datastore and establishes a new bot session.
func (*BotAPIServer) IDToken ¶
func (srv *BotAPIServer) IDToken(ctx context.Context, body *TokenRequest, r *botsrv.Request) (botsrv.Response, error)
IDToken mints ID tokens to be used inside the task.
See OAuthToken for details.
func (*BotAPIServer) OAuthToken ¶
func (srv *BotAPIServer) OAuthToken(ctx context.Context, body *TokenRequest, r *botsrv.Request) (botsrv.Response, error)
OAuthToken mints OAuth tokens to be used inside the task.
There are two flavors of service accounts the bot may use:
- "system": this account is associated directly with the bot (in bots.cfg), and can be used at any time (when running a task or not).
- "task": this account is associated with the task currently executing on the bot, and may be used only when bot is actually running this task.
The returned token is expected to be alive for at least ~5 min, but can live longer (but no longer than ~1h). In general the client should assume the token is short-lived.
Multiple bots may share the exact same access token if their configuration match (the token is cached by Swarming for performance reasons).
Besides the token, the response also contains the actual service account email (if it is really configured), or two special strings in place of the email:
- "none" if the bot is not configured to use service accounts at all.
- "bot" if the bot should use tokens produced by bot_config.py hook.
Returns following errors:
- INVALID_ARGUMENT on a bad request or if the service account is somehow misconfigured.
- PERMISSION_DENIED if the caller is not allowed to use the service account.
- INTERNAL on retriable transient errors.
func (*BotAPIServer) Poll ¶
func (srv *BotAPIServer) Poll(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
Poll implements the handler that tell the bot what to do next.
TODO: Doc, implement.
func (*BotAPIServer) TaskError ¶
func (srv *BotAPIServer) TaskError(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
TaskError implements the handler that collects internal task errors.
Uses optional "TaskID" route parameter with the task being worked on by the bot.
TODO: Doc, implement.
func (*BotAPIServer) TaskUpdate ¶
func (srv *BotAPIServer) TaskUpdate(ctx context.Context, body *UnimplementedRequest, r *botsrv.Request) (botsrv.Response, error)
TaskUpdate implements handler that collects task state updates.
Uses optional "TaskID" route parameter with the task being worked on by the bot.
TODO: Doc, implement.
type BotGroupCfg ¶
type BotGroupCfg struct { // Dimensions is the server-assigned dimensions from bots.cfg. Dimensions map[string][]string `json:"dimensions"` }
BotGroupCfg is derived from the server's bots.cfg and sent to the bot.
type BotRBEParams ¶
type BotRBEParams struct { // Instance if the full RBE instance name the bot should be using. Instance string `json:"instance"` // HybridMode, if true, indicates to use RBE and native scheduler together. HybridMode bool `json:"hybrid_mode"` // Sleep is how long to sleep (in seconds) before next Swarming check in. Sleep float64 `json:"sleep"` // PollToken is a legacy unused field preserved for compatibility. PollToken string `json:"poll_token"` }
BotRBEParams is sent to the bot by the handshake and poll handlers.
Describes how the bot should be interacting with RBE API.
type EventRequest ¶
type EventRequest struct { // Session is a serialized Swarming Bot Session proto. Session []byte `json:"session"` // RequestUUID is used to skip reporting duplicate events on retries. // // Generated by the client (usually an UUID4 string). Optional. RequestUUID string `json:"request_uuid,omitempty"` // Event is the kind of the event the bot is reporting. // // Required. Must be in the list of allowed events. Event model.BotEventType `json:"event"` // Message is an optional arbitrary text message associated with the event. // // Will show up in the UI and when listing bot events in the API. Not // interpreted by the server in any way. Message string `json:"message,omitempty"` // State is (mostly) arbitrary JSON dict with various properties of the bot. // // Optional. If set, will be used to see if the bot should be quarantined or // put into maintenance. If not set, the current bot state in the datastore // won't be affected. State botstate.Dict `json:"state,omitempty"` // Version is the bot's own version, if known. // // Optional. If set, ends up reported together with the event. Version string `json:"version,omitempty"` }
EventRequest is sent by the bot.
func (*EventRequest) ExtractDebugRequest ¶
func (r *EventRequest) ExtractDebugRequest() any
func (*EventRequest) ExtractSession ¶
func (r *EventRequest) ExtractSession() []byte
type HandshakeRequest ¶
type HandshakeRequest struct { // Dimensions are the initial dimensions collected by the bot. // // They are initial in a sense that they are collected by the base version // of the bot code, without using custom hooks script yet. In many cases, // these dimensions are very different from what the bot would end up using // after loading the hooks. For that reason these dimensions aren't actually // written to the datastore (to avoid the bot "flapping" between two sets of // dimensions when it restart and performs the handshake). They are still // used to check if the bot should be quarantined, and may be used in debug // logs. // // At least `id` dimension must be set. It is the bot ID. Dimensions map[string][]string `json:"dimensions"` // State is (mostly) arbitrary JSON dict with various properties of the bot. // // Values here are not indexed and they do not affect how tasks are scheduled // on the bot. The server is still aware of some keys and checks them to // decide how to handle the bot calls. State botstate.Dict `json:"state,omitempty"` // Version is the bot's own version. // // It is a digest of the running bot archive. Here it is used FYI only. Version string `json:"version"` // SessionID is an ID of a new session the bot is opening. // // If the bot has already opened this session (i.e. this is a retry), this // session will be reused. // // May be absent in calls from very old bots. An auto-generated ID will be // used instead in that case. Such bots will be asked to self update on the // very first poll call. SessionID string `json:"session_id,omitempty"` }
HandshakeRequest is sent by the bot.
func (*HandshakeRequest) ExtractDebugRequest ¶
func (r *HandshakeRequest) ExtractDebugRequest() any
func (*HandshakeRequest) ExtractSession ¶
func (r *HandshakeRequest) ExtractSession() []byte
type HandshakeResponse ¶
type HandshakeResponse struct { // Session is a serialized bot session proto. Session []byte `json:"session"` // BotVersion is the bot version the bot should be running, as FYI to the bot. BotVersion string `json:"bot_version"` // ServerVersion is the current server version, as FYI to the bot. ServerVersion string `json:"server_version"` // BotConfig is the body of the custom hooks script, if any. BotConfig string `json:"bot_config,omitempty"` // BotConfigName is the name of the custom hooks script or "bot_config.py". BotConfigName string `json:"bot_config_name"` // BotConfigRev is the revision of the main bot_config.py (not the hooks script). BotConfigRev string `json:"bot_config_rev"` // BotGroupCfg is derived from the server's bots.cfg. BotGroupCfg BotGroupCfg `json:"bot_group_cfg"` // RBE defines how the bot should be interacting with RBE API. RBE *BotRBEParams `json:"rbe,omitempty"` }
HandshakeResponse is returned by the server.
type TokenRequest ¶
type TokenRequest struct { // Session is a serialized Swarming Bot Session proto. Session []byte `json:"session"` // AccountID is either "system" or "task". // // Defines what sort of service account to mint a token for. AccountID string `json:"account_id"` // TaskID is the task ID that the bot thinks it is running. // // Required when minting tokens for "task" account. Will be checked against // the task ID associated with the bot in the datastore. TaskID string `json:"task_id,omitempty"` // Scopes is a list of OAuth scopes to mint a service account token with. // // Used only by OAuthToken handler. Must be unset in IDToken handler. Scopes []string `json:"scopes,omitempty"` // Audience is an audience to put into a minted ID token. // // Used only by IDToken handler. Must be unset in OAuthToken handler. Audience string `json:"audience,omitempty"` }
TokenRequest is sent by the bot.
func (*TokenRequest) ExtractDebugRequest ¶
func (r *TokenRequest) ExtractDebugRequest() any
func (*TokenRequest) ExtractSession ¶
func (r *TokenRequest) ExtractSession() []byte
type TokenResponse ¶
type TokenResponse struct { // ServiceAccount is a service account the token is from. // // This is either an email, or literals "bot" (if the bot is configured to use // its own service account as a system or task account) or "none" (if // there's no service account assigned at all). ServiceAccount string `json:"service_account"` // AccessToken is the minted OAuth access token. // // Returned only by OAuthToken handler when actually using an assigned service // account (i.e. not "bot" or "none"). Unset in IDToken handler response. AccessToken string `json:"access_token,omitempty"` // IDToken is the minted ID token. // // Returned only by IDToken handler when actually using an assigned service // account (i.e. not "bot" or "none"). Unset in OAuthToken handler response. IDToken string `json:"id_token,omitempty"` // Expiry is token's Unix expiration timestamp in seconds. // // Returned only when actually using an assigned service account (i.e. not // "bot" or "none"). Expiry int64 `json:"expiry,omitempty"` }
TokenResponse is returned by the server.
type UnimplementedRequest ¶
type UnimplementedRequest struct{}
UnimplementedRequest is used as a placeholder in unimplemented handlers.
func (*UnimplementedRequest) ExtractDebugRequest ¶
func (r *UnimplementedRequest) ExtractDebugRequest() any
func (*UnimplementedRequest) ExtractSession ¶
func (r *UnimplementedRequest) ExtractSession() []byte