[infra][ftx] Creates launch task step on ftx luciexe binary.

Bug: b/258456267
Change-Id: I260d945b247a71d8f76fd9d4de3c6e5cd6a0ad3f
Reviewed-on: https://fuchsia-review.googlesource.com/c/infra/infra/+/863350
Commit-Queue: Vinicius Felizardo <felizardo@google.com>
Reviewed-by: Rahul Bangar <rahulbn@google.com>
diff --git a/cmd/ftxtest/.gitignore b/cmd/ftxtest/.gitignore
new file mode 100644
index 0000000..eb2767b
--- /dev/null
+++ b/cmd/ftxtest/.gitignore
@@ -0,0 +1 @@
+ftxtest
diff --git a/cmd/ftxtest/main.go b/cmd/ftxtest/main.go
index 8833e69..15e5688 100644
--- a/cmd/ftxtest/main.go
+++ b/cmd/ftxtest/main.go
@@ -1,3 +1,6 @@
+// Copyright 2023 The Fuchsia Authors. All rights reserved
+// Use of this source code is governed by a BSD-style license that can
+// found in the LICENSE file.
 package main
 
 import (
@@ -13,12 +16,28 @@
 	input := &ftxproto.InputProperties{}
 	var writeOutputProps func(*any.Any)
 	build.Main(input, &writeOutputProps, nil, func(ctx context.Context, extraArgs []string, state *build.State) error {
-		fmt.Printf("Build started with args: %v\n", extraArgs)
-		return processInput(ctx, input)
+		_, _, err := LaunchTaskStep(ctx)
+		if err != nil {
+			return fmt.Errorf("LaunchTaskStep: %v", err)
+		}
+		return nil
 	})
 }
 
