diff --git a/Dockerfile b/Dockerfile index fa856d66..d221adae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,18 @@ -FROM golang:1.9 +FROM golang:1.19 -ENV CONSUL_VERSION=1.0.0 -ENV GLIDE_VERSION=0.12.3 +ENV CONSUL_VERSION=1.13.3 RUN apt-get update \ && apt-get install -y unzip \ - && go get github.com/golang/lint/golint \ - && curl -Lo /tmp/glide.tgz "https://github.com/Masterminds/glide/releases/download/v${GLIDE_VERSION}/glide-v${GLIDE_VERSION}-linux-amd64.tar.gz" \ - && tar -C /usr/bin -xzf /tmp/glide.tgz --strip=1 linux-amd64/glide \ - && curl --fail -Lso consul.zip "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" \ - && unzip consul.zip -d /usr/bin + && go install honnef.co/go/tools/cmd/staticcheck@latest + +RUN export CONSUL_CHECKSUM=5370b0b5bf765530e28cb80f90dcb47bd7d6ba78176c1ab2430f56e460ed279c \ + && export archive=consul_${CONSUL_VERSION}_linux_amd64.zip \ + && curl -Lso /tmp/${archive} https://releases.hashicorp.com/consul/${CONSUL_VERSION}/${archive} \ + && echo "${CONSUL_CHECKSUM} /tmp/${archive}" | sha256sum -c \ + && cd /bin \ + && unzip /tmp/${archive} \ + && chmod +x /bin/consul \ + && rm /tmp/${archive} ENV CGO_ENABLED 0 -ENV GOPATH /go:/cp diff --git a/client/client.go b/client/client.go index 267257b9..12d61a73 100644 --- a/client/client.go +++ b/client/client.go @@ -14,7 +14,8 @@ import ( // requests out to a ContainerPilot process's control socket. type HTTPClient struct { http.Client - socketPath string + // staticcheck U1000 field is unused + //socketPath string } var socketType = "unix" diff --git a/commands/commands.go b/commands/commands.go index be83ede9..c8b7f9fe 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -126,8 +126,8 @@ func (c *Command) Run(pctx context.Context, bus *events.EventBus) { defer log.Debugf("%s.Run end", c.Name) if err := c.Cmd.Start(); err != nil { log.Errorf("unable to start %s: %v", c.Name, err) - bus.Publish(events.Event{events.ExitFailed, c.Name}) - bus.Publish(events.Event{events.Error, err.Error()}) + bus.Publish(events.Event{Code: events.ExitFailed, Source: c.Name}) + bus.Publish(events.Event{Code: events.Error, Source: err.Error()}) return } @@ -150,12 +150,12 @@ func (c *Command) Run(pctx context.Context, bus *events.EventBus) { // we'll return from Wait() and publish events if err := c.Cmd.Wait(); err != nil { log.Errorf("%s exited with error: %v", c.Name, err) - bus.Publish(events.Event{events.ExitFailed, c.Name}) - bus.Publish(events.Event{events.Error, - fmt.Errorf("%s: %s", c.Name, err).Error()}) + bus.Publish(events.Event{Code: events.ExitFailed, Source: c.Name}) + bus.Publish(events.Event{Code: events.Error, + Source: fmt.Errorf("%s: %s", c.Name, err).Error()}) } else { log.Debugf("%s exited without error", c.Name) - bus.Publish(events.Event{events.ExitSuccess, c.Name}) + bus.Publish(events.Event{Code: events.ExitSuccess, Source: c.Name}) } }() } diff --git a/commands/commands_test.go b/commands/commands_test.go index 039134d2..b481a4f1 100644 --- a/commands/commands_test.go +++ b/commands/commands_test.go @@ -15,7 +15,7 @@ import ( func TestCommandRunWithTimeoutZero(t *testing.T) { cmd, _ := NewCommand("sleep 2", time.Duration(0), nil) got := runtestCommandRun(cmd) - timedout := events.Event{events.ExitFailed, "sleep"} + timedout := events.Event{Code: events.ExitFailed, Source: "sleep"} if got[timedout] != 1 { t.Fatalf("stopped command prior to test timeout, got events %v", got) } @@ -25,9 +25,9 @@ func TestCommandRunWithTimeoutKilled(t *testing.T) { cmd, _ := NewCommand("sleep 2", time.Duration(100*time.Millisecond), nil) cmd.Name = t.Name() got := runtestCommandRun(cmd) - testTimeout := events.Event{events.TimerExpired, "DebugSubscriberTimeout"} - expired := events.Event{events.ExitFailed, t.Name()} - errMsg := events.Event{events.Error, fmt.Sprintf("%s: signal: killed", cmd.Name)} + testTimeout := events.Event{Code: events.TimerExpired, Source: "DebugSubscriberTimeout"} + expired := events.Event{Code: events.ExitFailed, Source: t.Name()} + errMsg := events.Event{Code: events.Error, Source: fmt.Sprintf("%s: signal: killed", cmd.Name)} if got[testTimeout] > 0 || got[expired] != 1 || got[errMsg] != 1 { t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", expired, errMsg, got) } @@ -38,9 +38,9 @@ func TestCommandRunChildrenKilled(t *testing.T) { time.Duration(100*time.Millisecond), nil) cmd.Name = t.Name() got := runtestCommandRun(cmd) - testTimeout := events.Event{events.TimerExpired, "DebugSubscriberTimeout"} - expired := events.Event{events.ExitFailed, t.Name()} - errMsg := events.Event{events.Error, fmt.Sprintf("%s: signal: killed", cmd.Name)} + testTimeout := events.Event{Code: events.TimerExpired, Source: "DebugSubscriberTimeout"} + expired := events.Event{Code: events.ExitFailed, Source: t.Name()} + errMsg := events.Event{Code: events.Error, Source: fmt.Sprintf("%s: signal: killed", cmd.Name)} if got[testTimeout] > 0 || got[expired] != 1 || got[errMsg] != 1 { t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", expired, errMsg, got) } @@ -49,8 +49,8 @@ func TestCommandRunChildrenKilled(t *testing.T) { func TestCommandRunExecFailed(t *testing.T) { cmd, _ := NewCommand("./testdata/test.sh failStuff --debug", time.Duration(0), nil) got := runtestCommandRun(cmd) - failed := events.Event{events.ExitFailed, "./testdata/test.sh"} - errMsg := events.Event{events.Error, "./testdata/test.sh: exit status 255"} + failed := events.Event{Code: events.ExitFailed, Source: "./testdata/test.sh"} + errMsg := events.Event{Code: events.Error, Source: "./testdata/test.sh: exit status 255"} if got[failed] != 1 || got[errMsg] != 1 { t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", failed, errMsg, got) } @@ -59,9 +59,9 @@ func TestCommandRunExecFailed(t *testing.T) { func TestCommandRunExecInvalid(t *testing.T) { cmd, _ := NewCommand("./testdata/invalidCommand", time.Duration(0), nil) got := runtestCommandRun(cmd) - failed := events.Event{events.ExitFailed, "./testdata/invalidCommand"} - errMsg := events.Event{events.Error, - "fork/exec ./testdata/invalidCommand: no such file or directory"} + failed := events.Event{Code: events.ExitFailed, Source: "./testdata/invalidCommand"} + errMsg := events.Event{Code: events.Error, + Source: "fork/exec ./testdata/invalidCommand: no such file or directory"} if got[failed] != 1 || got[errMsg] != 1 { t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", failed, errMsg, got) } diff --git a/commands/testdata/test.sh b/commands/testdata/test.sh index 51c69222..3015caf9 100755 --- a/commands/testdata/test.sh +++ b/commands/testdata/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/config/config.go b/config/config.go index 676b3ade..7e220567 100644 --- a/config/config.go +++ b/config/config.go @@ -6,7 +6,7 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/flynn/json5" @@ -79,7 +79,7 @@ func RenderConfig(configFlag, renderFlag string) error { fmt.Printf("%s", renderedConfig) } else { var err error - if err = ioutil.WriteFile(renderFlag, renderedConfig, 0644); err != nil { + if err = os.WriteFile(renderFlag, renderedConfig, 0644); err != nil { return fmt.Errorf("could not write config file: %s", err) } } @@ -108,7 +108,7 @@ func loadConfigFile(configFlag string) ([]byte, error) { if configFlag == "" { return nil, errors.New("-config flag is required") } - data, err := ioutil.ReadFile(configFlag) + data, err := os.ReadFile(configFlag) if err != nil { return nil, fmt.Errorf("could not read config file: %s", err) } diff --git a/config/config_test.go b/config/config_test.go index 89b352ae..2372c3df 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,7 +1,6 @@ package config import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -184,8 +183,8 @@ func TestRenderConfigFileStdout(t *testing.T) { temp.Close() os.Stdout = old - renderedOut, _ := ioutil.ReadFile(fname) - renderedFile, _ := ioutil.ReadFile("testJSON.json") + renderedOut, _ := os.ReadFile(fname) + renderedFile, _ := os.ReadFile("testJSON.json") if string(renderedOut) != string(renderedFile) { t.Fatalf("expected the rendered file and stdout to be identical") } diff --git a/config/decode/decode.go b/config/decode/decode.go index f3a8fab4..572fea94 100644 --- a/config/decode/decode.go +++ b/config/decode/decode.go @@ -71,7 +71,7 @@ func interfaceToString(raw interface{}) string { } func interfaceToStringArray(rawArray []interface{}) []string { - if rawArray == nil || len(rawArray) == 0 { + if len(rawArray) == 0 { return nil } var stringArray []string diff --git a/config/logger/logging.go b/config/logger/logging.go index d593cc6c..0c3352b6 100644 --- a/config/logger/logging.go +++ b/config/logger/logging.go @@ -49,7 +49,7 @@ func (l *Config) Init() error { } level, err := logrus.ParseLevel(strings.ToLower(l.Level)) if err != nil { - return fmt.Errorf("Unknown log level '%s': %s", l.Level, err) + return fmt.Errorf("unknown log level '%s': %s", l.Level, err) } var formatter logrus.Formatter var output io.Writer @@ -65,7 +65,7 @@ func (l *Config) Init() error { TimestampFormat: time.RFC3339Nano, } default: - return fmt.Errorf("Unknown log format '%s'", l.Format) + return fmt.Errorf("unknown log format '%s'", l.Format) } switch strings.ToLower(l.Output) { case "stderr": @@ -73,11 +73,11 @@ func (l *Config) Init() error { case "stdout": output = os.Stdout case "": - return fmt.Errorf("Unknown output type '%s'", l.Output) + return fmt.Errorf("unknown output type '%s'", l.Output) default: f, err := reopen.NewFileWriter(l.Output) if err != nil { - return fmt.Errorf("Error initializing log file '%s': %s", l.Output, err) + return fmt.Errorf("error initializing log file '%s': %s", l.Output, err) } initializeSignal(f) output = f diff --git a/config/logger/logging_test.go b/config/logger/logging_test.go index 393fe475..c69372dc 100644 --- a/config/logger/logging_test.go +++ b/config/logger/logging_test.go @@ -1,7 +1,6 @@ package logger import ( - "io/ioutil" "os" "reflect" "strings" @@ -84,7 +83,7 @@ func TestFileLogger(t *testing.T) { // write a log message logMsg := "this is a test" logrus.Info(logMsg) - content, err := ioutil.ReadFile(filename) + content, err := os.ReadFile(filename) if err != nil { t.Errorf("Did not expect error: %v", err) } diff --git a/config/services/ips.go b/config/services/ips.go index 7c652e89..59854fa5 100644 --- a/config/services/ips.go +++ b/config/services/ips.go @@ -30,7 +30,7 @@ func IPFromInterfaces(raw interface{}) (string, error) { // GetIP determines the IP address of the container func GetIP(specList []string) (string, error) { - if specList == nil || len(specList) == 0 { + if len(specList) == 0 { // Use a sane default specList = []string{"eth0:inet", "inet"} } @@ -191,7 +191,7 @@ func parseInterfaceSpec(spec string) (interfaceSpec, error) { if _, err := strconv.Atoi(ip[1]); err != nil { nip := net.ParseIP(ip[1]) if nip == nil { - return nil, fmt.Errorf("Unable to parse static ip %s in %s", ip[0], spec) + return nil, fmt.Errorf("unable to parse static ip %s in %s", ip[0], spec) } return staticInterfaceSpec{Spec: spec, Name: "static", IP: nip}, nil } @@ -204,7 +204,7 @@ func parseInterfaceSpec(spec string) (interfaceSpec, error) { if index != "" { i, err := strconv.Atoi(index) if err != nil { - return nil, fmt.Errorf("Unable to parse index %s in %s", index, spec) + return nil, fmt.Errorf("unable to parse index %s in %s", index, spec) } return indexInterfaceSpec{Spec: spec, Name: name, Index: i}, nil } @@ -219,7 +219,7 @@ func parseInterfaceSpec(spec string) (interfaceSpec, error) { if _, net, err := net.ParseCIDR(spec); err == nil { return cidrInterfaceSpec{Spec: spec, Network: net}, nil } - return nil, fmt.Errorf("Unable to parse interface spec: %s", spec) + return nil, fmt.Errorf("unable to parse interface spec: %s", spec) } type interfaceIP struct { diff --git a/config/services/ips_test.go b/config/services/ips_test.go index 82b5f381..d5b53752 100644 --- a/config/services/ips_test.go +++ b/config/services/ips_test.go @@ -48,7 +48,7 @@ func TestGetIp(t *testing.T) { ip, _ := GetIP([]string{lo, "inet"}) assert.Equal(t, "127.0.0.1", ip, "expected to find loopback IP") - ip, err := GetIP([]string{"interface-does-not-exist"}) + _, err := GetIP([]string{"interface-does-not-exist"}) assert.Error(t, err, "expected interface not found, but instead got an IP") ip, _ = GetIP([]string{"static:192.168.1.100", lo}) diff --git a/config/template/template.go b/config/template/template.go index bad15d9b..1edeb742 100644 --- a/config/template/template.go +++ b/config/template/template.go @@ -65,9 +65,9 @@ func envFunc(env string) string { } func ensureInt(intv interface{}) (int, error) { - switch intv.(type) { + switch intv := intv.(type) { case string: - ret, err := strconv.Atoi(intv.(string)) + ret, err := strconv.Atoi(intv) if err != nil { return 0, err } diff --git a/config/timing/duration_test.go b/config/timing/duration_test.go index 8bac52de..730ea3d1 100644 --- a/config/timing/duration_test.go +++ b/config/timing/duration_test.go @@ -20,7 +20,7 @@ func TestGetTimeout(t *testing.T) { dur, err = GetTimeout("x") expectDurationCompare(t, dur, time.Duration(0), - err, errors.New("time: invalid duration x")) + err, errors.New("time: invalid duration \"x\"")) dur, err = GetTimeout("0") expectDurationCompare(t, dur, time.Duration(0), err, nil) @@ -67,7 +67,7 @@ func TestParseDuration(t *testing.T) { // Some parse errors expectError(t, "asf", "invalid duration") - expectError(t, "20yy", "unknown unit yy") + expectError(t, "20yy", "time: unknown unit \"yy\" in duration \"20yy\"") // Fractional expectError(t, 10.10, "unexpected duration of type float") diff --git a/control/control.go b/control/control.go index 7379508b..66bab982 100644 --- a/control/control.go +++ b/control/control.go @@ -81,7 +81,6 @@ func (srv *HTTPServer) Run(pctx context.Context, bus *events.EventBus) { go func() { defer srv.Stop() <-ctx.Done() - return }() } diff --git a/control/endpoints.go b/control/endpoints.go index 7119318f..d56be395 100644 --- a/control/endpoints.go +++ b/control/endpoints.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -56,7 +55,7 @@ func (pw PostHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // process. Returns empty response or HTTP422. func (e Endpoints) PutEnviron(r *http.Request) (interface{}, int) { var postEnv map[string]string - jsonBlob, err := ioutil.ReadAll(r.Body) + jsonBlob, err := io.ReadAll(r.Body) defer r.Body.Close() if err != nil { return nil, http.StatusUnprocessableEntity @@ -110,7 +109,7 @@ func (e Endpoints) PostDisableMaintenanceMode(r *http.Request) (interface{}, int // Returns empty response or HTTP422. func (e Endpoints) PostMetric(r *http.Request) (interface{}, int) { var postMetrics map[string]interface{} - jsonBlob, err := ioutil.ReadAll(r.Body) + jsonBlob, err := io.ReadAll(r.Body) defer r.Body.Close() if err != nil { @@ -123,7 +122,7 @@ func (e Endpoints) PostMetric(r *http.Request) (interface{}, int) { } for metricKey, metricValue := range postMetrics { eventVal := fmt.Sprintf("%v|%v", metricKey, metricValue) - e.bus.Publish(events.Event{events.Metric, eventVal}) + e.bus.Publish(events.Event{Code: events.Metric, Source: eventVal}) } return nil, http.StatusOK } diff --git a/control/endpoints_test.go b/control/endpoints_test.go index 97b40102..e6444fab 100644 --- a/control/endpoints_test.go +++ b/control/endpoints_test.go @@ -3,7 +3,7 @@ package control import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -65,7 +65,7 @@ func TestPostHandler(t *testing.T) { ph.ServeHTTP(w, req) resp := w.Result() defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) + body, _ := io.ReadAll(resp.Body) status := resp.StatusCode return status, string(body) } @@ -130,15 +130,15 @@ func TestPostMetric(t *testing.T) { }) t.Run("POST value", func(t *testing.T) { body := "{\"mymetric\": 1.0}" - expected := map[events.Event]int{{events.Metric, "mymetric|1"}: 1} + expected := map[events.Event]int{{Code: events.Metric, Source: "mymetric|1"}: 1} status := testFunc(t, expected, body) assert.Equal(t, http.StatusOK, status, "status was not 200OK") }) t.Run("POST multi-metric", func(t *testing.T) { body := "{\"mymetric\": 1.5, \"myothermetric\": 2}" status := testFunc(t, map[events.Event]int{ - {events.Metric, "mymetric|1.5"}: 1, - {events.Metric, "myothermetric|2"}: 1, + {Code: events.Metric, Source: "mymetric|1.5"}: 1, + {Code: events.Metric, Source: "myothermetric|2"}: 1, }, body) assert.Equal(t, http.StatusOK, status, "status was not 200OK") }) diff --git a/core/app_test.go b/core/app_test.go index 66111814..c8d18109 100644 --- a/core/app_test.go +++ b/core/app_test.go @@ -2,7 +2,6 @@ package core import ( "fmt" - "io/ioutil" "os" "strings" "testing" @@ -152,7 +151,7 @@ func TestReloadConfig(t *testing.T) { // write the configuration to a tempfile. caller is responsible // for calling 'defer os.Remove(f.Name())' when done func testCfgToTempFile(t *testing.T, text string) *os.File { - f, err := ioutil.TempFile(".", "test-") + f, err := os.CreateTemp(".", "test-") if err != nil { t.Fatal(err) } diff --git a/core/testdata/test.sh b/core/testdata/test.sh index c05a728d..68b2e59b 100755 --- a/core/testdata/test.sh +++ b/core/testdata/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/discovery/consul.go b/discovery/consul.go index 3be6b0c5..f7069b74 100644 --- a/discovery/consul.go +++ b/discovery/consul.go @@ -24,7 +24,7 @@ func init() { // Consul wraps the service discovery backend for the Hashicorp Consul client // and tracks the state of all watched dependencies. type Consul struct { - api.Client + *api.Client lock sync.RWMutex watchedServices map[string][]*api.ServiceEntry } @@ -53,7 +53,7 @@ func NewConsul(config interface{}) (*Consul, error) { return nil, err } watchedServices := make(map[string][]*api.ServiceEntry) - consul := &Consul{*client, sync.RWMutex{}, watchedServices} + consul := &Consul{client, sync.RWMutex{}, watchedServices} return consul, nil } diff --git a/discovery/consul_test.go b/discovery/consul_test.go index e06161d5..bd6ea898 100644 --- a/discovery/consul_test.go +++ b/discovery/consul_test.go @@ -89,7 +89,7 @@ func TestWithConsul(t *testing.T) { func testConsulTTLPass(testServer *TestServer) func(*testing.T) { return func(t *testing.T) { consul, _ := NewConsul(testServer.HTTPAddr) - name := fmt.Sprintf("TestConsulTTLPass") + name := "TestConsulTTLPass" service := generateServiceDefinition(name, consul) checkID := fmt.Sprintf("service:%s", service.ID) @@ -105,7 +105,7 @@ func testConsulTTLPass(testServer *TestServer) func(*testing.T) { func testConsulRegisterWithInitialStatus(testServer *TestServer) func(*testing.T) { return func(t *testing.T) { consul, _ := NewConsul(testServer.HTTPAddr) - name := fmt.Sprintf("TestConsulRegisterWithInitialStatus") + name := "TestConsulRegisterWithInitialStatus" service := generateServiceDefinition(name, consul) checkID := fmt.Sprintf("service:%s", service.ID) @@ -121,7 +121,7 @@ func testConsulRegisterWithInitialStatus(testServer *TestServer) func(*testing.T func testConsulReregister(testServer *TestServer) func(*testing.T) { return func(t *testing.T) { consul, _ := NewConsul(testServer.HTTPAddr) - name := fmt.Sprintf("TestConsulReregister") + name := "TestConsulReregister" service := generateServiceDefinition(name, consul) id := service.ID @@ -148,7 +148,7 @@ func testConsulReregister(testServer *TestServer) func(*testing.T) { func testConsulCheckForChanges(testServer *TestServer) func(*testing.T) { return func(t *testing.T) { - backend := fmt.Sprintf("TestConsulCheckForChanges") + backend := "TestConsulCheckForChanges" consul, _ := NewConsul(testServer.HTTPAddr) service := generateServiceDefinition(backend, consul) id := service.ID @@ -163,7 +163,7 @@ func testConsulCheckForChanges(testServer *TestServer) func(*testing.T) { if changed, _ := consul.CheckForUpstreamChanges(backend, "", ""); changed { t.Errorf("%v should not have changed without TTL expiring", id) } - check := fmt.Sprintf("service:TestConsulCheckForChanges") + check := "service:TestConsulCheckForChanges" consul.Agent().UpdateTTL(check, "expired", "critical") if changed, _ := consul.CheckForUpstreamChanges(backend, "", ""); !changed { t.Errorf("%v should have changed after TTL expired.", id) @@ -173,7 +173,7 @@ func testConsulCheckForChanges(testServer *TestServer) func(*testing.T) { func testConsulEnableTagOverride(testServer *TestServer) func(*testing.T) { return func(t *testing.T) { - backend := fmt.Sprintf("TestConsulEnableTagOverride") + backend := "TestConsulEnableTagOverride" consul, _ := NewConsul(testServer.HTTPAddr) service := &ServiceDefinition{ ID: backend, @@ -204,12 +204,12 @@ func testConsulEnableTagOverride(testServer *TestServer) func(*testing.T) { func generateServiceDefinition(serviceName string, consul *Consul) *ServiceDefinition { return &ServiceDefinition{ - ID: serviceName, - Name: serviceName, - IPAddress: "192.168.1.1", + ID: serviceName, + Name: serviceName, + IPAddress: "192.168.1.1", InitialStatus: "warning", - TTL: 5, - Port: 9000, - Consul: consul, + TTL: 5, + Port: 9000, + Consul: consul, } } diff --git a/discovery/service.go b/discovery/service.go index 6b3a4f79..b99211bd 100644 --- a/discovery/service.go +++ b/discovery/service.go @@ -59,19 +59,16 @@ func (service *ServiceDefinition) RegisterWithInitialStatus() { status := "" switch service.InitialStatus { - case "passing": - status = api.HealthPassing - break - case "warning": - status = api.HealthWarning - break - case "critical": - status = api.HealthCritical - break + case "passing": + status = api.HealthPassing + case "warning": + status = api.HealthWarning + case "critical": + status = api.HealthCritical } log.Infof("Registering service %v with initial status set to %v", - service.Name, service.InitialStatus) + service.Name, service.InitialStatus) service.register(status) } @@ -100,9 +97,9 @@ func (service *ServiceDefinition) registerService(status string) error { Address: service.IPAddress, EnableTagOverride: service.EnableTagOverride, Check: &api.AgentServiceCheck{ - TTL: fmt.Sprintf("%ds", service.TTL), - Status: status, - Notes: fmt.Sprintf("TTL for %s set by containerpilot", service.Name), + TTL: fmt.Sprintf("%ds", service.TTL), + Status: status, + Notes: fmt.Sprintf("TTL for %s set by containerpilot", service.Name), DeregisterCriticalServiceAfter: service.DeregisterCriticalServiceAfter, }, }, diff --git a/discovery/test_server.go b/discovery/test_server.go index cc32a8df..55623893 100644 --- a/discovery/test_server.go +++ b/discovery/test_server.go @@ -9,7 +9,7 @@ import ( "os/exec" "strconv" - "github.com/hashicorp/consul/testutil/retry" + "github.com/hashicorp/consul/sdk/testutil/retry" cleanhttp "github.com/hashicorp/go-cleanhttp" ) @@ -64,7 +64,8 @@ type failer struct { failed bool } -func (f *failer) Log(args ...interface{}) { fmt.Println(args) } +func (f *failer) Helper() {} +func (f *failer) Log(args ...interface{}) { fmt.Println(args...) } func (f *failer) FailNow() { f.failed = true } // WaitForAPI waits for only the agent HTTP endpoint to start responding. This diff --git a/docs/30-configuration/36-telemetry.md b/docs/30-configuration/36-telemetry.md index f1a09e1f..2cf46655 100644 --- a/docs/30-configuration/36-telemetry.md +++ b/docs/30-configuration/36-telemetry.md @@ -58,7 +58,7 @@ The `metrics` field is a list of user-defined metrics that the telemetry service The collectors can record metrics sent via the [HTTP control socket](./37-control-plane.md). If your application can't use this endpoint on its own, you can use a periodic job to record the metric value and call `containerpilot -putmetric`. An example of a good job script might be: ```bash -#!/bin/bash +#!/usr/bin/env bash # check free memory val=$(free | awk -F' +' '/Mem/{print $3}') ./containerpilot -putmetric "free_memory=$val" diff --git a/events/bus.go b/events/bus.go index f4e4879a..a1b8c049 100644 --- a/events/bus.go +++ b/events/bus.go @@ -115,9 +115,7 @@ func (bus *EventBus) Unsubscribe(subscriber EventSubscriber) { bus.lock.Lock() defer bus.lock.Unlock() sub := subscriber.(*Subscriber) - if _, ok := bus.registry[sub]; ok { - delete(bus.registry, sub) - } + delete(bus.registry, sub) bus.done.Done() } diff --git a/events/events_test.go b/events/events_test.go index 2488a746..fff12143 100644 --- a/events/events_test.go +++ b/events/events_test.go @@ -70,7 +70,7 @@ func TestPubSubInterfaces(t *testing.T) { ts.Run(ctx, bus) expected := []Event{ - Event{Startup, "serviceA"}, + {Startup, "serviceA"}, } for _, event := range expected { tp.Publish(event) diff --git a/glide.lock b/glide.lock deleted file mode 100644 index 2bd3f8e9..00000000 --- a/glide.lock +++ /dev/null @@ -1,73 +0,0 @@ -hash: c13286385a0d957eb3b4e47af1f85b6cd8d8b084c846737477f46ac04d2c44f2 -updated: 2017-11-13T21:22:43.229954534-05:00 -imports: -- name: github.com/beorn7/perks - version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 - subpackages: - - quantile -- name: github.com/client9/reopen - version: 1a6ccbeaae3f56aa0058f5491382cb21726e214e -- name: github.com/flynn/json5 - version: 7620272ed63390e979cf5882d2fa0506fe2a8db5 -- name: github.com/golang/protobuf - version: 6a1fa9404c0aebf36c879bc50152edcc953910d2 - subpackages: - - proto -- name: github.com/hashicorp/consul - version: 783a405d781ffc5edaf2d6b5eff41e22df96644f - subpackages: - - api - - testutil/retry -- name: github.com/hashicorp/go-cleanhttp - version: 3573b8b52aa7b37b9358d966a898feb387f62437 -- name: github.com/hashicorp/go-rootcerts - version: 6bb64b370b90e7ef1fa532be9e591a81c3493e00 -- name: github.com/hashicorp/serf - version: 91fd53b1d3e624389ed9a295a3fa380e5c7b9dfc - subpackages: - - coordinate -- name: github.com/matttproud/golang_protobuf_extensions - version: c12348ce28de40eed0136aa2b644d0ee0650e56c - subpackages: - - pbutil -- name: github.com/mitchellh/go-homedir - version: b8bc1bf767474819792c23f32d8286a45736f1c6 -- name: github.com/mitchellh/mapstructure - version: d2dd0262208475919e1a362f675cfc0e7c10e905 -- name: github.com/prometheus/client_golang - version: c5b7fccd204277076155f10851dad72b76a49317 - subpackages: - - prometheus -- name: github.com/prometheus/client_model - version: 6f3806018612930941127f2a7c6c453ba2c527d2 - subpackages: - - go -- name: github.com/prometheus/common - version: 0866df4b85a18d652b6965be022d007cdf076822 - subpackages: - - expfmt - - internal/bitbucket.org/ww/goautoneg - - model -- name: github.com/prometheus/procfs - version: e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2 - subpackages: - - xfs -- name: github.com/sirupsen/logrus - version: 202f25545ea4cf9b191ff7f846df5d87c9382c2b -- name: golang.org/x/sys - version: 94b76065f2d2081d0fef24a6e67c571f51a6408a - subpackages: - - unix -testImports: -- name: github.com/davecgh/go-spew - version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 - subpackages: - - spew -- name: github.com/pmezard/go-difflib - version: d8ed2627bdf02c080bf22230dbb337003b7aba2d - subpackages: - - difflib -- name: github.com/stretchr/testify - version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 - subpackages: - - assert diff --git a/glide.yaml b/glide.yaml deleted file mode 100644 index 4c0c1053..00000000 --- a/glide.yaml +++ /dev/null @@ -1,24 +0,0 @@ -package: github.com/joyent/containerpilot -homepage: https://www.joyent.com/containerpilot -license: MPL-2.0 -import: -- package: github.com/sirupsen/logrus - version: 1.0.0 -- package: github.com/hashicorp/consul - version: ~1.0.0 - subpackages: - - api -- package: github.com/mitchellh/mapstructure - version: d2dd0262208475919e1a362f675cfc0e7c10e905 -- package: github.com/prometheus/client_golang - version: 0.8.0 - subpackages: - - prometheus -- package: github.com/flynn/json5 - version: 7620272ed63390e979cf5882d2fa0506fe2a8db5 -testImport: -- package: github.com/stretchr/testify - version: v1.1.4 - subpackages: - - assert -- package: github.com/client9/reopen diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..0f4141d1 --- /dev/null +++ b/go.mod @@ -0,0 +1,42 @@ +module github.com/joyent/containerpilot + +go 1.18 + +require ( + github.com/client9/reopen v1.0.0 + github.com/flynn/json5 v0.0.0-20160717195620-7620272ed633 + github.com/hashicorp/consul/api v1.15.3 + github.com/hashicorp/consul/sdk v0.11.0 + github.com/hashicorp/go-cleanhttp v0.5.2 + github.com/mitchellh/mapstructure v1.5.0 + github.com/prometheus/client_golang v1.14.0 + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.1 +) + +require ( + github.com/armon/go-metrics v0.4.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/hashicorp/go-hclog v1.3.1 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/serf v0.10.1 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f // indirect + golang.org/x/sys v0.2.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..d3cb1abf --- /dev/null +++ b/go.sum @@ -0,0 +1,658 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= +github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/flynn/json5 v0.0.0-20160717195620-7620272ed633 h1:xJMmr4GMYIbALX5edyoDIOQpc2bOQTeJiWMeCl9lX/8= +github.com/flynn/json5 v0.0.0-20160717195620-7620272ed633/go.mod h1:NJDK3/o7abx6PP54EOe0G0n0RLmhCo9xv61gUYpI0EY= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +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/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/consul/api v1.15.3 h1:WYONYL2rxTXtlekAqblR2SCdJsizMDIj/uXb5wNy9zU= +github.com/hashicorp/consul/api v1.15.3/go.mod h1:/g/qgcoBcEXALCNZgRRisyTW0nY86++L0KbeAMXYCeY= +github.com/hashicorp/consul/sdk v0.11.0 h1:HRzj8YSCln2yGgCumN5CL8lYlD3gBurnervJRJAZyC4= +github.com/hashicorp/consul/sdk v0.11.0/go.mod h1:yPkX5Q6CsxTFMjQQDJwzeNmUUF5NUGGbrDsv9wTb8cw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= +github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY= +github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM= +github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +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/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +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= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +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/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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/integration_tests/fixtures/app/Dockerfile b/integration_tests/fixtures/app/Dockerfile index 6839f601..7bd8247e 100644 --- a/integration_tests/fixtures/app/Dockerfile +++ b/integration_tests/fixtures/app/Dockerfile @@ -1,8 +1,8 @@ -FROM node:slim +FROM node:18-slim RUN apt-get update && \ apt-get install -y \ - curl netcat-openbsd && \ + curl netcat-openbsd procps && \ rm -rf /var/lib/apt/lists/* RUN npm install -g json http-server diff --git a/integration_tests/fixtures/app/sensor.sh b/integration_tests/fixtures/app/sensor.sh index 00d3adb5..ce368d4e 100755 --- a/integration_tests/fixtures/app/sensor.sh +++ b/integration_tests/fixtures/app/sensor.sh @@ -1,3 +1,4 @@ -#!/bin/bash +#!/bin/bash -x +/bin/containerpilot -template /bin/containerpilot -putmetric 'containerpilot_app_some_counter=42' diff --git a/integration_tests/fixtures/consul/Dockerfile b/integration_tests/fixtures/consul/Dockerfile index 335683d7..45d70a32 100644 --- a/integration_tests/fixtures/consul/Dockerfile +++ b/integration_tests/fixtures/consul/Dockerfile @@ -1,3 +1,3 @@ -FROM consul:latest +FROM consul:1.13.3 RUN apk --no-cache add jq curl COPY assert /bin/assert diff --git a/integration_tests/fixtures/nginx/Dockerfile b/integration_tests/fixtures/nginx/Dockerfile index 34f04bfc..6a61c906 100644 --- a/integration_tests/fixtures/nginx/Dockerfile +++ b/integration_tests/fixtures/nginx/Dockerfile @@ -1,5 +1,5 @@ # Nginx container including ContainerPilot -FROM alpine:3.3 +FROM alpine:3.16 # install nginx and tooling we need RUN apk update && apk add \ @@ -9,8 +9,8 @@ RUN apk update && apk add \ && rm -rf /var/cache/apk/* # we use consul-template to re-write our Nginx virtualhost config -RUN curl -Lo /tmp/consul_template_0.14.0_linux_amd64.zip https://releases.hashicorp.com/consul-template/0.14.0/consul-template_0.14.0_linux_amd64.zip && \ - unzip /tmp/consul_template_0.14.0_linux_amd64.zip && \ +RUN curl -Lo /tmp/consul_template_0.29.5_linux_amd64.zip https://releases.hashicorp.com/consul-template/0.29.5/consul-template_0.29.5_linux_amd64.zip && \ + unzip /tmp/consul_template_0.29.5_linux_amd64.zip && \ mv consul-template /bin # add ContainerPilot build and configuration diff --git a/integration_tests/tests/test_config_reload/docker-compose.yml b/integration_tests/tests/test_config_reload/docker-compose.yml index 2e0c8110..5b44b340 100644 --- a/integration_tests/tests/test_config_reload/docker-compose.yml +++ b/integration_tests/tests/test_config_reload/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_config_reload/run.sh b/integration_tests/tests/test_config_reload/run.sh index d0ba1e61..7e5d7f02 100755 --- a/integration_tests/tests/test_config_reload/run.sh +++ b/integration_tests/tests/test_config_reload/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # test_config_reload: runs an application container and send it commands # to reload config diff --git a/integration_tests/tests/test_coprocess/docker-compose.yml b/integration_tests/tests/test_coprocess/docker-compose.yml index 10217d87..757a9ccd 100644 --- a/integration_tests/tests/test_coprocess/docker-compose.yml +++ b/integration_tests/tests/test_coprocess/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_coprocess/run.sh b/integration_tests/tests/test_coprocess/run.sh index 84f28bb4..c715c280 100755 --- a/integration_tests/tests/test_coprocess/run.sh +++ b/integration_tests/tests/test_coprocess/run.sh @@ -1,10 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash set -e function finish { result=$? if [[ "$result" -ne 0 ]]; then - docker exec -it "$app" ps -ef + docker exec -i "$app" ps -ef docker logs "$app" | tee app.log fi exit $result @@ -13,30 +13,30 @@ trap finish EXIT # stand up app and consul, and wait for consul to elect a leader docker-compose up -d -docker exec -it "$(docker-compose ps -q consul)" assert ready +docker exec -i "$(docker-compose ps -q consul)" assert ready # verify the coprocess is running app=$(docker-compose ps -q app) -docker exec -it "$app" ps -ef | grep coprocess +docker exec -i "$app" ps -ef | grep coprocess # kill the coprocess and verify it restarts -docker exec -it "$app" pkill coprocess +docker exec -i "$app" pkill coprocess sleep 1 -docker exec -it "$app" ps -ef | grep coprocess +docker exec -i "$app" ps -ef | grep coprocess # kill the coprocess and verify it doesn't restart again -docker exec -it "$app" pkill coprocess +docker exec -i "$app" pkill coprocess sleep 1 -docker exec -it "$app" ps -ef | grep coprocess && exit 1 +docker exec -i "$app" ps -ef | grep coprocess && exit 1 # update the ContainerPilot config and verify the coprocess is running # with the new flags (this resets the restart limit) -docker exec -it "$app" sed -i 's/arg1/arg2/' /etc/containerpilot-with-coprocess.json5 -docker exec -it "$app" /reload-containerpilot.sh single +docker exec -i "$app" sed -i 's/arg1/arg2/' /etc/containerpilot-with-coprocess.json5 +docker exec -i "$app" /reload-containerpilot.sh single sleep 1 -docker exec -it "$app" ps -ef | grep coprocess | grep arg2 +docker exec -i "$app" ps -ef | grep coprocess | grep arg2 # kill the coprocess and verify it restarts -docker exec -it "$app" pkill coprocess +docker exec -i "$app" pkill coprocess sleep 1 -docker exec -it "$app" ps -ef | grep coprocess +docker exec -i "$app" ps -ef | grep coprocess diff --git a/integration_tests/tests/test_discovery_consul/docker-compose.yml b/integration_tests/tests/test_discovery_consul/docker-compose.yml index 82a27f9c..6638438c 100644 --- a/integration_tests/tests/test_discovery_consul/docker-compose.yml +++ b/integration_tests/tests/test_discovery_consul/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_discovery_consul/run.sh b/integration_tests/tests/test_discovery_consul/run.sh index c19a7960..f39de099 100755 --- a/integration_tests/tests/test_discovery_consul/run.sh +++ b/integration_tests/tests/test_discovery_consul/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e function finish { @@ -22,17 +22,17 @@ trap finish EXIT # start up consul and wait for leader election docker-compose up -d consul consul=$(docker-compose ps -q consul) -docker exec -it "$consul" assert ready +docker exec -i "$consul" assert ready # start app and nginx, wait for them to register docker-compose up -d app nginx -docker exec -it "$consul" assert service app 1 -docker exec -it "$consul" assert service nginx 1 +docker exec -i "$consul" assert service app 1 +docker exec -i "$consul" assert service nginx 1 # test that nginx config has been updated nginx=$(docker-compose ps -q nginx) for _ in $(seq 0 10); do - docker exec -it "$nginx" curl -s -o /dev/null --fail "http://localhost:80/app/" + docker exec -i "$nginx" curl -s -o /dev/null --fail "http://localhost:80/app/" [ $? -eq 0 ] && exit 0 sleep 1 done || (echo "no route for /app/" && exit 1) diff --git a/integration_tests/tests/test_envvars/run.sh b/integration_tests/tests/test_envvars/run.sh index f5099831..60bf5731 100755 --- a/integration_tests/tests/test_envvars/run.sh +++ b/integration_tests/tests/test_envvars/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e ## run and make sure we get the env var out but print diff --git a/integration_tests/tests/test_logging/docker-compose.yml b/integration_tests/tests/test_logging/docker-compose.yml index cacedc38..a11ec5bf 100644 --- a/integration_tests/tests/test_logging/docker-compose.yml +++ b/integration_tests/tests/test_logging/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_logging/run.sh b/integration_tests/tests/test_logging/run.sh index 5a6285e6..b49d1034 100755 --- a/integration_tests/tests/test_logging/run.sh +++ b/integration_tests/tests/test_logging/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e function finish { @@ -11,7 +11,7 @@ trap finish EXIT # start up app & consul and wait for leader election docker-compose up -d consul app -docker exec -it "$(docker-compose ps -q consul)" assert ready +docker exec -i "$(docker-compose ps -q consul)" assert ready app=$(docker-compose ps -q app) sleep 1 # need time for 1st health checks to fire diff --git a/integration_tests/tests/test_no_command/run.sh b/integration_tests/tests/test_no_command/run.sh index 1906b62c..ee500fba 100755 --- a/integration_tests/tests/test_no_command/run.sh +++ b/integration_tests/tests/test_no_command/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash logFail() { echo "${1}" diff --git a/integration_tests/tests/test_reap_zombies/docker-compose.yml b/integration_tests/tests/test_reap_zombies/docker-compose.yml index 45e2e122..b291d9a6 100644 --- a/integration_tests/tests/test_reap_zombies/docker-compose.yml +++ b/integration_tests/tests/test_reap_zombies/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: @@ -9,7 +9,7 @@ services: command: agent -dev -client 0.0.0.0 -bind 0.0.0.0 zombies: - image: alpine:3.5 + image: alpine:3.16 mem_limit: 128m links: - consul:consul diff --git a/integration_tests/tests/test_reap_zombies/run.sh b/integration_tests/tests/test_reap_zombies/run.sh index 0c3a95a1..77094d9c 100755 --- a/integration_tests/tests/test_reap_zombies/run.sh +++ b/integration_tests/tests/test_reap_zombies/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # Test to verify that we're correctly reaping zombies. # At any given time we may have up to 1 zombie parented to PID1 (it has been @@ -8,7 +8,7 @@ set -e docker-compose up -d consul zombies consul=$(docker-compose ps -q consul) -docker exec -it "$consul" assert ready +docker exec -i "$consul" assert ready ID=$(docker-compose ps -q zombies) sleep 6 diff --git a/integration_tests/tests/test_reopen/run.sh b/integration_tests/tests/test_reopen/run.sh index b949a2f2..26dbbd33 100755 --- a/integration_tests/tests/test_reopen/run.sh +++ b/integration_tests/tests/test_reopen/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function finish { result=$? diff --git a/integration_tests/tests/test_reopen/test_reopen.sh b/integration_tests/tests/test_reopen/test_reopen.sh index b2e3708e..82cc3a44 100755 --- a/integration_tests/tests/test_reopen/test_reopen.sh +++ b/integration_tests/tests/test_reopen/test_reopen.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash CONTAINERPILOT_LOGFILE="/tmp/containerpilot.log" CONTAINERPILOT_ROTATEDLOGFILE="/tmp/containerpilot.log.1" @@ -28,4 +28,4 @@ if [ ! -f $CONTAINERPILOT_LOGFILE ] || [[ $logs != *"hello world"* ]]; then exit 1 fi -exit 0 \ No newline at end of file +exit 0 diff --git a/integration_tests/tests/test_sighup/docker-compose.yml b/integration_tests/tests/test_sighup/docker-compose.yml index 4b602b93..0d2b8d27 100644 --- a/integration_tests/tests/test_sighup/docker-compose.yml +++ b/integration_tests/tests/test_sighup/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_sighup/run.sh b/integration_tests/tests/test_sighup/run.sh index 58482942..324da27f 100755 --- a/integration_tests/tests/test_sighup/run.sh +++ b/integration_tests/tests/test_sighup/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e @@ -14,12 +14,12 @@ trap finish EXIT # start up consul and wait for leader election docker-compose up -d consul consul=$(docker-compose ps -q consul) -docker exec -it "$consul" assert ready +docker exec -i "$consul" assert ready # start up app and wait for it to register docker-compose up -d app app=$(docker-compose ps -q app) -docker exec -it "$consul" assert service app 1 +docker exec -i "$consul" assert service app 1 # send SIGHUP into the app container docker kill -s HUP "$app" @@ -29,6 +29,6 @@ docker kill -s USR2 "$app" # verify that the app is still running and that both `on-sighup` and # `on-sigusr2` signal event based jobs have executed -docker exec -it "$consul" assert service app 1 +docker exec -i "$consul" assert service app 1 docker logs "$app" | grep "msg=\"'on-sighup job fired on SIGHUP" docker logs "$app" | grep "msg=\"'on-sigusr2 job fired on SIGUSR2" diff --git a/integration_tests/tests/test_sigterm/docker-compose.yml b/integration_tests/tests/test_sigterm/docker-compose.yml index 4b602b93..0d2b8d27 100644 --- a/integration_tests/tests/test_sigterm/docker-compose.yml +++ b/integration_tests/tests/test_sigterm/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_sigterm/run.sh b/integration_tests/tests/test_sigterm/run.sh index fcaf8e94..d12bf648 100755 --- a/integration_tests/tests/test_sigterm/run.sh +++ b/integration_tests/tests/test_sigterm/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e @@ -14,18 +14,18 @@ trap finish EXIT # start up consul and wait for leader election docker-compose up -d consul consul=$(docker-compose ps -q consul) -docker exec -it "$consul" assert ready +docker exec -i "$consul" assert ready # start up app and wait for it to register docker-compose up -d app app=$(docker-compose ps -q app) -docker exec -it "$consul" assert service app 1 +docker exec -i "$consul" assert service app 1 # sigterm app container docker stop "$app" # and verify it's exited gracefully from consul, and that # both preStop and postStop jobs have executed -docker exec -it "$consul" assert service app 1 +docker exec -i "$consul" assert service app 1 docker logs "$app" | grep "msg=\"'preStop fired on app stopping" docker logs "$app" | grep "msg=\"'postStop fired on app stopped" diff --git a/integration_tests/tests/test_tasks/docker-compose.yml b/integration_tests/tests/test_tasks/docker-compose.yml index 98287eb3..a56177f0 100644 --- a/integration_tests/tests/test_tasks/docker-compose.yml +++ b/integration_tests/tests/test_tasks/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_tasks/run.sh b/integration_tests/tests/test_tasks/run.sh index f7ba6a95..f820c556 100755 --- a/integration_tests/tests/test_tasks/run.sh +++ b/integration_tests/tests/test_tasks/run.sh @@ -1,10 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash # test_tasks: runs multiple tasks with timeouts for a period of time and # then parses their logs to verify that they ran the expected number of times. # start up consul and wait for leader election docker-compose up -d consul -docker exec -it "$(docker-compose ps -q consul)" assert ready +docker exec -i "$(docker-compose ps -q consul)" assert ready docker-compose up -d app APP_ID="$(docker-compose ps -q app)" diff --git a/integration_tests/tests/test_tasks/task.sh b/integration_tests/tests/test_tasks/task.sh index eb0c7fad..511463b8 100755 --- a/integration_tests/tests/test_tasks/task.sh +++ b/integration_tests/tests/test_tasks/task.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash SLEEP=${1:-"1"} FILE=${2:-"/tmp/test"} diff --git a/integration_tests/tests/test_telemetry/check.sh b/integration_tests/tests/test_telemetry/check.sh index debe21fb..dac06a58 100755 --- a/integration_tests/tests/test_telemetry/check.sh +++ b/integration_tests/tests/test_telemetry/check.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -eo pipefail IP="$1" diff --git a/integration_tests/tests/test_telemetry/docker-compose.yml b/integration_tests/tests/test_telemetry/docker-compose.yml index a01485f8..b487224a 100644 --- a/integration_tests/tests/test_telemetry/docker-compose.yml +++ b/integration_tests/tests/test_telemetry/docker-compose.yml @@ -1,4 +1,4 @@ -version: "2.1" +version: "2.4" services: diff --git a/integration_tests/tests/test_telemetry/run.sh b/integration_tests/tests/test_telemetry/run.sh index be73fb2f..9ba03c5b 100755 --- a/integration_tests/tests/test_telemetry/run.sh +++ b/integration_tests/tests/test_telemetry/run.sh @@ -1,22 +1,22 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # start up consul and wait for leader election docker-compose up -d consul consul=$(docker-compose ps -q consul) -docker exec -it "$consul" assert ready +docker exec -i "$consul" assert ready # start up app docker-compose up -d app app="$(docker-compose ps -q app)" -IP=$(docker inspect -f '{{ .NetworkSettings.Networks.testtelemetry_default.IPAddress }}' "$app") +IP=$(docker inspect -f '{{ .NetworkSettings.Networks.test_telemetry_default.IPAddress }}' "$app") # This interface takes a while to converge for _ in $(seq 0 20); do sleep 1 - metrics=$(docker exec -it "$app" curl -s "${IP}:9090/metrics") + metrics=$(docker exec -i "$app" curl -s "${IP}:9090/metrics") echo "$metrics" | grep 'containerpilot_app_some_counter 42' && break done || (echo "did not get expected metrics output" && exit 1) @@ -29,9 +29,9 @@ echo "$metrics" | grep 'containerpilot_watch_instances' || \ ( echo 'no containerpilot_watch_instances metrics' && exit 1 ) # Check the status endpoint too -docker exec -it "$app" /check.sh "${IP}" +docker exec -i "$app" /check.sh "${IP}" # Make we register and tear down telemetry service in Consul -docker exec -it "$consul" assert service containerpilot 1 +docker exec -i "$consul" assert service containerpilot 1 docker-compose stop app -docker exec -it "$consul" curl -s --fail localhost:8500/v1/catalog/service/containerpilot | grep -v 'containerpilot' +docker exec -i "$consul" curl -s --fail localhost:8500/v1/catalog/service/containerpilot | grep -v 'containerpilot' diff --git a/integration_tests/tests/test_version_flag/run.sh b/integration_tests/tests/test_version_flag/run.sh index 54643aea..495b9323 100755 --- a/integration_tests/tests/test_version_flag/run.sh +++ b/integration_tests/tests/test_version_flag/run.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/usr/bin/env bash docker-compose run app -TEST_ID=$(docker ps -a | awk -F' +' '/testversionflag/{print $1}') +TEST_ID=$(docker ps -a | awk -F' +' '/test_version_flag/{print $1}') docker logs "$TEST_ID" | grep dev-build-not-for-release result=$? diff --git a/jobs/config.go b/jobs/config.go index 4c2dd0ab..a62e1ec0 100644 --- a/jobs/config.go +++ b/jobs/config.go @@ -133,7 +133,7 @@ func (cfg *Config) Validate(disc discovery.Backend) error { } func (cfg *Config) setStopping(name string) { - cfg.stoppingWaitEvent = events.Event{events.Stopped, name} + cfg.stoppingWaitEvent = events.Event{Code: events.Stopped, Source: name} } func (cfg *Config) validateDiscovery(disc discovery.Backend) error { @@ -241,7 +241,7 @@ func (cfg *Config) validateWhenEvent() error { cfg.whenStartsLimit = unlimited } - cfg.whenEvent = events.Event{eventCode, cfg.When.Source} + cfg.whenEvent = events.Event{Code: eventCode, Source: cfg.When.Source} return nil } diff --git a/jobs/config_test.go b/jobs/config_test.go index ddabdca5..e630ed9b 100644 --- a/jobs/config_test.go +++ b/jobs/config_test.go @@ -2,7 +2,7 @@ package jobs import ( "fmt" - "io/ioutil" + "os" "testing" "time" @@ -31,7 +31,7 @@ func TestJobConfigServiceWithPreStart(t *testing.T) { assert.Equal(job0.Tags, []string{"tag1", "tag2"}, "config for job0.Tags") assert.Equal(job0.restartLimit, 0, "config for job0.restartLimit") - assert.Equal(job0.whenEvent, events.Event{events.ExitSuccess, "preStart"}, + assert.Equal(job0.whenEvent, events.Event{Code: events.ExitSuccess, Source: "preStart"}, "config for serviceA.whenEvent") assert.Equal(job0.healthCheckExec.Exec, "/bin/healthCheckA.sh", "config for job0.healthCheckExec.Exec") @@ -58,12 +58,12 @@ func TestJobConfigHealthTimeout(t *testing.T) { job0 := jobs[0] assert.Equal(job0.Name, "serviceA", "config for job0.Name") - assert.Equal(job0.heartbeatInterval, time.Duration(10) * time.Second, "config for job0.Health") - assert.Equal(job0.healthCheckExec.Timeout, time.Duration(5) * time.Second, "config for job0.Name.Health") + assert.Equal(job0.heartbeatInterval, time.Duration(10)*time.Second, "config for job0.Health") + assert.Equal(job0.healthCheckExec.Timeout, time.Duration(5)*time.Second, "config for job0.Name.Health") job1 := jobs[1] assert.Equal(job1.Name, "serviceB", "config for job1.Name") - assert.Equal(job1.heartbeatInterval, time.Duration(10) * time.Second, "config for job1.Health") + assert.Equal(job1.heartbeatInterval, time.Duration(10)*time.Second, "config for job1.Health") assert.Equal(job1.healthCheckExec.Timeout, job1.heartbeatInterval, "config for job1.Health") } @@ -91,7 +91,7 @@ func TestJobConfigServiceWithStopping(t *testing.T) { // job0 is the main application job0 := jobs[0] assert.Equal(job0.Name, "serviceA", "config for job0.Name") - assert.Equal(job0.stoppingWaitEvent, events.Event{events.Stopped, "preStop"}, + assert.Equal(job0.stoppingWaitEvent, events.Event{Code: events.Stopped, Source: "preStop"}, "expected no stopping event for serviceA") // job1 is its preStart @@ -103,7 +103,7 @@ func TestJobConfigServiceWithStopping(t *testing.T) { assert.Equal(job2.Name, "preStop", "config for job2.Name") assert.Equal(job2.exec.Exec, "/bin/to/preStop.sh", "config for preStop.exec.Exec") - assert.Equal(job2.whenEvent, events.Event{events.Stopping, "serviceA"}, + assert.Equal(job2.whenEvent, events.Event{Code: events.Stopping, Source: "serviceA"}, "config for preStop.whenEvent") // job3 is its post-stop @@ -111,7 +111,7 @@ func TestJobConfigServiceWithStopping(t *testing.T) { assert.Equal(job3.Name, "postStop", "config for job3.Name") assert.Equal(job3.exec.Exec, "/bin/to/postStop.sh", "config for postStop.exec.Exec") - assert.Equal(job3.whenEvent, events.Event{events.Stopped, "serviceA"}, + assert.Equal(job3.whenEvent, events.Event{Code: events.Stopped, Source: "serviceA"}, "config for postStop.whenEvent") } @@ -165,7 +165,7 @@ func TestJobConfigConsulExtras(t *testing.T) { } func TestJobConfigSmokeTest(t *testing.T) { - data, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + data, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) testCfg := tests.DecodeRawToSlice(string(data)) assert := assert.New(t) @@ -285,7 +285,7 @@ func TestJobConfigValidateDiscovery(t *testing.T) { } func TestErrJobConfigConsulEnableTagOverride(t *testing.T) { - testCfg, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + testCfg, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) _, err := NewConfigs(tests.DecodeRawToSlice(string(testCfg)), noop) if err == nil { t.Errorf("ConsulExtras should have thrown error about EnableTagOverride being a string.") @@ -293,7 +293,7 @@ func TestErrJobConfigConsulEnableTagOverride(t *testing.T) { } func TestErrJobConfigConsulDeregisterCriticalServiceAfter(t *testing.T) { - testCfg, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + testCfg, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) _, err := NewConfigs(tests.DecodeRawToSlice(string(testCfg)), noop) if err == nil { t.Errorf("error should have been generated for duration 'nope'.") @@ -324,7 +324,7 @@ func TestJobConfigValidateFrequency(t *testing.T) { expectErr( `[{name: "E", exec: "/bin/taskE", timeout: "1ns", when: {interval: "xx"}}]`, - "unable to parse job[E].when.interval 'xx': time: invalid duration xx") + "unable to parse job[serviceC].timeout 'xx': time: invalid duration \"xx\"") testCfg := tests.DecodeRawToSlice( `[{name: "F", exec: "/bin/taskF", when: {interval: "1ms"}}]`) @@ -379,7 +379,7 @@ func TestJobConfigValidateExec(t *testing.T) { timeout: "xx" }]`) _, err = NewConfigs(testCfg, noop) - expected := "unable to parse job[serviceC].timeout 'xx': time: invalid duration xx" + expected := "unable to parse job[serviceC].timeout 'xx': time: invalid duration \"xx\"" if err == nil || err.Error() != expected { t.Fatalf("expected '%s', got '%v'", expected, err) } @@ -469,7 +469,7 @@ func TestHealthChecksConfigError(t *testing.T) { var noop = &mocks.NoopDiscoveryBackend{} func loadTestConfig(t *testing.T) []*Config { - data, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + data, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) testCfg := tests.DecodeRawToSlice(string(data)) jobs, err := NewConfigs(testCfg, noop) diff --git a/jobs/jobs.go b/jobs/jobs.go index 677e5dab..1a0d6bdd 100644 --- a/jobs/jobs.go +++ b/jobs/jobs.go @@ -33,7 +33,8 @@ type Job struct { statusLock *sync.RWMutex Service *discovery.ServiceDefinition healthCheckExec *commands.Command - healthCheckName string + // staticcheck U1000 field is unused + //healthCheckName string // starting events startEvent events.Event @@ -155,7 +156,7 @@ func (job *Job) Run(pctx context.Context, completedCh chan struct{}) { if job.startTimeout > 0 { timeoutName := fmt.Sprintf("%s.wait-timeout", job.Name) events.NewEventTimeout(ctx, job.Rx, job.startTimeout, timeoutName) - job.startTimeoutEvent = events.Event{events.TimerExpired, timeoutName} + job.startTimeoutEvent = events.Event{Code: events.TimerExpired, Source: timeoutName} } else { job.startTimeoutEvent = events.NonEvent } @@ -278,7 +279,7 @@ func (job *Job) onRunEveryTimerExpired(ctx context.Context) processEventStatus { func (job *Job) onHealthCheckFailed(ctx context.Context) processEventStatus { if job.GetStatus() != statusMaintenance { job.setStatus(statusUnhealthy) - job.Publish(events.Event{events.StatusUnhealthy, job.Name}) + job.Publish(events.Event{Code: events.StatusUnhealthy, Source: job.Name}) } return jobContinue } @@ -286,7 +287,7 @@ func (job *Job) onHealthCheckFailed(ctx context.Context) processEventStatus { func (job *Job) onHealthCheckPassed(ctx context.Context) processEventStatus { if job.GetStatus() != statusMaintenance { job.setStatus(statusHealthy) - job.Publish(events.Event{events.StatusHealthy, job.Name}) + job.Publish(events.Event{Code: events.StatusHealthy, Source: job.Name}) job.SendHeartbeat() } return jobContinue @@ -400,7 +401,7 @@ func (job *Job) cleanup(ctx context.Context, cancel context.CancelFunc) { switch event { case job.stoppingWaitEvent: break loop - case events.Event{events.Stopping, stoppingTimeout}: + case events.Event{Code: events.Stopping, Source: stoppingTimeout}: break loop } } diff --git a/jobs/jobs_test.go b/jobs/jobs_test.go index 9160106a..f0e48d4e 100644 --- a/jobs/jobs_test.go +++ b/jobs/jobs_test.go @@ -39,8 +39,8 @@ func TestJobRunSafeClose(t *testing.T) { expected := []events.Event{ events.GlobalStartup, - {events.Stopping, "myjob"}, - {events.Stopped, "myjob"}, + {Code: events.Stopping, Source: "myjob"}, + {Code: events.Stopped, Source: "myjob"}, } if !reflect.DeepEqual(expected, results) { t.Fatalf("expected: %v\ngot: %v", expected, results) @@ -241,7 +241,7 @@ func TestJobMaintenance(t *testing.T) { // in-flight health checks should not bump the Job out of maintenance t.Run("healthy no change", func(t *testing.T) { status := testFunc(t, statusMaintenance, - events.Event{events.ExitSuccess, "check.myjob"}) + events.Event{Code: events.ExitSuccess, Source: "check.myjob"}) assert.Equal(t, statusMaintenance, status, "job status after passing check while in maintenance") }) @@ -249,7 +249,7 @@ func TestJobMaintenance(t *testing.T) { // in-flight health checks should not bump the Job out of maintenance t.Run("unhealthy no change", func(t *testing.T) { status := testFunc(t, statusMaintenance, - events.Event{events.ExitFailed, "check.myjob"}) + events.Event{Code: events.ExitFailed, Source: "check.myjob"}) assert.Equal(t, statusMaintenance, status, "job status after failed check while in maintenance") }) @@ -262,7 +262,7 @@ func TestJobMaintenance(t *testing.T) { t.Run("now healthy", func(t *testing.T) { status := testFunc(t, statusUnknown, - events.Event{events.ExitSuccess, "check.myjob"}) + events.Event{Code: events.ExitSuccess, Source: "check.myjob"}) assert.Equal(t, statusHealthy, status, "job status after passing check out of maintenance") }) @@ -278,11 +278,11 @@ func TestJobProcessEvent(t *testing.T) { // } job := &Job{ Name: "testJob", - startEvent: events.Event{events.StatusChanged, "upstream"}, + startEvent: events.Event{Code: events.StatusChanged, Source: "upstream"}, startsRemain: 1, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 1st startEvent") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, 0, job.startsRemain) @@ -299,30 +299,30 @@ func TestJobProcessEvent(t *testing.T) { // restarts: 2 job := &Job{ Name: "testJob", - startEvent: events.Event{events.StatusChanged, "upstream"}, + startEvent: events.Event{Code: events.StatusChanged, Source: "upstream"}, startsRemain: 1, restartLimit: 2, restartsRemain: 2, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 1st startEvent") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, 0, job.startsRemain) assert.Equal(t, events.NonEvent, job.startEvent) - got = job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd startEvent") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 1st exit") assert.Equal(t, 1, job.restartsRemain) - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd exit") assert.Equal(t, 0, job.restartsRemain) - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobHalt, got, "processEvent after 3rd exit") }) @@ -337,26 +337,26 @@ func TestJobProcessEvent(t *testing.T) { // restarts: "unlimited" job := &Job{ Name: "testJob", - startEvent: events.Event{events.StatusChanged, "upstream"}, + startEvent: events.Event{Code: events.StatusChanged, Source: "upstream"}, startsRemain: 1, restartLimit: -1, restartsRemain: -1, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 1st startEvent") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, 0, job.startsRemain) assert.Equal(t, events.NonEvent, job.startEvent) - got = job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd startEvent") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 1st exit") assert.Equal(t, -2, job.restartsRemain) - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd exit") assert.Equal(t, -3, job.restartsRemain) }) @@ -369,26 +369,26 @@ func TestJobProcessEvent(t *testing.T) { // restarts: "none" job := &Job{ Name: "testJob", - startEvent: events.Event{events.StatusChanged, "upstream"}, + startEvent: events.Event{Code: events.StatusChanged, Source: "upstream"}, startsRemain: unlimited, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 1st startEvent") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, unlimited, job.startsRemain) - assert.Equal(t, events.Event{events.StatusChanged, "upstream"}, job.startEvent) + assert.Equal(t, events.Event{Code: events.StatusChanged, Source: "upstream"}, job.startEvent) - got = job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd startEvent") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after exit") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, unlimited, job.startsRemain) - assert.Equal(t, events.Event{events.StatusChanged, "upstream"}, job.startEvent) + assert.Equal(t, events.Event{Code: events.StatusChanged, Source: "upstream"}, job.startEvent) - got = job.processEvent(nil, events.Event{events.StatusChanged, "upstream"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.StatusChanged, Source: "upstream"}) assert.Equal(t, jobContinue, got, "processEvent after 3rd startEvent") }) @@ -402,16 +402,16 @@ func TestJobProcessEvent(t *testing.T) { restartsRemain: unlimited, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.GlobalStartup) + job.processEvent(context.TODO(), events.GlobalStartup) assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, 0, job.startsRemain) assert.Equal(t, events.NonEvent, job.startEvent) // should return False after each exit which means we don't stop job - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 1st exit") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 2nd exit") }) @@ -425,15 +425,15 @@ func TestJobProcessEvent(t *testing.T) { restartsRemain: 1, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, events.GlobalStartup) + job.processEvent(context.TODO(), events.GlobalStartup) assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, 0, job.startsRemain) assert.Equal(t, events.NonEvent, job.startEvent) - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got := job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after 1st exit") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobHalt, got, "processEvent after 2nd exit") }) @@ -443,7 +443,7 @@ func TestJobProcessEvent(t *testing.T) { // each: "changed" // }, // restart: "unlimited" - startEvent := events.Event{events.StatusChanged, "upstream"} + startEvent := events.Event{Code: events.StatusChanged, Source: "upstream"} job := &Job{ Name: "testJob", startEvent: startEvent, @@ -451,19 +451,19 @@ func TestJobProcessEvent(t *testing.T) { restartsRemain: unlimited, statusLock: &sync.RWMutex{}, } - got := job.processEvent(nil, startEvent) + got := job.processEvent(context.TODO(), startEvent) assert.Equal(t, jobContinue, got, "processEvent after 1st startEvent") assert.Equal(t, statusUnknown, job.Status) assert.Equal(t, unlimited, job.startsRemain) assert.Equal(t, startEvent, job.startEvent) - got = job.processEvent(nil, startEvent) + got = job.processEvent(context.TODO(), startEvent) assert.Equal(t, jobContinue, got, "processEvent after 2nd startEvent") - got = job.processEvent(nil, events.Event{events.ExitSuccess, "testJob"}) + got = job.processEvent(context.TODO(), events.Event{Code: events.ExitSuccess, Source: "testJob"}) assert.Equal(t, jobContinue, got, "processEvent after exit") - got = job.processEvent(nil, startEvent) + got = job.processEvent(context.TODO(), startEvent) assert.Equal(t, jobContinue, got, "processEvent after 3rd startEvent") }) diff --git a/jobs/testdata/test.sh b/jobs/testdata/test.sh index c05a728d..68b2e59b 100755 --- a/jobs/testdata/test.sh +++ b/jobs/testdata/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/jobs/testdata/test_coprocess.sh b/jobs/testdata/test_coprocess.sh index ab27a0b3..4bcf6e3d 100755 --- a/jobs/testdata/test_coprocess.sh +++ b/jobs/testdata/test_coprocess.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/jobs/testdata/test_tasks.sh b/jobs/testdata/test_tasks.sh index ab27a0b3..4bcf6e3d 100755 --- a/jobs/testdata/test_tasks.sh +++ b/jobs/testdata/test_tasks.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/makefile b/makefile index b95baf74..bc455a35 100644 --- a/makefile +++ b/makefile @@ -1,16 +1,16 @@ MAKEFLAGS += --warn-undefined-variables -SHELL := /bin/bash +SHELL := bash .SHELLFLAGS := -o pipefail -euc .DEFAULT_GOAL := build -.PHONY: clean test integration consul ship dockerfile docker cover lint local vendor dep-* tools kirby +.PHONY: clean test integration consul ship dockerfile docker cover lint local dep-* tools kirby IMPORT_PATH := github.com/joyent/containerpilot VERSION ?= dev-build-not-for-release LDFLAGS := -X ${IMPORT_PATH}/version.GitHash=$(shell git rev-parse --short HEAD) -X ${IMPORT_PATH}/version.Version=${VERSION} ROOT := $(shell pwd) -RUNNER := -v ${ROOT}:/go/src/${IMPORT_PATH} -w /go/src/${IMPORT_PATH} containerpilot_build +RUNNER := -v containerpilot_cache:/go -v ${ROOT}:/usr/src/containerpilot -w /usr/src/containerpilot containerpilot_build docker := docker run --rm -e LDFLAGS="${LDFLAGS}" $(RUNNER) export PATH :=$(PATH):$(GOPATH)/bin @@ -21,8 +21,7 @@ GOARCH ?= $(shell go env GOARCH) CGO_ENABLED := 0 GOEXPERIMENT := framepointer -CONSUL_VERSION := 1.0.0 -GLIDE_VERSION := 0.12.3 +CONSUL_VERSION := 1.13.3 ## display this help message help: @@ -41,7 +40,7 @@ help: ## build the ContainerPilot binary build: build/containerpilot -build/containerpilot: build/containerpilot_build build/glide-installed */*/*.go */*.go */*/*.go *.go +build/containerpilot: build/containerpilot_build */*/*.go */*.go */*/*.go *.go $(docker) go build -o build/containerpilot -ldflags "$(LDFLAGS)" @rm -rf src || true @@ -64,45 +63,34 @@ release: build @cd release && sha1sum containerpilot-$(VERSION).tar.gz > containerpilot-$(VERSION).sha1.txt @echo Upload files in release/ directory to GitHub release. -## remove build/test artifacts, test fixtures, and vendor directories +## remove build/test artifacts, test fixtures clean: - rm -rf build release cover vendor .glide + rm -rf build release cover docker rmi -f containerpilot_build > /dev/null 2>&1 || true docker rm -f containerpilot_consul > /dev/null 2>&1 || true + docker volume rm containerpilot_cache > /dev/null 2>&1 || true ./scripts/test.sh clean # ---------------------------------------------- # dependencies -# NOTE: glide will be replaced with `dep` when its production-ready -# ref https://github.com/golang/dep - -## install any changed packages in the glide.yaml -vendor: build/glide-installed -build/glide-installed: build/containerpilot_build glide.yaml - $(docker) glide install - mkdir -p vendor - @echo date > build/glide-installed - -## install all vendored packages in the glide.yaml -dep-install: - mkdir -p vendor - $(docker) glide install - @echo date > build/glide-installed - -# usage DEP=github.com/owner/package make dep-add -## fetch a dependency and vendor it via `glide` -dep-add: build/containerpilot_build - $(docker) bash -c "DEP=$(DEP) ./scripts/add_dep.sh" + +## install all packages in go.mod and go.sum +deps: build/dep-install +build/dep-install: build/containerpilot_build go.mod + $(docker) go get ./... + @echo date > build/update + +## update all dependencies (minor versions) +dep-update: + $(docker) go get -u ./... + @echo date > build/update # run 'GOOS=darwin make tools' if you're installing on MacOS ## set up local dev environment tools: - @go version | grep 1.9 || (echo 'WARNING: go1.9 should be installed!') + @go version | grep 1.19 || (echo 'WARNING: go1.19 should be installed!') @$(if $(value GOPATH),, $(error 'GOPATH not set')) - go get github.com/golang/lint/golint - curl --fail -Lso glide.tgz "https://github.com/Masterminds/glide/releases/download/v$(GLIDE_VERSION)/glide-v$(GLIDE_VERSION)-$(GOOS)-$(GOARCH).tar.gz" - tar -C "$(GOPATH)/bin" -xzf glide.tgz --strip=1 $(GOOS)-$(GOARCH)/glide - rm glide.tgz + go install honnef.co/go/tools/cmd/staticcheck@latest curl --fail -Lso consul.zip "https://releases.hashicorp.com/consul/$(CONSUL_VERSION)/consul_$(CONSUL_VERSION)_$(GOOS)_$(GOARCH).zip" unzip consul.zip -d "$(GOPATH)/bin" rm consul.zip @@ -135,7 +123,7 @@ local: | quiet quiet: # this is silly but shuts up 'Nothing to be done for `local`' @: -## run `go lint` and other code quality tools +## run `go vet`, `staticcheck` and other code quality tools lint: $(docker) bash ./scripts/lint.sh diff --git a/scripts/add_dep.sh b/scripts/add_dep.sh deleted file mode 100755 index 17833c13..00000000 --- a/scripts/add_dep.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -x -if [ -z "$DEP" ]; then - echo "No dependency provided. Expected: DEP=" - exit 1 -fi -glide get ${DEP} diff --git a/scripts/cover.sh b/scripts/cover.sh index 5c05484f..94be0357 100755 --- a/scripts/cover.sh +++ b/scripts/cover.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash OUT=${OUT:-cover/cover.out} TMP=${TMP:-cover/temp.out} echo "mode: set" > $OUT diff --git a/scripts/lint.sh b/scripts/lint.sh index 0e78dc99..aba0bd80 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/usr/bin/env bash result=0 -for pkg in $(glide novendor) +for pkg in $(go list ./...) do - golint -set_exit_status "$pkg" || result=1 + staticcheck "$pkg" || result=1 go vet "$pkg" || result=1 done exit $result diff --git a/scripts/test.sh b/scripts/test.sh index 9c3d2901..3f23aff9 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" DEBUG_LOG=${DEBUG_LOG:-"/dev/null"} diff --git a/scripts/unit_test.sh b/scripts/unit_test.sh index 226cac6c..c3638a87 100755 --- a/scripts/unit_test.sh +++ b/scripts/unit_test.sh @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash go test -v $(go list ./... | grep -v '/vendor\|_test' | sed 's+_/'$(pwd)'+github.com/joyent/containerpilot+') -bench . diff --git a/subcommands/subcommands.go b/subcommands/subcommands.go index 4c5c7c72..8feecf0e 100644 --- a/subcommands/subcommands.go +++ b/subcommands/subcommands.go @@ -130,8 +130,10 @@ func initClient(configPath string) (*client.HTTPClient, error) { // we're using an interface{} for params for Handler but these should // never fail to type-assert. so this assert should be unreachable // unless we've screwed something up. -func assert(ok bool, msg string) { - if !ok { - panic("invalid parameter types for %v") - } -} +// +// staticcheck U1000 func unused +//func assert(ok bool, msg string) { +// if !ok { +// panic("invalid parameter types for %v") +// } +//} diff --git a/telemetry/metrics_test.go b/telemetry/metrics_test.go index c8942182..13ab0bef 100644 --- a/telemetry/metrics_test.go +++ b/telemetry/metrics_test.go @@ -3,7 +3,7 @@ package telemetry import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "reflect" @@ -12,6 +12,7 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/stretchr/testify/assert" "github.com/joyent/containerpilot/events" @@ -25,7 +26,7 @@ the prometheus handler and then check the results of a GET. */ func TestMetricRun(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() cfg := &MetricConfig{ Namespace: "telemetry", @@ -41,7 +42,7 @@ func TestMetricRun(t *testing.T) { ctx := context.Background() metric.Run(ctx, bus) - record := events.Event{events.Metric, fmt.Sprintf("%s|84", metric.Name)} + record := events.Event{Code: events.Metric, Source: fmt.Sprintf("%s|84", metric.Name)} bus.Publish(record) metric.Receive(events.QuitByTest) @@ -61,7 +62,7 @@ func TestMetricRun(t *testing.T) { // TestMetricProcessMetric covers the same ground as the 4 collector- // specific tests below, but checks the unhappy path. func TestMetricProcessMetric(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() cfg := &MetricConfig{ Namespace: "telemetry", @@ -106,7 +107,7 @@ func TestMetricProcessMetric(t *testing.T) { } func TestMetricRecordCounter(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() metric := &Metric{ Type: Counter, @@ -135,7 +136,7 @@ func TestMetricRecordCounter(t *testing.T) { } func TestMetricRecordGauge(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() metric := &Metric{ Type: Gauge, @@ -165,7 +166,7 @@ func TestMetricRecordGauge(t *testing.T) { } func TestMetricRecordHistogram(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() metric := &Metric{ @@ -202,15 +203,18 @@ func TestMetricRecordHistogram(t *testing.T) { } func TestMetricRecordSummary(t *testing.T) { - testServer := httptest.NewServer(prometheus.UninstrumentedHandler()) + testServer := httptest.NewServer(promhttp.Handler()) defer testServer.Close() + objMap := map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} + metric := &Metric{ Type: Summary, collector: prometheus.NewSummary(prometheus.SummaryOpts{ - Namespace: "telemetry", - Subsystem: "metrics", - Name: "TestMetricRecordSummary", - Help: "help", + Namespace: "telemetry", + Subsystem: "metrics", + Name: "TestMetricRecordSummary", + Help: "help", + Objectives: objMap, })} prometheus.MustRegister(metric.collector) patt := `telemetry_metrics_TestMetricRecordSummary{quantile="([\.0-9]*)"} ([0-9\.]*)` @@ -266,7 +270,7 @@ func getFromTestServer(t *testing.T, testServer *httptest.Server) string { t.Fatal(err) } else { defer res.Body.Close() - if resp, err := ioutil.ReadAll(res.Body); err != nil { + if resp, err := io.ReadAll(res.Body); err != nil { t.Fatal(err) } else { response := string(resp) diff --git a/telemetry/status.go b/telemetry/status.go index 8746887c..79ecc920 100644 --- a/telemetry/status.go +++ b/telemetry/status.go @@ -2,7 +2,6 @@ package telemetry import ( "encoding/json" - "fmt" "net/http" "strings" @@ -51,7 +50,7 @@ func (sh StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } for _, job := range sh.telem.Status.jobs { - status := fmt.Sprintf("%s", job.GetStatus()) + status := job.GetStatus().String() for _, service := range sh.telem.Status.Services { if service.Name == job.Name { service.Status = status @@ -78,13 +77,13 @@ func (t *Telemetry) MonitorJobs(jobs []*jobs.Job) { Name: job.Name, Address: job.Service.IPAddress, Port: job.Service.Port, - Status: fmt.Sprintf("%s", job.GetStatus()), + Status: job.GetStatus().String(), } t.Status.Services = append(t.Status.Services, serviceResponse) } else { jobResponse := &jobStatusResponse{ Name: job.Name, - Status: fmt.Sprintf("%s", job.GetStatus()), + Status: job.GetStatus().String(), } t.Status.Jobs = append(t.Status.Jobs, jobResponse) } diff --git a/telemetry/telemetry.go b/telemetry/telemetry.go index a5ab52fa..1fcaf9e5 100644 --- a/telemetry/telemetry.go +++ b/telemetry/telemetry.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" log "github.com/sirupsen/logrus" "github.com/joyent/containerpilot/version" @@ -21,8 +21,10 @@ type Telemetry struct { Status *Status // supports '/status' endpoint fields // server - router *http.ServeMux - addr net.TCPAddr + + // staticcheck U1000 field is unused + //router *http.ServeMux + addr net.TCPAddr http.Server } @@ -39,7 +41,7 @@ func NewTelemetry(cfg *Config) *Telemetry { t.addr = cfg.addr router := http.NewServeMux() - router.Handle("/metrics", prometheus.Handler()) + router.Handle("/metrics", promhttp.Handler()) router.Handle("/status", NewStatusHandler(t)) t.Handler = router @@ -57,7 +59,6 @@ func (t *Telemetry) Run(ctx context.Context) { go func() { defer t.Stop(ctx) <-ctx.Done() - return }() } diff --git a/telemetry/telemetry_config_test.go b/telemetry/telemetry_config_test.go index 51ccf377..b2cb4dfc 100644 --- a/telemetry/telemetry_config_test.go +++ b/telemetry/telemetry_config_test.go @@ -2,7 +2,7 @@ package telemetry import ( "fmt" - "io/ioutil" + "os" "strings" "testing" @@ -13,7 +13,7 @@ import ( ) func TestTelemetryConfigParse(t *testing.T) { - data, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + data, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) testCfg := tests.DecodeRaw(string(data)) telem, err := NewConfig(testCfg, &mocks.NoopDiscoveryBackend{}) if err != nil { diff --git a/telemetry/testdata/test.sh b/telemetry/testdata/test.sh index b3696f3b..ace995b3 100755 --- a/telemetry/testdata/test.sh +++ b/telemetry/testdata/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/watches/config_test.go b/watches/config_test.go index f034afc0..3e644c3b 100644 --- a/watches/config_test.go +++ b/watches/config_test.go @@ -2,7 +2,7 @@ package watches import ( "fmt" - "io/ioutil" + "os" "testing" "github.com/stretchr/testify/assert" @@ -11,7 +11,7 @@ import ( ) func TestWatchesParse(t *testing.T) { - data, _ := ioutil.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) + data, _ := os.ReadFile(fmt.Sprintf("./testdata/%s.json5", t.Name())) testCfg := tests.DecodeRawToSlice(string(data)) watches, err := NewConfigs(testCfg, nil) if err != nil { diff --git a/watches/testdata/test.sh b/watches/testdata/test.sh index c05a728d..68b2e59b 100755 --- a/watches/testdata/test.sh +++ b/watches/testdata/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash trap 'exit 2' SIGTERM diff --git a/watches/watches.go b/watches/watches.go index b549b7c3..105576fa 100644 --- a/watches/watches.go +++ b/watches/watches.go @@ -82,16 +82,16 @@ func (watch *Watch) Run(pctx context.Context, bus *events.EventBus) { if !ok || event == events.QuitByTest { return } - if event == (events.Event{events.TimerExpired, timerSource}) { + if event == (events.Event{Code: events.TimerExpired, Source: timerSource}) { didChange, isHealthy := watch.CheckForUpstreamChanges() if didChange { - watch.Publish(events.Event{events.StatusChanged, watch.Name}) + watch.Publish(events.Event{Code: events.StatusChanged, Source: watch.Name}) // we only send the StatusHealthy and StatusUnhealthy // events if there was a change if isHealthy { - watch.Publish(events.Event{events.StatusHealthy, watch.Name}) + watch.Publish(events.Event{Code: events.StatusHealthy, Source: watch.Name}) } else { - watch.Publish(events.Event{events.StatusUnhealthy, watch.Name}) + watch.Publish(events.Event{Code: events.StatusUnhealthy, Source: watch.Name}) } } } diff --git a/watches/watches_test.go b/watches/watches_test.go index 1dcb42bc..9caf196c 100644 --- a/watches/watches_test.go +++ b/watches/watches_test.go @@ -18,8 +18,8 @@ func TestWatchPollOk(t *testing.T) { // this discovery backend will always return true when we check // it for changed got := runWatchTest(cfg, 5, &mocks.NoopDiscoveryBackend{Val: true}) - changed := events.Event{events.StatusChanged, "watch.mywatchOk"} - healthy := events.Event{events.StatusHealthy, "watch.mywatchOk"} + changed := events.Event{Code: events.StatusChanged, Source: "watch.mywatchOk"} + healthy := events.Event{Code: events.StatusHealthy, Source: "watch.mywatchOk"} if got[changed] != 1 || got[healthy] != 1 { t.Fatalf("expected 2 successful StatusHealthy events but got %v", got) } @@ -31,8 +31,8 @@ func TestWatchPollFail(t *testing.T) { Poll: 1, } got := runWatchTest(cfg, 3, &mocks.NoopDiscoveryBackend{Val: false}) - changed := events.Event{events.StatusChanged, "watch.mywatchFail"} - unhealthy := events.Event{events.StatusUnhealthy, "watch.mywatchFail"} + changed := events.Event{Code: events.StatusChanged, Source: "watch.mywatchFail"} + unhealthy := events.Event{Code: events.StatusUnhealthy, Source: "watch.mywatchFail"} if got[changed] != 0 || got[unhealthy] != 0 { t.Fatalf("expected 2 failed poll events without changes, but got %v", got) } @@ -44,7 +44,7 @@ func runWatchTest(cfg *Config, count int, disc discovery.Backend) map[events.Eve watch := NewWatch(cfg) ctx := context.Background() watch.Run(ctx, bus) - poll := events.Event{events.TimerExpired, fmt.Sprintf("%s.poll", cfg.Name)} + poll := events.Event{Code: events.TimerExpired, Source: fmt.Sprintf("%s.poll", cfg.Name)} watch.Receive(poll) watch.Receive(poll) // Ensure we can run it more than once watch.Receive(events.QuitByTest)