Skip to content

Commit 3a58c16

Browse files
authored
Merge pull request #2080 from chrischdi/pr-hack-tools-go-install
🌱 Refactor how tools are built to align with CAPI and get rid of tools go.mod
2 parents 2100b43 + 3c08fec commit 3a58c16

File tree

6 files changed

+229
-998
lines changed

6 files changed

+229
-998
lines changed

Makefile

Lines changed: 150 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,16 @@ export KUBEBUILDER_ENVTEST_KUBERNETES_VERSION ?= 1.25.0
4141
# Directories
4242
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
4343
BIN_DIR := $(ROOT_DIR)/bin
44-
TOOLS_DIR := $(ROOT_DIR)/hack/tools
45-
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin
44+
TOOLS_BIN_DIR := $(ROOT_DIR)/hack/tools/bin
4645
export PATH := $(abspath $(TOOLS_BIN_DIR)):$(PATH)
46+
47+
# Set --output-base for conversion-gen if we are not within GOPATH
48+
ifneq ($(abspath $(ROOT_DIR)),$(shell go env GOPATH)/src/sigs.k8s.io/cluster-api-provider-vsphere)
49+
OUTPUT_BASE := --output-base=$(ROOT_DIR)
50+
else
51+
export GOPATH := $(shell go env GOPATH)
52+
endif
53+
4754
FLAVOR_DIR := $(ROOT_DIR)/templates
4855

4956
E2E_CONF_FILE ?= "$(abspath test/e2e/config/vsphere-dev.yaml)"
@@ -56,41 +63,75 @@ CLUSTERCTL := $(BIN_DIR)/clusterctl
5663

5764
# Tooling binaries
5865
GO_INSTALL := ./hack/go-install.sh
66+
GO_TOOLS_BUILD := ./hack/go-tools-build.sh
67+
68+
# Helper function to get dependency version from go.mod
69+
get_go_version = $(shell go list -m $1 | awk '{print $$NF}')
70+
71+
#
72+
# Binaries.
73+
#
74+
# Note: Need to use abspath so we can invoke these from subdirectories
75+
KUSTOMIZE_VER := v4.5.2
76+
KUSTOMIZE_BIN := kustomize
77+
KUSTOMIZE := $(abspath $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN)-$(KUSTOMIZE_VER))
78+
KUSTOMIZE_PKG := sigs.k8s.io/kustomize/kustomize/v4
79+
80+
SETUP_ENVTEST_VER := v0.0.0-20211110210527-619e6b92dab9
81+
SETUP_ENVTEST_BIN := setup-envtest
82+
SETUP_ENVTEST := $(abspath $(TOOLS_BIN_DIR)/$(SETUP_ENVTEST_BIN)-$(SETUP_ENVTEST_VER))
83+
SETUP_ENVTEST_PKG := sigs.k8s.io/controller-runtime/tools/setup-envtest
5984

6085
CONTROLLER_GEN_VER := v0.12.1
6186
CONTROLLER_GEN_BIN := controller-gen
6287
CONTROLLER_GEN := $(abspath $(TOOLS_BIN_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER))
6388
CONTROLLER_GEN_PKG := sigs.k8s.io/controller-tools/cmd/controller-gen
6489

65-
GOVC_VER := $(shell cat go.mod | grep "github.com/vmware/govmomi" | awk '{print $$NF}')
66-
GOVC_BIN := govc
67-
GOVC := $(abspath $(TOOLS_BIN_DIR)/$(GOVC_BIN)-$(GOVC_VER))
68-
GOVC_PKG := github.com/vmware/govmomi/govc
90+
CONVERSION_GEN_VER := v0.27.1
91+
CONVERSION_GEN_BIN := conversion-gen
92+
# We are intentionally using the binary without version suffix, to avoid the version
93+
# in generated files.
94+
CONVERSION_GEN := $(abspath $(TOOLS_BIN_DIR)/$(CONVERSION_GEN_BIN))
95+
CONVERSION_GEN_PKG := k8s.io/code-generator/cmd/conversion-gen
6996

