sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/plugins/golang/v4/scaffolds/internal/templates/makefile.go (about) 1 /* 2 Copyright 2022 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 17 package templates 18 19 import ( 20 "sigs.k8s.io/kubebuilder/v3/pkg/machinery" 21 ) 22 23 var _ machinery.Template = &Makefile{} 24 25 // Makefile scaffolds a file that defines project management CLI commands 26 type Makefile struct { 27 machinery.TemplateMixin 28 machinery.ComponentConfigMixin 29 machinery.ProjectNameMixin 30 31 // Image is controller manager image name 32 Image string 33 // BoilerplatePath is the path to the boilerplate file 34 BoilerplatePath string 35 // Controller tools version to use in the project 36 ControllerToolsVersion string 37 // Kustomize version to use in the project 38 KustomizeVersion string 39 // ControllerRuntimeVersion version to be used to download the envtest setup script 40 ControllerRuntimeVersion string 41 // EnvtestVersion store the name of the verions to be used to install setup-envtest 42 EnvtestVersion string 43 } 44 45 // SetTemplateDefaults implements file.Template 46 func (f *Makefile) SetTemplateDefaults() error { 47 if f.Path == "" { 48 f.Path = "Makefile" 49 } 50 51 f.TemplateBody = makefileTemplate 52 53 f.IfExistsAction = machinery.Error 54 55 if f.Image == "" { 56 f.Image = "controller:latest" 57 } 58 59 // TODO: Looking for ways to tag the controller-runtime 60 // release using tag versions. Note that we cannot 61 // relay upon the branch since we cannot ensure that 62 // it will be generated for all releases. We must be 63 // able to use the tag. 64 if f.EnvtestVersion == "" { 65 f.EnvtestVersion = "latest" 66 } 67 return nil 68 } 69 70 //nolint:lll 71 const makefileTemplate = ` 72 # Image URL to use all building/pushing image targets 73 IMG ?= {{ .Image }} 74 # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. 75 ENVTEST_K8S_VERSION = 1.29.0 76 77 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) 78 ifeq (,$(shell go env GOBIN)) 79 GOBIN=$(shell go env GOPATH)/bin 80 else 81 GOBIN=$(shell go env GOBIN) 82 endif 83 84 # CONTAINER_TOOL defines the container tool to be used for building images. 85 # Be aware that the target commands are only tested with Docker which is 86 # scaffolded by default. However, you might want to replace it to use other 87 # tools. (i.e. podman) 88 CONTAINER_TOOL ?= docker 89 90 # Setting SHELL to bash allows bash commands to be executed by recipes. 91 # Options are set to exit when a recipe line exits non-zero or a piped command fails. 92 SHELL = /usr/bin/env bash -o pipefail 93 .SHELLFLAGS = -ec 94 95 .PHONY: all 96 all: build 97 98 ##@ General 99 100 # The help target prints out all targets with their descriptions organized 101 # beneath their categories. The categories are represented by '##@' and the 102 # target descriptions by '##'. The awk command is responsible for reading the 103 # entire set of makefiles included in this invocation, looking for lines of the 104 # file as xyz: ## something, and then pretty-format the target and help. Then, 105 # if there's a line with ##@ something, that gets pretty-printed as a category. 106 # More info on the usage of ANSI control characters for terminal formatting: 107 # https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters 108 # More info on the awk command: 109 # http://linuxcommand.org/lc3_adv_awk.php 110 111 .PHONY: help 112 help: ## Display this help. 113 @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\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) 114 115 ##@ Development 116 117 .PHONY: manifests 118 manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. 119 $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases 120 121 .PHONY: generate 122 generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. 123 {{ if .BoilerplatePath -}} 124 $(CONTROLLER_GEN) object:headerFile={{printf "%q" .BoilerplatePath}} paths="./..." 125 {{- else -}} 126 $(CONTROLLER_GEN) object paths="./..." 127 {{- end }} 128 129 .PHONY: fmt 130 fmt: ## Run go fmt against code. 131 go fmt ./... 132 133 .PHONY: vet 134 vet: ## Run go vet against code. 135 go vet ./... 136 137 .PHONY: test 138 test: manifests generate fmt vet envtest ## Run tests. 139 KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out 140 141 # Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors. 142 .PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up. 143 test-e2e: 144 go test ./test/e2e/ -v -ginkgo.v 145 146 .PHONY: lint 147 lint: golangci-lint ## Run golangci-lint linter & yamllint 148 $(GOLANGCI_LINT) run 149 150 .PHONY: lint-fix 151 lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes 152 $(GOLANGCI_LINT) run --fix 153 154 ##@ Build 155 156 .PHONY: build 157 build: manifests generate fmt vet ## Build manager binary. 158 go build -o bin/manager cmd/main.go 159 160 .PHONY: run 161 run: manifests generate fmt vet ## Run a controller from your host. 162 go run ./cmd/main.go 163 164 # If you wish to build the manager image targeting other platforms you can use the --platform flag. 165 # (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. 166 # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ 167 .PHONY: docker-build 168 docker-build: ## Build docker image with the manager. 169 $(CONTAINER_TOOL) build -t ${IMG} . 170 171 .PHONY: docker-push 172 docker-push: ## Push docker image with the manager. 173 $(CONTAINER_TOOL) push ${IMG} 174 175 # PLATFORMS defines the target platforms for the manager image be built to provide support to multiple 176 # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: 177 # - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ 178 # - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ 179 # - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail) 180 # To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. 181 PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le 182 .PHONY: docker-buildx 183 docker-buildx: ## Build and push docker image for the manager for cross-platform support 184 # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile 185 sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross 186 - $(CONTAINER_TOOL) buildx create --name project-v3-builder 187 $(CONTAINER_TOOL) buildx use project-v3-builder 188 - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . 189 - $(CONTAINER_TOOL) buildx rm project-v3-builder 190 rm Dockerfile.cross 191 192 .PHONY: build-installer 193 build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. 194 mkdir -p dist 195 @if [ -d "config/crd" ]; then \ 196 $(KUSTOMIZE) build config/crd > dist/install.yaml; \ 197 fi 198 echo "---" >> dist/install.yaml # Add a document separator before appending 199 cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} 200 $(KUSTOMIZE) build config/default >> dist/install.yaml 201 202 ##@ Deployment 203 204 ifndef ignore-not-found 205 ignore-not-found = false 206 endif 207 208 .PHONY: install 209 install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. 210 $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - 211 212 .PHONY: uninstall 213 uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. 214 $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - 215 216 .PHONY: deploy 217 deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. 218 cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} 219 $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - 220 221 .PHONY: undeploy 222 undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. 223 $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - 224 225 ##@ Dependencies 226 227 ## Location to install dependencies to 228 LOCALBIN ?= $(shell pwd)/bin 229 $(LOCALBIN): 230 mkdir -p $(LOCALBIN) 231 232 ## Tool Binaries 233 KUBECTL ?= kubectl 234 KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION) 235 CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION) 236 ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION) 237 GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION) 238 239 ## Tool Versions 240 KUSTOMIZE_VERSION ?= {{ .KustomizeVersion }} 241 CONTROLLER_TOOLS_VERSION ?= {{ .ControllerToolsVersion }} 242 ENVTEST_VERSION ?= {{ .EnvtestVersion }} 243 GOLANGCI_LINT_VERSION ?= v1.54.2 244 245 .PHONY: kustomize 246 kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. 247 $(KUSTOMIZE): $(LOCALBIN) 248 $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) 249 250 .PHONY: controller-gen 251 controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. 252 $(CONTROLLER_GEN): $(LOCALBIN) 253 $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) 254 255 .PHONY: envtest 256 envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. 257 $(ENVTEST): $(LOCALBIN) 258 $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) 259 260 .PHONY: golangci-lint 261 golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. 262 $(GOLANGCI_LINT): $(LOCALBIN) 263 $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION}) 264 265 # go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist 266 # $1 - target path with name of binary (ideally with version) 267 # $2 - package url which can be installed 268 # $3 - specific version of package 269 define go-install-tool 270 @[ -f $(1) ] || { \ 271 set -e; \ 272 package=$(2)@$(3) ;\ 273 echo "Downloading $${package}" ;\ 274 GOBIN=$(LOCALBIN) go install $${package} ;\ 275 mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\ 276 } 277 endef 278 `