diff --git a/connector/collector/docker.go b/connector/collector/docker.go index 68a1274..d6d0384 100644 --- a/connector/collector/docker.go +++ b/connector/collector/docker.go @@ -1,15 +1,19 @@ package collector import ( + "context" + "encoding/json" "github.com/bcicen/ctop/models" - api "github.com/fsouza/go-dockerclient" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "io" ) // Docker collector type Docker struct { models.Metrics id string - client *api.Client + client *client.Client running bool stream chan models.Metrics done chan bool @@ -17,7 +21,7 @@ type Docker struct { lastSysCpu float64 } -func NewDocker(client *api.Client, id string) *Docker { +func NewDocker(client *client.Client, id string) *Docker { return &Docker{ Metrics: models.Metrics{}, id: id, @@ -28,17 +32,24 @@ func NewDocker(client *api.Client, id string) *Docker { func (c *Docker) Start() { c.done = make(chan bool) c.stream = make(chan models.Metrics) - stats := make(chan *api.Stats) + stats := make(chan *types.StatsJSON) go func() { - opts := api.StatsOptions{ - ID: c.id, - Stats: stats, - Stream: true, - Done: c.done, + ctx := context.Background() + ss, err := c.client.ContainerStats(ctx, c.id, true) + if err == nil { + c.running = false + } + decoder := json.NewDecoder(ss.Body) + cStats := new(types.StatsJSON) + + for err := decoder.Decode(cStats); err != io.EOF; err = decoder.Decode(cStats) { + if err != nil { + break + } + stats <- cStats + cStats = new(types.StatsJSON) } - c.client.Stats(opts) - c.running = false }() go func() { @@ -75,10 +86,10 @@ func (c *Docker) Stop() { c.done <- true } -func (c *Docker) ReadCPU(stats *api.Stats) { +func (c *Docker) ReadCPU(stats *types.StatsJSON) { ncpus := uint8(len(stats.CPUStats.CPUUsage.PercpuUsage)) total := float64(stats.CPUStats.CPUUsage.TotalUsage) - system := float64(stats.CPUStats.SystemCPUUsage) + system := float64(stats.CPUStats.SystemUsage) cpudiff := total - c.lastCpu syscpudiff := system - c.lastSysCpu @@ -90,13 +101,13 @@ func (c *Docker) ReadCPU(stats *api.Stats) { c.Pids = int(stats.PidsStats.Current) } -func (c *Docker) ReadMem(stats *api.Stats) { - c.MemUsage = int64(stats.MemoryStats.Usage - stats.MemoryStats.Stats.Cache) +func (c *Docker) ReadMem(stats *types.StatsJSON) { + c.MemUsage = int64(stats.MemoryStats.Usage - stats.MemoryStats.Stats["cache"]) c.MemLimit = int64(stats.MemoryStats.Limit) c.MemPercent = percent(float64(c.MemUsage), float64(c.MemLimit)) } -func (c *Docker) ReadNet(stats *api.Stats) { +func (c *Docker) ReadNet(stats *types.StatsJSON) { var rx, tx int64 for _, network := range stats.Networks { rx += int64(network.RxBytes) @@ -105,9 +116,9 @@ func (c *Docker) ReadNet(stats *api.Stats) { c.NetRx, c.NetTx = rx, tx } -func (c *Docker) ReadIO(stats *api.Stats) { +func (c *Docker) ReadIO(stats *types.StatsJSON) { var read, write int64 - for _, blk := range stats.BlkioStats.IOServiceBytesRecursive { + for _, blk := range stats.BlkioStats.IoServiceBytesRecursive { if blk.Op == "Read" { read += int64(blk.Value) } diff --git a/connector/collector/docker_logs.go b/connector/collector/docker_logs.go index 84cdd14..d5cb5db 100644 --- a/connector/collector/docker_logs.go +++ b/connector/collector/docker_logs.go @@ -1,23 +1,19 @@ package collector import ( - "bufio" - "context" - "io" - "strings" + "github.com/docker/docker/client" "time" "github.com/bcicen/ctop/models" - api "github.com/fsouza/go-dockerclient" ) type DockerLogs struct { id string - client *api.Client + client *client.Client done chan bool } -func NewDockerLogs(id string, client *api.Client) *DockerLogs { +func NewDockerLogs(id string, client *client.Client) *DockerLogs { return &DockerLogs{ id: id, client: client, @@ -26,9 +22,9 @@ func NewDockerLogs(id string, client *api.Client) *DockerLogs { } func (l *DockerLogs) Stream() chan models.Log { - r, w := io.Pipe() + //r, w := io.Pipe() logCh := make(chan models.Log) - ctx, cancel := context.WithCancel(context.Background()) + /*ctx, cancel := context.WithCancel(context.Background()) opts := api.LogsOptions{ Context: ctx, @@ -65,7 +61,7 @@ func (l *DockerLogs) Stream() chan models.Log { go func() { <-l.done cancel() - }() + }()*/ log.Infof("log reader started for container: %s", l.id) return logCh diff --git a/connector/docker.go b/connector/docker.go index 063392f..13c2e0f 100644 --- a/connector/docker.go +++ b/connector/docker.go @@ -1,15 +1,20 @@ package connector import ( + "context" "fmt" - "github.com/op/go-logging" - "strings" - "sync" - "github.com/bcicen/ctop/connector/collector" "github.com/bcicen/ctop/connector/manager" "github.com/bcicen/ctop/container" - api "github.com/fsouza/go-dockerclient" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/client" + "github.com/docker/go-connections/nat" + "github.com/op/go-logging" + "strings" + "sync" + "time" ) func init() { enabled["docker"] = NewDocker } @@ -29,7 +34,7 @@ type StatusUpdate struct { } type Docker struct { - client *api.Client + client *client.Client containers map[string]*container.Container needsRefresh chan string // container IDs requiring refresh statuses chan StatusUpdate @@ -39,7 +44,8 @@ type Docker struct { func NewDocker() (Connector, error) { // init docker client - client, err := api.NewClientFromEnv() + ctx := context.Background() + client, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return nil, err } @@ -53,7 +59,7 @@ func NewDocker() (Connector, error) { } // query info as pre-flight healthcheck - info, err := client.Info() + info, err := client.Info(ctx) if err != nil { return nil, err } @@ -77,19 +83,23 @@ func (cm *Docker) Wait() struct{} { return <-cm.closed } // Docker events watcher func (cm *Docker) watchEvents() { log.Info("docker event listener starting") - events := make(chan *api.APIEvents) - cm.client.AddEventListener(events) + ctx := context.Background() + filter := filters.NewArgs() + filter.Add("type", "container") + filter.Add("event", "health_status") + filter.Add("event", "create") + filter.Add("event", "destroy") + filter.Add("event", "start") + filter.Add("event", "die") + filter.Add("event", "stop") + filter.Add("event", "pause") + filter.Add("event", "unpause") + + eventsOpts := types.EventsOptions{Filters: filter} + events, _ := cm.client.Events(ctx, eventsOpts) for e := range events { - if e.Type != "container" { - continue - } - actionName := e.Action - // fast skip all exec_* events: exec_create, exec_start, exec_die - if strings.HasPrefix(actionName, "exec_") { - continue - } // Action may have additional param i.e. "health_status: healthy" // We need to strip to have only action name sepIdx := strings.Index(actionName, ": ") @@ -130,7 +140,7 @@ func (cm *Docker) watchEvents() { close(cm.closed) } -func portsFormat(ports map[api.Port][]api.PortBinding) string { +func portsFormat(ports nat.PortMap) string { var exposed []string var published []string @@ -148,7 +158,7 @@ func portsFormat(ports map[api.Port][]api.PortBinding) string { return strings.Join(append(exposed, published...), "\n") } -func ipsFormat(networks map[string]api.ContainerNetwork) string { +func ipsFormat(networks map[string]*network.EndpointSettings) string { var ips []string for k, v := range networks { @@ -173,18 +183,23 @@ func (cm *Docker) refresh(c *container.Container) { c.SetMeta("image", insp.Config.Image) c.SetMeta("IPs", ipsFormat(insp.NetworkSettings.Networks)) c.SetMeta("ports", portsFormat(insp.NetworkSettings.Ports)) - c.SetMeta("created", insp.Created.Format("Mon Jan 2 15:04:05 2006")) - c.SetMeta("health", insp.State.Health.Status) + if created, err := time.Parse(time.RFC3339, insp.Created); err == nil { + c.SetMeta("created", created.Format("Mon Jan 2 15:04:05 2006")) + } + if insp.State.Health != nil { + c.SetMeta("health", insp.State.Health.Status) + } for _, env := range insp.Config.Env { c.SetMeta("[ENV-VAR]", env) } c.SetState(insp.State.Status) } -func (cm *Docker) inspect(id string) (insp *api.Container, found bool, failed bool) { - c, err := cm.client.InspectContainer(id) +func (cm *Docker) inspect(id string) (insp types.ContainerJSON, found bool, error bool) { + ctx := context.Background() + c, err := cm.client.ContainerInspect(ctx, id) if err != nil { - if _, notFound := err.(*api.NoSuchContainer); notFound { + if client.IsErrNotFound(err) { return c, false, false } // other error e.g. connection failed @@ -196,8 +211,9 @@ func (cm *Docker) inspect(id string) (insp *api.Container, found bool, failed bo // Mark all container IDs for refresh func (cm *Docker) refreshAll() { - opts := api.ListContainersOptions{All: true} - allContainers, err := cm.client.ListContainers(opts) + ctx := context.Background() + opts := types.ContainerListOptions{All: true} + allContainers, err := cm.client.ContainerList(ctx, opts) if err != nil { log.Errorf("%s (%T)", err.Error(), err) return diff --git a/connector/manager/docker.go b/connector/manager/docker.go index 5b683fc..2a5d638 100644 --- a/connector/manager/docker.go +++ b/connector/manager/docker.go @@ -1,19 +1,21 @@ package manager import ( + "context" "fmt" - api "github.com/fsouza/go-dockerclient" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" "github.com/pkg/errors" "io" - "os" + "time" ) type Docker struct { id string - client *api.Client + client *client.Client } -func NewDocker(client *api.Client, id string) *Docker { +func NewDocker(client *client.Client, id string) *Docker { return &Docker{ id: id, client: client, @@ -81,69 +83,76 @@ func (w *frameWriter) Write(p []byte) (n int, err error) { } func (dc *Docker) Exec(cmd []string) error { - execCmd, err := dc.client.CreateExec(api.CreateExecOptions{ + ctx := context.Background() + execConfig := types.ExecConfig{ AttachStdin: true, AttachStdout: true, AttachStderr: true, Cmd: cmd, - Container: dc.id, Tty: true, - }) - + } + execCmd, err := dc.client.ContainerExecCreate(ctx, dc.id, execConfig) if err != nil { return err } - return dc.client.StartExec(execCmd.ID, api.StartExecOptions{ - InputStream: &noClosableReader{os.Stdin}, - OutputStream: &frameWriter{os.Stdout, os.Stderr, os.Stdin}, - ErrorStream: os.Stderr, - RawTerminal: true, - }) + execStartConfig := types.ExecStartCheck{} + //execStartConfig := types.ExecStartCheck{ + // InputStream: &noClosableReader{os.Stdin}, + // OutputStream: &frameWriter{os.Stdout, os.Stderr, os.Stdin}, + // ErrorStream: os.Stderr, + // RawTerminal: true, + //} + return dc.client.ContainerExecStart(ctx, execCmd.ID, execStartConfig) } func (dc *Docker) Start() error { - c, err := dc.client.InspectContainer(dc.id) - if err != nil { - return fmt.Errorf("cannot inspect container: %v", err) - } - - if err := dc.client.StartContainer(c.ID, c.HostConfig); err != nil { + ctx := context.Background() + opts := types.ContainerStartOptions{} + if err := dc.client.ContainerStart(ctx, dc.id, opts); err != nil { return fmt.Errorf("cannot start container: %v", err) } return nil } func (dc *Docker) Stop() error { - if err := dc.client.StopContainer(dc.id, 3); err != nil { + ctx := context.Background() + timeout := 3 * time.Second + if err := dc.client.ContainerStop(ctx, dc.id, &timeout); err != nil { return fmt.Errorf("cannot stop container: %v", err) } return nil } func (dc *Docker) Remove() error { - if err := dc.client.RemoveContainer(api.RemoveContainerOptions{ID: dc.id}); err != nil { + ctx := context.Background() + opts := types.ContainerRemoveOptions{} + if err := dc.client.ContainerRemove(ctx, dc.id, opts); err != nil { return fmt.Errorf("cannot remove container: %v", err) } return nil } func (dc *Docker) Pause() error { - if err := dc.client.PauseContainer(dc.id); err != nil { + ctx := context.Background() + if err := dc.client.ContainerPause(ctx, dc.id); err != nil { return fmt.Errorf("cannot pause container: %v", err) } return nil } func (dc *Docker) Unpause() error { - if err := dc.client.UnpauseContainer(dc.id); err != nil { + ctx := context.Background() + if err := dc.client.ContainerUnpause(ctx, dc.id); err != nil { return fmt.Errorf("cannot unpause container: %v", err) } return nil } func (dc *Docker) Restart() error { - if err := dc.client.RestartContainer(dc.id, 3); err != nil { + ctx := context.Background() + timeout := 3 * time.Second + if err := dc.client.ContainerRestart(ctx, dc.id, &timeout); err != nil { return fmt.Errorf("cannot restart container: %v", err) } return nil diff --git a/go.mod b/go.mod index 4495847..d80ccae 100644 --- a/go.mod +++ b/go.mod @@ -3,17 +3,25 @@ module github.com/bcicen/ctop require ( github.com/BurntSushi/toml v0.3.1 github.com/c9s/goprocinfo v0.0.0-20170609001544-b34328d6e0cd - github.com/fsouza/go-dockerclient v1.6.6 + github.com/containerd/containerd v1.4.1 // indirect + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible + github.com/docker/go-connections v0.4.0 github.com/gizak/termui v2.3.0+incompatible + github.com/gogo/protobuf v1.3.1 // indirect github.com/jgautheron/codename-generator v0.0.0-20150829203204-16d037c7cc3c github.com/mattn/go-runewidth v0.0.0-20170201023540-14207d285c6c // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/nsf/termbox-go v0.0.0-20180303152453-e2050e41c884 github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d github.com/op/go-logging v0.0.0-20160211212156-b2cb9fa56473 + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/runc v1.0.0-rc92 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.4.0 + golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect + google.golang.org/grpc v1.33.2 // indirect ) replace github.com/gizak/termui => github.com/bcicen/termui v0.0.0-20180326052246-4eb80249d3f5 diff --git a/go.sum b/go.sum index 874df58..32916c4 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvx github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1 h1:pASeJT3R3YyVn+94qEPk0SnU1OQ20Jd/T+SPKy9xehY= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb h1:nXPkFq8X1a9ycY3GYQpFNxHh3j2JgY7zDZfq2EXMIzk= github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= @@ -49,6 +51,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible h1:ZxJX4ZSNg1LORBsStUojbrLfkrE3Ut122XhzyZnN110= github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -57,6 +61,7 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -82,6 +87,7 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -89,8 +95,10 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -135,6 +143,8 @@ github.com/op/go-logging v0.0.0-20160211212156-b2cb9fa56473/go.mod h1:HzydrMdWEr github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -191,6 +201,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -204,6 +215,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -227,9 +240,12 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -247,20 +263,29 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=