70-
KUSTOMIZE_VER := v4.5.2
71-
KUSTOMIZE_BIN := kustomize
72-
KUSTOMIZE := $(abspath $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN)-$(KUSTOMIZE_VER))
73-
KUSTOMIZE_PKG := sigs.k8s.io/kustomize/kustomize/v4
97+
GO_APIDIFF_VER := v0.6.0
98+
GO_APIDIFF_BIN := go-apidiff
99+
GO_APIDIFF := $(abspath $(TOOLS_BIN_DIR)/$(GO_APIDIFF_BIN)-$(GO_APIDIFF_VER))
100+
GO_APIDIFF_PKG := github.com/joelanford/go-apidiff
101+
102+
GINKGO_BIN := ginkgo
103+
GINGKO_VER := $(call get_go_version,github.com/onsi/ginkgo/v2)
104+
GINKGO := $(abspath $(TOOLS_BIN_DIR)/$(GINKGO_BIN)-$(GINGKO_VER))
105+
GINKGO_PKG := github.com/onsi/ginkgo/v2/ginkgo
74106

75107
GOLANGCI_LINT_BIN := golangci-lint
76108
GOLANGCI_LINT_VER := $(shell cat .github/workflows/golangci-lint.yaml | grep [[:space:]]version: | sed 's/.*version: //')
77109
GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER))
78110
GOLANGCI_LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint
79111

80-
CONVERSION_GEN := $(TOOLS_BIN_DIR)/conversion-gen
81-
GINKGO := $(TOOLS_BIN_DIR)/ginkgo
82-
KIND := $(TOOLS_BIN_DIR)/kind
83-
SETUP_ENVTEST := $(abspath $(TOOLS_BIN_DIR)/setup-envtest)
84-
CONVERSION_VERIFIER := $(abspath $(TOOLS_BIN_DIR)/conversion-verifier)
85-
GO_APIDIFF := $(TOOLS_BIN_DIR)/go-apidiff
86-
RELEASE_NOTES := $(TOOLS_BIN_DIR)/release-notes
87-
TOOLING_BINARIES := $(CONVERSION_GEN) $(GINKGO) $(KIND) $(CONVERSION_VERIFIER) $(GO_APIDIFF) $(RELEASE_NOTES)
88-
ARTIFACTS ?= $(ROOT_DIR)/_artifacts
112+
GOVC_VER := $(shell cat go.mod | grep "github.com/vmware/govmomi" | awk '{print $$NF}')
113+
GOVC_BIN := govc
114+
GOVC := $(abspath $(TOOLS_BIN_DIR)/$(GOVC_BIN)-$(GOVC_VER))
115+
GOVC_PKG := github.com/vmware/govmomi/govc
89116

90-
# Set --output-base for conversion-gen if we are not within GOPATH
91-
ifneq ($(abspath $(ROOT_DIR)),$(shell go env GOPATH)/src/sigs.k8s.io/cluster-api-provider-vsphere)
92-
OUTPUT_BASE := --output-base=$(ROOT_DIR)
93-
endif
117+
KIND_VER := $(call get_go_version,sigs.k8s.io/kind)
118+
KIND_BIN := kind
119+
KIND := $(abspath $(TOOLS_BIN_DIR)/$(KIND_BIN)-$(KIND_VER))
120+
KIND_PKG := sigs.k8s.io/kind
121+
122+
CAPI_HACK_TOOLS_VER := 038b533a1 # Note: this is the commit ID of the dependend CAPI release tag, currently v1.5.0-rc.0
123+
124+
CONVERSION_VERIFIER_VER := $(CAPI_HACK_TOOLS_VER)
125+
CONVERSION_VERIFIER_BIN := conversion-verifier
126+
CONVERSION_VERIFIER := $(abspath $(TOOLS_BIN_DIR)/$(CONVERSION_VERIFIER_BIN)-$(CONVERSION_VERIFIER_VER))
127+
CONVERSION_VERIFIER_PKG := sigs.k8s.io/cluster-api/hack/tools/conversion-verifier
128+
129+
RELEASE_NOTES_VER := $(CAPI_HACK_TOOLS_VER)
130+
RELEASE_NOTES_BIN := release-notes
131+
RELEASE_NOTES := $(abspath $(TOOLS_BIN_DIR)/$(RELEASE_NOTES_BIN)-$(RELEASE_NOTES_VER))
132+
RELEASE_NOTES_PKG := sigs.k8s.io/cluster-api/hack/tools/release
133+
134+
ARTIFACTS ?= $(ROOT_DIR)/_artifacts
94135