-func processInput(ctx context.Context, input *ftxproto.InputProperties) error {
-	fmt.Printf("Build input: %+v\n", input)
-	return nil
+func LaunchTaskStep(ctx context.Context) (*Swarming, string, error) {
+	step, ctx := build.StartStep(ctx, "Launch Swarming Task")
+	swarming, err := NewSwarming(ctx)
+	if err != nil {
+		step.End(err)
+		return nil, "", fmt.Errorf("NewSwarming: %v", err)
+	}
+	taskId, err := swarming.LaunchTask()
+	if err != nil {
+		step.End(err)
+		return nil, "", fmt.Errorf("LaunchTask: %v", err)
+	}
+	md := fmt.Sprintf("* [swarming task](https://chrome-swarming.appspot.com/task?id=%s)", taskId)
+	step.SetSummaryMarkdown(md)
+	step.End(nil)
+	return swarming, taskId, nil
 }
diff --git a/cmd/ftxtest/run.sh b/cmd/ftxtest/run.sh
index 3cdb93d..82befe3 100755
--- a/cmd/ftxtest/run.sh
+++ b/cmd/ftxtest/run.sh
@@ -3,4 +3,4 @@
 set -x
 
 ./gen.sh
-LUCIEXE_FAKEBUILD=test/build.json go run main.go -- -working-dir=$PWD
+LUCIEXE_FAKEBUILD=test/build.json go run -mod=vendor *.go -- -working-dir=$PWD
diff --git a/cmd/ftxtest/swarming.go b/cmd/ftxtest/swarming.go
new file mode 100644
index 0000000..bfcdf60
--- /dev/null
+++ b/cmd/ftxtest/swarming.go
@@ -0,0 +1,37 @@
+// Copyright 2023 The Fuchsia Authors. All rights reserved
+// Use of this source code is governed by a BSD-style license that can
+// found in the LICENSE file.
+package main
+
+import (
+	"context"
+	"fmt"
+
+	"go.chromium.org/luci/auth"
+	"go.chromium.org/luci/common/api/swarming/swarming/v1"
+)
+
+type Swarming struct {
+	client *swarming.Service
+}
+
+func NewSwarming(ctx context.Context) (*Swarming, error) {
+	authenticator := auth.NewAuthenticator(ctx, auth.SilentLogin, auth.Options{})
+	httpClient, err := authenticator.Client()
+	if err != nil {
+		return nil, fmt.Errorf("authenticator.Client: %v", err)
+	}
+	swarmingClient, err := swarming.New(httpClient)
+	if err != nil {
+		return nil, fmt.Errorf("swarming.New: %v", err)
+	}
+	swarming := &Swarming{
+		client: swarmingClient,
+	}
+	return swarming, nil
+}
+
+func (s *Swarming) LaunchTask() (string, error) {
+	// TODO(b/258456267): Launch swarming task...
+	return "foo", nil
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/LICENSE b/vendor/go.chromium.org/luci/common/api/internal/gensupport/LICENSE
new file mode 100644
index 0000000..263aa7a
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2011 Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/buffer.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/buffer.go
new file mode 100644
index 0000000..3d0817e
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/buffer.go
@@ -0,0 +1,79 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"bytes"
+	"io"
+
+	"google.golang.org/api/googleapi"
+)
+
+// MediaBuffer buffers data from an io.Reader to support uploading media in
+// retryable chunks. It should be created with NewMediaBuffer.
+type MediaBuffer struct {
+	media io.Reader
+
+	chunk []byte // The current chunk which is pending upload.  The capacity is the chunk size.
+	err   error  // Any error generated when populating chunk by reading media.
+
+	// The absolute position of chunk in the underlying media.
+	off int64
+}
+
+// NewMediaBuffer initializes a MediaBuffer.
+func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer {
+	return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)}
+}
+
+// Chunk returns the current buffered chunk, the offset in the underlying media
+// from which the chunk is drawn, and the size of the chunk.
+// Successive calls to Chunk return the same chunk between calls to Next.
+func (mb *MediaBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) {
+	// There may already be data in chunk if Next has not been called since the previous call to Chunk.
+	if mb.err == nil && len(mb.chunk) == 0 {
+		mb.err = mb.loadChunk()
+	}
+	return bytes.NewReader(mb.chunk), mb.off, len(mb.chunk), mb.err
+}
+
+// loadChunk will read from media into chunk, up to the capacity of chunk.
+func (mb *MediaBuffer) loadChunk() error {
+	bufSize := cap(mb.chunk)
+	mb.chunk = mb.chunk[:bufSize]
+
+	read := 0
+	var err error
+	for err == nil && read < bufSize {
+		var n int
+		n, err = mb.media.Read(mb.chunk[read:])
+		read += n
+	}
+	mb.chunk = mb.chunk[:read]
+	return err
+}
+
+// Next advances to the next chunk, which will be returned by the next call to Chunk.
+// Calls to Next without a corresponding prior call to Chunk will have no effect.
+func (mb *MediaBuffer) Next() {
+	mb.off += int64(len(mb.chunk))
+	mb.chunk = mb.chunk[0:0]
+}
+
+type readerTyper struct {
+	io.Reader
+	googleapi.ContentTyper
+}
+
+// ReaderAtToReader adapts a ReaderAt to be used as a Reader.
+// If ra implements googleapi.ContentTyper, then the returned reader
+// will also implement googleapi.ContentTyper, delegating to ra.
+func ReaderAtToReader(ra io.ReaderAt, size int64) io.Reader {
+	r := io.NewSectionReader(ra, 0, size)
+	if typer, ok := ra.(googleapi.ContentTyper); ok {
+		return readerTyper{r, typer}
+	}
+	return r
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/doc.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/doc.go
new file mode 100644
index 0000000..752c4b4
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/doc.go
@@ -0,0 +1,10 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gensupport is an internal implementation detail used by code
+// generated by the google-api-go-generator tool.
+//
+// This package may be modified at any time without regard for backwards
+// compatibility. It should not be used directly by API users.
+package gensupport
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/error.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/error.go
new file mode 100644
index 0000000..886c653
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/error.go
@@ -0,0 +1,24 @@
+// Copyright 2022 Google LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"errors"
+
+	"github.com/googleapis/gax-go/v2/apierror"
+	"google.golang.org/api/googleapi"
+)
+
+// WrapError creates an [apierror.APIError] from err, wraps it in err, and
+// returns err. If err is not a [googleapi.Error] (or a
+// [google.golang.org/grpc/status.Status]), it returns err without modification.
+func WrapError(err error) error {
+	var herr *googleapi.Error
+	apiError, ok := apierror.ParseError(err, false)
+	if ok && errors.As(err, &herr) {
+		herr.Wrap(apiError)
+	}
+	return err
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/json.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/json.go
new file mode 100644
index 0000000..eab49a1
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/json.go
@@ -0,0 +1,236 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"encoding/json"
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// MarshalJSON returns a JSON encoding of schema containing only selected fields.
+// A field is selected if any of the following is true:
+//   - it has a non-empty value
+//   - its field name is present in forceSendFields and it is not a nil pointer or nil interface
+//   - its field name is present in nullFields.
+//
+// The JSON key for each selected field is taken from the field's json: struct tag.
+func MarshalJSON(schema interface{}, forceSendFields, nullFields []string) ([]byte, error) {
+	if len(forceSendFields) == 0 && len(nullFields) == 0 {
+		return json.Marshal(schema)
+	}
+
+	mustInclude := make(map[string]bool)
+	for _, f := range forceSendFields {
+		mustInclude[f] = true
+	}
+	useNull := make(map[string]bool)
+	useNullMaps := make(map[string]map[string]bool)
+	for _, nf := range nullFields {
+		parts := strings.SplitN(nf, ".", 2)
+		field := parts[0]
+		if len(parts) == 1 {
+			useNull[field] = true
+		} else {
+			if useNullMaps[field] == nil {
+				useNullMaps[field] = map[string]bool{}
+			}
+			useNullMaps[field][parts[1]] = true
+		}
+	}
+
+	dataMap, err := schemaToMap(schema, mustInclude, useNull, useNullMaps)
+	if err != nil {
+		return nil, err
+	}
+	return json.Marshal(dataMap)
+}
+
+func schemaToMap(schema interface{}, mustInclude, useNull map[string]bool, useNullMaps map[string]map[string]bool) (map[string]interface{}, error) {
+	m := make(map[string]interface{})
+	s := reflect.ValueOf(schema)
+	st := s.Type()
+
+	for i := 0; i < s.NumField(); i++ {
+		jsonTag := st.Field(i).Tag.Get("json")
+		if jsonTag == "" {
+			continue
+		}
+		tag, err := parseJSONTag(jsonTag)
+		if err != nil {
+			return nil, err
+		}
+		if tag.ignore {
+			continue
+		}
+
+		v := s.Field(i)
+		f := st.Field(i)
+
+		if useNull[f.Name] {
+			if !isEmptyValue(v) {
+				return nil, fmt.Errorf("field %q in NullFields has non-empty value", f.Name)
+			}
+			m[tag.apiName] = nil
+			continue
+		}
+
+		if !includeField(v, f, mustInclude) {
+			continue
+		}
+
+		// If map fields are explicitly set to null, use a map[string]interface{}.
+		if f.Type.Kind() == reflect.Map && useNullMaps[f.Name] != nil {
+			ms, ok := v.Interface().(map[string]string)
+			if !ok {
+				mi, err := initMapSlow(v, f.Name, useNullMaps)
+				if err != nil {
+					return nil, err
+				}
+				m[tag.apiName] = mi
+				continue
+			}
+			mi := map[string]interface{}{}
+			for k, v := range ms {
+				mi[k] = v
+			}
+			for k := range useNullMaps[f.Name] {
+				mi[k] = nil
+			}
+			m[tag.apiName] = mi
+			continue
+		}
+
+		// nil maps are treated as empty maps.
+		if f.Type.Kind() == reflect.Map && v.IsNil() {
+			m[tag.apiName] = map[string]string{}
+			continue
+		}
+
+		// nil slices are treated as empty slices.
+		if f.Type.Kind() == reflect.Slice && v.IsNil() {
+			m[tag.apiName] = []bool{}
+			continue
+		}
+
+		if tag.stringFormat {
+			m[tag.apiName] = formatAsString(v, f.Type.Kind())
+		} else {
+			m[tag.apiName] = v.Interface()
+		}
+	}
+	return m, nil
+}
+
+// initMapSlow uses reflection to build up a map object. This is slower than
+// the default behavior so it should be used only as a fallback.
+func initMapSlow(rv reflect.Value, fieldName string, useNullMaps map[string]map[string]bool) (map[string]interface{}, error) {
+	mi := map[string]interface{}{}
+	iter := rv.MapRange()
+	for iter.Next() {
+		k, ok := iter.Key().Interface().(string)
+		if !ok {
+			return nil, fmt.Errorf("field %q has keys in NullFields but is not a map[string]any", fieldName)
+		}
+		v := iter.Value().Interface()
+		mi[k] = v
+	}
+	for k := range useNullMaps[fieldName] {
+		mi[k] = nil
+	}
+	return mi, nil
+}
+
+// formatAsString returns a string representation of v, dereferencing it first if possible.
+func formatAsString(v reflect.Value, kind reflect.Kind) string {
+	if kind == reflect.Ptr && !v.IsNil() {
+		v = v.Elem()
+	}
+
+	return fmt.Sprintf("%v", v.Interface())
+}
+
+// jsonTag represents a restricted version of the struct tag format used by encoding/json.
+// It is used to describe the JSON encoding of fields in a Schema struct.
+type jsonTag struct {
+	apiName      string
+	stringFormat bool
+	ignore       bool
+}
+
+// parseJSONTag parses a restricted version of the struct tag format used by encoding/json.
+// The format of the tag must match that generated by the Schema.writeSchemaStruct method
+// in the api generator.
+func parseJSONTag(val string) (jsonTag, error) {
+	if val == "-" {
+		return jsonTag{ignore: true}, nil
+	}
+
+	var tag jsonTag
+
+	i := strings.Index(val, ",")
+	if i == -1 || val[:i] == "" {
+		return tag, fmt.Errorf("malformed json tag: %s", val)
+	}
+
+	tag = jsonTag{
+		apiName: val[:i],
+	}
+
+	switch val[i+1:] {
+	case "omitempty":
+	case "omitempty,string":
+		tag.stringFormat = true
+	default:
+		return tag, fmt.Errorf("malformed json tag: %s", val)
+	}
+
+	return tag, nil
+}
+
+// Reports whether the struct field "f" with value "v" should be included in JSON output.
+func includeField(v reflect.Value, f reflect.StructField, mustInclude map[string]bool) bool {
+	// The regular JSON encoding of a nil pointer is "null", which means "delete this field".
+	// Therefore, we could enable field deletion by honoring pointer fields' presence in the mustInclude set.
+	// However, many fields are not pointers, so there would be no way to delete these fields.
+	// Rather than partially supporting field deletion, we ignore mustInclude for nil pointer fields.
+	// Deletion will be handled by a separate mechanism.
+	if f.Type.Kind() == reflect.Ptr && v.IsNil() {
+		return false
+	}
+
+	// The "any" type is represented as an interface{}.  If this interface
+	// is nil, there is no reasonable representation to send.  We ignore
+	// these fields, for the same reasons as given above for pointers.
+	if f.Type.Kind() == reflect.Interface && v.IsNil() {
+		return false
+	}
+
+	return mustInclude[f.Name] || !isEmptyValue(v)
+}
+
+// isEmptyValue reports whether v is the empty value for its type.  This
+// implementation is based on that of the encoding/json package, but its
+// correctness does not depend on it being identical. What's important is that
+// this function return false in situations where v should not be sent as part
+// of a PATCH operation.
+func isEmptyValue(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return v.IsNil()
+	}
+	return false
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/jsonfloat.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/jsonfloat.go
new file mode 100644
index 0000000..13c2f93
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/jsonfloat.go
@@ -0,0 +1,47 @@
+// Copyright 2016 Google LLC.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"math"
+)
+
+// JSONFloat64 is a float64 that supports proper unmarshaling of special float
+// values in JSON, according to
+// https://developers.google.com/protocol-buffers/docs/proto3#json. Although
+// that is a proto-to-JSON spec, it applies to all Google APIs.
+//
+// The jsonpb package
+// (https://github.com/golang/protobuf/blob/master/jsonpb/jsonpb.go) has
+// similar functionality, but only for direct translation from proto messages
+// to JSON.
+type JSONFloat64 float64
+
+func (f *JSONFloat64) UnmarshalJSON(data []byte) error {
+	var ff float64
+	if err := json.Unmarshal(data, &ff); err == nil {
+		*f = JSONFloat64(ff)
+		return nil
+	}
+	var s string
+	if err := json.Unmarshal(data, &s); err == nil {
+		switch s {
+		case "NaN":
+			ff = math.NaN()
+		case "Infinity":
+			ff = math.Inf(1)
+		case "-Infinity":
+			ff = math.Inf(-1)
+		default:
+			return fmt.Errorf("google.golang.org/api/internal: bad float string %q", s)
+		}
+		*f = JSONFloat64(ff)
+		return nil
+	}
+	return errors.New("google.golang.org/api/internal: data not float or string")
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/media.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/media.go
new file mode 100644
index 0000000..8356e7f
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/media.go
@@ -0,0 +1,312 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"mime"
+	"mime/multipart"
+	"net/http"
+	"net/textproto"
+	"strings"
+	"sync"
+	"time"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/googleapi"
+)
+
+type typeReader struct {
+	io.Reader
+	typ string
+}
+
+// multipartReader combines the contents of multiple readers to create a multipart/related HTTP body.
+// Close must be called if reads from the multipartReader are abandoned before reaching EOF.
+type multipartReader struct {
+	pr       *io.PipeReader
+	ctype    string
+	mu       sync.Mutex
+	pipeOpen bool
+}
+
+// boundary optionally specifies the MIME boundary
+func newMultipartReader(parts []typeReader, boundary string) *multipartReader {
+	mp := &multipartReader{pipeOpen: true}
+	var pw *io.PipeWriter
+	mp.pr, pw = io.Pipe()
+	mpw := multipart.NewWriter(pw)
+	if boundary != "" {
+		mpw.SetBoundary(boundary)
+	}
+	mp.ctype = "multipart/related; boundary=" + mpw.Boundary()
+	go func() {
+		for _, part := range parts {
+			w, err := mpw.CreatePart(typeHeader(part.typ))
+			if err != nil {
+				mpw.Close()
+				pw.CloseWithError(fmt.Errorf("googleapi: CreatePart failed: %v", err))
+				return
+			}
+			_, err = io.Copy(w, part.Reader)
+			if err != nil {
+				mpw.Close()
+				pw.CloseWithError(fmt.Errorf("googleapi: Copy failed: %v", err))
+				return
+			}
+		}
+
+		mpw.Close()
+		pw.Close()
+	}()
+	return mp
+}
+
+func (mp *multipartReader) Read(data []byte) (n int, err error) {
+	return mp.pr.Read(data)
+}
+
+func (mp *multipartReader) Close() error {
+	mp.mu.Lock()
+	if !mp.pipeOpen {
+		mp.mu.Unlock()
+		return nil
+	}
+	mp.pipeOpen = false
+	mp.mu.Unlock()
+	return mp.pr.Close()
+}
+
+// CombineBodyMedia combines a json body with media content to create a multipart/related HTTP body.
+// It returns a ReadCloser containing the combined body, and the overall "multipart/related" content type, with random boundary.
+//
+// The caller must call Close on the returned ReadCloser if reads are abandoned before reaching EOF.
+func CombineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType string) (io.ReadCloser, string) {
+	return combineBodyMedia(body, bodyContentType, media, mediaContentType, "")
+}
+
+// combineBodyMedia is CombineBodyMedia but with an optional mimeBoundary field.
+func combineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType, mimeBoundary string) (io.ReadCloser, string) {
+	mp := newMultipartReader([]typeReader{
+		{body, bodyContentType},
+		{media, mediaContentType},
+	}, mimeBoundary)
+	return mp, mp.ctype
+}
+
+func typeHeader(contentType string) textproto.MIMEHeader {
+	h := make(textproto.MIMEHeader)
+	if contentType != "" {
+		h.Set("Content-Type", contentType)
+	}
+	return h
+}
+
+// PrepareUpload determines whether the data in the supplied reader should be
+// uploaded in a single request, or in sequential chunks.
+// chunkSize is the size of the chunk that media should be split into.
+//
+// If chunkSize is zero, media is returned as the first value, and the other
+// two return values are nil, true.
+//
+// Otherwise, a MediaBuffer is returned, along with a bool indicating whether the
+// contents of media fit in a single chunk.
+//
+// After PrepareUpload has been called, media should no longer be used: the
+// media content should be accessed via one of the return values.
+func PrepareUpload(media io.Reader, chunkSize int) (r io.Reader, mb *MediaBuffer, singleChunk bool) {
+	if chunkSize == 0 { // do not chunk
+		return media, nil, true
+	}
+	mb = NewMediaBuffer(media, chunkSize)
+	_, _, _, err := mb.Chunk()
+	// If err is io.EOF, we can upload this in a single request. Otherwise, err is
+	// either nil or a non-EOF error. If it is the latter, then the next call to
+	// mb.Chunk will return the same error. Returning a MediaBuffer ensures that this
+	// error will be handled at some point.
+	return nil, mb, err == io.EOF
+}
+
+// MediaInfo holds information for media uploads. It is intended for use by generated
+// code only.
+type MediaInfo struct {
+	// At most one of Media and MediaBuffer will be set.
+	media              io.Reader
+	buffer             *MediaBuffer
+	singleChunk        bool
+	mType              string
+	size               int64 // mediaSize, if known.  Used only for calls to progressUpdater_.
+	progressUpdater    googleapi.ProgressUpdater
+	chunkRetryDeadline time.Duration
+}
+
+// NewInfoFromMedia should be invoked from the Media method of a call. It returns a
+// MediaInfo populated with chunk size and content type, and a reader or MediaBuffer
+// if needed.
+func NewInfoFromMedia(r io.Reader, options []googleapi.MediaOption) *MediaInfo {
+	mi := &MediaInfo{}
+	opts := googleapi.ProcessMediaOptions(options)
+	if !opts.ForceEmptyContentType {
+		mi.mType = opts.ContentType
+		if mi.mType == "" {
+			r, mi.mType = gax.DetermineContentType(r)
+		}
+	}
+	mi.chunkRetryDeadline = opts.ChunkRetryDeadline
+	mi.media, mi.buffer, mi.singleChunk = PrepareUpload(r, opts.ChunkSize)
+	return mi
+}
+
+// NewInfoFromResumableMedia should be invoked from the ResumableMedia method of a
+// call. It returns a MediaInfo using the given reader, size and media type.
+func NewInfoFromResumableMedia(r io.ReaderAt, size int64, mediaType string) *MediaInfo {
+	rdr := ReaderAtToReader(r, size)
+	mType := mediaType
+	if mType == "" {
+		rdr, mType = gax.DetermineContentType(rdr)
+	}
+
+	return &MediaInfo{
+		size:        size,
+		mType:       mType,
+		buffer:      NewMediaBuffer(rdr, googleapi.DefaultUploadChunkSize),
+		media:       nil,
+		singleChunk: false,
+	}
+}
+
+// SetProgressUpdater sets the progress updater for the media info.
+func (mi *MediaInfo) SetProgressUpdater(pu googleapi.ProgressUpdater) {
+	if mi != nil {
+		mi.progressUpdater = pu
+	}
+}
+
+// UploadType determines the type of upload: a single request, or a resumable
+// series of requests.
+func (mi *MediaInfo) UploadType() string {
+	if mi.singleChunk {
+		return "multipart"
+	}
+	return "resumable"
+}
+
+// UploadRequest sets up an HTTP request for media upload. It adds headers
+// as necessary, and returns a replacement for the body and a function for http.Request.GetBody.
+func (mi *MediaInfo) UploadRequest(reqHeaders http.Header, body io.Reader) (newBody io.Reader, getBody func() (io.ReadCloser, error), cleanup func()) {
+	cleanup = func() {}
+	if mi == nil {
+		return body, nil, cleanup
+	}
+	var media io.Reader
+	if mi.media != nil {
+		// This only happens when the caller has turned off chunking. In that
+		// case, we write all of media in a single non-retryable request.
+		media = mi.media
+	} else if mi.singleChunk {
+		// The data fits in a single chunk, which has now been read into the MediaBuffer.
+		// We obtain that chunk so we can write it in a single request. The request can
+		// be retried because the data is stored in the MediaBuffer.
+		media, _, _, _ = mi.buffer.Chunk()
+	}
+	toCleanup := []io.Closer{}
+	if media != nil {
+		fb := readerFunc(body)
+		fm := readerFunc(media)
+		combined, ctype := CombineBodyMedia(body, "application/json", media, mi.mType)
+		toCleanup = append(toCleanup, combined)
+		if fb != nil && fm != nil {
+			getBody = func() (io.ReadCloser, error) {
+				rb := ioutil.NopCloser(fb())
+				rm := ioutil.NopCloser(fm())
+				var mimeBoundary string
+				if _, params, err := mime.ParseMediaType(ctype); err == nil {
+					mimeBoundary = params["boundary"]
+				}
+				r, _ := combineBodyMedia(rb, "application/json", rm, mi.mType, mimeBoundary)
+				toCleanup = append(toCleanup, r)
+				return r, nil
+			}
+		}
+		reqHeaders.Set("Content-Type", ctype)
+		body = combined
+	}
+	if mi.buffer != nil && mi.mType != "" && !mi.singleChunk {
+		// This happens when initiating a resumable upload session.
+		// The initial request contains a JSON body rather than media.
+		// It can be retried with a getBody function that re-creates the request body.
+		fb := readerFunc(body)
+		if fb != nil {
+			getBody = func() (io.ReadCloser, error) {
+				rb := ioutil.NopCloser(fb())
+				toCleanup = append(toCleanup, rb)
+				return rb, nil
+			}
+		}
+		reqHeaders.Set("X-Upload-Content-Type", mi.mType)
+	}
+	// Ensure that any bodies created in getBody are cleaned up.
+	cleanup = func() {
+		for _, closer := range toCleanup {
+			_ = closer.Close()
+		}
+
+	}
+	return body, getBody, cleanup
+}
+
+// readerFunc returns a function that always returns an io.Reader that has the same
+// contents as r, provided that can be done without consuming r. Otherwise, it
+// returns nil.
+// See http.NewRequest (in net/http/request.go).
+func readerFunc(r io.Reader) func() io.Reader {
+	switch r := r.(type) {
+	case *bytes.Buffer:
+		buf := r.Bytes()
+		return func() io.Reader { return bytes.NewReader(buf) }
+	case *bytes.Reader:
+		snapshot := *r
+		return func() io.Reader { r := snapshot; return &r }
+	case *strings.Reader:
+		snapshot := *r
+		return func() io.Reader { r := snapshot; return &r }
+	default:
+		return nil
+	}
+}
+
+// ResumableUpload returns an appropriately configured ResumableUpload value if the
+// upload is resumable, or nil otherwise.
+func (mi *MediaInfo) ResumableUpload(locURI string) *ResumableUpload {
+	if mi == nil || mi.singleChunk {
+		return nil
+	}
+	return &ResumableUpload{
+		URI:       locURI,
+		Media:     mi.buffer,
+		MediaType: mi.mType,
+		Callback: func(curr int64) {
+			if mi.progressUpdater != nil {
+				mi.progressUpdater(curr, mi.size)
+			}
+		},
+		ChunkRetryDeadline: mi.chunkRetryDeadline,
+	}
+}
+
+// SetGetBody sets the GetBody field of req to f. This was once needed
+// to gracefully support Go 1.7 and earlier which didn't have that
+// field.
+//
+// Deprecated: the code generator no longer uses this as of
+// 2019-02-19. Nothing else should be calling this anyway, but we
+// won't delete this immediately; it will be deleted in as early as 6
+// months.
+func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) {
+	req.GetBody = f
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/params.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/params.go
new file mode 100644
index 0000000..1a30d2c
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/params.go
@@ -0,0 +1,57 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"net/url"
+
+	"google.golang.org/api/googleapi"
+)
+
+// URLParams is a simplified replacement for url.Values
+// that safely builds up URL parameters for encoding.
+type URLParams map[string][]string
+
+// Get returns the first value for the given key, or "".
+func (u URLParams) Get(key string) string {
+	vs := u[key]
+	if len(vs) == 0 {
+		return ""
+	}
+	return vs[0]
+}
+
+// Set sets the key to value.
+// It replaces any existing values.
+func (u URLParams) Set(key, value string) {
+	u[key] = []string{value}
+}
+
+// SetMulti sets the key to an array of values.
+// It replaces any existing values.
+// Note that values must not be modified after calling SetMulti
+// so the caller is responsible for making a copy if necessary.
+func (u URLParams) SetMulti(key string, values []string) {
+	u[key] = values
+}
+
+// Encode encodes the values into “URL encoded” form
+// ("bar=baz&foo=quux") sorted by key.
+func (u URLParams) Encode() string {
+	return url.Values(u).Encode()
+}
+
+// SetOptions sets the URL params and any additional `CallOption` or
+// `MultiCallOption` passed in.
+func SetOptions(u URLParams, opts ...googleapi.CallOption) {
+	for _, o := range opts {
+		m, ok := o.(googleapi.MultiCallOption)
+		if ok {
+			u.SetMulti(m.GetMulti())
+			continue
+		}
+		u.Set(o.Get())
+	}
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/resumable.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/resumable.go
new file mode 100644
index 0000000..a38f5dd
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/resumable.go
@@ -0,0 +1,264 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/google/uuid"
+)
+
+// ResumableUpload is used by the generated APIs to provide resumable uploads.
+// It is not used by developers directly.
+type ResumableUpload struct {
+	Client *http.Client
+	// URI is the resumable resource destination provided by the server after specifying "&uploadType=resumable".
+	URI       string
+	UserAgent string // User-Agent for header of the request
+	// Media is the object being uploaded.
+	Media *MediaBuffer
+	// MediaType defines the media type, e.g. "image/jpeg".
+	MediaType string
+
+	mu       sync.Mutex // guards progress
+	progress int64      // number of bytes uploaded so far
+
+	// Callback is an optional function that will be periodically called with the cumulative number of bytes uploaded.
+	Callback func(int64)
+
+	// Retry optionally configures retries for requests made against the upload.
+	Retry *RetryConfig
+
+	// ChunkRetryDeadline configures the per-chunk deadline after which no further
+	// retries should happen.
+	ChunkRetryDeadline time.Duration
+
+	// Track current request invocation ID and attempt count for retry metric
+	// headers.
+	invocationID string
+	attempts     int
+}
+
+// Progress returns the number of bytes uploaded at this point.
+func (rx *ResumableUpload) Progress() int64 {
+	rx.mu.Lock()
+	defer rx.mu.Unlock()
+	return rx.progress
+}
+
+// doUploadRequest performs a single HTTP request to upload data.
+// off specifies the offset in rx.Media from which data is drawn.
+// size is the number of bytes in data.
+// final specifies whether data is the final chunk to be uploaded.
+func (rx *ResumableUpload) doUploadRequest(ctx context.Context, data io.Reader, off, size int64, final bool) (*http.Response, error) {
+	req, err := http.NewRequest("POST", rx.URI, data)
+	if err != nil {
+		return nil, err
+	}
+
+	req.ContentLength = size
+	var contentRange string
+	if final {
+		if size == 0 {
+			contentRange = fmt.Sprintf("bytes */%v", off)
+		} else {
+			contentRange = fmt.Sprintf("bytes %v-%v/%v", off, off+size-1, off+size)
+		}
+	} else {
+		contentRange = fmt.Sprintf("bytes %v-%v/*", off, off+size-1)
+	}
+	req.Header.Set("Content-Range", contentRange)
+	req.Header.Set("Content-Type", rx.MediaType)
+	req.Header.Set("User-Agent", rx.UserAgent)
+
+	baseXGoogHeader := "gl-go/" + GoVersion() + " gdcl/" + "luci-go"
+	invocationHeader := fmt.Sprintf("gccl-invocation-id/%s gccl-attempt-count/%d", rx.invocationID, rx.attempts)
+	req.Header.Set("X-Goog-Api-Client", strings.Join([]string{baseXGoogHeader, invocationHeader}, " "))
+
+	// Google's upload endpoint uses status code 308 for a
+	// different purpose than the "308 Permanent Redirect"
+	// since-standardized in RFC 7238. Because of the conflict in
+	// semantics, Google added this new request header which
+	// causes it to not use "308" and instead reply with 200 OK
+	// and sets the upload-specific "X-HTTP-Status-Code-Override:
+	// 308" response header.
+	req.Header.Set("X-GUploader-No-308", "yes")
+
+	return SendRequest(ctx, rx.Client, req)
+}
+
+func statusResumeIncomplete(resp *http.Response) bool {
+	// This is how the server signals "status resume incomplete"
+	// when X-GUploader-No-308 is set to "yes":
+	return resp != nil && resp.Header.Get("X-Http-Status-Code-Override") == "308"
+}
+
+// reportProgress calls a user-supplied callback to report upload progress.
+// If old==updated, the callback is not called.
+func (rx *ResumableUpload) reportProgress(old, updated int64) {
+	if updated-old == 0 {
+		return
+	}
+	rx.mu.Lock()
+	rx.progress = updated
+	rx.mu.Unlock()
+	if rx.Callback != nil {
+		rx.Callback(updated)
+	}
+}
+
+// transferChunk performs a single HTTP request to upload a single chunk from rx.Media.
+func (rx *ResumableUpload) transferChunk(ctx context.Context) (*http.Response, error) {
+	chunk, off, size, err := rx.Media.Chunk()
+
+	done := err == io.EOF
+	if !done && err != nil {
+		return nil, err
+	}
+
+	res, err := rx.doUploadRequest(ctx, chunk, off, int64(size), done)
+	if err != nil {
+		return res, err
+	}
+
+	// We sent "X-GUploader-No-308: yes" (see comment elsewhere in
+	// this file), so we don't expect to get a 308.
+	if res.StatusCode == 308 {
+		return nil, errors.New("unexpected 308 response status code")
+	}
+
+	if res.StatusCode == http.StatusOK {
+		rx.reportProgress(off, off+int64(size))
+	}
+
+	if statusResumeIncomplete(res) {
+		rx.Media.Next()
+	}
+	return res, nil
+}
+
+// Upload starts the process of a resumable upload with a cancellable context.
+// It retries using the provided back off strategy until cancelled or the
+// strategy indicates to stop retrying.
+// It is called from the auto-generated API code and is not visible to the user.
+// Before sending an HTTP request, Upload calls any registered hook functions,
+// and calls the returned functions after the request returns (see send.go).
+// rx is private to the auto-generated API code.
+// Exactly one of resp or err will be nil.  If resp is non-nil, the caller must call resp.Body.Close.
+func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err error) {
+
+	// There are a couple of cases where it's possible for err and resp to both
+	// be non-nil. However, we expose a simpler contract to our callers: exactly
+	// one of resp and err will be non-nil. This means that any response body
+	// must be closed here before returning a non-nil error.
+	var prepareReturn = func(resp *http.Response, err error) (*http.Response, error) {
+		if err != nil {
+			if resp != nil && resp.Body != nil {
+				resp.Body.Close()
+			}
+			return nil, err
+		}
+		// This case is very unlikely but possible only if rx.ChunkRetryDeadline is
+		// set to a very small value, in which case no requests will be sent before
+		// the deadline. Return an error to avoid causing a panic.
+		if resp == nil {
+			return nil, fmt.Errorf("upload request to %v not sent, choose larger value for ChunkRetryDealine", rx.URI)
+		}
+		return resp, nil
+	}
+	// Configure retryable error criteria.
+	errorFunc := rx.Retry.errorFunc()
+
+	// Configure per-chunk retry deadline.
+	var retryDeadline time.Duration
+	if rx.ChunkRetryDeadline != 0 {
+		retryDeadline = rx.ChunkRetryDeadline
+	} else {
+		retryDeadline = defaultRetryDeadline
+	}
+
+	// Send all chunks.
+	for {
+		var pause time.Duration
+
+		// Each chunk gets its own initialized-at-zero backoff and invocation ID.
+		bo := rx.Retry.backoff()
+		quitAfterTimer := time.NewTimer(retryDeadline)
+		rx.attempts = 1
+		rx.invocationID = uuid.New().String()
+
+		// Retry loop for a single chunk.
+		for {
+			pauseTimer := time.NewTimer(pause)
+			select {
+			case <-ctx.Done():
+				quitAfterTimer.Stop()
+				pauseTimer.Stop()
+				if err == nil {
+					err = ctx.Err()
+				}
+				return prepareReturn(resp, err)
+			case <-pauseTimer.C:
+				quitAfterTimer.Stop()
+			case <-quitAfterTimer.C:
+				pauseTimer.Stop()
+				return prepareReturn(resp, err)
+			}
+			pauseTimer.Stop()
+
+			// Check for context cancellation or timeout once more. If more than one
+			// case in the select statement above was satisfied at the same time, Go
+			// will choose one arbitrarily.
+			// That can cause an operation to go through even if the context was
+			// canceled before or the timeout was reached.
+			select {
+			case <-ctx.Done():
+				quitAfterTimer.Stop()
+				if err == nil {
+					err = ctx.Err()
+				}
+				return prepareReturn(resp, err)
+			case <-quitAfterTimer.C:
+				return prepareReturn(resp, err)
+			default:
+				quitAfterTimer.Stop()
+			}
+
+			resp, err = rx.transferChunk(ctx)
+
+			var status int
+			if resp != nil {
+				status = resp.StatusCode
+			}
+
+			// Check if we should retry the request.
+			if !errorFunc(status, err) {
+				break
+			}
+
+			rx.attempts++
+			pause = bo.Pause()
+			if resp != nil && resp.Body != nil {
+				resp.Body.Close()
+			}
+		}
+
+		// If the chunk was uploaded successfully, but there's still
+		// more to go, upload the next chunk without any delay.
+		if statusResumeIncomplete(resp) {
+			resp.Body.Close()
+			continue
+		}
+
+		return prepareReturn(resp, err)
+	}
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/retry.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/retry.go
new file mode 100644
index 0000000..20b57d9
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/retry.go
@@ -0,0 +1,121 @@
+// Copyright 2021 Google LLC.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"errors"
+	"io"
+	"net"
+	"strings"
+	"time"
+
+	"github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/googleapi"
+)
+
+// Backoff is an interface around gax.Backoff's Pause method, allowing tests to provide their
+// own implementation.
+type Backoff interface {
+	Pause() time.Duration
+}
+
+// These are declared as global variables so that tests can overwrite them.
+var (
+	// Default per-chunk deadline for resumable uploads.
+	defaultRetryDeadline = 32 * time.Second
+	// Default backoff timer.
+	backoff = func() Backoff {
+		return &gax.Backoff{Initial: 100 * time.Millisecond}
+	}
+	// syscallRetryable is a platform-specific hook, specified in retryable_linux.go
+	syscallRetryable func(error) bool = func(err error) bool { return false }
+)
+
+const (
+	// statusTooManyRequests is returned by the storage API if the
+	// per-project limits have been temporarily exceeded. The request
+	// should be retried.
+	// https://cloud.google.com/storage/docs/json_api/v1/status-codes#standardcodes
+	statusTooManyRequests = 429
+
+	// statusRequestTimeout is returned by the storage API if the
+	// upload connection was broken. The request should be retried.
+	statusRequestTimeout = 408
+)
+
+// shouldRetry indicates whether an error is retryable for the purposes of this
+// package, unless a ShouldRetry func is specified by the RetryConfig instead.
+// It follows guidance from
+// https://cloud.google.com/storage/docs/exponential-backoff .
+func shouldRetry(status int, err error) bool {
+	if 500 <= status && status <= 599 {
+		return true
+	}
+	if status == statusTooManyRequests || status == statusRequestTimeout {
+		return true
+	}
+	if err == io.ErrUnexpectedEOF {
+		return true
+	}
+	// Transient network errors should be retried.
+	if syscallRetryable(err) {
+		return true
+	}
+	if err, ok := err.(interface{ Temporary() bool }); ok {
+		if err.Temporary() {
+			return true
+		}
+	}
+	var opErr *net.OpError
+	if errors.As(err, &opErr) {
+		if strings.Contains(opErr.Error(), "use of closed network connection") {
+			// TODO: check against net.ErrClosed (go 1.16+) instead of string
+			return true
+		}
+	}
+
+	// If Go 1.13 error unwrapping is available, use this to examine wrapped
+	// errors.
+	if err, ok := err.(interface{ Unwrap() error }); ok {
+		return shouldRetry(status, err.Unwrap())
+	}
+	return false
+}
+
+// RetryConfig allows configuration of backoff timing and retryable errors.
+type RetryConfig struct {
+	Backoff     *gax.Backoff
+	ShouldRetry func(err error) bool
+}
+
+// Get a new backoff object based on the configured values.
+func (r *RetryConfig) backoff() Backoff {
+	if r == nil || r.Backoff == nil {
+		return backoff()
+	}
+	return &gax.Backoff{
+		Initial:    r.Backoff.Initial,
+		Max:        r.Backoff.Max,
+		Multiplier: r.Backoff.Multiplier,
+	}
+}
+
+// This is kind of hacky; it is necessary because ShouldRetry expects to
+// handle HTTP errors via googleapi.Error, but the error has not yet been
+// wrapped with a googleapi.Error at this layer, and the ErrorFunc type
+// in the manual layer does not pass in a status explicitly as it does
+// here. So, we must wrap error status codes in a googleapi.Error so that
+// ShouldRetry can parse this correctly.
+func (r *RetryConfig) errorFunc() func(status int, err error) bool {
+	if r == nil || r.ShouldRetry == nil {
+		return shouldRetry
+	}
+	return func(status int, err error) bool {
+		if status >= 400 {
+			return r.ShouldRetry(&googleapi.Error{Code: status})
+		}
+		return r.ShouldRetry(err)
+	}
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/retryable_linux.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/retryable_linux.go
new file mode 100644
index 0000000..a916c3d
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/retryable_linux.go
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package gensupport
+
+import "syscall"
+
+func init() {
+	// Initialize syscallRetryable to return true on transient socket-level
+	// errors. These errors are specific to Linux.
+	syscallRetryable = func(err error) bool { return err == syscall.ECONNRESET || err == syscall.ECONNREFUSED }
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/send.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/send.go
new file mode 100644
index 0000000..85c7bcb
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/send.go
@@ -0,0 +1,180 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/google/uuid"
+	"github.com/googleapis/gax-go/v2"
+)
+
+// Use this error type to return an error which allows introspection of both
+// the context error and the error from the service.
+type wrappedCallErr struct {
+	ctxErr     error
+	wrappedErr error
+}
+
+func (e wrappedCallErr) Error() string {
+	return fmt.Sprintf("retry failed with %v; last error: %v", e.ctxErr, e.wrappedErr)
+}
+
+func (e wrappedCallErr) Unwrap() error {
+	return e.wrappedErr
+}
+
+// Is allows errors.Is to match the error from the call as well as context
+// sentinel errors.
+func (e wrappedCallErr) Is(target error) bool {
+	return errors.Is(e.ctxErr, target) || errors.Is(e.wrappedErr, target)
+}
+
+// SendRequest sends a single HTTP request using the given client.
+// If ctx is non-nil, it calls all hooks, then sends the request with
+// req.WithContext, then calls any functions returned by the hooks in
+// reverse order.
+func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
+	// Disallow Accept-Encoding because it interferes with the automatic gzip handling
+	// done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219.
+	if _, ok := req.Header["Accept-Encoding"]; ok {
+		return nil, errors.New("google api: custom Accept-Encoding headers not allowed")
+	}
+	if ctx == nil {
+		return client.Do(req)
+	}
+	return send(ctx, client, req)
+}
+
+func send(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
+	if client == nil {
+		client = http.DefaultClient
+	}
+	resp, err := client.Do(req.WithContext(ctx))
+	// If we got an error, and the context has been canceled,
+	// the context's error is probably more useful.
+	if err != nil {
+		select {
+		case <-ctx.Done():
+			err = ctx.Err()
+		default:
+		}
+	}
+	return resp, err
+}
+
+// SendRequestWithRetry sends a single HTTP request using the given client,
+// with retries if a retryable error is returned.
+// If ctx is non-nil, it calls all hooks, then sends the request with
+// req.WithContext, then calls any functions returned by the hooks in
+// reverse order.
+func SendRequestWithRetry(ctx context.Context, client *http.Client, req *http.Request, retry *RetryConfig) (*http.Response, error) {
+	// Disallow Accept-Encoding because it interferes with the automatic gzip handling
+	// done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219.
+	if _, ok := req.Header["Accept-Encoding"]; ok {
+		return nil, errors.New("google api: custom Accept-Encoding headers not allowed")
+	}
+	if ctx == nil {
+		return client.Do(req)
+	}
+	return sendAndRetry(ctx, client, req, retry)
+}
+
+func sendAndRetry(ctx context.Context, client *http.Client, req *http.Request, retry *RetryConfig) (*http.Response, error) {
+	if client == nil {
+		client = http.DefaultClient
+	}
+
+	var resp *http.Response
+	var err error
+	attempts := 1
+	invocationID := uuid.New().String()
+	baseXGoogHeader := req.Header.Get("X-Goog-Api-Client")
+
+	// Loop to retry the request, up to the context deadline.
+	var pause time.Duration
+	var bo Backoff
+	if retry != nil && retry.Backoff != nil {
+		bo = &gax.Backoff{
+			Initial:    retry.Backoff.Initial,
+			Max:        retry.Backoff.Max,
+			Multiplier: retry.Backoff.Multiplier,
+		}
+	} else {
+		bo = backoff()
+	}
+
+	var errorFunc = retry.errorFunc()
+
+	for {
+		t := time.NewTimer(pause)
+		select {
+		case <-ctx.Done():
+			t.Stop()
+			// If we got an error and the context has been canceled, return an error acknowledging
+			// both the context cancelation and the service error.
+			if err != nil {
+				return resp, wrappedCallErr{ctx.Err(), err}
+			}
+			return resp, ctx.Err()
+		case <-t.C:
+		}
+
+		if ctx.Err() != nil {
+			// Check for context cancellation once more. If more than one case in a
+			// select is satisfied at the same time, Go will choose one arbitrarily.
+			// That can cause an operation to go through even if the context was
+			// canceled before.
+			if err != nil {
+				return resp, wrappedCallErr{ctx.Err(), err}
+			}
+			return resp, ctx.Err()
+		}
+		invocationHeader := fmt.Sprintf("gccl-invocation-id/%s gccl-attempt-count/%d", invocationID, attempts)
+		xGoogHeader := strings.Join([]string{invocationHeader, baseXGoogHeader}, " ")
+		req.Header.Set("X-Goog-Api-Client", xGoogHeader)
+
+		resp, err = client.Do(req.WithContext(ctx))
+
+		var status int
+		if resp != nil {
+			status = resp.StatusCode
+		}
+
+		// Check if we can retry the request. A retry can only be done if the error
+		// is retryable and the request body can be re-created using GetBody (this
+		// will not be possible if the body was unbuffered).
+		if req.GetBody == nil || !errorFunc(status, err) {
+			break
+		}
+		attempts++
+		var errBody error
+		req.Body, errBody = req.GetBody()
+		if errBody != nil {
+			break
+		}
+
+		pause = bo.Pause()
+		if resp != nil && resp.Body != nil {
+			resp.Body.Close()
+		}
+	}
+	return resp, err
+}
+
+// DecodeResponse decodes the body of res into target. If there is no body,
+// target is unchanged.
+func DecodeResponse(target interface{}, res *http.Response) error {
+	if res.StatusCode == http.StatusNoContent {
+		return nil
+	}
+	return json.NewDecoder(res.Body).Decode(target)
+}
diff --git a/vendor/go.chromium.org/luci/common/api/internal/gensupport/version.go b/vendor/go.chromium.org/luci/common/api/internal/gensupport/version.go
new file mode 100644
index 0000000..23f6aa2
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/internal/gensupport/version.go
@@ -0,0 +1,53 @@
+// Copyright 2020 Google LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gensupport
+
+import (
+	"runtime"
+	"strings"
+	"unicode"
+)
+
+// GoVersion returns the Go runtime version. The returned string
+// has no whitespace.
+func GoVersion() string {
+	return goVersion
+}
+
+var goVersion = goVer(runtime.Version())
+
+const develPrefix = "devel +"
+
+func goVer(s string) string {
+	if strings.HasPrefix(s, develPrefix) {
+		s = s[len(develPrefix):]
+		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+			s = s[:p]
+		}
+		return s
+	}
+
+	if strings.HasPrefix(s, "go1") {
+		s = s[2:]
+		var prerelease string
+		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
+			s, prerelease = s[:p], s[p:]
+		}
+		if strings.HasSuffix(s, ".") {
+			s += "0"
+		} else if strings.Count(s, ".") < 2 {
+			s += ".0"
+		}
+		if prerelease != "" {
+			s += "-" + prerelease
+		}
+		return s
+	}
+	return ""
+}
+
+func notSemverRune(r rune) bool {
+	return !strings.ContainsRune("0123456789.", r)
+}
diff --git a/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-api.json b/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-api.json
new file mode 100644
index 0000000..501371c
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-api.json
@@ -0,0 +1,2239 @@
+{
+  "auth": {
+    "oauth2": {
+      "scopes": {
+        "https://www.googleapis.com/auth/userinfo.email": {
+          "description": "https://www.googleapis.com/auth/userinfo.email"
+        }
+      }
+    }
+  },
+  "basePath": "/_ah/api/swarming/v1",
+  "baseUrl": "https://chromium-swarm.appspot.com/_ah/api/swarming/v1",
+  "batchPath": "batch",
+  "description": "API to interact with the Swarming service. Permits to create, view and cancel tasks, query tasks and bots",
+  "discoveryVersion": "v1",
+  "icons": {
+    "x16": "https://www.google.com/images/icons/product/search-16.gif",
+    "x32": "https://www.google.com/images/icons/product/search-32.gif"
+  },
+  "id": "swarming:v1",
+  "kind": "discovery#restDescription",
+  "name": "swarming",
+  "parameters": {
+    "alt": {
+      "default": "json",
+      "description": "Data format for the response.",
+      "enum": [
+        "json"
+      ],
+      "enumDescriptions": [
+        "Responses with Content-Type of application/json"
+      ],
+      "location": "query",
+      "type": "string"
+    },
+    "fields": {
+      "description": "Selector specifying which fields to include in a partial response.",
+      "location": "query",
+      "type": "string"
+    },
+    "key": {
+      "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
+      "location": "query",
+      "type": "string"
+    },
+    "oauth_token": {
+      "description": "OAuth 2.0 token for the current user.",
+      "location": "query",
+      "type": "string"
+    },
+    "prettyPrint": {
+      "default": "true",
+      "description": "Returns response with indentations and line breaks.",
+      "location": "query",
+      "type": "boolean"
+    },
+    "quotaUser": {
+      "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.",
+      "location": "query",
+      "type": "string"
+    },
+    "userIp": {
+      "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.",
+      "location": "query",
+      "type": "string"
+    }
+  },
+  "protocol": "rest",
+  "resources": {
+    "bot": {
+      "methods": {
+        "delete": {
+          "description": "Deletes the bot corresponding to a provided bot_id. At that point, the bot will not appears in the list of bots but it is still possible to get information about the bot with its bot id is known, as historical data is not deleted. It is meant to remove from the DB the presence of a bot that was retired, e.g. the VM was shut down already. Use 'terminate' instead of the bot is still alive.",
+          "httpMethod": "POST",
+          "id": "swarming.bot.delete",
+          "parameterOrder": [
+            "bot_id"
+          ],
+          "parameters": {
+            "bot_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "bot/{bot_id}/delete",
+          "response": {
+            "$ref": "SwarmingRpcsDeletedResponse"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "events": {
+          "description": "Returns events that happened on a bot.",
+          "httpMethod": "GET",
+          "id": "swarming.bot.events",
+          "parameterOrder": [
+            "bot_id"
+          ],
+          "parameters": {
+            "bot_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            },
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "end": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "start": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            }
+          },
+          "path": "bot/{bot_id}/events",
+          "response": {
+            "$ref": "SwarmingRpcsBotEvents"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "get": {
+          "description": "Returns information about a known bot. This includes its state and dimensions, and if it is currently running a task.",
+          "httpMethod": "GET",
+          "id": "swarming.bot.get",
+          "parameterOrder": [
+            "bot_id"
+          ],
+          "parameters": {
+            "bot_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "bot/{bot_id}/get",
+          "response": {
+            "$ref": "SwarmingRpcsBotInfo"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "tasks": {
+          "description": "Lists a given bot's tasks within the specified date range. In this case, the tasks are effectively TaskRunResult since it's individual task tries sent to this specific bot. It is impossible to search by both tags and bot id. If there's a need, TaskRunResult.tags will be added (via a copy from TaskRequest.tags).",
+          "httpMethod": "GET",
+          "id": "swarming.bot.tasks",
+          "parameterOrder": [
+            "bot_id"
+          ],
+          "parameters": {
+            "bot_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            },
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "end": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "include_performance_stats": {
+              "location": "query",
+              "type": "boolean"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "sort": {
+              "default": "CREATED_TS",
+              "enum": [
+                "ABANDONED_TS",
+                "COMPLETED_TS",
+                "CREATED_TS",
+                "STARTED_TS"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "start": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "state": {
+              "default": "ALL",
+              "enum": [
+                "ALL",
+                "BOT_DIED",
+                "CANCELED",
+                "CLIENT_ERROR",
+                "COMPLETED",
+                "COMPLETED_FAILURE",
+                "COMPLETED_SUCCESS",
+                "DEDUPED",
+                "EXPIRED",
+                "KILLED",
+                "NO_RESOURCE",
+                "PENDING",
+                "PENDING_RUNNING",
+                "RUNNING",
+                "TIMED_OUT"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            }
+          },
+          "path": "bot/{bot_id}/tasks",
+          "response": {
+            "$ref": "SwarmingRpcsBotTasks"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "terminate": {
+          "description": "Asks a bot to terminate itself gracefully. The bot will stay in the DB, use 'delete' to remove it from the DB afterward. This request returns a pseudo-taskid that can be waited for to wait for the bot to turn down. This command is particularly useful when a privileged user needs to safely debug a machine specific issue. The user can trigger a terminate for one of the bot exhibiting the issue, wait for the pseudo-task to run then access the machine with the guarantee that the bot is not running anymore.",
+          "httpMethod": "POST",
+          "id": "swarming.bot.terminate",
+          "parameterOrder": [
+            "bot_id"
+          ],
+          "parameters": {
+            "bot_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "bot/{bot_id}/terminate",
+          "response": {
+            "$ref": "SwarmingRpcsTerminateResponse"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    },
+    "bots": {
+      "methods": {
+        "count": {
+          "description": "Counts number of bots with given dimensions.",
+          "httpMethod": "GET",
+          "id": "swarming.bots.count",
+          "parameters": {
+            "dimensions": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            }
+          },
+          "path": "bots/count",
+          "response": {
+            "$ref": "SwarmingRpcsBotsCount"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "dimensions": {
+          "description": "Returns the cached set of dimensions currently in use in the fleet.",
+          "httpMethod": "GET",
+          "id": "swarming.bots.dimensions",
+          "parameters": {
+            "pool": {
+              "location": "query",
+              "type": "string"
+            }
+          },
+          "path": "bots/dimensions",
+          "response": {
+            "$ref": "SwarmingRpcsBotsDimensions"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "list": {
+          "description": "Provides list of known bots. Deleted bots will not be listed.",
+          "httpMethod": "GET",
+          "id": "swarming.bots.list",
+          "parameters": {
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "dimensions": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            },
+            "in_maintenance": {
+              "default": "NONE",
+              "enum": [
+                "FALSE",
+                "NONE",
+                "TRUE"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "is_busy": {
+              "default": "NONE",
+              "enum": [
+                "FALSE",
+                "NONE",
+                "TRUE"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "is_dead": {
+              "default": "NONE",
+              "enum": [
+                "FALSE",
+                "NONE",
+                "TRUE"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "quarantined": {
+              "default": "NONE",
+              "enum": [
+                "FALSE",
+                "NONE",
+                "TRUE"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            }
+          },
+          "path": "bots/list",
+          "response": {
+            "$ref": "SwarmingRpcsBotList"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    },
+    "queues": {
+      "methods": {
+        "list": {
+          "httpMethod": "GET",
+          "id": "swarming.queues.list",
+          "parameters": {
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            }
+          },
+          "path": "queues/list",
+          "response": {
+            "$ref": "SwarmingRpcsTaskQueueList"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    },
+    "server": {
+      "methods": {
+        "details": {
+          "description": "Returns information about the server.",
+          "httpMethod": "GET",
+          "id": "swarming.server.details",
+          "path": "server/details",
+          "response": {
+            "$ref": "SwarmingRpcsServerDetails"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "get_bootstrap": {
+          "description": "Retrieves the current version of bootstrap.py.",
+          "httpMethod": "GET",
+          "id": "swarming.server.get_bootstrap",
+          "path": "server/get_bootstrap",
+          "response": {
+            "$ref": "SwarmingRpcsFileContent"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "get_bot_config": {
+          "description": "Retrieves the current version of bot_config.py.",
+          "httpMethod": "GET",
+          "id": "swarming.server.get_bot_config",
+          "path": "server/get_bot_config",
+          "response": {
+            "$ref": "SwarmingRpcsFileContent"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "permissions": {
+          "description": "Returns the caller's permissions.",
+          "httpMethod": "GET",
+          "id": "swarming.server.permissions",
+          "parameters": {
+            "bot_id": {
+              "location": "query",
+              "type": "string"
+            },
+            "tags": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            },
+            "task_id": {
+              "location": "query",
+              "type": "string"
+            }
+          },
+          "path": "server/permissions",
+          "response": {
+            "$ref": "SwarmingRpcsClientPermissions"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "token": {
+          "description": "Returns a token to bootstrap a new bot. This may seem strange to be a POST and not a GET, but it's very important to make sure GET requests are idempotent and safe to be pre-fetched; generating a token is neither of those things.",
+          "httpMethod": "POST",
+          "id": "swarming.server.token",
+          "path": "server/token",
+          "response": {
+            "$ref": "SwarmingRpcsBootstrapToken"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    },
+    "task": {
+      "methods": {
+        "cancel": {
+          "description": "Cancels a task. If a bot was running the task, the bot will forcibly cancel the task.",
+          "httpMethod": "POST",
+          "id": "swarming.task.cancel",
+          "parameterOrder": [
+            "task_id"
+          ],
+          "parameters": {
+            "task_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "task/{task_id}/cancel",
+          "request": {
+            "$ref": "SwarmingRpcsTaskCancelRequest",
+            "parameterName": "resource"
+          },
+          "response": {
+            "$ref": "SwarmingRpcsCancelResponse"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "request": {
+          "description": "Returns the task request corresponding to a task ID.",
+          "httpMethod": "GET",
+          "id": "swarming.task.request",
+          "parameterOrder": [
+            "task_id"
+          ],
+          "parameters": {
+            "task_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "task/{task_id}/request",
+          "response": {
+            "$ref": "SwarmingRpcsTaskRequest"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "result": {
+          "description": "Reports the result of the task corresponding to a task ID. It can be a 'run' ID specifying a specific retry or a 'summary' ID hidding the fact that a task may have been retried transparently, when a bot reports BOT_DIED. A summary ID ends with '0', a run ID ends with '1' or '2'.",
+          "httpMethod": "GET",
+          "id": "swarming.task.result",
+          "parameterOrder": [
+            "task_id"
+          ],
+          "parameters": {
+            "include_performance_stats": {
+              "location": "query",
+              "type": "boolean"
+            },
+            "task_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "task/{task_id}/result",
+          "response": {
+            "$ref": "SwarmingRpcsTaskResult"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "stdout": {
+          "description": "Returns the output of the task corresponding to a task ID.",
+          "httpMethod": "GET",
+          "id": "swarming.task.stdout",
+          "parameterOrder": [
+            "task_id"
+          ],
+          "parameters": {
+            "length": {
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "offset": {
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "task_id": {
+              "location": "path",
+              "required": true,
+              "type": "string"
+            }
+          },
+          "path": "task/{task_id}/stdout",
+          "response": {
+            "$ref": "SwarmingRpcsTaskOutput"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    },
+    "tasks": {
+      "methods": {
+        "cancel": {
+          "description": "Cancel a subset of pending tasks based on the tags. Cancellation happens asynchronously, so when this call returns, cancellations will not have completed yet.",
+          "httpMethod": "POST",
+          "id": "swarming.tasks.cancel",
+          "path": "tasks/cancel",
+          "request": {
+            "$ref": "SwarmingRpcsTasksCancelRequest",
+            "parameterName": "resource"
+          },
+          "response": {
+            "$ref": "SwarmingRpcsTasksCancelResponse"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "count": {
+          "description": "Counts number of tasks in a given state.",
+          "httpMethod": "GET",
+          "id": "swarming.tasks.count",
+          "parameters": {
+            "end": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "start": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "state": {
+              "default": "ALL",
+              "enum": [
+                "ALL",
+                "BOT_DIED",
+                "CANCELED",
+                "CLIENT_ERROR",
+                "COMPLETED",
+                "COMPLETED_FAILURE",
+                "COMPLETED_SUCCESS",
+                "DEDUPED",
+                "EXPIRED",
+                "KILLED",
+                "NO_RESOURCE",
+                "PENDING",
+                "PENDING_RUNNING",
+                "RUNNING",
+                "TIMED_OUT"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "tags": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            }
+          },
+          "path": "tasks/count",
+          "response": {
+            "$ref": "SwarmingRpcsTasksCount"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "get_states": {
+          "description": "Returns task state for a specific set of tasks.",
+          "httpMethod": "GET",
+          "id": "swarming.tasks.get_states",
+          "parameters": {
+            "task_id": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            }
+          },
+          "path": "tasks/get_states",
+          "response": {
+            "$ref": "SwarmingRpcsTaskStates"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "list": {
+          "description": "Returns full task results based on the filters. This endpoint is significantly slower than 'count'. Use 'count' when possible. If you just want the state of tasks, use 'get_states'.",
+          "httpMethod": "GET",
+          "id": "swarming.tasks.list",
+          "parameters": {
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "end": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "include_performance_stats": {
+              "location": "query",
+              "type": "boolean"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "sort": {
+              "default": "CREATED_TS",
+              "enum": [
+                "ABANDONED_TS",
+                "COMPLETED_TS",
+                "CREATED_TS",
+                "STARTED_TS"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "start": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "state": {
+              "default": "ALL",
+              "enum": [
+                "ALL",
+                "BOT_DIED",
+                "CANCELED",
+                "CLIENT_ERROR",
+                "COMPLETED",
+                "COMPLETED_FAILURE",
+                "COMPLETED_SUCCESS",
+                "DEDUPED",
+                "EXPIRED",
+                "KILLED",
+                "NO_RESOURCE",
+                "PENDING",
+                "PENDING_RUNNING",
+                "RUNNING",
+                "TIMED_OUT"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "tags": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            }
+          },
+          "path": "tasks/list",
+          "response": {
+            "$ref": "SwarmingRpcsTaskList"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "new": {
+          "description": "Creates a new task. The task will be enqueued in the tasks list and will be executed at the earliest opportunity by a bot that has at least the dimensions as described in the task request.",
+          "httpMethod": "POST",
+          "id": "swarming.tasks.new",
+          "path": "tasks/new",
+          "request": {
+            "$ref": "SwarmingRpcsNewTaskRequest",
+            "parameterName": "resource"
+          },
+          "response": {
+            "$ref": "SwarmingRpcsTaskRequestMetadata"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        },
+        "requests": {
+          "description": "Returns tasks requests based on the filters. This endpoint is slightly slower than 'list'. Use 'list' or 'count' when possible.",
+          "httpMethod": "GET",
+          "id": "swarming.tasks.requests",
+          "parameters": {
+            "cursor": {
+              "location": "query",
+              "type": "string"
+            },
+            "end": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "include_performance_stats": {
+              "location": "query",
+              "type": "boolean"
+            },
+            "limit": {
+              "default": "200",
+              "format": "int64",
+              "location": "query",
+              "type": "string"
+            },
+            "sort": {
+              "default": "CREATED_TS",
+              "enum": [
+                "ABANDONED_TS",
+                "COMPLETED_TS",
+                "CREATED_TS",
+                "STARTED_TS"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "start": {
+              "format": "double",
+              "location": "query",
+              "type": "number"
+            },
+            "state": {
+              "default": "ALL",
+              "enum": [
+                "ALL",
+                "BOT_DIED",
+                "CANCELED",
+                "CLIENT_ERROR",
+                "COMPLETED",
+                "COMPLETED_FAILURE",
+                "COMPLETED_SUCCESS",
+                "DEDUPED",
+                "EXPIRED",
+                "KILLED",
+                "NO_RESOURCE",
+                "PENDING",
+                "PENDING_RUNNING",
+                "RUNNING",
+                "TIMED_OUT"
+              ],
+              "enumDescriptions": [
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                "",
+                ""
+              ],
+              "location": "query",
+              "type": "string"
+            },
+            "tags": {
+              "location": "query",
+              "repeated": true,
+              "type": "string"
+            }
+          },
+          "path": "tasks/requests",
+          "response": {
+            "$ref": "SwarmingRpcsTaskRequests"
+          },
+          "scopes": [
+            "https://www.googleapis.com/auth/userinfo.email"
+          ]
+        }
+      }
+    }
+  },
+  "rootUrl": "https://chromium-swarm.appspot.com/_ah/api/",
+  "schemas": {
+    "SwarmingRpcsBootstrapToken": {
+      "description": "Returns a token to bootstrap a new bot.",
+      "id": "SwarmingRpcsBootstrapToken",
+      "properties": {
+        "bootstrap_token": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotEvent": {
+      "id": "SwarmingRpcsBotEvent",
+      "properties": {
+        "authenticated_as": {
+          "type": "string"
+        },
+        "dimensions": {
+          "description": "Represents a mapping of string to list of strings.",
+          "items": {
+            "$ref": "SwarmingRpcsStringListPair"
+          },
+          "type": "array"
+        },
+        "event_type": {
+          "type": "string"
+        },
+        "external_ip": {
+          "type": "string"
+        },
+        "maintenance_msg": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "quarantined": {
+          "type": "boolean"
+        },
+        "state": {
+          "type": "string"
+        },
+        "task_id": {
+          "type": "string"
+        },
+        "ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "version": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotEvents": {
+      "id": "SwarmingRpcsBotEvents",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "items": {
+          "items": {
+            "$ref": "SwarmingRpcsBotEvent"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotInfo": {
+      "description": "Representation of the BotInfo ndb model.",
+      "id": "SwarmingRpcsBotInfo",
+      "properties": {
+        "authenticated_as": {
+          "type": "string"
+        },
+        "bot_id": {
+          "type": "string"
+        },
+        "deleted": {
+          "type": "boolean"
+        },
+        "dimensions": {
+          "description": "Represents a mapping of string to list of strings.",
+          "items": {
+            "$ref": "SwarmingRpcsStringListPair"
+          },
+          "type": "array"
+        },
+        "external_ip": {
+          "type": "string"
+        },
+        "first_seen_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "is_dead": {
+          "type": "boolean"
+        },
+        "last_seen_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "lease_expiration_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "lease_id": {
+          "type": "string"
+        },
+        "leased_indefinitely": {
+          "type": "boolean"
+        },
+        "machine_lease": {
+          "type": "string"
+        },
+        "machine_type": {
+          "type": "string"
+        },
+        "maintenance_msg": {
+          "type": "string"
+        },
+        "quarantined": {
+          "type": "boolean"
+        },
+        "state": {
+          "type": "string"
+        },
+        "task_id": {
+          "type": "string"
+        },
+        "task_name": {
+          "type": "string"
+        },
+        "version": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotList": {
+      "description": "Wraps a list of BotInfo.",
+      "id": "SwarmingRpcsBotList",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "death_timeout": {
+          "format": "int64",
+          "type": "string"
+        },
+        "items": {
+          "description": "Representation of the BotInfo ndb model.",
+          "items": {
+            "$ref": "SwarmingRpcsBotInfo"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotTasks": {
+      "id": "SwarmingRpcsBotTasks",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "items": {
+          "description": "Representation of the TaskResultSummary or TaskRunResult ndb model.",
+          "items": {
+            "$ref": "SwarmingRpcsTaskResult"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotsCount": {
+      "description": "Returns the count, as requested.",
+      "id": "SwarmingRpcsBotsCount",
+      "properties": {
+        "busy": {
+          "format": "int64",
+          "type": "string"
+        },
+        "count": {
+          "format": "int64",
+          "type": "string"
+        },
+        "dead": {
+          "format": "int64",
+          "type": "string"
+        },
+        "maintenance": {
+          "format": "int64",
+          "type": "string"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "quarantined": {
+          "format": "int64",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsBotsDimensions": {
+      "description": "Returns all the dimensions and dimension possibilities in the fleet.",
+      "id": "SwarmingRpcsBotsDimensions",
+      "properties": {
+        "bots_dimensions": {
+          "description": "Represents a mapping of string to list of strings.",
+          "items": {
+            "$ref": "SwarmingRpcsStringListPair"
+          },
+          "type": "array"
+        },
+        "ts": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCASOperationStats": {
+      "id": "SwarmingRpcsCASOperationStats",
+      "properties": {
+        "duration": {
+          "format": "double",
+          "type": "number"
+        },
+        "initial_number_items": {
+          "format": "int64",
+          "type": "string"
+        },
+        "initial_size": {
+          "format": "int64",
+          "type": "string"
+        },
+        "items_cold": {
+          "format": "byte",
+          "type": "string"
+        },
+        "items_hot": {
+          "format": "byte",
+          "type": "string"
+        },
+        "num_items_cold": {
+          "format": "int64",
+          "type": "string"
+        },
+        "num_items_hot": {
+          "format": "int64",
+          "type": "string"
+        },
+        "total_bytes_items_cold": {
+          "format": "int64",
+          "type": "string"
+        },
+        "total_bytes_items_hot": {
+          "format": "int64",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCASReference": {
+      "id": "SwarmingRpcsCASReference",
+      "properties": {
+        "cas_instance": {
+          "type": "string"
+        },
+        "digest": {
+          "$ref": "SwarmingRpcsDigest"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCacheEntry": {
+      "description": "Describes a named cache that should be present on the bot. A CacheEntry in a task specified that the task prefers the cache to be present on the bot. A symlink to the cache directory is created at \u003crun_dir\u003e/|path|. If cache is not present on the machine, the directory is empty. If the tasks makes any changes to the contents of the cache directory, they are persisted on the machine. If another task runs on the same machine and requests the same named cache, even if mapped to a different path, it will see the changes.",
+      "id": "SwarmingRpcsCacheEntry",
+      "properties": {
+        "name": {
+          "type": "string"
+        },
+        "path": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCancelResponse": {
+      "description": "Result of a request to cancel a task.",
+      "id": "SwarmingRpcsCancelResponse",
+      "properties": {
+        "ok": {
+          "type": "boolean"
+        },
+        "was_running": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCipdInput": {
+      "description": "Defines CIPD packages to install in task run directory.",
+      "id": "SwarmingRpcsCipdInput",
+      "properties": {
+        "client_package": {
+          "$ref": "SwarmingRpcsCipdPackage",
+          "description": "A CIPD package to install in the run dir before task execution."
+        },
+        "packages": {
+          "description": "A CIPD package to install in the run dir before task execution.",
+          "items": {
+            "$ref": "SwarmingRpcsCipdPackage"
+          },
+          "type": "array"
+        },
+        "server": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCipdPackage": {
+      "description": "A CIPD package to install in the run dir before task execution.",
+      "id": "SwarmingRpcsCipdPackage",
+      "properties": {
+        "package_name": {
+          "type": "string"
+        },
+        "path": {
+          "type": "string"
+        },
+        "version": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsCipdPins": {
+      "description": "Defines pinned CIPD packages that were installed during the task.",
+      "id": "SwarmingRpcsCipdPins",
+      "properties": {
+        "client_package": {
+          "$ref": "SwarmingRpcsCipdPackage",
+          "description": "A CIPD package to install in the run dir before task execution."
+        },
+        "packages": {
+          "description": "A CIPD package to install in the run dir before task execution.",
+          "items": {
+            "$ref": "SwarmingRpcsCipdPackage"
+          },
+          "type": "array"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsClientPermissions": {
+      "description": "Reports the client's permissions.",
+      "id": "SwarmingRpcsClientPermissions",
+      "properties": {
+        "cancel_task": {
+          "type": "boolean"
+        },
+        "cancel_tasks": {
+          "type": "boolean"
+        },
+        "delete_bot": {
+          "type": "boolean"
+        },
+        "delete_bots": {
+          "type": "boolean"
+        },
+        "get_bootstrap_token": {
+          "type": "boolean"
+        },
+        "get_configs": {
+          "type": "boolean"
+        },
+        "list_bots": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "list_tasks": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "put_configs": {
+          "type": "boolean"
+        },
+        "terminate_bot": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsContainment": {
+      "description": "See proto/api/swarming.proto for description.",
+      "id": "SwarmingRpcsContainment",
+      "properties": {
+        "containment_type": {
+          "enum": [
+            "AUTO",
+            "JOB_OBJECT",
+            "NONE",
+            "NOT_SPECIFIED"
+          ],
+          "enumDescriptions": [
+            "",
+            "",
+            "",
+            ""
+          ],
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsDeletedResponse": {
+      "description": "Indicates whether a bot was deleted.",
+      "id": "SwarmingRpcsDeletedResponse",
+      "properties": {
+        "deleted": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsDigest": {
+      "id": "SwarmingRpcsDigest",
+      "properties": {
+        "hash": {
+          "type": "string"
+        },
+        "size_bytes": {
+          "format": "int64",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsFileContent": {
+      "description": "Content of a file.",
+      "id": "SwarmingRpcsFileContent",
+      "properties": {
+        "content": {
+          "type": "string"
+        },
+        "version": {
+          "type": "string"
+        },
+        "when": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "who": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsNewTaskRequest": {
+      "description": "Description of a new task request as described by the client. This message is used to create a new task.",
+      "id": "SwarmingRpcsNewTaskRequest",
+      "properties": {
+        "bot_ping_tolerance_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "evaluate_only": {
+          "type": "boolean"
+        },
+        "expiration_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "parent_task_id": {
+          "type": "string"
+        },
+        "pool_task_template": {
+          "default": "AUTO",
+          "enum": [
+            "AUTO",
+            "CANARY_NEVER",
+            "CANARY_PREFER",
+            "SKIP"
+          ],
+          "enumDescriptions": [
+            "",
+            "",
+            "",
+            ""
+          ],
+          "type": "string"
+        },
+        "priority": {
+          "format": "int64",
+          "type": "string"
+        },
+        "properties": {
+          "$ref": "SwarmingRpcsTaskProperties",
+          "description": "Important metadata about a particular task."
+        },
+        "pubsub_auth_token": {
+          "type": "string"
+        },
+        "pubsub_topic": {
+          "type": "string"
+        },
+        "pubsub_userdata": {
+          "type": "string"
+        },
+        "realm": {
+          "type": "string"
+        },
+        "request_uuid": {
+          "type": "string"
+        },
+        "resultdb": {
+          "$ref": "SwarmingRpcsResultDBCfg",
+          "description": "Swarming:ResultDB integration configuration for a task. See NewTaskRequest.resultdb for more details."
+        },
+        "service_account": {
+          "type": "string"
+        },
+        "tags": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "task_slices": {
+          "description": "Defines a possible task execution for a task request to be run on the Swarming infrastructure. This is one of the possible fallback on a task request.",
+          "items": {
+            "$ref": "SwarmingRpcsTaskSlice"
+          },
+          "type": "array"
+        },
+        "user": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsOperationStats": {
+      "id": "SwarmingRpcsOperationStats",
+      "properties": {
+        "duration": {
+          "format": "double",
+          "type": "number"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsPerformanceStats": {
+      "description": "Performance stats of task execution. See task_result.PerformanceStats for details.",
+      "id": "SwarmingRpcsPerformanceStats",
+      "properties": {
+        "bot_overhead": {
+          "format": "double",
+          "type": "number"
+        },
+        "cache_trim": {
+          "$ref": "SwarmingRpcsOperationStats"
+        },
+        "cleanup": {
+          "$ref": "SwarmingRpcsOperationStats"
+        },
+        "isolated_download": {
+          "$ref": "SwarmingRpcsCASOperationStats"
+        },
+        "isolated_upload": {
+          "$ref": "SwarmingRpcsCASOperationStats"
+        },
+        "named_caches_install": {
+          "$ref": "SwarmingRpcsOperationStats"
+        },
+        "named_caches_uninstall": {
+          "$ref": "SwarmingRpcsOperationStats"
+        },
+        "package_installation": {
+          "$ref": "SwarmingRpcsOperationStats"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsResultDBCfg": {
+      "description": "Swarming:ResultDB integration configuration for a task. See NewTaskRequest.resultdb for more details.",
+      "id": "SwarmingRpcsResultDBCfg",
+      "properties": {
+        "enable": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsResultDBInfo": {
+      "description": "ResultDB related properties.",
+      "id": "SwarmingRpcsResultDBInfo",
+      "properties": {
+        "hostname": {
+          "type": "string"
+        },
+        "invocation": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsServerDetails": {
+      "description": "Reports details about the server.",
+      "id": "SwarmingRpcsServerDetails",
+      "properties": {
+        "bot_version": {
+          "type": "string"
+        },
+        "cas_viewer_server": {
+          "type": "string"
+        },
+        "display_server_url_template": {
+          "type": "string"
+        },
+        "luci_config": {
+          "type": "string"
+        },
+        "machine_provider_template": {
+          "type": "string"
+        },
+        "server_version": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsStringListPair": {
+      "description": "Represents a mapping of string to list of strings.",
+      "id": "SwarmingRpcsStringListPair",
+      "properties": {
+        "key": {
+          "type": "string"
+        },
+        "value": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsStringPair": {
+      "description": "Represents a mapping of string to string.",
+      "id": "SwarmingRpcsStringPair",
+      "properties": {
+        "key": {
+          "type": "string"
+        },
+        "value": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskCancelRequest": {
+      "description": "Request to cancel one task.",
+      "id": "SwarmingRpcsTaskCancelRequest",
+      "properties": {
+        "kill_running": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskList": {
+      "description": "Wraps a list of TaskResult.",
+      "id": "SwarmingRpcsTaskList",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "items": {
+          "description": "Representation of the TaskResultSummary or TaskRunResult ndb model.",
+          "items": {
+            "$ref": "SwarmingRpcsTaskResult"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskOutput": {
+      "description": "A task's output as a string.",
+      "id": "SwarmingRpcsTaskOutput",
+      "properties": {
+        "output": {
+          "type": "string"
+        },
+        "state": {
+          "enum": [
+            "BOT_DIED",
+            "CANCELED",
+            "CLIENT_ERROR",
+            "COMPLETED",
+            "EXPIRED",
+            "INVALID",
+            "KILLED",
+            "NO_RESOURCE",
+            "PENDING",
+            "RUNNING",
+            "TIMED_OUT"
+          ],
+          "enumDescriptions": [
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            ""
+          ],
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskProperties": {
+      "description": "Important metadata about a particular task.",
+      "id": "SwarmingRpcsTaskProperties",
+      "properties": {
+        "caches": {
+          "description": "Describes a named cache that should be present on the bot. A CacheEntry in a task specified that the task prefers the cache to be present on the bot. A symlink to the cache directory is created at \u003crun_dir\u003e/|path|. If cache is not present on the machine, the directory is empty. If the tasks makes any changes to the contents of the cache directory, they are persisted on the machine. If another task runs on the same machine and requests the same named cache, even if mapped to a different path, it will see the changes.",
+          "items": {
+            "$ref": "SwarmingRpcsCacheEntry"
+          },
+          "type": "array"
+        },
+        "cas_input_root": {
+          "$ref": "SwarmingRpcsCASReference"
+        },
+        "cipd_input": {
+          "$ref": "SwarmingRpcsCipdInput",
+          "description": "Defines CIPD packages to install in task run directory."
+        },
+        "command": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "containment": {
+          "$ref": "SwarmingRpcsContainment",
+          "description": "See proto/api/swarming.proto for description."
+        },
+        "dimensions": {
+          "description": "Represents a mapping of string to string.",
+          "items": {
+            "$ref": "SwarmingRpcsStringPair"
+          },
+          "type": "array"
+        },
+        "env": {
+          "description": "Represents a mapping of string to string.",
+          "items": {
+            "$ref": "SwarmingRpcsStringPair"
+          },
+          "type": "array"
+        },
+        "env_prefixes": {
+          "description": "Represents a mapping of string to list of strings.",
+          "items": {
+            "$ref": "SwarmingRpcsStringListPair"
+          },
+          "type": "array"
+        },
+        "execution_timeout_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "grace_period_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "idempotent": {
+          "type": "boolean"
+        },
+        "io_timeout_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "outputs": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "relative_cwd": {
+          "type": "string"
+        },
+        "secret_bytes": {
+          "format": "byte",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskQueue": {
+      "id": "SwarmingRpcsTaskQueue",
+      "properties": {
+        "dimensions": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "valid_until_ts": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskQueueList": {
+      "id": "SwarmingRpcsTaskQueueList",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "items": {
+          "items": {
+            "$ref": "SwarmingRpcsTaskQueue"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskRequest": {
+      "description": "Description of a task request as registered by the server. This message is used when retrieving information about an existing task. See NewTaskRequest for more details.",
+      "id": "SwarmingRpcsTaskRequest",
+      "properties": {
+        "authenticated": {
+          "type": "string"
+        },
+        "bot_ping_tolerance_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "created_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "expiration_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "parent_task_id": {
+          "type": "string"
+        },
+        "priority": {
+          "format": "int64",
+          "type": "string"
+        },
+        "properties": {
+          "$ref": "SwarmingRpcsTaskProperties",
+          "description": "Important metadata about a particular task."
+        },
+        "pubsub_topic": {
+          "type": "string"
+        },
+        "pubsub_userdata": {
+          "type": "string"
+        },
+        "rbe_instance": {
+          "type": "string"
+        },
+        "realm": {
+          "type": "string"
+        },
+        "resultdb": {
+          "$ref": "SwarmingRpcsResultDBCfg",
+          "description": "Swarming:ResultDB integration configuration for a task. See NewTaskRequest.resultdb for more details."
+        },
+        "service_account": {
+          "type": "string"
+        },
+        "tags": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "task_id": {
+          "type": "string"
+        },
+        "task_slices": {
+          "description": "Defines a possible task execution for a task request to be run on the Swarming infrastructure. This is one of the possible fallback on a task request.",
+          "items": {
+            "$ref": "SwarmingRpcsTaskSlice"
+          },
+          "type": "array"
+        },
+        "user": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskRequestMetadata": {
+      "description": "Provides the ID of the requested TaskRequest.",
+      "id": "SwarmingRpcsTaskRequestMetadata",
+      "properties": {
+        "request": {
+          "$ref": "SwarmingRpcsTaskRequest",
+          "description": "Description of a task request as registered by the server. This message is used when retrieving information about an existing task. See NewTaskRequest for more details."
+        },
+        "task_id": {
+          "type": "string"
+        },
+        "task_result": {
+          "$ref": "SwarmingRpcsTaskResult",
+          "description": "Representation of the TaskResultSummary or TaskRunResult ndb model."
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskRequests": {
+      "description": "Wraps a list of TaskRequest.",
+      "id": "SwarmingRpcsTaskRequests",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "items": {
+          "description": "Description of a task request as registered by the server. This message is used when retrieving information about an existing task. See NewTaskRequest for more details.",
+          "items": {
+            "$ref": "SwarmingRpcsTaskRequest"
+          },
+          "type": "array"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskResult": {
+      "description": "Representation of the TaskResultSummary or TaskRunResult ndb model.",
+      "id": "SwarmingRpcsTaskResult",
+      "properties": {
+        "abandoned_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "bot_dimensions": {
+          "description": "Represents a mapping of string to list of strings.",
+          "items": {
+            "$ref": "SwarmingRpcsStringListPair"
+          },
+          "type": "array"
+        },
+        "bot_id": {
+          "type": "string"
+        },
+        "bot_idle_since_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "bot_logs_cloud_project": {
+          "type": "string"
+        },
+        "bot_version": {
+          "type": "string"
+        },
+        "cas_output_root": {
+          "$ref": "SwarmingRpcsCASReference"
+        },
+        "children_task_ids": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "cipd_pins": {
+          "$ref": "SwarmingRpcsCipdPins",
+          "description": "Defines pinned CIPD packages that were installed during the task."
+        },
+        "completed_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "cost_saved_usd": {
+          "format": "double",
+          "type": "number"
+        },
+        "costs_usd": {
+          "items": {
+            "format": "double",
+            "type": "number"
+          },
+          "type": "array"
+        },
+        "created_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "current_task_slice": {
+          "format": "int64",
+          "type": "string"
+        },
+        "deduped_from": {
+          "type": "string"
+        },
+        "duration": {
+          "format": "double",
+          "type": "number"
+        },
+        "exit_code": {
+          "format": "int64",
+          "type": "string"
+        },
+        "failure": {
+          "type": "boolean"
+        },
+        "internal_failure": {
+          "type": "boolean"
+        },
+        "missing_cas": {
+          "items": {
+            "$ref": "SwarmingRpcsCASReference"
+          },
+          "type": "array"
+        },
+        "missing_cipd": {
+          "description": "A CIPD package to install in the run dir before task execution.",
+          "items": {
+            "$ref": "SwarmingRpcsCipdPackage"
+          },
+          "type": "array"
+        },
+        "modified_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "performance_stats": {
+          "$ref": "SwarmingRpcsPerformanceStats",
+          "description": "Performance stats of task execution. See task_result.PerformanceStats for details."
+        },
+        "resultdb_info": {
+          "$ref": "SwarmingRpcsResultDBInfo",
+          "description": "ResultDB related properties."
+        },
+        "run_id": {
+          "type": "string"
+        },
+        "server_versions": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "started_ts": {
+          "format": "date-time",
+          "type": "string"
+        },
+        "state": {
+          "enum": [
+            "BOT_DIED",
+            "CANCELED",
+            "CLIENT_ERROR",
+            "COMPLETED",
+            "EXPIRED",
+            "INVALID",
+            "KILLED",
+            "NO_RESOURCE",
+            "PENDING",
+            "RUNNING",
+            "TIMED_OUT"
+          ],
+          "enumDescriptions": [
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            ""
+          ],
+          "type": "string"
+        },
+        "tags": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "task_id": {
+          "type": "string"
+        },
+        "user": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskSlice": {
+      "description": "Defines a possible task execution for a task request to be run on the Swarming infrastructure. This is one of the possible fallback on a task request.",
+      "id": "SwarmingRpcsTaskSlice",
+      "properties": {
+        "expiration_secs": {
+          "format": "int64",
+          "type": "string"
+        },
+        "properties": {
+          "$ref": "SwarmingRpcsTaskProperties",
+          "description": "Important metadata about a particular task."
+        },
+        "wait_for_capacity": {
+          "type": "boolean"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTaskStates": {
+      "description": "Only holds states. Used in the 'get_states' RPC.",
+      "id": "SwarmingRpcsTaskStates",
+      "properties": {
+        "states": {
+          "items": {
+            "enum": [
+              "BOT_DIED",
+              "CANCELED",
+              "CLIENT_ERROR",
+              "COMPLETED",
+              "EXPIRED",
+              "INVALID",
+              "KILLED",
+              "NO_RESOURCE",
+              "PENDING",
+              "RUNNING",
+              "TIMED_OUT"
+            ],
+            "enumDescriptions": [
+              "",
+              "",
+              "",
+              "",
+              "",
+              "",
+              "",
+              "",
+              "",
+              "",
+              ""
+            ],
+            "type": "string"
+          },
+          "type": "array"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTasksCancelRequest": {
+      "description": "Request to cancel some subset of pending/running tasks.",
+      "id": "SwarmingRpcsTasksCancelRequest",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "end": {
+          "format": "double",
+          "type": "number"
+        },
+        "kill_running": {
+          "type": "boolean"
+        },
+        "limit": {
+          "default": "100",
+          "format": "int64",
+          "type": "string"
+        },
+        "start": {
+          "format": "double",
+          "type": "number"
+        },
+        "tags": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTasksCancelResponse": {
+      "description": "Result of canceling some subset of pending tasks.",
+      "id": "SwarmingRpcsTasksCancelResponse",
+      "properties": {
+        "cursor": {
+          "type": "string"
+        },
+        "matched": {
+          "format": "int64",
+          "type": "string"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTasksCount": {
+      "description": "Returns the count, as requested.",
+      "id": "SwarmingRpcsTasksCount",
+      "properties": {
+        "count": {
+          "format": "int64",
+          "type": "string"
+        },
+        "now": {
+          "format": "date-time",
+          "type": "string"
+        }
+      },
+      "type": "object"
+    },
+    "SwarmingRpcsTerminateResponse": {
+      "description": "Returns the pseudo taskid to wait for the bot to shut down.",
+      "id": "SwarmingRpcsTerminateResponse",
+      "properties": {
+        "task_id": {
+          "type": "string"
+        }
+      },
+      "type": "object"
+    }
+  },
+  "servicePath": "swarming/v1/",
+  "version": "v1"
+}
\ No newline at end of file
diff --git a/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-gen.go b/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-gen.go
new file mode 100644
index 0000000..19fca6e
--- /dev/null
+++ b/vendor/go.chromium.org/luci/common/api/swarming/swarming/v1/swarming-gen.go
@@ -0,0 +1,6106 @@
+// Copyright 2023 The LUCI Authors.
+//
+// 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.
+
+// Code generated file. DO NOT EDIT.
+
+// Package swarming provides access to the .
+//
+// # Creating a client
+//
+// Usage example:
+//
+//	import "go.chromium.org/luci/common/api/swarming/swarming/v1"
+//	...
+//	ctx := context.Background()
+//	swarmingService, err := swarming.NewService(ctx)
+//
+// In this example, Google Application Default Credentials are used for authentication.
+//
+// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
+//
+// # Other authentication options
+//
+// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
+//
+//	swarmingService, err := swarming.NewService(ctx, option.WithAPIKey("AIza..."))
+//
+// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
+//
+//	config := &oauth2.Config{...}
+//	// ...
+//	token, err := config.Exchange(ctx, ...)
+//	swarmingService, err := swarming.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
+//
+// See https://godoc.org/google.golang.org/api/option/ for details on options.
+package swarming // import "go.chromium.org/luci/common/api/swarming/swarming/v1"
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+
+	googleapi "google.golang.org/api/googleapi"
+	gensupport "go.chromium.org/luci/common/api/internal/gensupport"
+	option "google.golang.org/api/option"
+	internaloption "google.golang.org/api/option/internaloption"
+	htransport "google.golang.org/api/transport/http"
+)
+
+// Always reference these packages, just in case the auto-generated code
+// below doesn't.
+var _ = bytes.NewBuffer
+var _ = strconv.Itoa
+var _ = fmt.Sprintf
+var _ = json.NewDecoder
+var _ = io.Copy
+var _ = url.Parse
+var _ = gensupport.MarshalJSON
+var _ = googleapi.Version
+var _ = errors.New
+var _ = strings.Replace
+var _ = context.Canceled
+var _ = internaloption.WithDefaultEndpoint
+
+const apiId = "swarming:v1"
+const apiName = "swarming"
+const apiVersion = "v1"
+const basePath = "http://localhost:8080/_ah/api/swarming/v1"
+
+// OAuth2 scopes used by this API.
+const (
+	// https://www.googleapis.com/auth/userinfo.email
+	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
+)
+
+// NewService creates a new Service.
+func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
+	scopesOption := internaloption.WithDefaultScopes(
+		"https://www.googleapis.com/auth/userinfo.email",
+	)
+	// NOTE: prepend, so we don't override user-specified scopes.
+	opts = append([]option.ClientOption{scopesOption}, opts...)
+	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+	client, endpoint, err := htransport.NewClient(ctx, opts...)
+	if err != nil {
+		return nil, err
+	}
+	s, err := New(client)
+	if err != nil {
+		return nil, err
+	}
+	if endpoint != "" {
+		s.BasePath = endpoint
+	}
+	return s, nil
+}
+
+// New creates a new Service. It uses the provided http.Client for requests.
+//
+// Deprecated: please use NewService instead.
+// To provide a custom HTTP client, use option.WithHTTPClient.
+// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
+func New(client *http.Client) (*Service, error) {
+	if client == nil {
+		return nil, errors.New("client is nil")
+	}
+	s := &Service{client: client, BasePath: basePath}
+	s.Bot = NewBotService(s)
+	s.Bots = NewBotsService(s)
+	s.Queues = NewQueuesService(s)
+	s.Server = NewServerService(s)
+	s.Task = NewTaskService(s)
+	s.Tasks = NewTasksService(s)
+	return s, nil
+}
+
+type Service struct {
+	client    *http.Client
+	BasePath  string // API endpoint base URL
+	UserAgent string // optional additional User-Agent fragment
+
+	Bot *BotService
+
+	Bots *BotsService
+
+	Queues *QueuesService
+
+	Server *ServerService
+
+	Task *TaskService
+
+	Tasks *TasksService
+}
+
+func (s *Service) userAgent() string {
+	if s.UserAgent == "" {
+		return googleapi.UserAgent
+	}
+	return googleapi.UserAgent + " " + s.UserAgent
+}
+
+func NewBotService(s *Service) *BotService {
+	rs := &BotService{s: s}
+	return rs
+}
+
+type BotService struct {
+	s *Service
+}
+
+func NewBotsService(s *Service) *BotsService {
+	rs := &BotsService{s: s}
+	return rs
+}
+
+type BotsService struct {
+	s *Service
+}
+
+func NewQueuesService(s *Service) *QueuesService {
+	rs := &QueuesService{s: s}
+	return rs
+}
+
+type QueuesService struct {
+	s *Service
+}
+
+func NewServerService(s *Service) *ServerService {
+	rs := &ServerService{s: s}
+	return rs
+}
+
+type ServerService struct {
+	s *Service
+}
+
+func NewTaskService(s *Service) *TaskService {
+	rs := &TaskService{s: s}
+	return rs
+}
+
+type TaskService struct {
+	s *Service
+}
+
+func NewTasksService(s *Service) *TasksService {
+	rs := &TasksService{s: s}
+	return rs
+}
+
+type TasksService struct {
+	s *Service
+}
+
+// SwarmingRpcsBootstrapToken: Returns a token to bootstrap a new bot.
+type SwarmingRpcsBootstrapToken struct {
+	BootstrapToken string `json:"bootstrap_token,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "BootstrapToken") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "BootstrapToken") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBootstrapToken) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBootstrapToken
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsBotEvent struct {
+	AuthenticatedAs string `json:"authenticated_as,omitempty"`
+
+	// Dimensions: Represents a mapping of string to list of strings.
+	Dimensions []*SwarmingRpcsStringListPair `json:"dimensions,omitempty"`
+
+	EventType string `json:"event_type,omitempty"`
+
+	ExternalIp string `json:"external_ip,omitempty"`
+
+	MaintenanceMsg string `json:"maintenance_msg,omitempty"`
+
+	Message string `json:"message,omitempty"`
+
+	Quarantined bool `json:"quarantined,omitempty"`
+
+	State string `json:"state,omitempty"`
+
+	TaskId string `json:"task_id,omitempty"`
+
+	Ts string `json:"ts,omitempty"`
+
+	Version string `json:"version,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "AuthenticatedAs") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "AuthenticatedAs") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotEvent) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotEvent
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsBotEvents struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	Items []*SwarmingRpcsBotEvent `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotEvents) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotEvents
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsBotInfo: Representation of the BotInfo ndb model.
+type SwarmingRpcsBotInfo struct {
+	AuthenticatedAs string `json:"authenticated_as,omitempty"`
+
+	BotId string `json:"bot_id,omitempty"`
+
+	Deleted bool `json:"deleted,omitempty"`
+
+	// Dimensions: Represents a mapping of string to list of strings.
+	Dimensions []*SwarmingRpcsStringListPair `json:"dimensions,omitempty"`
+
+	ExternalIp string `json:"external_ip,omitempty"`
+
+	FirstSeenTs string `json:"first_seen_ts,omitempty"`
+
+	IsDead bool `json:"is_dead,omitempty"`
+
+	LastSeenTs string `json:"last_seen_ts,omitempty"`
+
+	LeaseExpirationTs string `json:"lease_expiration_ts,omitempty"`
+
+	LeaseId string `json:"lease_id,omitempty"`
+
+	LeasedIndefinitely bool `json:"leased_indefinitely,omitempty"`
+
+	MachineLease string `json:"machine_lease,omitempty"`
+
+	MachineType string `json:"machine_type,omitempty"`
+
+	MaintenanceMsg string `json:"maintenance_msg,omitempty"`
+
+	Quarantined bool `json:"quarantined,omitempty"`
+
+	State string `json:"state,omitempty"`
+
+	TaskId string `json:"task_id,omitempty"`
+
+	TaskName string `json:"task_name,omitempty"`
+
+	Version string `json:"version,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "AuthenticatedAs") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "AuthenticatedAs") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotInfo) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotInfo
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsBotList: Wraps a list of BotInfo.
+type SwarmingRpcsBotList struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	DeathTimeout int64 `json:"death_timeout,omitempty,string"`
+
+	// Items: Representation of the BotInfo ndb model.
+	Items []*SwarmingRpcsBotInfo `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotList) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotList
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsBotTasks struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	// Items: Representation of the TaskResultSummary or TaskRunResult ndb
+	// model.
+	Items []*SwarmingRpcsTaskResult `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotTasks) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotTasks
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsBotsCount: Returns the count, as requested.
+type SwarmingRpcsBotsCount struct {
+	Busy int64 `json:"busy,omitempty,string"`
+
+	Count int64 `json:"count,omitempty,string"`
+
+	Dead int64 `json:"dead,omitempty,string"`
+
+	Maintenance int64 `json:"maintenance,omitempty,string"`
+
+	Now string `json:"now,omitempty"`
+
+	Quarantined int64 `json:"quarantined,omitempty,string"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Busy") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Busy") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotsCount) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotsCount
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsBotsDimensions: Returns all the dimensions and dimension
+// possibilities in the fleet.
+type SwarmingRpcsBotsDimensions struct {
+	// BotsDimensions: Represents a mapping of string to list of strings.
+	BotsDimensions []*SwarmingRpcsStringListPair `json:"bots_dimensions,omitempty"`
+
+	Ts string `json:"ts,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "BotsDimensions") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "BotsDimensions") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsBotsDimensions) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsBotsDimensions
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsCASOperationStats struct {
+	Duration float64 `json:"duration,omitempty"`
+
+	InitialNumberItems int64 `json:"initial_number_items,omitempty,string"`
+
+	InitialSize int64 `json:"initial_size,omitempty,string"`
+
+	ItemsCold string `json:"items_cold,omitempty"`
+
+	ItemsHot string `json:"items_hot,omitempty"`
+
+	NumItemsCold int64 `json:"num_items_cold,omitempty,string"`
+
+	NumItemsHot int64 `json:"num_items_hot,omitempty,string"`
+
+	TotalBytesItemsCold int64 `json:"total_bytes_items_cold,omitempty,string"`
+
+	TotalBytesItemsHot int64 `json:"total_bytes_items_hot,omitempty,string"`
+
+	// ForceSendFields is a list of field names (e.g. "Duration") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Duration") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCASOperationStats) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCASOperationStats
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+func (s *SwarmingRpcsCASOperationStats) UnmarshalJSON(data []byte) error {
+	type NoMethod SwarmingRpcsCASOperationStats
+	var s1 struct {
+		Duration gensupport.JSONFloat64 `json:"duration"`
+		*NoMethod
+	}
+	s1.NoMethod = (*NoMethod)(s)
+	if err := json.Unmarshal(data, &s1); err != nil {
+		return err
+	}
+	s.Duration = float64(s1.Duration)
+	return nil
+}
+
+type SwarmingRpcsCASReference struct {
+	CasInstance string `json:"cas_instance,omitempty"`
+
+	Digest *SwarmingRpcsDigest `json:"digest,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "CasInstance") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "CasInstance") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCASReference) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCASReference
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsCacheEntry: Describes a named cache that should be
+// present on the bot. A CacheEntry in a task specified that the task
+// prefers the cache to be present on the bot. A symlink to the cache
+// directory is created at <run_dir>/|path|. If cache is not present on
+// the machine, the directory is empty. If the tasks makes any changes
+// to the contents of the cache directory, they are persisted on the
+// machine. If another task runs on the same machine and requests the
+// same named cache, even if mapped to a different path, it will see the
+// changes.
+type SwarmingRpcsCacheEntry struct {
+	Name string `json:"name,omitempty"`
+
+	Path string `json:"path,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Name") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Name") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCacheEntry) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCacheEntry
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsCancelResponse: Result of a request to cancel a task.
+type SwarmingRpcsCancelResponse struct {
+	Ok bool `json:"ok,omitempty"`
+
+	WasRunning bool `json:"was_running,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Ok") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Ok") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCancelResponse) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCancelResponse
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsCipdInput: Defines CIPD packages to install in task run
+// directory.
+type SwarmingRpcsCipdInput struct {
+	// ClientPackage: A CIPD package to install in the run dir before task
+	// execution.
+	ClientPackage *SwarmingRpcsCipdPackage `json:"client_package,omitempty"`
+
+	// Packages: A CIPD package to install in the run dir before task
+	// execution.
+	Packages []*SwarmingRpcsCipdPackage `json:"packages,omitempty"`
+
+	Server string `json:"server,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "ClientPackage") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "ClientPackage") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCipdInput) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCipdInput
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsCipdPackage: A CIPD package to install in the run dir
+// before task execution.
+type SwarmingRpcsCipdPackage struct {
+	PackageName string `json:"package_name,omitempty"`
+
+	Path string `json:"path,omitempty"`
+
+	Version string `json:"version,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "PackageName") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "PackageName") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCipdPackage) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCipdPackage
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsCipdPins: Defines pinned CIPD packages that were
+// installed during the task.
+type SwarmingRpcsCipdPins struct {
+	// ClientPackage: A CIPD package to install in the run dir before task
+	// execution.
+	ClientPackage *SwarmingRpcsCipdPackage `json:"client_package,omitempty"`
+
+	// Packages: A CIPD package to install in the run dir before task
+	// execution.
+	Packages []*SwarmingRpcsCipdPackage `json:"packages,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "ClientPackage") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "ClientPackage") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsCipdPins) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsCipdPins
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsClientPermissions: Reports the client's permissions.
+type SwarmingRpcsClientPermissions struct {
+	CancelTask bool `json:"cancel_task,omitempty"`
+
+	CancelTasks bool `json:"cancel_tasks,omitempty"`
+
+	DeleteBot bool `json:"delete_bot,omitempty"`
+
+	DeleteBots bool `json:"delete_bots,omitempty"`
+
+	GetBootstrapToken bool `json:"get_bootstrap_token,omitempty"`
+
+	GetConfigs bool `json:"get_configs,omitempty"`
+
+	ListBots []string `json:"list_bots,omitempty"`
+
+	ListTasks []string `json:"list_tasks,omitempty"`
+
+	PutConfigs bool `json:"put_configs,omitempty"`
+
+	TerminateBot bool `json:"terminate_bot,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "CancelTask") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "CancelTask") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsClientPermissions) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsClientPermissions
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsContainment: See proto/api/swarming.proto for
+// description.
+type SwarmingRpcsContainment struct {
+	// Possible values:
+	//   "AUTO"
+	//   "JOB_OBJECT"
+	//   "NONE"
+	//   "NOT_SPECIFIED"
+	ContainmentType string `json:"containment_type,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "ContainmentType") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "ContainmentType") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsContainment) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsContainment
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsDeletedResponse: Indicates whether a bot was deleted.
+type SwarmingRpcsDeletedResponse struct {
+	Deleted bool `json:"deleted,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Deleted") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Deleted") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsDeletedResponse) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsDeletedResponse
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsDigest struct {
+	Hash string `json:"hash,omitempty"`
+
+	SizeBytes int64 `json:"size_bytes,omitempty,string"`
+
+	// ForceSendFields is a list of field names (e.g. "Hash") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Hash") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsDigest) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsDigest
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsFileContent: Content of a file.
+type SwarmingRpcsFileContent struct {
+	Content string `json:"content,omitempty"`
+
+	Version string `json:"version,omitempty"`
+
+	When string `json:"when,omitempty"`
+
+	Who string `json:"who,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Content") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Content") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsFileContent) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsFileContent
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsNewTaskRequest: Description of a new task request as
+// described by the client. This message is used to create a new task.
+type SwarmingRpcsNewTaskRequest struct {
+	BotPingToleranceSecs int64 `json:"bot_ping_tolerance_secs,omitempty,string"`
+
+	EvaluateOnly bool `json:"evaluate_only,omitempty"`
+
+	ExpirationSecs int64 `json:"expiration_secs,omitempty,string"`
+
+	Name string `json:"name,omitempty"`
+
+	ParentTaskId string `json:"parent_task_id,omitempty"`
+
+	// Possible values:
+	//   "AUTO" (default)
+	//   "CANARY_NEVER"
+	//   "CANARY_PREFER"
+	//   "SKIP"
+	PoolTaskTemplate string `json:"pool_task_template,omitempty"`
+
+	Priority int64 `json:"priority,omitempty,string"`
+
+	// Properties: Important metadata about a particular task.
+	Properties *SwarmingRpcsTaskProperties `json:"properties,omitempty"`
+
+	PubsubAuthToken string `json:"pubsub_auth_token,omitempty"`
+
+	PubsubTopic string `json:"pubsub_topic,omitempty"`
+
+	PubsubUserdata string `json:"pubsub_userdata,omitempty"`
+
+	Realm string `json:"realm,omitempty"`
+
+	RequestUuid string `json:"request_uuid,omitempty"`
+
+	// Resultdb: Swarming:ResultDB integration configuration for a task. See
+	// NewTaskRequest.resultdb for more details.
+	Resultdb *SwarmingRpcsResultDBCfg `json:"resultdb,omitempty"`
+
+	ServiceAccount string `json:"service_account,omitempty"`
+
+	Tags []string `json:"tags,omitempty"`
+
+	// TaskSlices: Defines a possible task execution for a task request to
+	// be run on the Swarming infrastructure. This is one of the possible
+	// fallback on a task request.
+	TaskSlices []*SwarmingRpcsTaskSlice `json:"task_slices,omitempty"`
+
+	User string `json:"user,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g.
+	// "BotPingToleranceSecs") to unconditionally include in API requests.
+	// By default, fields with empty or default values are omitted from API
+	// requests. However, any non-pointer, non-interface field appearing in
+	// ForceSendFields will be sent to the server regardless of whether the
+	// field is empty or not. This may be used to include empty fields in
+	// Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "BotPingToleranceSecs") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsNewTaskRequest) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsNewTaskRequest
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsOperationStats struct {
+	Duration float64 `json:"duration,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Duration") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Duration") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsOperationStats) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsOperationStats
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+func (s *SwarmingRpcsOperationStats) UnmarshalJSON(data []byte) error {
+	type NoMethod SwarmingRpcsOperationStats
+	var s1 struct {
+		Duration gensupport.JSONFloat64 `json:"duration"`
+		*NoMethod
+	}
+	s1.NoMethod = (*NoMethod)(s)
+	if err := json.Unmarshal(data, &s1); err != nil {
+		return err
+	}
+	s.Duration = float64(s1.Duration)
+	return nil
+}
+
+// SwarmingRpcsPerformanceStats: Performance stats of task execution.
+// See task_result.PerformanceStats for details.
+type SwarmingRpcsPerformanceStats struct {
+	BotOverhead float64 `json:"bot_overhead,omitempty"`
+
+	CacheTrim *SwarmingRpcsOperationStats `json:"cache_trim,omitempty"`
+
+	Cleanup *SwarmingRpcsOperationStats `json:"cleanup,omitempty"`
+
+	IsolatedDownload *SwarmingRpcsCASOperationStats `json:"isolated_download,omitempty"`
+
+	IsolatedUpload *SwarmingRpcsCASOperationStats `json:"isolated_upload,omitempty"`
+
+	NamedCachesInstall *SwarmingRpcsOperationStats `json:"named_caches_install,omitempty"`
+
+	NamedCachesUninstall *SwarmingRpcsOperationStats `json:"named_caches_uninstall,omitempty"`
+
+	PackageInstallation *SwarmingRpcsOperationStats `json:"package_installation,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "BotOverhead") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "BotOverhead") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsPerformanceStats) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsPerformanceStats
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+func (s *SwarmingRpcsPerformanceStats) UnmarshalJSON(data []byte) error {
+	type NoMethod SwarmingRpcsPerformanceStats
+	var s1 struct {
+		BotOverhead gensupport.JSONFloat64 `json:"bot_overhead"`
+		*NoMethod
+	}
+	s1.NoMethod = (*NoMethod)(s)
+	if err := json.Unmarshal(data, &s1); err != nil {
+		return err
+	}
+	s.BotOverhead = float64(s1.BotOverhead)
+	return nil
+}
+
+// SwarmingRpcsResultDBCfg: Swarming:ResultDB integration configuration
+// for a task. See NewTaskRequest.resultdb for more details.
+type SwarmingRpcsResultDBCfg struct {
+	Enable bool `json:"enable,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Enable") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Enable") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsResultDBCfg) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsResultDBCfg
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsResultDBInfo: ResultDB related properties.
+type SwarmingRpcsResultDBInfo struct {
+	Hostname string `json:"hostname,omitempty"`
+
+	Invocation string `json:"invocation,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Hostname") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Hostname") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsResultDBInfo) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsResultDBInfo
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsServerDetails: Reports details about the server.
+type SwarmingRpcsServerDetails struct {
+	BotVersion string `json:"bot_version,omitempty"`
+
+	CasViewerServer string `json:"cas_viewer_server,omitempty"`
+
+	DisplayServerUrlTemplate string `json:"display_server_url_template,omitempty"`
+
+	LuciConfig string `json:"luci_config,omitempty"`
+
+	MachineProviderTemplate string `json:"machine_provider_template,omitempty"`
+
+	ServerVersion string `json:"server_version,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "BotVersion") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "BotVersion") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsServerDetails) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsServerDetails
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsStringListPair: Represents a mapping of string to list of
+// strings.
+type SwarmingRpcsStringListPair struct {
+	Key string `json:"key,omitempty"`
+
+	Value []string `json:"value,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Key") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Key") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsStringListPair) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsStringListPair
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsStringPair: Represents a mapping of string to string.
+type SwarmingRpcsStringPair struct {
+	Key string `json:"key,omitempty"`
+
+	Value string `json:"value,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Key") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Key") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsStringPair) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsStringPair
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskCancelRequest: Request to cancel one task.
+type SwarmingRpcsTaskCancelRequest struct {
+	KillRunning bool `json:"kill_running,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "KillRunning") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "KillRunning") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskCancelRequest) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskCancelRequest
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskList: Wraps a list of TaskResult.
+type SwarmingRpcsTaskList struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	// Items: Representation of the TaskResultSummary or TaskRunResult ndb
+	// model.
+	Items []*SwarmingRpcsTaskResult `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskList) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskList
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskOutput: A task's output as a string.
+type SwarmingRpcsTaskOutput struct {
+	Output string `json:"output,omitempty"`
+
+	// Possible values:
+	//   "BOT_DIED"
+	//   "CANCELED"
+	//   "CLIENT_ERROR"
+	//   "COMPLETED"
+	//   "EXPIRED"
+	//   "INVALID"
+	//   "KILLED"
+	//   "NO_RESOURCE"
+	//   "PENDING"
+	//   "RUNNING"
+	//   "TIMED_OUT"
+	State string `json:"state,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Output") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Output") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskOutput) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskOutput
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskProperties: Important metadata about a particular
+// task.
+type SwarmingRpcsTaskProperties struct {
+	// Caches: Describes a named cache that should be present on the bot. A
+	// CacheEntry in a task specified that the task prefers the cache to be
+	// present on the bot. A symlink to the cache directory is created at
+	// <run_dir>/|path|. If cache is not present on the machine, the
+	// directory is empty. If the tasks makes any changes to the contents of
+	// the cache directory, they are persisted on the machine. If another
+	// task runs on the same machine and requests the same named cache, even
+	// if mapped to a different path, it will see the changes.
+	Caches []*SwarmingRpcsCacheEntry `json:"caches,omitempty"`
+
+	CasInputRoot *SwarmingRpcsCASReference `json:"cas_input_root,omitempty"`
+
+	// CipdInput: Defines CIPD packages to install in task run directory.
+	CipdInput *SwarmingRpcsCipdInput `json:"cipd_input,omitempty"`
+
+	Command []string `json:"command,omitempty"`
+
+	// Containment: See proto/api/swarming.proto for description.
+	Containment *SwarmingRpcsContainment `json:"containment,omitempty"`
+
+	// Dimensions: Represents a mapping of string to string.
+	Dimensions []*SwarmingRpcsStringPair `json:"dimensions,omitempty"`
+
+	// Env: Represents a mapping of string to string.
+	Env []*SwarmingRpcsStringPair `json:"env,omitempty"`
+
+	// EnvPrefixes: Represents a mapping of string to list of strings.
+	EnvPrefixes []*SwarmingRpcsStringListPair `json:"env_prefixes,omitempty"`
+
+	ExecutionTimeoutSecs int64 `json:"execution_timeout_secs,omitempty,string"`
+
+	GracePeriodSecs int64 `json:"grace_period_secs,omitempty,string"`
+
+	Idempotent bool `json:"idempotent,omitempty"`
+
+	IoTimeoutSecs int64 `json:"io_timeout_secs,omitempty,string"`
+
+	Outputs []string `json:"outputs,omitempty"`
+
+	RelativeCwd string `json:"relative_cwd,omitempty"`
+
+	SecretBytes string `json:"secret_bytes,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Caches") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Caches") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskProperties) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskProperties
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsTaskQueue struct {
+	Dimensions []string `json:"dimensions,omitempty"`
+
+	ValidUntilTs string `json:"valid_until_ts,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Dimensions") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Dimensions") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskQueue) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskQueue
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+type SwarmingRpcsTaskQueueList struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	Items []*SwarmingRpcsTaskQueue `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskQueueList) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskQueueList
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskRequest: Description of a task request as registered
+// by the server. This message is used when retrieving information about
+// an existing task. See NewTaskRequest for more details.
+type SwarmingRpcsTaskRequest struct {
+	Authenticated string `json:"authenticated,omitempty"`
+
+	BotPingToleranceSecs int64 `json:"bot_ping_tolerance_secs,omitempty,string"`
+
+	CreatedTs string `json:"created_ts,omitempty"`
+
+	ExpirationSecs int64 `json:"expiration_secs,omitempty,string"`
+
+	Name string `json:"name,omitempty"`
+
+	ParentTaskId string `json:"parent_task_id,omitempty"`
+
+	Priority int64 `json:"priority,omitempty,string"`
+
+	// Properties: Important metadata about a particular task.
+	Properties *SwarmingRpcsTaskProperties `json:"properties,omitempty"`
+
+	PubsubTopic string `json:"pubsub_topic,omitempty"`
+
+	PubsubUserdata string `json:"pubsub_userdata,omitempty"`
+
+	RbeInstance string `json:"rbe_instance,omitempty"`
+
+	Realm string `json:"realm,omitempty"`
+
+	// Resultdb: Swarming:ResultDB integration configuration for a task. See
+	// NewTaskRequest.resultdb for more details.
+	Resultdb *SwarmingRpcsResultDBCfg `json:"resultdb,omitempty"`
+
+	ServiceAccount string `json:"service_account,omitempty"`
+
+	Tags []string `json:"tags,omitempty"`
+
+	TaskId string `json:"task_id,omitempty"`
+
+	// TaskSlices: Defines a possible task execution for a task request to
+	// be run on the Swarming infrastructure. This is one of the possible
+	// fallback on a task request.
+	TaskSlices []*SwarmingRpcsTaskSlice `json:"task_slices,omitempty"`
+
+	User string `json:"user,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Authenticated") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Authenticated") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskRequest) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskRequest
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskRequestMetadata: Provides the ID of the requested
+// TaskRequest.
+type SwarmingRpcsTaskRequestMetadata struct {
+	// Request: Description of a task request as registered by the server.
+	// This message is used when retrieving information about an existing
+	// task. See NewTaskRequest for more details.
+	Request *SwarmingRpcsTaskRequest `json:"request,omitempty"`
+
+	TaskId string `json:"task_id,omitempty"`
+
+	// TaskResult: Representation of the TaskResultSummary or TaskRunResult
+	// ndb model.
+	TaskResult *SwarmingRpcsTaskResult `json:"task_result,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Request") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Request") to include in
+	// API requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskRequestMetadata) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskRequestMetadata
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskRequests: Wraps a list of TaskRequest.
+type SwarmingRpcsTaskRequests struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	// Items: Description of a task request as registered by the server.
+	// This message is used when retrieving information about an existing
+	// task. See NewTaskRequest for more details.
+	Items []*SwarmingRpcsTaskRequest `json:"items,omitempty"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskRequests) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskRequests
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskResult: Representation of the TaskResultSummary or
+// TaskRunResult ndb model.
+type SwarmingRpcsTaskResult struct {
+	AbandonedTs string `json:"abandoned_ts,omitempty"`
+
+	// BotDimensions: Represents a mapping of string to list of strings.
+	BotDimensions []*SwarmingRpcsStringListPair `json:"bot_dimensions,omitempty"`
+
+	BotId string `json:"bot_id,omitempty"`
+
+	BotIdleSinceTs string `json:"bot_idle_since_ts,omitempty"`
+
+	BotLogsCloudProject string `json:"bot_logs_cloud_project,omitempty"`
+
+	BotVersion string `json:"bot_version,omitempty"`
+
+	CasOutputRoot *SwarmingRpcsCASReference `json:"cas_output_root,omitempty"`
+
+	ChildrenTaskIds []string `json:"children_task_ids,omitempty"`
+
+	// CipdPins: Defines pinned CIPD packages that were installed during the
+	// task.
+	CipdPins *SwarmingRpcsCipdPins `json:"cipd_pins,omitempty"`
+
+	CompletedTs string `json:"completed_ts,omitempty"`
+
+	CostSavedUsd float64 `json:"cost_saved_usd,omitempty"`
+
+	CostsUsd []float64 `json:"costs_usd,omitempty"`
+
+	CreatedTs string `json:"created_ts,omitempty"`
+
+	CurrentTaskSlice int64 `json:"current_task_slice,omitempty,string"`
+
+	DedupedFrom string `json:"deduped_from,omitempty"`
+
+	Duration float64 `json:"duration,omitempty"`
+
+	ExitCode int64 `json:"exit_code,omitempty,string"`
+
+	Failure bool `json:"failure,omitempty"`
+
+	InternalFailure bool `json:"internal_failure,omitempty"`
+
+	MissingCas []*SwarmingRpcsCASReference `json:"missing_cas,omitempty"`
+
+	// MissingCipd: A CIPD package to install in the run dir before task
+	// execution.
+	MissingCipd []*SwarmingRpcsCipdPackage `json:"missing_cipd,omitempty"`
+
+	ModifiedTs string `json:"modified_ts,omitempty"`
+
+	Name string `json:"name,omitempty"`
+
+	// PerformanceStats: Performance stats of task execution. See
+	// task_result.PerformanceStats for details.
+	PerformanceStats *SwarmingRpcsPerformanceStats `json:"performance_stats,omitempty"`
+
+	// ResultdbInfo: ResultDB related properties.
+	ResultdbInfo *SwarmingRpcsResultDBInfo `json:"resultdb_info,omitempty"`
+
+	RunId string `json:"run_id,omitempty"`
+
+	ServerVersions []string `json:"server_versions,omitempty"`
+
+	StartedTs string `json:"started_ts,omitempty"`
+
+	// Possible values:
+	//   "BOT_DIED"
+	//   "CANCELED"
+	//   "CLIENT_ERROR"
+	//   "COMPLETED"
+	//   "EXPIRED"
+	//   "INVALID"
+	//   "KILLED"
+	//   "NO_RESOURCE"
+	//   "PENDING"
+	//   "RUNNING"
+	//   "TIMED_OUT"
+	State string `json:"state,omitempty"`
+
+	Tags []string `json:"tags,omitempty"`
+
+	TaskId string `json:"task_id,omitempty"`
+
+	User string `json:"user,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "AbandonedTs") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "AbandonedTs") to include
+	// in API requests with the JSON null value. By default, fields with
+	// empty values are omitted from API requests. However, any field with
+	// an empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskResult) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskResult
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+func (s *SwarmingRpcsTaskResult) UnmarshalJSON(data []byte) error {
+	type NoMethod SwarmingRpcsTaskResult
+	var s1 struct {
+		CostSavedUsd gensupport.JSONFloat64 `json:"cost_saved_usd"`
+		Duration     gensupport.JSONFloat64 `json:"duration"`
+		*NoMethod
+	}
+	s1.NoMethod = (*NoMethod)(s)
+	if err := json.Unmarshal(data, &s1); err != nil {
+		return err
+	}
+	s.CostSavedUsd = float64(s1.CostSavedUsd)
+	s.Duration = float64(s1.Duration)
+	return nil
+}
+
+// SwarmingRpcsTaskSlice: Defines a possible task execution for a task
+// request to be run on the Swarming infrastructure. This is one of the
+// possible fallback on a task request.
+type SwarmingRpcsTaskSlice struct {
+	ExpirationSecs int64 `json:"expiration_secs,omitempty,string"`
+
+	// Properties: Important metadata about a particular task.
+	Properties *SwarmingRpcsTaskProperties `json:"properties,omitempty"`
+
+	WaitForCapacity bool `json:"wait_for_capacity,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "ExpirationSecs") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "ExpirationSecs") to
+	// include in API requests with the JSON null value. By default, fields
+	// with empty values are omitted from API requests. However, any field
+	// with an empty value appearing in NullFields will be sent to the
+	// server as null. It is an error if a field in this list has a
+	// non-empty value. This may be used to include null fields in Patch
+	// requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskSlice) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskSlice
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTaskStates: Only holds states. Used in the 'get_states'
+// RPC.
+type SwarmingRpcsTaskStates struct {
+	// Possible values:
+	//   "BOT_DIED"
+	//   "CANCELED"
+	//   "CLIENT_ERROR"
+	//   "COMPLETED"
+	//   "EXPIRED"
+	//   "INVALID"
+	//   "KILLED"
+	//   "NO_RESOURCE"
+	//   "PENDING"
+	//   "RUNNING"
+	//   "TIMED_OUT"
+	States []string `json:"states,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "States") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "States") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTaskStates) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTaskStates
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTasksCancelRequest: Request to cancel some subset of
+// pending/running tasks.
+type SwarmingRpcsTasksCancelRequest struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	End float64 `json:"end,omitempty"`
+
+	KillRunning bool `json:"kill_running,omitempty"`
+
+	// Default: 100
+	Limit *int64 `json:"limit,omitempty,string"`
+
+	Start float64 `json:"start,omitempty"`
+
+	Tags []string `json:"tags,omitempty"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTasksCancelRequest) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTasksCancelRequest
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+func (s *SwarmingRpcsTasksCancelRequest) UnmarshalJSON(data []byte) error {
+	type NoMethod SwarmingRpcsTasksCancelRequest
+	var s1 struct {
+		End   gensupport.JSONFloat64 `json:"end"`
+		Start gensupport.JSONFloat64 `json:"start"`
+		*NoMethod
+	}
+	s1.NoMethod = (*NoMethod)(s)
+	if err := json.Unmarshal(data, &s1); err != nil {
+		return err
+	}
+	s.End = float64(s1.End)
+	s.Start = float64(s1.Start)
+	return nil
+}
+
+// SwarmingRpcsTasksCancelResponse: Result of canceling some subset of
+// pending tasks.
+type SwarmingRpcsTasksCancelResponse struct {
+	Cursor string `json:"cursor,omitempty"`
+
+	Matched int64 `json:"matched,omitempty,string"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Cursor") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Cursor") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTasksCancelResponse) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTasksCancelResponse
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTasksCount: Returns the count, as requested.
+type SwarmingRpcsTasksCount struct {
+	Count int64 `json:"count,omitempty,string"`
+
+	Now string `json:"now,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "Count") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "Count") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTasksCount) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTasksCount
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// SwarmingRpcsTerminateResponse: Returns the pseudo taskid to wait for
+// the bot to shut down.
+type SwarmingRpcsTerminateResponse struct {
+	TaskId string `json:"task_id,omitempty"`
+
+	// ServerResponse contains the HTTP response code and headers from the
+	// server.
+	googleapi.ServerResponse `json:"-"`
+
+	// ForceSendFields is a list of field names (e.g. "TaskId") to
+	// unconditionally include in API requests. By default, fields with
+	// empty or default values are omitted from API requests. However, any
+	// non-pointer, non-interface field appearing in ForceSendFields will be
+	// sent to the server regardless of whether the field is empty or not.
+	// This may be used to include empty fields in Patch requests.
+	ForceSendFields []string `json:"-"`
+
+	// NullFields is a list of field names (e.g. "TaskId") to include in API
+	// requests with the JSON null value. By default, fields with empty
+	// values are omitted from API requests. However, any field with an
+	// empty value appearing in NullFields will be sent to the server as
+	// null. It is an error if a field in this list has a non-empty value.
+	// This may be used to include null fields in Patch requests.
+	NullFields []string `json:"-"`
+}
+
+func (s *SwarmingRpcsTerminateResponse) MarshalJSON() ([]byte, error) {
+	type NoMethod SwarmingRpcsTerminateResponse
+	raw := NoMethod(*s)
+	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// method id "swarming.bot.delete":
+
+type BotDeleteCall struct {
+	s          *Service
+	botId      string
+	urlParams_ gensupport.URLParams
+	ctx_       context.Context
+	header_    http.Header
+}
+
+// Delete: Deletes the bot corresponding to a provided bot_id. At that
+// point, the bot will not appears in the list of bots but it is still
+// possible to get information about the bot with its bot id is known,
+// as historical data is not deleted. It is meant to remove from the DB
+// the presence of a bot that was retired, e.g. the VM was shut down
+// already. Use 'terminate' instead of the bot is still alive.
+//
+// - botId: .
+func (r *BotService) Delete(botId string) *BotDeleteCall {
+	c := &BotDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.botId = botId
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotDeleteCall) Fields(s ...googleapi.Field) *BotDeleteCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotDeleteCall) Context(ctx context.Context) *BotDeleteCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotDeleteCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotDeleteCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bot/{bot_id}/delete")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"bot_id": c.botId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bot.delete" call.
+// Exactly one of *SwarmingRpcsDeletedResponse or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsDeletedResponse.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotDeleteCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsDeletedResponse, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsDeletedResponse{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Deletes the bot corresponding to a provided bot_id. At that point, the bot will not appears in the list of bots but it is still possible to get information about the bot with its bot id is known, as historical data is not deleted. It is meant to remove from the DB the presence of a bot that was retired, e.g. the VM was shut down already. Use 'terminate' instead of the bot is still alive.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.bot.delete",
+	//   "parameterOrder": [
+	//     "bot_id"
+	//   ],
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bot/{bot_id}/delete",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsDeletedResponse"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bot.events":
+
+type BotEventsCall struct {
+	s            *Service
+	botId        string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Events: Returns events that happened on a bot.
+//
+// - botId: .
+func (r *BotService) Events(botId string) *BotEventsCall {
+	c := &BotEventsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.botId = botId
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *BotEventsCall) Cursor(cursor string) *BotEventsCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// End sets the optional parameter "end":
+func (c *BotEventsCall) End(end float64) *BotEventsCall {
+	c.urlParams_.Set("end", fmt.Sprint(end))
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *BotEventsCall) Limit(limit int64) *BotEventsCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Start sets the optional parameter "start":
+func (c *BotEventsCall) Start(start float64) *BotEventsCall {
+	c.urlParams_.Set("start", fmt.Sprint(start))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotEventsCall) Fields(s ...googleapi.Field) *BotEventsCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotEventsCall) IfNoneMatch(entityTag string) *BotEventsCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotEventsCall) Context(ctx context.Context) *BotEventsCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotEventsCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotEventsCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bot/{bot_id}/events")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"bot_id": c.botId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bot.events" call.
+// Exactly one of *SwarmingRpcsBotEvents or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotEvents.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotEventsCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotEvents, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotEvents{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns events that happened on a bot.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bot.events",
+	//   "parameterOrder": [
+	//     "bot_id"
+	//   ],
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     },
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "end": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "start": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     }
+	//   },
+	//   "path": "bot/{bot_id}/events",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotEvents"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bot.get":
+
+type BotGetCall struct {
+	s            *Service
+	botId        string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Get: Returns information about a known bot. This includes its state
+// and dimensions, and if it is currently running a task.
+//
+// - botId: .
+func (r *BotService) Get(botId string) *BotGetCall {
+	c := &BotGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.botId = botId
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotGetCall) Fields(s ...googleapi.Field) *BotGetCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotGetCall) IfNoneMatch(entityTag string) *BotGetCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotGetCall) Context(ctx context.Context) *BotGetCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotGetCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotGetCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bot/{bot_id}/get")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"bot_id": c.botId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bot.get" call.
+// Exactly one of *SwarmingRpcsBotInfo or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotInfo.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotGetCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotInfo, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotInfo{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns information about a known bot. This includes its state and dimensions, and if it is currently running a task.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bot.get",
+	//   "parameterOrder": [
+	//     "bot_id"
+	//   ],
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bot/{bot_id}/get",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotInfo"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bot.tasks":
+
+type BotTasksCall struct {
+	s            *Service
+	botId        string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Tasks: Lists a given bot's tasks within the specified date range. In
+// this case, the tasks are effectively TaskRunResult since it's
+// individual task tries sent to this specific bot. It is impossible to
+// search by both tags and bot id. If there's a need, TaskRunResult.tags
+// will be added (via a copy from TaskRequest.tags).
+//
+// - botId: .
+func (r *BotService) Tasks(botId string) *BotTasksCall {
+	c := &BotTasksCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.botId = botId
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *BotTasksCall) Cursor(cursor string) *BotTasksCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// End sets the optional parameter "end":
+func (c *BotTasksCall) End(end float64) *BotTasksCall {
+	c.urlParams_.Set("end", fmt.Sprint(end))
+	return c
+}
+
+// IncludePerformanceStats sets the optional parameter
+// "include_performance_stats":
+func (c *BotTasksCall) IncludePerformanceStats(includePerformanceStats bool) *BotTasksCall {
+	c.urlParams_.Set("include_performance_stats", fmt.Sprint(includePerformanceStats))
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *BotTasksCall) Limit(limit int64) *BotTasksCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Sort sets the optional parameter "sort":
+//
+// Possible values:
+//
+//	"ABANDONED_TS"
+//	"COMPLETED_TS"
+//	"CREATED_TS" (default)
+//	"STARTED_TS"
+func (c *BotTasksCall) Sort(sort string) *BotTasksCall {
+	c.urlParams_.Set("sort", sort)
+	return c
+}
+
+// Start sets the optional parameter "start":
+func (c *BotTasksCall) Start(start float64) *BotTasksCall {
+	c.urlParams_.Set("start", fmt.Sprint(start))
+	return c
+}
+
+// State sets the optional parameter "state":
+//
+// Possible values:
+//
+//	"ALL" (default)
+//	"BOT_DIED"
+//	"CANCELED"
+//	"CLIENT_ERROR"
+//	"COMPLETED"
+//	"COMPLETED_FAILURE"
+//	"COMPLETED_SUCCESS"
+//	"DEDUPED"
+//	"EXPIRED"
+//	"KILLED"
+//	"NO_RESOURCE"
+//	"PENDING"
+//	"PENDING_RUNNING"
+//	"RUNNING"
+//	"TIMED_OUT"
+func (c *BotTasksCall) State(state string) *BotTasksCall {
+	c.urlParams_.Set("state", state)
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotTasksCall) Fields(s ...googleapi.Field) *BotTasksCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotTasksCall) IfNoneMatch(entityTag string) *BotTasksCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotTasksCall) Context(ctx context.Context) *BotTasksCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotTasksCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotTasksCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bot/{bot_id}/tasks")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"bot_id": c.botId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bot.tasks" call.
+// Exactly one of *SwarmingRpcsBotTasks or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotTasks.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotTasksCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotTasks, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotTasks{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Lists a given bot's tasks within the specified date range. In this case, the tasks are effectively TaskRunResult since it's individual task tries sent to this specific bot. It is impossible to search by both tags and bot id. If there's a need, TaskRunResult.tags will be added (via a copy from TaskRequest.tags).",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bot.tasks",
+	//   "parameterOrder": [
+	//     "bot_id"
+	//   ],
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     },
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "end": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "include_performance_stats": {
+	//       "location": "query",
+	//       "type": "boolean"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "sort": {
+	//       "default": "CREATED_TS",
+	//       "enum": [
+	//         "ABANDONED_TS",
+	//         "COMPLETED_TS",
+	//         "CREATED_TS",
+	//         "STARTED_TS"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "start": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "state": {
+	//       "default": "ALL",
+	//       "enum": [
+	//         "ALL",
+	//         "BOT_DIED",
+	//         "CANCELED",
+	//         "CLIENT_ERROR",
+	//         "COMPLETED",
+	//         "COMPLETED_FAILURE",
+	//         "COMPLETED_SUCCESS",
+	//         "DEDUPED",
+	//         "EXPIRED",
+	//         "KILLED",
+	//         "NO_RESOURCE",
+	//         "PENDING",
+	//         "PENDING_RUNNING",
+	//         "RUNNING",
+	//         "TIMED_OUT"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bot/{bot_id}/tasks",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotTasks"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bot.terminate":
+
+type BotTerminateCall struct {
+	s          *Service
+	botId      string
+	urlParams_ gensupport.URLParams
+	ctx_       context.Context
+	header_    http.Header
+}
+
+// Terminate: Asks a bot to terminate itself gracefully. The bot will
+// stay in the DB, use 'delete' to remove it from the DB afterward. This
+// request returns a pseudo-taskid that can be waited for to wait for
+// the bot to turn down. This command is particularly useful when a
+// privileged user needs to safely debug a machine specific issue. The
+// user can trigger a terminate for one of the bot exhibiting the issue,
+// wait for the pseudo-task to run then access the machine with the
+// guarantee that the bot is not running anymore.
+//
+// - botId: .
+func (r *BotService) Terminate(botId string) *BotTerminateCall {
+	c := &BotTerminateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.botId = botId
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotTerminateCall) Fields(s ...googleapi.Field) *BotTerminateCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotTerminateCall) Context(ctx context.Context) *BotTerminateCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotTerminateCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotTerminateCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bot/{bot_id}/terminate")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"bot_id": c.botId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bot.terminate" call.
+// Exactly one of *SwarmingRpcsTerminateResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *SwarmingRpcsTerminateResponse.ServerResponse.Header or (if a
+// response was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotTerminateCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTerminateResponse, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTerminateResponse{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Asks a bot to terminate itself gracefully. The bot will stay in the DB, use 'delete' to remove it from the DB afterward. This request returns a pseudo-taskid that can be waited for to wait for the bot to turn down. This command is particularly useful when a privileged user needs to safely debug a machine specific issue. The user can trigger a terminate for one of the bot exhibiting the issue, wait for the pseudo-task to run then access the machine with the guarantee that the bot is not running anymore.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.bot.terminate",
+	//   "parameterOrder": [
+	//     "bot_id"
+	//   ],
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bot/{bot_id}/terminate",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTerminateResponse"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bots.count":
+
+type BotsCountCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Count: Counts number of bots with given dimensions.
+func (r *BotsService) Count() *BotsCountCall {
+	c := &BotsCountCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Dimensions sets the optional parameter "dimensions":
+func (c *BotsCountCall) Dimensions(dimensions ...string) *BotsCountCall {
+	c.urlParams_.SetMulti("dimensions", append([]string{}, dimensions...))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotsCountCall) Fields(s ...googleapi.Field) *BotsCountCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotsCountCall) IfNoneMatch(entityTag string) *BotsCountCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotsCountCall) Context(ctx context.Context) *BotsCountCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotsCountCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotsCountCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bots/count")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bots.count" call.
+// Exactly one of *SwarmingRpcsBotsCount or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotsCount.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotsCountCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotsCount, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotsCount{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Counts number of bots with given dimensions.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bots.count",
+	//   "parameters": {
+	//     "dimensions": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bots/count",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotsCount"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bots.dimensions":
+
+type BotsDimensionsCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Dimensions: Returns the cached set of dimensions currently in use in
+// the fleet.
+func (r *BotsService) Dimensions() *BotsDimensionsCall {
+	c := &BotsDimensionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Pool sets the optional parameter "pool":
+func (c *BotsDimensionsCall) Pool(pool string) *BotsDimensionsCall {
+	c.urlParams_.Set("pool", pool)
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotsDimensionsCall) Fields(s ...googleapi.Field) *BotsDimensionsCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotsDimensionsCall) IfNoneMatch(entityTag string) *BotsDimensionsCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotsDimensionsCall) Context(ctx context.Context) *BotsDimensionsCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotsDimensionsCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotsDimensionsCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bots/dimensions")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bots.dimensions" call.
+// Exactly one of *SwarmingRpcsBotsDimensions or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotsDimensions.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotsDimensionsCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotsDimensions, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotsDimensions{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns the cached set of dimensions currently in use in the fleet.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bots.dimensions",
+	//   "parameters": {
+	//     "pool": {
+	//       "location": "query",
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bots/dimensions",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotsDimensions"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.bots.list":
+
+type BotsListCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// List: Provides list of known bots. Deleted bots will not be listed.
+func (r *BotsService) List() *BotsListCall {
+	c := &BotsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *BotsListCall) Cursor(cursor string) *BotsListCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// Dimensions sets the optional parameter "dimensions":
+func (c *BotsListCall) Dimensions(dimensions ...string) *BotsListCall {
+	c.urlParams_.SetMulti("dimensions", append([]string{}, dimensions...))
+	return c
+}
+
+// InMaintenance sets the optional parameter "in_maintenance":
+//
+// Possible values:
+//
+//	"FALSE"
+//	"NONE" (default)
+//	"TRUE"
+func (c *BotsListCall) InMaintenance(inMaintenance string) *BotsListCall {
+	c.urlParams_.Set("in_maintenance", inMaintenance)
+	return c
+}
+
+// IsBusy sets the optional parameter "is_busy":
+//
+// Possible values:
+//
+//	"FALSE"
+//	"NONE" (default)
+//	"TRUE"
+func (c *BotsListCall) IsBusy(isBusy string) *BotsListCall {
+	c.urlParams_.Set("is_busy", isBusy)
+	return c
+}
+
+// IsDead sets the optional parameter "is_dead":
+//
+// Possible values:
+//
+//	"FALSE"
+//	"NONE" (default)
+//	"TRUE"
+func (c *BotsListCall) IsDead(isDead string) *BotsListCall {
+	c.urlParams_.Set("is_dead", isDead)
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *BotsListCall) Limit(limit int64) *BotsListCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Quarantined sets the optional parameter "quarantined":
+//
+// Possible values:
+//
+//	"FALSE"
+//	"NONE" (default)
+//	"TRUE"
+func (c *BotsListCall) Quarantined(quarantined string) *BotsListCall {
+	c.urlParams_.Set("quarantined", quarantined)
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *BotsListCall) Fields(s ...googleapi.Field) *BotsListCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *BotsListCall) IfNoneMatch(entityTag string) *BotsListCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *BotsListCall) Context(ctx context.Context) *BotsListCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *BotsListCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *BotsListCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "bots/list")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.bots.list" call.
+// Exactly one of *SwarmingRpcsBotList or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBotList.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *BotsListCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBotList, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBotList{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Provides list of known bots. Deleted bots will not be listed.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.bots.list",
+	//   "parameters": {
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "dimensions": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     },
+	//     "in_maintenance": {
+	//       "default": "NONE",
+	//       "enum": [
+	//         "FALSE",
+	//         "NONE",
+	//         "TRUE"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "is_busy": {
+	//       "default": "NONE",
+	//       "enum": [
+	//         "FALSE",
+	//         "NONE",
+	//         "TRUE"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "is_dead": {
+	//       "default": "NONE",
+	//       "enum": [
+	//         "FALSE",
+	//         "NONE",
+	//         "TRUE"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "quarantined": {
+	//       "default": "NONE",
+	//       "enum": [
+	//         "FALSE",
+	//         "NONE",
+	//         "TRUE"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "bots/list",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBotList"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.queues.list":
+
+type QueuesListCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// List:
+func (r *QueuesService) List() *QueuesListCall {
+	c := &QueuesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *QueuesListCall) Cursor(cursor string) *QueuesListCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *QueuesListCall) Limit(limit int64) *QueuesListCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *QueuesListCall) Fields(s ...googleapi.Field) *QueuesListCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *QueuesListCall) IfNoneMatch(entityTag string) *QueuesListCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *QueuesListCall) Context(ctx context.Context) *QueuesListCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *QueuesListCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *QueuesListCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "queues/list")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.queues.list" call.
+// Exactly one of *SwarmingRpcsTaskQueueList or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskQueueList.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *QueuesListCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskQueueList, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskQueueList{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "httpMethod": "GET",
+	//   "id": "swarming.queues.list",
+	//   "parameters": {
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "queues/list",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskQueueList"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.server.details":
+
+type ServerDetailsCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Details: Returns information about the server.
+func (r *ServerService) Details() *ServerDetailsCall {
+	c := &ServerDetailsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ServerDetailsCall) Fields(s ...googleapi.Field) *ServerDetailsCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ServerDetailsCall) IfNoneMatch(entityTag string) *ServerDetailsCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ServerDetailsCall) Context(ctx context.Context) *ServerDetailsCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ServerDetailsCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *ServerDetailsCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "server/details")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.server.details" call.
+// Exactly one of *SwarmingRpcsServerDetails or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsServerDetails.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ServerDetailsCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsServerDetails, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsServerDetails{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns information about the server.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.server.details",
+	//   "path": "server/details",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsServerDetails"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.server.get_bootstrap":
+
+type ServerGetBootstrapCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// GetBootstrap: Retrieves the current version of bootstrap.py.
+func (r *ServerService) GetBootstrap() *ServerGetBootstrapCall {
+	c := &ServerGetBootstrapCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ServerGetBootstrapCall) Fields(s ...googleapi.Field) *ServerGetBootstrapCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ServerGetBootstrapCall) IfNoneMatch(entityTag string) *ServerGetBootstrapCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ServerGetBootstrapCall) Context(ctx context.Context) *ServerGetBootstrapCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ServerGetBootstrapCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *ServerGetBootstrapCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "server/get_bootstrap")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.server.get_bootstrap" call.
+// Exactly one of *SwarmingRpcsFileContent or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsFileContent.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ServerGetBootstrapCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsFileContent, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsFileContent{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Retrieves the current version of bootstrap.py.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.server.get_bootstrap",
+	//   "path": "server/get_bootstrap",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsFileContent"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.server.get_bot_config":
+
+type ServerGetBotConfigCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// GetBotConfig: Retrieves the current version of bot_config.py.
+func (r *ServerService) GetBotConfig() *ServerGetBotConfigCall {
+	c := &ServerGetBotConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ServerGetBotConfigCall) Fields(s ...googleapi.Field) *ServerGetBotConfigCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ServerGetBotConfigCall) IfNoneMatch(entityTag string) *ServerGetBotConfigCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ServerGetBotConfigCall) Context(ctx context.Context) *ServerGetBotConfigCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ServerGetBotConfigCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *ServerGetBotConfigCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "server/get_bot_config")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.server.get_bot_config" call.
+// Exactly one of *SwarmingRpcsFileContent or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsFileContent.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ServerGetBotConfigCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsFileContent, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsFileContent{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Retrieves the current version of bot_config.py.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.server.get_bot_config",
+	//   "path": "server/get_bot_config",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsFileContent"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.server.permissions":
+
+type ServerPermissionsCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Permissions: Returns the caller's permissions.
+func (r *ServerService) Permissions() *ServerPermissionsCall {
+	c := &ServerPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// BotId sets the optional parameter "bot_id":
+func (c *ServerPermissionsCall) BotId(botId string) *ServerPermissionsCall {
+	c.urlParams_.Set("bot_id", botId)
+	return c
+}
+
+// Tags sets the optional parameter "tags":
+func (c *ServerPermissionsCall) Tags(tags ...string) *ServerPermissionsCall {
+	c.urlParams_.SetMulti("tags", append([]string{}, tags...))
+	return c
+}
+
+// TaskId sets the optional parameter "task_id":
+func (c *ServerPermissionsCall) TaskId(taskId string) *ServerPermissionsCall {
+	c.urlParams_.Set("task_id", taskId)
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ServerPermissionsCall) Fields(s ...googleapi.Field) *ServerPermissionsCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ServerPermissionsCall) IfNoneMatch(entityTag string) *ServerPermissionsCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ServerPermissionsCall) Context(ctx context.Context) *ServerPermissionsCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ServerPermissionsCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *ServerPermissionsCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "server/permissions")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.server.permissions" call.
+// Exactly one of *SwarmingRpcsClientPermissions or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *SwarmingRpcsClientPermissions.ServerResponse.Header or (if a
+// response was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ServerPermissionsCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsClientPermissions, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsClientPermissions{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns the caller's permissions.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.server.permissions",
+	//   "parameters": {
+	//     "bot_id": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "tags": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     },
+	//     "task_id": {
+	//       "location": "query",
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "server/permissions",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsClientPermissions"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.server.token":
+
+type ServerTokenCall struct {
+	s          *Service
+	urlParams_ gensupport.URLParams
+	ctx_       context.Context
+	header_    http.Header
+}
+
+// Token: Returns a token to bootstrap a new bot. This may seem strange
+// to be a POST and not a GET, but it's very important to make sure GET
+// requests are idempotent and safe to be pre-fetched; generating a
+// token is neither of those things.
+func (r *ServerService) Token() *ServerTokenCall {
+	c := &ServerTokenCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ServerTokenCall) Fields(s ...googleapi.Field) *ServerTokenCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ServerTokenCall) Context(ctx context.Context) *ServerTokenCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ServerTokenCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *ServerTokenCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "server/token")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.server.token" call.
+// Exactly one of *SwarmingRpcsBootstrapToken or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsBootstrapToken.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ServerTokenCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsBootstrapToken, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsBootstrapToken{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns a token to bootstrap a new bot. This may seem strange to be a POST and not a GET, but it's very important to make sure GET requests are idempotent and safe to be pre-fetched; generating a token is neither of those things.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.server.token",
+	//   "path": "server/token",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsBootstrapToken"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.task.cancel":
+
+type TaskCancelCall struct {
+	s                             *Service
+	taskId                        string
+	swarmingrpcstaskcancelrequest *SwarmingRpcsTaskCancelRequest
+	urlParams_                    gensupport.URLParams
+	ctx_                          context.Context
+	header_                       http.Header
+}
+
+// Cancel: Cancels a task. If a bot was running the task, the bot will
+// forcibly cancel the task.
+//
+// - taskId: .
+func (r *TaskService) Cancel(taskId string, swarmingrpcstaskcancelrequest *SwarmingRpcsTaskCancelRequest) *TaskCancelCall {
+	c := &TaskCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.taskId = taskId
+	c.swarmingrpcstaskcancelrequest = swarmingrpcstaskcancelrequest
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TaskCancelCall) Fields(s ...googleapi.Field) *TaskCancelCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TaskCancelCall) Context(ctx context.Context) *TaskCancelCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TaskCancelCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TaskCancelCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	body, err := googleapi.WithoutDataWrapper.JSONReader(c.swarmingrpcstaskcancelrequest)
+	if err != nil {
+		return nil, err
+	}
+	reqHeaders.Set("Content-Type", "application/json")
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "task/{task_id}/cancel")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"task_id": c.taskId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.task.cancel" call.
+// Exactly one of *SwarmingRpcsCancelResponse or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsCancelResponse.ServerResponse.Header or (if a response
+// was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TaskCancelCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsCancelResponse, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsCancelResponse{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Cancels a task. If a bot was running the task, the bot will forcibly cancel the task.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.task.cancel",
+	//   "parameterOrder": [
+	//     "task_id"
+	//   ],
+	//   "parameters": {
+	//     "task_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "task/{task_id}/cancel",
+	//   "request": {
+	//     "$ref": "SwarmingRpcsTaskCancelRequest",
+	//     "parameterName": "resource"
+	//   },
+	//   "response": {
+	//     "$ref": "SwarmingRpcsCancelResponse"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.task.request":
+
+type TaskRequestCall struct {
+	s            *Service
+	taskId       string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Request: Returns the task request corresponding to a task ID.
+//
+// - taskId: .
+func (r *TaskService) Request(taskId string) *TaskRequestCall {
+	c := &TaskRequestCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.taskId = taskId
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TaskRequestCall) Fields(s ...googleapi.Field) *TaskRequestCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TaskRequestCall) IfNoneMatch(entityTag string) *TaskRequestCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TaskRequestCall) Context(ctx context.Context) *TaskRequestCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TaskRequestCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TaskRequestCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "task/{task_id}/request")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"task_id": c.taskId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.task.request" call.
+// Exactly one of *SwarmingRpcsTaskRequest or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskRequest.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TaskRequestCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskRequest, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskRequest{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns the task request corresponding to a task ID.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.task.request",
+	//   "parameterOrder": [
+	//     "task_id"
+	//   ],
+	//   "parameters": {
+	//     "task_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "task/{task_id}/request",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskRequest"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.task.result":
+
+type TaskResultCall struct {
+	s            *Service
+	taskId       string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Result: Reports the result of the task corresponding to a task ID. It
+// can be a 'run' ID specifying a specific retry or a 'summary' ID
+// hidding the fact that a task may have been retried transparently,
+// when a bot reports BOT_DIED. A summary ID ends with '0', a run ID
+// ends with '1' or '2'.
+//
+// - taskId: .
+func (r *TaskService) Result(taskId string) *TaskResultCall {
+	c := &TaskResultCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.taskId = taskId
+	return c
+}
+
+// IncludePerformanceStats sets the optional parameter
+// "include_performance_stats":
+func (c *TaskResultCall) IncludePerformanceStats(includePerformanceStats bool) *TaskResultCall {
+	c.urlParams_.Set("include_performance_stats", fmt.Sprint(includePerformanceStats))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TaskResultCall) Fields(s ...googleapi.Field) *TaskResultCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TaskResultCall) IfNoneMatch(entityTag string) *TaskResultCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TaskResultCall) Context(ctx context.Context) *TaskResultCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TaskResultCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TaskResultCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "task/{task_id}/result")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"task_id": c.taskId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.task.result" call.
+// Exactly one of *SwarmingRpcsTaskResult or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskResult.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TaskResultCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskResult, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskResult{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Reports the result of the task corresponding to a task ID. It can be a 'run' ID specifying a specific retry or a 'summary' ID hidding the fact that a task may have been retried transparently, when a bot reports BOT_DIED. A summary ID ends with '0', a run ID ends with '1' or '2'.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.task.result",
+	//   "parameterOrder": [
+	//     "task_id"
+	//   ],
+	//   "parameters": {
+	//     "include_performance_stats": {
+	//       "location": "query",
+	//       "type": "boolean"
+	//     },
+	//     "task_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "task/{task_id}/result",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskResult"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.task.stdout":
+
+type TaskStdoutCall struct {
+	s            *Service
+	taskId       string
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Stdout: Returns the output of the task corresponding to a task ID.
+//
+// - taskId: .
+func (r *TaskService) Stdout(taskId string) *TaskStdoutCall {
+	c := &TaskStdoutCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.taskId = taskId
+	return c
+}
+
+// Length sets the optional parameter "length":
+func (c *TaskStdoutCall) Length(length int64) *TaskStdoutCall {
+	c.urlParams_.Set("length", fmt.Sprint(length))
+	return c
+}
+
+// Offset sets the optional parameter "offset":
+func (c *TaskStdoutCall) Offset(offset int64) *TaskStdoutCall {
+	c.urlParams_.Set("offset", fmt.Sprint(offset))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TaskStdoutCall) Fields(s ...googleapi.Field) *TaskStdoutCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TaskStdoutCall) IfNoneMatch(entityTag string) *TaskStdoutCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TaskStdoutCall) Context(ctx context.Context) *TaskStdoutCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TaskStdoutCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TaskStdoutCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "task/{task_id}/stdout")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	googleapi.Expand(req.URL, map[string]string{
+		"task_id": c.taskId,
+	})
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.task.stdout" call.
+// Exactly one of *SwarmingRpcsTaskOutput or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskOutput.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TaskStdoutCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskOutput, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskOutput{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns the output of the task corresponding to a task ID.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.task.stdout",
+	//   "parameterOrder": [
+	//     "task_id"
+	//   ],
+	//   "parameters": {
+	//     "length": {
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "offset": {
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "task_id": {
+	//       "location": "path",
+	//       "required": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "task/{task_id}/stdout",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskOutput"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.cancel":
+
+type TasksCancelCall struct {
+	s                              *Service
+	swarmingrpcstaskscancelrequest *SwarmingRpcsTasksCancelRequest
+	urlParams_                     gensupport.URLParams
+	ctx_                           context.Context
+	header_                        http.Header
+}
+
+// Cancel: Cancel a subset of pending tasks based on the tags.
+// Cancellation happens asynchronously, so when this call returns,
+// cancellations will not have completed yet.
+func (r *TasksService) Cancel(swarmingrpcstaskscancelrequest *SwarmingRpcsTasksCancelRequest) *TasksCancelCall {
+	c := &TasksCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.swarmingrpcstaskscancelrequest = swarmingrpcstaskscancelrequest
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksCancelCall) Fields(s ...googleapi.Field) *TasksCancelCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksCancelCall) Context(ctx context.Context) *TasksCancelCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksCancelCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksCancelCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	body, err := googleapi.WithoutDataWrapper.JSONReader(c.swarmingrpcstaskscancelrequest)
+	if err != nil {
+		return nil, err
+	}
+	reqHeaders.Set("Content-Type", "application/json")
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/cancel")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.cancel" call.
+// Exactly one of *SwarmingRpcsTasksCancelResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *SwarmingRpcsTasksCancelResponse.ServerResponse.Header or (if
+// a response was returned at all) in error.(*googleapi.Error).Header.
+// Use googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksCancelCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTasksCancelResponse, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTasksCancelResponse{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Cancel a subset of pending tasks based on the tags. Cancellation happens asynchronously, so when this call returns, cancellations will not have completed yet.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.tasks.cancel",
+	//   "path": "tasks/cancel",
+	//   "request": {
+	//     "$ref": "SwarmingRpcsTasksCancelRequest",
+	//     "parameterName": "resource"
+	//   },
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTasksCancelResponse"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.count":
+
+type TasksCountCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Count: Counts number of tasks in a given state.
+func (r *TasksService) Count() *TasksCountCall {
+	c := &TasksCountCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// End sets the optional parameter "end":
+func (c *TasksCountCall) End(end float64) *TasksCountCall {
+	c.urlParams_.Set("end", fmt.Sprint(end))
+	return c
+}
+
+// Start sets the optional parameter "start":
+func (c *TasksCountCall) Start(start float64) *TasksCountCall {
+	c.urlParams_.Set("start", fmt.Sprint(start))
+	return c
+}
+
+// State sets the optional parameter "state":
+//
+// Possible values:
+//
+//	"ALL" (default)
+//	"BOT_DIED"
+//	"CANCELED"
+//	"CLIENT_ERROR"
+//	"COMPLETED"
+//	"COMPLETED_FAILURE"
+//	"COMPLETED_SUCCESS"
+//	"DEDUPED"
+//	"EXPIRED"
+//	"KILLED"
+//	"NO_RESOURCE"
+//	"PENDING"
+//	"PENDING_RUNNING"
+//	"RUNNING"
+//	"TIMED_OUT"
+func (c *TasksCountCall) State(state string) *TasksCountCall {
+	c.urlParams_.Set("state", state)
+	return c
+}
+
+// Tags sets the optional parameter "tags":
+func (c *TasksCountCall) Tags(tags ...string) *TasksCountCall {
+	c.urlParams_.SetMulti("tags", append([]string{}, tags...))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksCountCall) Fields(s ...googleapi.Field) *TasksCountCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TasksCountCall) IfNoneMatch(entityTag string) *TasksCountCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksCountCall) Context(ctx context.Context) *TasksCountCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksCountCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksCountCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/count")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.count" call.
+// Exactly one of *SwarmingRpcsTasksCount or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTasksCount.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksCountCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTasksCount, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTasksCount{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Counts number of tasks in a given state.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.tasks.count",
+	//   "parameters": {
+	//     "end": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "start": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "state": {
+	//       "default": "ALL",
+	//       "enum": [
+	//         "ALL",
+	//         "BOT_DIED",
+	//         "CANCELED",
+	//         "CLIENT_ERROR",
+	//         "COMPLETED",
+	//         "COMPLETED_FAILURE",
+	//         "COMPLETED_SUCCESS",
+	//         "DEDUPED",
+	//         "EXPIRED",
+	//         "KILLED",
+	//         "NO_RESOURCE",
+	//         "PENDING",
+	//         "PENDING_RUNNING",
+	//         "RUNNING",
+	//         "TIMED_OUT"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "tags": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "tasks/count",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTasksCount"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.get_states":
+
+type TasksGetStatesCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// GetStates: Returns task state for a specific set of tasks.
+func (r *TasksService) GetStates() *TasksGetStatesCall {
+	c := &TasksGetStatesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// TaskId sets the optional parameter "task_id":
+func (c *TasksGetStatesCall) TaskId(taskId ...string) *TasksGetStatesCall {
+	c.urlParams_.SetMulti("task_id", append([]string{}, taskId...))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksGetStatesCall) Fields(s ...googleapi.Field) *TasksGetStatesCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TasksGetStatesCall) IfNoneMatch(entityTag string) *TasksGetStatesCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksGetStatesCall) Context(ctx context.Context) *TasksGetStatesCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksGetStatesCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksGetStatesCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/get_states")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.get_states" call.
+// Exactly one of *SwarmingRpcsTaskStates or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskStates.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksGetStatesCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskStates, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskStates{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns task state for a specific set of tasks.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.tasks.get_states",
+	//   "parameters": {
+	//     "task_id": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "tasks/get_states",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskStates"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.list":
+
+type TasksListCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// List: Returns full task results based on the filters. This endpoint
+// is significantly slower than 'count'. Use 'count' when possible. If
+// you just want the state of tasks, use 'get_states'.
+func (r *TasksService) List() *TasksListCall {
+	c := &TasksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *TasksListCall) Cursor(cursor string) *TasksListCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// End sets the optional parameter "end":
+func (c *TasksListCall) End(end float64) *TasksListCall {
+	c.urlParams_.Set("end", fmt.Sprint(end))
+	return c
+}
+
+// IncludePerformanceStats sets the optional parameter
+// "include_performance_stats":
+func (c *TasksListCall) IncludePerformanceStats(includePerformanceStats bool) *TasksListCall {
+	c.urlParams_.Set("include_performance_stats", fmt.Sprint(includePerformanceStats))
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *TasksListCall) Limit(limit int64) *TasksListCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Sort sets the optional parameter "sort":
+//
+// Possible values:
+//
+//	"ABANDONED_TS"
+//	"COMPLETED_TS"
+//	"CREATED_TS" (default)
+//	"STARTED_TS"
+func (c *TasksListCall) Sort(sort string) *TasksListCall {
+	c.urlParams_.Set("sort", sort)
+	return c
+}
+
+// Start sets the optional parameter "start":
+func (c *TasksListCall) Start(start float64) *TasksListCall {
+	c.urlParams_.Set("start", fmt.Sprint(start))
+	return c
+}
+
+// State sets the optional parameter "state":
+//
+// Possible values:
+//
+//	"ALL" (default)
+//	"BOT_DIED"
+//	"CANCELED"
+//	"CLIENT_ERROR"
+//	"COMPLETED"
+//	"COMPLETED_FAILURE"
+//	"COMPLETED_SUCCESS"
+//	"DEDUPED"
+//	"EXPIRED"
+//	"KILLED"
+//	"NO_RESOURCE"
+//	"PENDING"
+//	"PENDING_RUNNING"
+//	"RUNNING"
+//	"TIMED_OUT"
+func (c *TasksListCall) State(state string) *TasksListCall {
+	c.urlParams_.Set("state", state)
+	return c
+}
+
+// Tags sets the optional parameter "tags":
+func (c *TasksListCall) Tags(tags ...string) *TasksListCall {
+	c.urlParams_.SetMulti("tags", append([]string{}, tags...))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksListCall) Fields(s ...googleapi.Field) *TasksListCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TasksListCall) IfNoneMatch(entityTag string) *TasksListCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksListCall) Context(ctx context.Context) *TasksListCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksListCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksListCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/list")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.list" call.
+// Exactly one of *SwarmingRpcsTaskList or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskList.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksListCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskList, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskList{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns full task results based on the filters. This endpoint is significantly slower than 'count'. Use 'count' when possible. If you just want the state of tasks, use 'get_states'.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.tasks.list",
+	//   "parameters": {
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "end": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "include_performance_stats": {
+	//       "location": "query",
+	//       "type": "boolean"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "sort": {
+	//       "default": "CREATED_TS",
+	//       "enum": [
+	//         "ABANDONED_TS",
+	//         "COMPLETED_TS",
+	//         "CREATED_TS",
+	//         "STARTED_TS"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "start": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "state": {
+	//       "default": "ALL",
+	//       "enum": [
+	//         "ALL",
+	//         "BOT_DIED",
+	//         "CANCELED",
+	//         "CLIENT_ERROR",
+	//         "COMPLETED",
+	//         "COMPLETED_FAILURE",
+	//         "COMPLETED_SUCCESS",
+	//         "DEDUPED",
+	//         "EXPIRED",
+	//         "KILLED",
+	//         "NO_RESOURCE",
+	//         "PENDING",
+	//         "PENDING_RUNNING",
+	//         "RUNNING",
+	//         "TIMED_OUT"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "tags": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "tasks/list",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskList"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.new":
+
+type TasksNewCall struct {
+	s                          *Service
+	swarmingrpcsnewtaskrequest *SwarmingRpcsNewTaskRequest
+	urlParams_                 gensupport.URLParams
+	ctx_                       context.Context
+	header_                    http.Header
+}
+
+// New: Creates a new task. The task will be enqueued in the tasks list
+// and will be executed at the earliest opportunity by a bot that has at
+// least the dimensions as described in the task request.
+func (r *TasksService) New(swarmingrpcsnewtaskrequest *SwarmingRpcsNewTaskRequest) *TasksNewCall {
+	c := &TasksNewCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	c.swarmingrpcsnewtaskrequest = swarmingrpcsnewtaskrequest
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksNewCall) Fields(s ...googleapi.Field) *TasksNewCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksNewCall) Context(ctx context.Context) *TasksNewCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksNewCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksNewCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	var body io.Reader = nil
+	body, err := googleapi.WithoutDataWrapper.JSONReader(c.swarmingrpcsnewtaskrequest)
+	if err != nil {
+		return nil, err
+	}
+	reqHeaders.Set("Content-Type", "application/json")
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/new")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("POST", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.new" call.
+// Exactly one of *SwarmingRpcsTaskRequestMetadata or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *SwarmingRpcsTaskRequestMetadata.ServerResponse.Header or (if
+// a response was returned at all) in error.(*googleapi.Error).Header.
+// Use googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksNewCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskRequestMetadata, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskRequestMetadata{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Creates a new task. The task will be enqueued in the tasks list and will be executed at the earliest opportunity by a bot that has at least the dimensions as described in the task request.",
+	//   "httpMethod": "POST",
+	//   "id": "swarming.tasks.new",
+	//   "path": "tasks/new",
+	//   "request": {
+	//     "$ref": "SwarmingRpcsNewTaskRequest",
+	//     "parameterName": "resource"
+	//   },
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskRequestMetadata"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
+
+// method id "swarming.tasks.requests":
+
+type TasksRequestsCall struct {
+	s            *Service
+	urlParams_   gensupport.URLParams
+	ifNoneMatch_ string
+	ctx_         context.Context
+	header_      http.Header
+}
+
+// Requests: Returns tasks requests based on the filters. This endpoint
+// is slightly slower than 'list'. Use 'list' or 'count' when possible.
+func (r *TasksService) Requests() *TasksRequestsCall {
+	c := &TasksRequestsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+	return c
+}
+
+// Cursor sets the optional parameter "cursor":
+func (c *TasksRequestsCall) Cursor(cursor string) *TasksRequestsCall {
+	c.urlParams_.Set("cursor", cursor)
+	return c
+}
+
+// End sets the optional parameter "end":
+func (c *TasksRequestsCall) End(end float64) *TasksRequestsCall {
+	c.urlParams_.Set("end", fmt.Sprint(end))
+	return c
+}
+
+// IncludePerformanceStats sets the optional parameter
+// "include_performance_stats":
+func (c *TasksRequestsCall) IncludePerformanceStats(includePerformanceStats bool) *TasksRequestsCall {
+	c.urlParams_.Set("include_performance_stats", fmt.Sprint(includePerformanceStats))
+	return c
+}
+
+// Limit sets the optional parameter "limit":
+func (c *TasksRequestsCall) Limit(limit int64) *TasksRequestsCall {
+	c.urlParams_.Set("limit", fmt.Sprint(limit))
+	return c
+}
+
+// Sort sets the optional parameter "sort":
+//
+// Possible values:
+//
+//	"ABANDONED_TS"
+//	"COMPLETED_TS"
+//	"CREATED_TS" (default)
+//	"STARTED_TS"
+func (c *TasksRequestsCall) Sort(sort string) *TasksRequestsCall {
+	c.urlParams_.Set("sort", sort)
+	return c
+}
+
+// Start sets the optional parameter "start":
+func (c *TasksRequestsCall) Start(start float64) *TasksRequestsCall {
+	c.urlParams_.Set("start", fmt.Sprint(start))
+	return c
+}
+
+// State sets the optional parameter "state":
+//
+// Possible values:
+//
+//	"ALL" (default)
+//	"BOT_DIED"
+//	"CANCELED"
+//	"CLIENT_ERROR"
+//	"COMPLETED"
+//	"COMPLETED_FAILURE"
+//	"COMPLETED_SUCCESS"
+//	"DEDUPED"
+//	"EXPIRED"
+//	"KILLED"
+//	"NO_RESOURCE"
+//	"PENDING"
+//	"PENDING_RUNNING"
+//	"RUNNING"
+//	"TIMED_OUT"
+func (c *TasksRequestsCall) State(state string) *TasksRequestsCall {
+	c.urlParams_.Set("state", state)
+	return c
+}
+
+// Tags sets the optional parameter "tags":
+func (c *TasksRequestsCall) Tags(tags ...string) *TasksRequestsCall {
+	c.urlParams_.SetMulti("tags", append([]string{}, tags...))
+	return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *TasksRequestsCall) Fields(s ...googleapi.Field) *TasksRequestsCall {
+	c.urlParams_.Set("fields", googleapi.CombineFields(s))
+	return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *TasksRequestsCall) IfNoneMatch(entityTag string) *TasksRequestsCall {
+	c.ifNoneMatch_ = entityTag
+	return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *TasksRequestsCall) Context(ctx context.Context) *TasksRequestsCall {
+	c.ctx_ = ctx
+	return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *TasksRequestsCall) Header() http.Header {
+	if c.header_ == nil {
+		c.header_ = make(http.Header)
+	}
+	return c.header_
+}
+
+func (c *TasksRequestsCall) doRequest(alt string) (*http.Response, error) {
+	reqHeaders := make(http.Header)
+	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+"luci-go")
+	for k, v := range c.header_ {
+		reqHeaders[k] = v
+	}
+	reqHeaders.Set("User-Agent", c.s.userAgent())
+	if c.ifNoneMatch_ != "" {
+		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+	}
+	var body io.Reader = nil
+	c.urlParams_.Set("alt", alt)
+	c.urlParams_.Set("prettyPrint", "false")
+	urls := googleapi.ResolveRelative(c.s.BasePath, "tasks/requests")
+	urls += "?" + c.urlParams_.Encode()
+	req, err := http.NewRequest("GET", urls, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header = reqHeaders
+	return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "swarming.tasks.requests" call.
+// Exactly one of *SwarmingRpcsTaskRequests or error will be non-nil.
+// Any non-2xx status code is an error. Response headers are in either
+// *SwarmingRpcsTaskRequests.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *TasksRequestsCall) Do(opts ...googleapi.CallOption) (*SwarmingRpcsTaskRequests, error) {
+	gensupport.SetOptions(c.urlParams_, opts...)
+	res, err := c.doRequest("json")
+	if res != nil && res.StatusCode == http.StatusNotModified {
+		if res.Body != nil {
+			res.Body.Close()
+		}
+		return nil, gensupport.WrapError(&googleapi.Error{
+			Code:   res.StatusCode,
+			Header: res.Header,
+		})
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer googleapi.CloseBody(res)
+	if err := googleapi.CheckResponse(res); err != nil {
+		return nil, gensupport.WrapError(err)
+	}
+	ret := &SwarmingRpcsTaskRequests{
+		ServerResponse: googleapi.ServerResponse{
+			Header:         res.Header,
+			HTTPStatusCode: res.StatusCode,
+		},
+	}
+	target := &ret
+	if err := gensupport.DecodeResponse(target, res); err != nil {
+		return nil, err
+	}
+	return ret, nil
+	// {
+	//   "description": "Returns tasks requests based on the filters. This endpoint is slightly slower than 'list'. Use 'list' or 'count' when possible.",
+	//   "httpMethod": "GET",
+	//   "id": "swarming.tasks.requests",
+	//   "parameters": {
+	//     "cursor": {
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "end": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "include_performance_stats": {
+	//       "location": "query",
+	//       "type": "boolean"
+	//     },
+	//     "limit": {
+	//       "default": "200",
+	//       "format": "int64",
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "sort": {
+	//       "default": "CREATED_TS",
+	//       "enum": [
+	//         "ABANDONED_TS",
+	//         "COMPLETED_TS",
+	//         "CREATED_TS",
+	//         "STARTED_TS"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "start": {
+	//       "format": "double",
+	//       "location": "query",
+	//       "type": "number"
+	//     },
+	//     "state": {
+	//       "default": "ALL",
+	//       "enum": [
+	//         "ALL",
+	//         "BOT_DIED",
+	//         "CANCELED",
+	//         "CLIENT_ERROR",
+	//         "COMPLETED",
+	//         "COMPLETED_FAILURE",
+	//         "COMPLETED_SUCCESS",
+	//         "DEDUPED",
+	//         "EXPIRED",
+	//         "KILLED",
+	//         "NO_RESOURCE",
+	//         "PENDING",
+	//         "PENDING_RUNNING",
+	//         "RUNNING",
+	//         "TIMED_OUT"
+	//       ],
+	//       "enumDescriptions": [
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         "",
+	//         ""
+	//       ],
+	//       "location": "query",
+	//       "type": "string"
+	//     },
+	//     "tags": {
+	//       "location": "query",
+	//       "repeated": true,
+	//       "type": "string"
+	//     }
+	//   },
+	//   "path": "tasks/requests",
+	//   "response": {
+	//     "$ref": "SwarmingRpcsTaskRequests"
+	//   },
+	//   "scopes": [
+	//     "https://www.googleapis.com/auth/userinfo.email"
+	//   ]
+	// }
+
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index d2c2265..784f266 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -350,6 +350,8 @@
 go.chromium.org/luci/client/versioncli
 go.chromium.org/luci/common/api/gerrit
 go.chromium.org/luci/common/api/gitiles
+go.chromium.org/luci/common/api/internal/gensupport
+go.chromium.org/luci/common/api/swarming/swarming/v1
 go.chromium.org/luci/common/bq/pb
 go.chromium.org/luci/common/cli
 go.chromium.org/luci/common/clock