diff --git a/Makefile b/Makefile index f3536c864..b2c0b1f9b 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ IMAGE_PREFIX := quay.io/weaveworks IMAGE_TAG := $(shell ./tools/image-tag) GIT_REVISION := $(shell git rev-parse HEAD) UPTODATE := .uptodate +GO_TEST_IMAGE := golang:1.12.1 # Building Docker images is now automated. The convention is every directory # with a Dockerfile in it builds an image calls quay.io/weaveworks/. @@ -188,7 +189,7 @@ notification-eventmanager/$(UPTODATE): $(wildcard notification-eventmanager/migr SUDO := $(shell docker info >/dev/null 2>&1 || echo "sudo -E") BUILD_IN_CONTAINER := true RM := --rm -GO_FLAGS := -ldflags "-extldflags \"-static\" -linkmode=external -s -w" -tags netgo -i +GO_FLAGS := -ldflags "-extldflags \"-static\" -s -w" -tags netgo -i NETGO_CHECK = @strings $@ | grep cgo_stub\\\.go >/dev/null || { \ rm $@; \ echo "\nYour go standard library was built without the 'netgo' build tag."; \ @@ -272,13 +273,13 @@ $(CODECGEN_TARGETS): $(CODECGEN_EXE) $(call GET_CODECGEN_DEPS,vendor/github.com/ cd $(@D) && $(WITH_GO_HOST_ENV) $(shell pwd)/$(CODECGEN_EXE) -d $(CODECGEN_UID) -rt $(GO_BUILD_TAGS) -u -o $(@F) $(notdir $(call GET_CODECGEN_DEPS,$(@D))) $(EXES): build/$(UPTODATE) $(PROTO_GOS) - go build $(GO_FLAGS) -o $@ ./$(@D) + CGO_ENABLED=0 go build $(GO_FLAGS) -o $@ ./$(@D) $(NETGO_CHECK) %.pb.go: build/$(UPTODATE) protoc -I ./vendor:./$(@D) --gogoslick_out=plugins=grpc:./$(@D) ./$(patsubst %.pb.go,%.proto,$@) -lint: build/$(UPTODATE) +lint: build/$(UPTODATE) $(PROTO_GOS) $(MOCK_GOS) ./tools/lint . test: build/$(UPTODATE) $(PROTO_GOS) $(MOCK_GOS) $(CODECGEN_TARGETS) @@ -320,7 +321,7 @@ notebooks-integration-test: $(NOTEBOOKS_UPTODATE) -v $(shell pwd)/notebooks/db/migrations:/migrations \ --workdir /go/src/github.com/weaveworks/service/notebooks \ --link "$$DB_CONTAINER":configs-db.weave.local \ - golang:1.9.2-stretch \ + $(GO_TEST_IMAGE) \ /bin/bash -c "go test -tags integration -timeout 30s ./..."; \ status=$$?; \ test -n "$(CIRCLECI)" || docker rm -f "$$DB_CONTAINER"; \ @@ -333,7 +334,7 @@ users-integration-test: $(USERS_UPTODATE) $(PROTO_GOS) $(MOCK_GOS) -v $(shell pwd)/users/db/migrations:/migrations \ --workdir /go/src/github.com/weaveworks/service/users \ --link "$$DB_CONTAINER":users-db.weave.local \ - golang:1.9.2-stretch \ + $(GO_TEST_IMAGE) \ /bin/bash -c "go test -tags integration -timeout 30s ./..."; \ status=$$?; \ test -n "$(CIRCLECI)" || docker rm -f "$$DB_CONTAINER"; \ @@ -345,7 +346,7 @@ pubsub-integration-test: -v $(shell pwd):/go/src/github.com/weaveworks/service \ --net=host -p 127.0.0.1:1337:1337 \ --workdir /go/src/github.com/weaveworks/service/common/gcp/pubsub \ - golang:1.9.2-stretch \ + $(GO_TEST_IMAGE) \ /bin/bash -c "RUN_MANUAL_TEST=1 go test -tags integration -timeout 30s ./..."; \ status=$$?; \ test -n "$(CIRCLECI)" || docker rm -f "$$PUBSUB_EMU_CONTAINER"; \ @@ -357,7 +358,7 @@ kubectl-service-integration-test: kubectl-service/$(UPTODATE) kubectl-service/gr -v $(shell pwd):/go/src/github.com/weaveworks/service \ --workdir /go/src/github.com/weaveworks/service/kubectl-service \ --link "$$SVC_CONTAINER":kubectl-service.weave.local \ - golang:1.9.2-stretch \ + $(GO_TEST_IMAGE) \ /bin/bash -c "go test -tags integration -timeout 30s ./..."; \ status=$$?; \ test -n "$(CIRCLECI)" || docker rm -f "$$SVC_CONTAINER"; \ @@ -369,7 +370,7 @@ gcp-service-integration-test: gcp-service/$(UPTODATE) gcp-service/grpc/gcp-servi -v $(shell pwd):/go/src/github.com/weaveworks/service \ --workdir /go/src/github.com/weaveworks/service/gcp-service \ --link "$$SVC_CONTAINER":gcp-service.weave.local \ - golang:1.9.2-stretch \ + $(GO_TEST_IMAGE) \ /bin/bash -c "go test -tags integration -timeout 30s ./..."; \ status=$$?; \ test -n "$(CIRCLECI)" || docker rm -f "$$SVC_CONTAINER"; \ diff --git a/billing-api/routes/invoices_test.go b/billing-api/routes/invoices_test.go index c80115c2d..d1fbbfc56 100644 --- a/billing-api/routes/invoices_test.go +++ b/billing-api/routes/invoices_test.go @@ -65,18 +65,18 @@ func (z *zuoraStubInvoices) CreateInvoice(ctx context.Context, zuoraAccountNumbe func createInvoice(status, fileURL string) zuora.Invoice { return zuora.Invoice{ - ID: "2c92c0955e0d9cb9015e0f8492c00ef5", - AccountName: "feisty-resonance-96", - AccountNumber: "Wbee8866756aee4702b5e4f9021a44a2", - InvoiceDate: "2017-08-23", - InvoiceNumber: "INV00000030", - DueDate: "2017-08-23", - InvoiceTargetDate: "2017-09-08", - Amount: 19.86, - Balance: 19.86, + ID: "2c92c0955e0d9cb9015e0f8492c00ef5", + AccountName: "feisty-resonance-96", + AccountNumber: "Wbee8866756aee4702b5e4f9021a44a2", + InvoiceDate: "2017-08-23", + InvoiceNumber: "INV00000030", + DueDate: "2017-08-23", + InvoiceTargetDate: "2017-09-08", + Amount: 19.86, + Balance: 19.86, CreditBalanceAdjustmentAmount: 0, - Status: status, - Body: fileURL, + Status: status, + Body: fileURL, InvoiceItems: []zuora.InvoiceItem{ { ID: "2c92c0955e0d9cb9015e0f8492c40ef7", diff --git a/build/Dockerfile b/build/Dockerfile index 332b04580..a89ecfdd2 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.10.8 +FROM golang:1.12.1 RUN apt-get update && apt-get install -y \ python-pip \ python-requests \ @@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y \ libprotobuf-dev=3.0.0-9 && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN go clean -i net && \ - go install -tags netgo std && \ + CGO_ENABLED=0 go install -tags netgo std && \ go install -race -tags netgo std sync/atomic RUN go get -tags netgo \ github.com/fzipp/gocyclo \ diff --git a/build/build.sh b/build/build.sh index e83dfa810..3807f1c52 100755 --- a/build/build.sh +++ b/build/build.sh @@ -18,6 +18,6 @@ echo "weave:*:::::::" >>/etc/shadow echo "weave ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers # Grant full access to paths where dependencies are typically installed: -chmod -R 777 /go/pkg +chmod -R 777 /go/pkg /usr/local/go/pkg su weave -c "PATH=$PATH make -C $SRC_PATH BUILD_IN_CONTAINER=false $*" diff --git a/common/gcp/gke/kubeconfig.go b/common/gcp/gke/kubeconfig.go index 91ee3621c..5b284624d 100644 --- a/common/gcp/gke/kubeconfig.go +++ b/common/gcp/gke/kubeconfig.go @@ -82,7 +82,7 @@ func NewKubeConfig(clusterName, endpoint, username, password, clusterCaCertifica Name: clusterName, Cluster: ClusterCfg{ CertificateAuthorityData: clusterCaCertificate, - Server: fmt.Sprintf("https://%v", endpoint), + Server: fmt.Sprintf("https://%v", endpoint), }, }, }, diff --git a/common/gcp/gke/kubeconfig_test.go b/common/gcp/gke/kubeconfig_test.go index 31ab71519..fd593c3bf 100644 --- a/common/gcp/gke/kubeconfig_test.go +++ b/common/gcp/gke/kubeconfig_test.go @@ -85,7 +85,7 @@ func TestCreateManuallyAndMarshalKubeConfig(t *testing.T) { Name: "dev", Cluster: gke.ClusterCfg{ CertificateAuthorityData: "foo", - Server: "https://192.168.0.1", + Server: "https://192.168.0.1", }, }, }, diff --git a/common/zuora/payments_test.go b/common/zuora/payments_test.go index 8db5f85ce..d68f5e9c9 100644 --- a/common/zuora/payments_test.go +++ b/common/zuora/payments_test.go @@ -85,7 +85,7 @@ func TestGetPaymentTransactionLog(t *testing.T) { }, }, GatewayTransactionNumber: "", - Status: "Error", + Status: "Error", }, payment) txLog, err := client.GetPaymentTransactionLog(context.Background(), payment.ID) diff --git a/flux-api/http/server.go b/flux-api/http/server.go index f18df1037..4565cab93 100644 --- a/flux-api/http/server.go +++ b/flux-api/http/server.go @@ -126,9 +126,9 @@ func (s Server) MakeHandler(r *mux.Router) http.Handler { transport.RegisterDaemonV11: s.registerV11, transport.LogEvent: s.logEvent, // UI routes - Status: s.status, - History: s.history, - Ping: s.ping, + Status: s.status, + History: s.history, + Ping: s.ping, PostIntegrationsGithub: s.postIntegrationsGithub, GetGithubRepos: s.getGithubRepos, // Webhooks diff --git a/gcp-launcher-webhook/main.go b/gcp-launcher-webhook/main.go index 5c325e882..f5f3b266e 100644 --- a/gcp-launcher-webhook/main.go +++ b/gcp-launcher-webhook/main.go @@ -92,7 +92,7 @@ func main() { HTTPListenPort: cfg.port, MetricsNamespace: common.PrometheusNamespace, RegisterInstrumentation: true, - Log: logging.Logrus(log.StandardLogger()), + Log: logging.Logrus(log.StandardLogger()), } server, err := server.New(serverCfg) if err != nil { diff --git a/gcp-service/main.go b/gcp-service/main.go index e73a88a83..3085b6dcb 100644 --- a/gcp-service/main.go +++ b/gcp-service/main.go @@ -46,7 +46,7 @@ func main() { GRPCListenPort: *grpcPort, GRPCMiddleware: []googlegrpc.UnaryServerInterceptor{render.GRPCErrorInterceptor}, RegisterInstrumentation: true, - Log: logging.Logrus(log.StandardLogger()), + Log: logging.Logrus(log.StandardLogger()), }) if err != nil { log.Fatalf("Failed to create gcp-service's server: %v", err) diff --git a/notebooks/db/postgres/postgres.go b/notebooks/db/postgres/postgres.go index a4cfc404a..82fdf45a1 100644 --- a/notebooks/db/postgres/postgres.go +++ b/notebooks/db/postgres/postgres.go @@ -267,7 +267,7 @@ func (d DB) Transaction(f func(DB) error) error { if err != nil { // Rollback error is ignored as we already have one in progress if err2 := tx.Rollback(); err2 != nil { - log.Warn("transaction rollback: %v (ignored)", err2) + log.Warnf("transaction rollback: %v (ignored)", err2) } return err } diff --git a/notification-eventmanager/eventmanager/notification.go b/notification-eventmanager/eventmanager/notification.go index 78d98c0d2..5603cfa55 100644 --- a/notification-eventmanager/eventmanager/notification.go +++ b/notification-eventmanager/eventmanager/notification.go @@ -97,7 +97,7 @@ func (em *EventManager) notificationBatchToSendInput(batch []types.Notification) for i, notif := range batch { notifStr, err := notificationToString(notif) if err != nil { - return nil, errors.Wrapf(err, "cannot marshal notification %s to string", notif) + return nil, errors.Wrapf(err, "cannot marshal notification %v to string", notif) } entry := &sqs.SendMessageBatchRequestEntry{ Id: aws.String(strconv.Itoa(i)), @@ -114,7 +114,7 @@ func (em *EventManager) notificationBatchToSendInput(batch []types.Notification) func notificationToString(n types.Notification) (string, error) { raw, err := json.Marshal(n) if err != nil { - return "", errors.Wrapf(err, "cannot marshal notification %s", n) + return "", errors.Wrapf(err, "cannot marshal notification %v", n) } return string(raw), nil diff --git a/notification-eventmanager/eventmanager/render/cortex.go b/notification-eventmanager/eventmanager/render/cortex.go index f0781279c..f385b7b4a 100644 --- a/notification-eventmanager/eventmanager/render/cortex.go +++ b/notification-eventmanager/eventmanager/render/cortex.go @@ -557,7 +557,7 @@ func PagerDutyFromAlert(wa types.WebhookAlert, etype, instanceName string) (json msgRaw, err := json.Marshal(pdMsg) if err != nil { - return nil, errors.Wrapf(err, "cannot marshal to json PagerDuty message: %s", pdMsg) + return nil, errors.Wrapf(err, "cannot marshal to json PagerDuty message: %v", pdMsg) } return msgRaw, nil diff --git a/notification-eventmanager/eventmanager/render/slack.go b/notification-eventmanager/eventmanager/render/slack.go index 48dd0dacf..05510ed6a 100644 --- a/notification-eventmanager/eventmanager/render/slack.go +++ b/notification-eventmanager/eventmanager/render/slack.go @@ -142,7 +142,7 @@ func PagerDutyFromSlack(text, etype, instanceName, link, linkText string) (json. msgRaw, err := json.Marshal(pdMsg) if err != nil { - return nil, errors.Wrapf(err, "cannot marshal to json PagerDuty message: %s", pdMsg) + return nil, errors.Wrapf(err, "cannot marshal to json PagerDuty message: %v", pdMsg) } return msgRaw, nil diff --git a/notification-sender/pagerduty.go b/notification-sender/pagerduty.go index 10be47442..bb965efe7 100644 --- a/notification-sender/pagerduty.go +++ b/notification-sender/pagerduty.go @@ -46,14 +46,14 @@ func (pds *PagerDutySender) Send(ctx context.Context, addr json.RawMessage, noti var m types.PagerDutyMessage if err := json.Unmarshal(notif.Data, &m); err != nil { - return errors.Wrapf(err, "cannot unmarshal PagerDuty data %s", notif.Data) + return errors.Wrapf(err, "cannot unmarshal PagerDuty data %v", notif.Data) } m.RoutingKey = key b, err := json.Marshal(m) if err != nil { - return errors.Wrapf(err, "cannot marshal PagerDuty message %s", m) + return errors.Wrapf(err, "cannot marshal PagerDuty message %v", m) } req, err := http.NewRequest("POST", endpoint, bytes.NewReader(b)) diff --git a/tools/build/golang/Dockerfile b/tools/build/golang/Dockerfile index 17c19ed3f..e20873a44 100644 --- a/tools/build/golang/Dockerfile +++ b/tools/build/golang/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.11.1-stretch +FROM golang:1.12.1-stretch RUN apt-get update && \ apt-get install -y \ curl \ diff --git a/tools/lint b/tools/lint index 9db7970d1..40ad4e7f6 100755 --- a/tools/lint +++ b/tools/lint @@ -65,6 +65,7 @@ spell_check() { } lint_go() { + # This function is called on a whole directory containing Go files local filename="$1" local lint_result=0 @@ -73,7 +74,7 @@ lint_go() { echo "${filename}: run gofmt -s -w ${filename}" fi - go tool vet "${filename}" || lint_result=$? + go vet "${filename}" || lint_result=$? # golint is completely optional. If you don't like it # don't have it installed. @@ -185,7 +186,7 @@ lint() { case "$mimetype.$ext" in text/x-shellscript.*) lint_sh "${filename}" || lint_result=1 ;; - *.go) lint_go "${filename}" || lint_result=1 ;; + *.go) ;; # done at directory level *.tf) lint_tf "${filename}" || lint_result=1 ;; *.md) lint_md "${filename}" || lint_result=1 ;; *.py) lint_py "${filename}" || lint_result=1 ;; @@ -208,7 +209,7 @@ lint_files() { while read -r filename; do lint "${filename}" || lint_result=1 done - exit $lint_result + return $lint_result } matches_any() { @@ -239,18 +240,33 @@ filter_out() { fi } -list_files() { +lint_directory() { + local dirname="$1" + local lint_result=0 + # This test is just checking if there are any Go files in the directory + if compgen -G "$dirname/*.go" >/dev/null; then + lint_go "${dirname}" || lint_result=1 + fi + ls $dirname/* | filter_out "$LINT_IGNORE_FILE" | lint_files + return $lint_result +} + +lint_directories() { + local lint_result=0 + while read -r dirname; do + lint_directory "${dirname}" || lint_result=1 + done + exit $lint_result +} + +list_directories() { if [ $# -gt 0 ]; then - find "$@" \( -name vendor -o -name .git \) -prune -o -type f - else - git ls-files --exclude-standard | grep -vE '(^|/)vendor/' + find "$@" \( -name vendor -o -name .git -o -name .cache -o -name .pkg \) -prune -o -type d fi } if [ $# = 1 ] && [ -f "$1" ]; then lint "$1" -elif [ -n "$PARALLEL" ]; then - list_files "$@" | filter_out "$LINT_IGNORE_FILE" | xargs -n1 -P16 "$0" else - list_files "$@" | filter_out "$LINT_IGNORE_FILE" | lint_files + list_directories "$@" | lint_directories fi diff --git a/users-sync/cmd/users-sync.go b/users-sync/cmd/users-sync.go index 06445dba7..1a9914620 100644 --- a/users-sync/cmd/users-sync.go +++ b/users-sync/cmd/users-sync.go @@ -101,7 +101,7 @@ func main() { GRPCListenPort: *grpcPort, GRPCMiddleware: []grpc.UnaryServerInterceptor{render.GRPCErrorInterceptor}, RegisterInstrumentation: true, - Log: logger, + Log: logger, }) if err != nil { logrus.Fatalf("Failed to create server: %v", err) diff --git a/users/api/org_test.go b/users/api/org_test.go index 13ed22530..d0aebd9fe 100644 --- a/users/api/org_test.go +++ b/users/api/org_test.go @@ -453,7 +453,7 @@ func Test_CustomExternalIDOrganization_Validation(t *testing.T) { user, otherOrg := getOrg(t) for id, errMsg := range map[string]string{ - "": "ID cannot be blank", + "": "ID cannot be blank", "org with^/invalid&characters": "ID can only contain letters, numbers, hyphen, and underscore", otherOrg.ExternalID: "ID is already taken", } { diff --git a/users/client/middleware.go b/users/client/middleware.go index 018b5bc62..a41138fdb 100644 --- a/users/client/middleware.go +++ b/users/client/middleware.go @@ -378,7 +378,7 @@ func (a UserPermissionsMiddleware) Wrap(next http.Handler) http.Handler { if MethodMatched && URIMatched { if _, err := a.UsersClient.RequireOrgMemberPermissionTo(r.Context(), &users.RequireOrgMemberPermissionToRequest{ - OrgID: &users.RequireOrgMemberPermissionToRequest_OrgExternalID{mux.Vars(r)["orgExternalID"]}, + OrgID: &users.RequireOrgMemberPermissionToRequest_OrgExternalID{OrgExternalID: mux.Vars(r)["orgExternalID"]}, UserID: r.Header.Get(a.UserIDHeader), PermissionID: p.PermissionID, }); err != nil { @@ -403,7 +403,7 @@ func (a ScopeCensorMiddleware) Wrap(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // If the user has no permission to view the token, we tell Scope to hide all the sensitive data for the request. if _, err := a.UsersClient.RequireOrgMemberPermissionTo(r.Context(), &users.RequireOrgMemberPermissionToRequest{ - OrgID: &users.RequireOrgMemberPermissionToRequest_OrgExternalID{mux.Vars(r)["orgExternalID"]}, + OrgID: &users.RequireOrgMemberPermissionToRequest_OrgExternalID{OrgExternalID: mux.Vars(r)["orgExternalID"]}, UserID: r.Header.Get(a.UserIDHeader), PermissionID: permission.ViewToken, }); err != nil { diff --git a/users/cmd/users/main.go b/users/cmd/users/main.go index d5ef22b92..3d43c1561 100644 --- a/users/cmd/users/main.go +++ b/users/cmd/users/main.go @@ -210,7 +210,7 @@ func main() { GRPCListenPort: *grpcPort, GRPCMiddleware: []grpc.UnaryServerInterceptor{render.GRPCErrorInterceptor}, RegisterInstrumentation: true, - Log: logging.Logrus(log.StandardLogger()), + Log: logging.Logrus(log.StandardLogger()), }) if err != nil { log.Fatalf("Failed to create server: %v", err) diff --git a/users/marketing/queue.go b/users/marketing/queue.go index dc6f1bb13..6992e302d 100644 --- a/users/marketing/queue.go +++ b/users/marketing/queue.go @@ -196,7 +196,7 @@ func (c *Queue) OrganizationBillingConfigured(email string, orgExternalID string c.Lock() defer c.Unlock() c.prospects = append(c.prospects, Prospect{ - Email: email, + Email: email, OrganizationBillingConfiguredExternalID: orgExternalID, OrganizationBillingConfiguredName: orgName, })