From e37b86fda6a02976388505a43be985b5b27f762e Mon Sep 17 00:00:00 2001 From: Blaine Gardner Date: Thu, 15 Aug 2024 16:55:54 -0600 Subject: [PATCH] standardize make tooling with top level Makefile Standardize make tooling. Remove unnecessary duplication where possible, including with common copies of go fmt/vet/test targets. Slighty shift around controller and sidecar 'cmd/' directories to allow specifying a template Dockerfile that can be used to generate Dockerfiles for each image easily. Where it makes sense, this work adopts the make target naming and Dockerfile usage of the kubebuilder project. The biggest divergence from that template is because we build 2 images from one repo, and because we have a 'proto/' dir for gRPC code. Significant testing was done to ensure that the tooling works with Unix make on MacOS as well as GNU-Make (gmake). Testing was also done to ensure the `make all` target works well with `make -j`'s parallel execution flag, allowing dev speedup where possible. Some proto targets were adjusted to allow make to do a better job detecting when file/code generation is not necessary, saving time in the common case where there are no proto changes. A future goal, which this helps lay groundwork for, will be to make sure that there are top-level make targets that are usable by Prow CI. For example, 'test' can be used to run all unit tests. Any unit tests added to any component can be included in 'make test' to ensure we don't need to make frequent changes to Prow CI definitions. Similarly 'make build' should build all binaries and images to ensure builds work. 'make generate' and 'make codegen' should include targets that generate files in any way, which will allow Prow CI to ensure developers are running all generators. In the future, we have room to add intall and/or e2e tests as make targets. Signed-off-by: Blaine Gardner --- Makefile | 108 +++++++++++++++--- client/Makefile | 26 +---- controller/Dockerfile | 33 +++--- controller/Makefile | 38 ------ .../controller-manager.go | 0 hack/Dockerfile.in | 44 +++++++ hack/gen-dockerfile.sh | 12 ++ proto/Makefile | 55 +++++---- sidecar/Dockerfile | 36 +++--- sidecar/Makefile | 38 ------ .../cmd/{objectstorage-sidecar => }/cmd.go | 0 .../cmd/{objectstorage-sidecar => }/main.go | 0 12 files changed, 219 insertions(+), 171 deletions(-) delete mode 100644 controller/Makefile rename controller/cmd/{controller-manager => }/controller-manager.go (100%) create mode 100644 hack/Dockerfile.in create mode 100755 hack/gen-dockerfile.sh delete mode 100644 sidecar/Makefile rename sidecar/cmd/{objectstorage-sidecar => }/cmd.go (100%) rename sidecar/cmd/{objectstorage-sidecar => }/main.go (100%) diff --git a/Makefile b/Makefile index 5ad22c02..8e78ef42 100644 --- a/Makefile +++ b/Makefile @@ -12,26 +12,98 @@ # See the License for the specific language governing permissions and # limitations under the License. -PROJECTNAME := $(shell basename "$(PWD)") -GOFILES := $(wildcard controller/*.go) -GOBIN := $(GOBASE)/bin +.DEFAULT_GOAL := help +.SUFFIXES: # remove legacy builtin suffixes to allow easier make debugging +SHELL = /usr/bin/env bash +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -#CMDS=cosi-controller-manager -all: unit build -#.PHONY: reltools -reltools: release-tools/build.make -release-tools/build.make: - echo "TODO: update kubernetes/test-infra when controller and sidecar can build successfully" +## +## ==== ARGS ===== # -build: -test: -unit: -codegen: - @echo "Running update-codegen to generate the code..." - bash ./hack/update-codegen.sh +## Container build tool compatible with `docker` API +DOCKER ?= docker - @echo "Running update-crd to generate the crd..." - bash ./hack/update-crd.sh +## Platform for 'build' +PLATFORM ?= linux/$(GOARCH) -include release-tools/build.make +## Image tag for controller image build +CONTROLLER_TAG ?= cosi-controller:latest + +## Image tag for sidecar image build +SIDECAR_TAG ?= cosi-provisioner-sidecar:latest + + +##@ Development + +.PHONY: all .gen +.gen: generate codegen # can be done in parallel with 'make -j' +.NOTPARALLEL: all # codegen must be finished before fmt/vet +all: .gen fmt vet build ## Build all targets, plus their prerequisites (faster with 'make -j') + +.PHONY: generate +generate: controller/Dockerfile sidecar/Dockerfile ## Generate files + $(MAKE) -C client crds + $(MAKE) -C proto generate + +.PHONY: codegen +codegen: codegen.client codegen.proto ## Generate code + +.PHONY: fmt +fmt: fmt.client fmt.controller fmt.sidecar ## Format code + +.PHONY: vet +vet: vet.client vet.controller vet.sidecar ## Vet code + +.PHONY: test +test: .test.proto test.client test.controller test.sidecar ## Run tests including unit tests + + +##@ Build + +.PHONY: build +build: build.controller build.sidecar ## Build all container images for development + +.PHONY: build.controller build.sidecar +build.controller: controller/Dockerfile ## Build only the controller container image + $(DOCKER) build --file controller/Dockerfile --platform $(PLATFORM) --tag $(CONTROLLER_TAG) . +build.sidecar: sidecar/Dockerfile ## Build only the sidecar container image + $(DOCKER) build --file sidecar/Dockerfile --platform $(PLATFORM) --tag $(SIDECAR_TAG) . + +.PHONY: clean +## Clean build environment +clean: + $(MAKE) -C proto clean + +.PHONY: clobber +## Clean build environment and cached tools +clobber: + $(MAKE) -C proto clobber + + +## +## === INTERMEDIATES === # + +%/Dockerfile: hack/Dockerfile.in hack/gen-dockerfile.sh + hack/gen-dockerfile.sh $* > "$@" + +codegen.%: FORCE + $(MAKE) -C $* codegen + +fmt.%: FORCE + cd $* && go fmt ./... + +vet.%: FORCE + cd $* && go vet ./... + +test.%: fmt.% vet.% FORCE + cd $* && go test ./... + +.PHONY: .test.proto +.test.proto: # gRPC proto has a special unit test + $(MAKE) -C proto check + +.PHONY: FORCE # use this to force phony behavior for targets with pattern rules +FORCE: diff --git a/client/Makefile b/client/Makefile index 4791d068..87a3954b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,5 +1,3 @@ -GO ?= go - # # Setting SHELL to bash allows bash commands to be executed by recipes. # Options are set to exit when a recipe line exits non-zero or a piped command fails. SHELL = /usr/bin/env bash -o pipefail @@ -15,34 +13,14 @@ help: ## Display this help. ##@ Development .PHONY: generate -generate: crds codegen fmt module vendor ## Run all code generation/modification tools. - -.PHONY: test -test: vet ## Run all tests +generate: crds codegen fmt ## Run all code generation/modification tools. ##@ Generators .PHONY: crds crds: ## Generate CustomResourceDefinitions. - $(GO) run -v ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen crd paths="./apis/objectstorage/..." + go run -v ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen crd paths="./apis/objectstorage/..." .PHONY: codegen: ## Generate deepcopy, client, informer, and lister implementations. ./hack/update-codegen.sh - -.PHONY: fmt -fmt: ## Run go fmt - $(GO) fmt ./... - -.PHONY: module ## Update go mod - $(GO) mod tidy - -.PHONY: vendor -vendor: ## Update vendor dir - $(GO) mod vendor - -##@ Tests - -.PHONY: vet -vet: ## Run go vet - $(GO) vet ./... diff --git a/controller/Dockerfile b/controller/Dockerfile index af2aaf1f..cd96dd26 100644 --- a/controller/Dockerfile +++ b/controller/Dockerfile @@ -1,43 +1,46 @@ -# NOTE: context is expected to be repo root, not controller/ dir +# DO NOT EDIT! This file is generated by 'hack/gen-dockerfile.sh' from 'Dockerfile.in' # # BUILDER # -FROM docker.io/library/golang:1.22.5 AS builder +FROM docker.io/library/golang:1.22 AS builder WORKDIR /buildroot # Cache deps before building and copying source, so that we don't need to re-download # as much and so that source changes don't invalidate our downloaded layer. COPY client/ client/ +COPY proto/ proto/ COPY internal/ internal/ + COPY controller/go.mod controller/go.mod COPY controller/go.sum controller/go.sum -WORKDIR /buildroot/controller - -RUN go mod download +RUN cd controller && go mod download -COPY controller/cmd/ cmd/ -COPY controller/pkg/ pkg/ +COPY controller/cmd/ controller/cmd/ +COPY controller/pkg/ controller/pkg/ -ENV CGO_ENABLED=0 +WORKDIR /buildroot/controller -RUN go build -o artifacts/controller-manager cmd/controller-manager/*.go +RUN CGO_ENABLED=0 go build -o /buildroot/artifacts/controller cmd/*.go # # FINAL IMAGE # -FROM gcr.io/distroless/static:latest +FROM gcr.io/distroless/static:nonroot LABEL maintainers="Kubernetes Authors" -LABEL description="COSI Controller" +LABEL description="COSI controller" -LABEL org.opencontainers.image.title="COSI Controller" -LABEL org.opencontainers.image.description="Container Object Storage Interface (COSI) Controller" +LABEL org.opencontainers.image.title="COSI controller" +LABEL org.opencontainers.image.description="Container Object Storage Interface (COSI) controller" LABEL org.opencontainers.image.source="https://github.com/kubernetes-sigs/container-object-storage-interface-api/controller" LABEL org.opencontainers.image.licenses="APACHE-2.0" -COPY --from=builder /buildroot/controller/artifacts/controller-manager . -ENTRYPOINT ["/controller-manager"] +WORKDIR / +COPY --from=builder /buildroot/artifacts/controller . +USER 65532:65532 + +ENTRYPOINT ["/controller"] diff --git a/controller/Makefile b/controller/Makefile deleted file mode 100644 index c5f666b6..00000000 --- a/controller/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -.DEFAULT_GOAL := help -SHELL = /usr/bin/env bash -THIS_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) - -# 'go env' vars aren't always available in make environments, so get defaults for needed ones -GOARCH ?= $(shell go env GOARCH) - -## -## ==== ARGS ===== # - -## Container build tool compatible with `docker` API -DOCKER ?= docker - -## Platform for 'build' -PLATFORM ?= linux/$(GOARCH) - -## Image tag for all builds -IMAGE_TAG ?= cosi-controller:latest - -## -## === TARGETS === # - -.PHONY: build -## Build local image for development, defaulting linux/ -build: - cd .. && $(DOCKER) build --file $(THIS_DIR)/Dockerfile --platform $(PLATFORM) --tag $(IMAGE_TAG) . - -.PHONY: test -## Test packages -test: - go vet ./... - go test ./... - -# print out lines beginning with double-comments, plus next line as basic help text -.PHONY: help -## Show this help text -help: - @sed -n -e "/^##/{N;s/^/\n/p;}" $(MAKEFILE_LIST) diff --git a/controller/cmd/controller-manager/controller-manager.go b/controller/cmd/controller-manager.go similarity index 100% rename from controller/cmd/controller-manager/controller-manager.go rename to controller/cmd/controller-manager.go diff --git a/hack/Dockerfile.in b/hack/Dockerfile.in new file mode 100644 index 00000000..7b8206f2 --- /dev/null +++ b/hack/Dockerfile.in @@ -0,0 +1,44 @@ +# +# BUILDER +# +FROM docker.io/library/golang:1.22 AS builder + +WORKDIR /buildroot + +# Cache deps before building and copying source, so that we don't need to re-download +# as much and so that source changes don't invalidate our downloaded layer. +COPY client/ client/ +COPY proto/ proto/ +COPY internal/ internal/ + +COPY {{COMPONENT}}/go.mod {{COMPONENT}}/go.mod +COPY {{COMPONENT}}/go.sum {{COMPONENT}}/go.sum + +RUN cd {{COMPONENT}} && go mod download + +COPY {{COMPONENT}}/cmd/ {{COMPONENT}}/cmd/ +COPY {{COMPONENT}}/pkg/ {{COMPONENT}}/pkg/ + +WORKDIR /buildroot/{{COMPONENT}} + +RUN CGO_ENABLED=0 go build -o /buildroot/artifacts/{{COMPONENT}} cmd/*.go + + +# +# FINAL IMAGE +# +FROM gcr.io/distroless/static:nonroot + +LABEL maintainers="Kubernetes Authors" +LABEL description="COSI {{COMPONENT}}" + +LABEL org.opencontainers.image.title="COSI {{COMPONENT}}" +LABEL org.opencontainers.image.description="Container Object Storage Interface (COSI) {{COMPONENT}}" +LABEL org.opencontainers.image.source="https://github.com/kubernetes-sigs/container-object-storage-interface-api/{{COMPONENT}}" +LABEL org.opencontainers.image.licenses="APACHE-2.0" + +WORKDIR / +COPY --from=builder /buildroot/artifacts/{{COMPONENT}} . +USER 65532:65532 + +ENTRYPOINT ["/{{COMPONENT}}"] diff --git a/hack/gen-dockerfile.sh b/hack/gen-dockerfile.sh new file mode 100755 index 00000000..d62000ba --- /dev/null +++ b/hack/gen-dockerfile.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +# set -o xtrace + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +COMPONENT="$1" + +echo "# DO NOT EDIT! This file is generated by '${BASH_SOURCE[0]}' from 'Dockerfile.in'" +echo "" # empty line +sed "s/{{COMPONENT}}/$COMPONENT/g" "$SCRIPT_DIR"/Dockerfile.in diff --git a/proto/Makefile b/proto/Makefile index b9673e6e..32b118b4 100644 --- a/proto/Makefile +++ b/proto/Makefile @@ -1,4 +1,6 @@ -all: build +all: check + +.SUFFIXES: # remove legacy builtin suffixes to allow easier make debugging ######################################################################## ## GOLANG ## @@ -39,7 +41,8 @@ endif PROTOC_ZIP := protoc-$(PROTOC_VER)-$(PROTOC_OS)-$(PROTOC_ARCH).zip PROTOC_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VER)/$(PROTOC_ZIP) PROTOC_TMP_DIR := .protoc -PROTOC := $(PROTOC_TMP_DIR)/bin/protoc +PROTOC_BIN_DIR := $(PROTOC_TMP_DIR)/bin +PROTOC := $(PROTOC_BIN_DIR)/protoc PROTOC_TMP_INC := $(PROTOC_TMP_DIR)/include $(PROTOC): @@ -50,17 +53,19 @@ $(PROTOC): chmod 0755 "$@" stat "$@" > /dev/null 2>&1 -$(GOBIN)/protoc-gen-go: go.mod - go install google.golang.org/protobuf/cmd/protoc-gen-go +$(PROTOC_BIN_DIR)/protoc-gen-go: go.mod + GOBIN="$(CURDIR)"/$(PROTOC_BIN_DIR) go install google.golang.org/protobuf/cmd/protoc-gen-go -$(GOBIN)/protoc-gen-go-grpc: - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 +$(PROTOC_BIN_DIR)/protoc-gen-go-grpc: + GOBIN="$(CURDIR)"/$(PROTOC_BIN_DIR) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 -$(GOBIN)/protoc-gen-go-json: - go install github.com/mitchellh/protoc-gen-go-json@v1.1.0 +$(PROTOC_BIN_DIR)/protoc-gen-go-json: + GOBIN="$(CURDIR)"/$(PROTOC_BIN_DIR) go install github.com/mitchellh/protoc-gen-go-json@v1.1.0 -PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(GOBIN)/protoc-gen-go-json $(PROTOC) +PROTOC_ALL := $(PROTOC_BIN_DIR)/protoc-gen-go $(PROTOC_BIN_DIR)/protoc-gen-go-grpc $(PROTOC_BIN_DIR)/protoc-gen-go-json $(PROTOC) +# Update PATH to discover the protoc binaries +export PATH := $(PROTOC_BIN_DIR):$(PATH) ######################################################################## ## PROTOC-GEN-GO-FAKE ## @@ -68,14 +73,10 @@ PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(GOBIN)/protoc # This is the recipe for getting and installing the grpc go PROTOC_GEN_GO_FAKE_SRC := ./hack/fake-gen -PROTOC_GEN_GO_FAKE := $(PROTOC_TMP_DIR)/bin/protoc-gen-gofake -$(PROTOC_GEN_GO_FAKE): +PROTOC_GEN_GO_FAKE := $(PROTOC_BIN_DIR)/protoc-gen-gofake +$(PROTOC_GEN_GO_FAKE): $(PROTOC_GEN_GO_FAKE_SRC) go build -o $(PROTOC_GEN_GO_FAKE) $(PROTOC_GEN_GO_FAKE_SRC) -# Update PATH to discover the protoc-gen-gofake binary -export PATH := $(PROTOC_TMP_DIR)/bin:$(PATH) - - ######################################################################## ## BUILD ## ######################################################################## @@ -104,7 +105,7 @@ $(COSI_PROTO): $(COSI_SPEC) echo "// Code generated by make; DO NOT EDIT." > "$(COSI_PROTO)" cat $(COSI_SPEC) | sed -n -e '/```protobuf$$/,/^```$$/ p' | sed '/^```/d' >> "$(COSI_PROTO)" -$(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE): $(COSI_PROTO) $(PROTOC_ALL) $(PROTOC_GEN_GO_FAKE) +$(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE) &: $(COSI_PROTO) $(PROTOC_ALL) $(PROTOC_GEN_GO_FAKE) mkdir -p "$(BUILD_TMP_DIR)" mkdir -p "$(BUILD_TMP_DIR)/fake" $(PROTOC) -I. -I$(PROTOC_TMP_INC) \ @@ -113,17 +114,29 @@ $(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE): $(COSI_PROTO) $(PROT --go-json_out=$(GO_JSON_OPTS):$(BUILD_TMP_DIR) \ --gofake_out=$(GO_FAKE_OPTS):$(BUILD_TMP_DIR)/fake \ "$(\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +.PHONY: generate generate: $(COSI_PROTO) ## Generate cosi.proto -build: generate $(BUILD_TMP_COSI_A) ## Generate protobuf files, and ensure they build +.PHONY: codegen +codegen: $(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE) ## Generate protobuf files + +.PHONY: check +check: $(BUILD_TMP_COSI_A) ## Generate protobuf files, and ensure they build .PHONY: clean clean: ## Clean all builds and generated files diff --git a/sidecar/Dockerfile b/sidecar/Dockerfile index dac57552..3952564d 100644 --- a/sidecar/Dockerfile +++ b/sidecar/Dockerfile @@ -1,44 +1,46 @@ -# NOTE: context is expected to be repo root, not sidecar/ dir +# DO NOT EDIT! This file is generated by 'hack/gen-dockerfile.sh' from 'Dockerfile.in' # # BUILDER # -FROM docker.io/library/golang:1.22.5 AS builder +FROM docker.io/library/golang:1.22 AS builder WORKDIR /buildroot # Cache deps before building and copying source, so that we don't need to re-download # as much and so that source changes don't invalidate our downloaded layer. COPY client/ client/ -COPY internal/ internal/ COPY proto/ proto/ +COPY internal/ internal/ + COPY sidecar/go.mod sidecar/go.mod COPY sidecar/go.sum sidecar/go.sum -WORKDIR /buildroot/sidecar +RUN cd sidecar && go mod download -RUN go mod download +COPY sidecar/cmd/ sidecar/cmd/ +COPY sidecar/pkg/ sidecar/pkg/ -COPY sidecar/cmd/ cmd/ -COPY sidecar/pkg/ pkg/ - -ENV CGO_ENABLED=0 +WORKDIR /buildroot/sidecar -RUN go build -o artifacts/objectstorage-sidecar cmd/objectstorage-sidecar/*.go +RUN CGO_ENABLED=0 go build -o /buildroot/artifacts/sidecar cmd/*.go # # FINAL IMAGE # -FROM gcr.io/distroless/static:latest +FROM gcr.io/distroless/static:nonroot LABEL maintainers="Kubernetes Authors" -LABEL description="COSI Storage Sidecar" +LABEL description="COSI sidecar" -LABEL org.opencontainers.image.title="COSI Storage Sidecar" -LABEL org.opencontainers.image.description="Container Object Storage Interface (COSI) Storage Provisioner Sidecar" -LABEL org.opencontainers.image.source="https://github.com/kubernetes-sigs/container-object-storage-interface-provisioner-api/sidecar" +LABEL org.opencontainers.image.title="COSI sidecar" +LABEL org.opencontainers.image.description="Container Object Storage Interface (COSI) sidecar" +LABEL org.opencontainers.image.source="https://github.com/kubernetes-sigs/container-object-storage-interface-api/sidecar" LABEL org.opencontainers.image.licenses="APACHE-2.0" -COPY --from=builder /buildroot/sidecar/artifacts/objectstorage-sidecar . -ENTRYPOINT ["/objectstorage-sidecar"] +WORKDIR / +COPY --from=builder /buildroot/artifacts/sidecar . +USER 65532:65532 + +ENTRYPOINT ["/sidecar"] diff --git a/sidecar/Makefile b/sidecar/Makefile deleted file mode 100644 index 52540807..00000000 --- a/sidecar/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -.DEFAULT_GOAL := help -SHELL = /usr/bin/env bash -THIS_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) - -# 'go env' vars aren't always available in make environments, so get defaults for needed ones -GOARCH ?= $(shell go env GOARCH) - -## -## ==== ARGS ===== # - -## Container build tool compatible with `docker` API -DOCKER ?= docker - -## Platform for 'build' -PLATFORM ?= linux/$(GOARCH) - -## Image tag for all builds -IMAGE_TAG ?= cosi-provisioner-sidecar:latest - -## -## === TARGETS === # - -.PHONY: build -## Build local image for development, defaulting linux/ -build: - cd .. && $(DOCKER) build --file $(THIS_DIR)/Dockerfile --platform $(PLATFORM) --tag $(IMAGE_TAG) . - -.PHONY: test -## Test packages -test: - go vet ./... - go test ./... - -# print out lines beginning with double-comments, plus next line as basic help text -.PHONY: help -## Show this help text -help: - @sed -n -e "/^##/{N;s/^/\n/p;}" $(MAKEFILE_LIST) diff --git a/sidecar/cmd/objectstorage-sidecar/cmd.go b/sidecar/cmd/cmd.go similarity index 100% rename from sidecar/cmd/objectstorage-sidecar/cmd.go rename to sidecar/cmd/cmd.go diff --git a/sidecar/cmd/objectstorage-sidecar/main.go b/sidecar/cmd/main.go similarity index 100% rename from sidecar/cmd/objectstorage-sidecar/main.go rename to sidecar/cmd/main.go