95136
# Allow overriding manifest generation destination directory
96137
MANIFEST_ROOT ?= ./config
@@ -146,7 +187,7 @@ LDFLAGS := $(shell hack/version.sh)
146187
## --------------------------------------
147188

148189
help: ## Display this help
149-
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
190+
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[0-9A-Za-z_-]+:.*?##/ { printf " \033[36m%-50s\033[0m %s\n", $$1, $$2 } /^\$$\([0-9A-Za-z_-]+\):.*?##/ { gsub("_","-", $$1); printf " \033[36m%-50s\033[0m %s\n", tolower(substr($$1, 3, length($$1)-7)), $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
150191

151192
## --------------------------------------
152193
## Testing
@@ -237,42 +278,6 @@ clusterctl: $(CLUSTERCTL) ## Build clusterctl binary
237278
$(CLUSTERCTL): go.mod
238279
go build -o $@ sigs.k8s.io/cluster-api/cmd/clusterctl
239280

240-
$(SETUP_ENVTEST): $(TOOLS_DIR)/go.mod # Build setup-envtest from tools folder.
241-
cd $(TOOLS_DIR); go build -tags=tools -o $(TOOLS_BIN_DIR)/setup-envtest sigs.k8s.io/controller-runtime/tools/setup-envtest
242-
243-
## --------------------------------------
244-
## Tooling Binaries
245-
## --------------------------------------
246-
tools: $(TOOLING_BINARIES) ## Build tooling binaries
247-
.PHONY: $(TOOLING_BINARIES)
248-
$(TOOLING_BINARIES):
249-
make -C $(TOOLS_DIR) $(@F)
250-
251-
$(CONTROLLER_GEN): # Build CONTROLLER_GEN from tools folder.
252-
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(CONTROLLER_GEN_PKG) $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER)
253-
254-
.PHONY: $(CONTROLLER_GEN_BIN)
255-
$(CONTROLLER_GEN_BIN): $(CONTROLLER_GEN) ## Build a local copy of controller-gen.
256-
257-
258-
$(GOVC): # Build GOVC from tools folder.
259-
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOVC_PKG) $(GOVC_BIN) $(GOVC_VER)
260-
261-
.PHONY: $(GOVC_BIN)
262-
$(GOVC_BIN): $(GOVC) ## Build a local copy of govc.
263-
264-
$(KUSTOMIZE): # Build kustomize from tools folder.
265-
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(KUSTOMIZE_PKG) $(KUSTOMIZE_BIN) $(KUSTOMIZE_VER)
266-
267-
.PHONY: $(KUSTOMIZE_BIN)
268-
$(KUSTOMIZE_BIN): $(KUSTOMIZE) ## Build a local copy of kustomize.
269-
270-
.PHONY: $(GOLANGCI_LINT_BIN)
271-
$(GOLANGCI_LINT_BIN): $(GOLANGCI_LINT) ## Build a local copy of golangci-lint.
272-
273-
$(GOLANGCI_LINT): # Build golangci-lint from tools folder.
274-
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOLANGCI_LINT_PKG) $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER)
275-
276281
## --------------------------------------
277282
## Linting and fixing linter errors
278283
## --------------------------------------
@@ -317,7 +322,6 @@ apidiff: $(GO_APIDIFF) ## Run the apidiff tool
317322
.PHONY: modules
318323
modules: ## Runs go mod to ensure proper vendoring
319324
go mod tidy
320-
cd $(TOOLS_DIR); go mod tidy
321325

322326
.PHONY: generate
323327
generate: ## Generate code
@@ -422,7 +426,7 @@ manifests: $(STAGE)-version-check $(STAGE)-flavors $(MANIFEST_DIR) $(BUILD_DIR)
422426
"$(KUSTOMIZE)" build $(BUILD_DIR)/config/supervisor > $(MANIFEST_DIR)/infrastructure-components-supervisor.yaml
423427

