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  `