424428
.PHONY: generate-release-notes
425-
generate-release-notes: $(RELEASE_NOTES_DIR) $(TOOLING_BINARIES)
429+
generate-release-notes: $(RELEASE_NOTES_DIR)
426430
if [ -n "${PRE_RELEASE}" ]; then \
427431
echo ":rotating_light: This is a RELEASE CANDIDATE. Use it only for testing purposes. If you find any bugs, file an [issue](https://github.com/kubernetes-sigs/cluster-api/issues/new)." > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md; \
428432
else \
@@ -458,7 +462,7 @@ verify-gen: generate ## Verfiy go generated files are up to date
458462

459463
.PHONY: verify-modules
460464
verify-modules: modules ## Verify go modules are up to date
461-
@if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum); then \
465+
@if !(git diff --quiet HEAD -- go.sum go.mod); then \
462466
git diff; \
463467
echo "go module files are out of date"; exit 1; \
464468
fi
@@ -506,7 +510,7 @@ clean-build:
506510
.PHONY: clean-bin
507511
clean-bin: ## Remove all generated binaries
508512
rm -rf bin
509-
$(MAKE) -C $(TOOLS_DIR) clean
513+
rm -rf $(TOOLS_BIN_DIR)
510514

511515
.PHONY: clean-temporary
512516
clean-temporary: ## Remove all temporary files and folders
@@ -549,5 +553,87 @@ docker-push: ## Push the docker image
549553
-t $(DEV_CONTROLLER_IMG):$(DEV_TAG) .
550554
docker buildx rm capv
551555

556+
557+
## --------------------------------------
558+
## Hack / Tools
559+
## --------------------------------------
560+
561+
##@ hack/tools:
562+
563+
.PHONY: $(CONTROLLER_GEN_BIN)
564+
$(CONTROLLER_GEN_BIN): $(CONTROLLER_GEN) ## Build a local copy of controller-gen.
565+
566+
.PHONY: $(CONVERSION_GEN_BIN)
567+
$(CONVERSION_GEN_BIN): $(CONVERSION_GEN) ## Build a local copy of conversion-gen.
568+
569+
.PHONY: $(GO_APIDIFF_BIN)
570+
$(GO_APIDIFF_BIN): $(GO_APIDIFF) ## Build a local copy of go-apidiff
571+
572+
.PHONY: $(KUSTOMIZE_BIN)
573+
$(KUSTOMIZE_BIN): $(KUSTOMIZE) ## Build a local copy of kustomize.
574+
575+
.PHONY: $(SETUP_ENVTEST_BIN)
576+
$(SETUP_ENVTEST_BIN): $(SETUP_ENVTEST) ## Build a local copy of setup-envtest.
577+
578+
.PHONY: $(GINKGO_BIN)
579+
$(GINKGO_BIN): $(GINKGO) ## Build a local copy of ginkgo.
580+
581+
.PHONY: $(GOLANGCI_LINT_BIN)
582+
$(GOLANGCI_LINT_BIN): $(GOLANGCI_LINT) ## Build a local copy of golangci-lint.
583+
584+
.PHONY: $(GOVC_BIN)
585+
$(GOVC_BIN): $(GOVC) ## Build a local copy of govc.
586+
587+
.PHONY: $(KIND_BIN)
588+
$(KIND_BIN): $(KIND) ## Build a local copy of kind.
589+
590+
.PHONY: $(CONVERSION_VERIFIER_BIN)
591+
$(CONVERSION_VERIFIER_BIN): $(CONVERSION_VERIFIER) ## Build a local copy of conversion-verifier.
592+
593+
.PHONY: $(RELEASE_NOTES_BIN)
594+
$(RELEASE_NOTES_BIN): $(RELEASE_NOTES) ## Build a local copy of release-notes.
595+
596+
$(CONTROLLER_GEN): # Build CONTROLLER_GEN.
597+
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(CONTROLLER_GEN_PKG) $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER)
598+
599+
## We are forcing a rebuilt of conversion-gen via PHONY so that we're always using an up-to-date version.
600+
## We can't use a versioned name for the binary, because that would be reflected in generated files.
601+
.PHONY: $(CONVERSION_GEN)
602+
$(CONVERSION_GEN): # Build conversion-gen.
603+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(CONVERSION_GEN_PKG) $(CONVERSION_GEN_BIN) $(CONVERSION_GEN_VER)
604+
605+
$(GO_APIDIFF): # Build go-apidiff.
606+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GO_APIDIFF_PKG) $(GO_APIDIFF_BIN) $(GO_APIDIFF_VER)
607+
608+
$(KUSTOMIZE): # Build kustomize.
609+
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(KUSTOMIZE_PKG) $(KUSTOMIZE_BIN) $(KUSTOMIZE_VER)
610+
611+
$(SETUP_ENVTEST): # Build setup-envtest.
612+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(SETUP_ENVTEST_PKG) $(SETUP_ENVTEST_BIN) $(SETUP_ENVTEST_VER)
613+
614+
$(GINKGO): # Build ginkgo.
615+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GINKGO_PKG) $(GINKGO_BIN) $(GINGKO_VER)
616+
617+
$(GOLANGCI_LINT): # Build golangci-lint.
618+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOLANGCI_LINT_PKG) $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER)
619+
620+
$(GOVC): # Build GOVC.
621+
CGO_ENABLED=0 GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOVC_PKG) $(GOVC_BIN) $(GOVC_VER)
622+
623+
$(KIND): # Build kind.
624+
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(KIND_PKG) $(KIND_BIN) $(KIND_VER)
625+
626+
$(CONVERSION_VERIFIER): # Build conversion-verifier.
627+
GOBIN=$(TOOLS_BIN_DIR) $(GO_TOOLS_BUILD) $(CONVERSION_VERIFIER_PKG) $(CONVERSION_VERIFIER_BIN) $(CONVERSION_VERIFIER_VER)
628+
629+
$(RELEASE_NOTES): # Build release-notes.
630+
GOBIN=$(TOOLS_BIN_DIR) $(GO_TOOLS_BUILD) $(RELEASE_NOTES_PKG) $(RELEASE_NOTES_BIN) $(RELEASE_NOTES_VER)
631+
632+
## --------------------------------------
633+
## Helpers
634+
## --------------------------------------
635+
636+
##@ helpers:
637+
552638
go-version: ## Print the go version we use to compile our binaries and images
553639
@echo $(GO_VERSION)

hack/go-tools-build.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2023 The Kubernetes Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
if [ -z "${1}" ]; then
21+
echo "must provide module as first parameter"
22+
exit 1
23+
fi
24+
25+
if [ -z "${2}" ]; then
26+
echo "must provide binary name as second parameter"
27+
exit 1
28+
fi
29+
30+
if [ -z "${3}" ]; then
31+
echo "must provide version as third parameter"
32+
exit 1
33+
fi
34+
35+
if [ -z "${GOBIN}" ]; then
36+
echo "GOBIN is not set. Must set GOBIN to install the bin in a specified directory."
37+
exit 1
38+
fi
39+
40+
CAPI_HACK_TOOLS="sigs.k8s.io/cluster-api/hack/tools"
41+
42+
rm -f "${GOBIN}/${2}"* || true
43+
44+
ORIGINAL_WORKDIR="$(pwd)"
45+
TMP_MODULE_DIR="${2}.tmp"
46+
47+
# Create TMP_MODULE_DIR to create a go module for building the binary.
48+
# This is required because CAPI's hack/tools is not compatible to `go install`.
49+
rm -r "${TMP_MODULE_DIR}" || true
50+
mkdir -p "${TMP_MODULE_DIR}"
51+
cd "${TMP_MODULE_DIR}"
52+
53+
# Initialize a go module and place a tools.go file for building the binary.
54+
go mod init "tools"
55+
# Set require for "sigs.k8s.io/cluster-api" to let go resolve the tools version via the CAPI version.
56+
go mod edit -require "${CAPI_HACK_TOOLS}@${3}"
57+
58+
# Create go file which imports the required package and resolve dependencies.
59+
cat << EOF > tools.go
60+
//go:build tools
61+
// +build tools
62+
package tools
63+
64+
import (
65+
_ "${1}"
66+
)
67+
EOF
68+
69+
go mod tidy
70+
71+
# Build the binary.
72+
go build -tags=tools -o "${GOBIN}/${2}-${3}" "${1}"
73+
74+
# Get back to the original directory and cleanup the temporary directory.
75+
cd "${ORIGINAL_WORKDIR}"
76+
rm -r "${TMP_MODULE_DIR}"
77+
78+
# Link the unversioned name to the versioned binary.
79+
ln -sf "${GOBIN}/${2}-${3}" "${GOBIN}/${2}"

0 commit comments

Comments
 (0)