11
22# Image URL to use all building/pushing image targets
33IMG ?= controller:latest
4+ REGISTRY ?= localhost
45# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
5- ENVTEST_K8S_VERSION = 1.24
6+ ENVTEST_K8S_VERSION = 1.25.0
7+ OS ?= $(shell go env GOOS )
8+ ARCH ?= $(shell go env GOARCH )
69
710# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
811ifeq (,$(shell go env GOBIN) )
@@ -12,14 +15,16 @@ GOBIN=$(shell go env GOBIN)
1215endif
1316
1417# Setting SHELL to bash allows bash commands to be executed by recipes.
15- # This is a requirement for 'setup-envtest.sh' in the test target.
1618# Options are set to exit when a recipe line exits non-zero or a piped command fails.
1719SHELL = /usr/bin/env bash -o pipefail
1820.SHELLFLAGS = -ec
1921
2022.PHONY : all
2123all : build
2224
25+ # kcp specific
26+ APIEXPORT_PREFIX ?= catalog
27+
2328# #@ General
2429
2530# The help target prints out all targets with their descriptions organized
@@ -41,12 +46,16 @@ help: ## Display this help.
4146
4247.PHONY : manifests
4348manifests : controller-gen # # Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
44- $(CONTROLLER_GEN ) rbac:roleName=manager-role crd webhook paths=" ./..." output:crd:artifacts:config=config/crd
49+ $(CONTROLLER_GEN ) rbac:roleName=manager-role crd webhook paths=" ./..." output:crd:artifacts:config=config/crd/bases
4550
4651.PHONY : generate
4752generate : controller-gen # # Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
4853 $(CONTROLLER_GEN ) object:headerFile=" hack/boilerplate.go.txt" paths=" ./..."
4954
55+ .PHONY : apiresourceschemas
56+ apiresourceschemas : $(KUSTOMIZE ) # # Convert CRDs from config/crds to APIResourceSchemas. Specify APIEXPORT_PREFIX as needed.
57+ $(KUSTOMIZE ) build config/crd | kubectl kcp crd snapshot -f - --prefix $(APIEXPORT_PREFIX ) > config/kcp/$(APIEXPORT_PREFIX ) .apiresourceschemas.yaml
58+
5059.PHONY : fmt
5160fmt : # # Run go fmt against code.
5261 go fmt ./...
@@ -57,18 +66,77 @@ vet: ## Run go vet against code.
5766
5867.PHONY : test
5968test : manifests generate fmt vet envtest # # Run tests.
60- KUBEBUILDER_ASSETS=" $( shell $( ENVTEST) use $( ENVTEST_K8S_VERSION) -p path) " go test ./... -coverprofile cover.out
69+ KUBEBUILDER_ASSETS=" $( shell $( ENVTEST) use $( ENVTEST_K8S_VERSION) --bin-dir $( LOCALBIN) -p path) " go test ./... -coverprofile cover.out
70+
71+ ARTIFACT_DIR ?= .test
72+
73+ .PHONY : test-e2e
74+ test-e2e : $(ARTIFACT_DIR ) /kind.kubeconfig kcp-synctarget run-test-e2e# # Set up prerequisites and run end-to-end tests on a cluster.
75+
76+ .PHONY : run-test-e2e
77+ run-test-e2e : # # Run end-to-end tests on a cluster.
78+ go test ./test/e2e/... --kubeconfig $(abspath $(ARTIFACT_DIR ) /kcp.kubeconfig) --workspace $(shell $(KCP_KUBECTL ) kcp workspace . --short)
79+
80+ .PHONY : kind-image
81+ kind-image : docker-build # # Load the controller-manager image into the kind cluster.
82+ kind load docker-image $(REGISTRY ) /$(IMG ) --name catalog
83+
84+ $(ARTIFACT_DIR ) /kind.kubeconfig : $(ARTIFACT_DIR ) # # Run a kind cluster and generate a $KUBECONFIG for it.
85+ @if ! kind get clusters --quiet | grep --quiet catalog; then kind create cluster --name catalog; fi
86+ kind get kubeconfig --name catalog > $(ARTIFACT_DIR ) /kind.kubeconfig
87+
88+ $(ARTIFACT_DIR ) : # # Create a directory for test artifacts.
89+ mkdir -p $(ARTIFACT_DIR )
90+
91+ KCP_KUBECTL ?= PATH=$(LOCALBIN ) :$(PATH ) KUBECONFIG=$(ARTIFACT_DIR ) /kcp.kubeconfig kubectl
92+ KIND_KUBECTL ?= kubectl --kubeconfig $(ARTIFACT_DIR ) /kind.kubeconfig
93+
94+ .PHONY : kcp-synctarget
95+ kcp-synctarget : kcp-workspace $(ARTIFACT_DIR ) /syncer.yaml $(YQ ) # # Add the kind cluster to kcp as a target for workloads.
96+ $(KIND_KUBECTL ) apply -f $(ARTIFACT_DIR ) /syncer.yaml
97+ $(eval DEPLOYMENT_NAME = $(shell $(YQ ) 'select(.kind=="Deployment") | .metadata.name' < $(ARTIFACT_DIR ) /syncer.yaml ) )
98+ $(eval DEPLOYMENT_NAMESPACE = $(shell $(YQ ) 'select(.kind=="Deployment") | .metadata.namespace' < $(ARTIFACT_DIR ) /syncer.yaml ) )
99+ $(KIND_KUBECTL ) --namespace $(DEPLOYMENT_NAMESPACE ) rollout status deployment/$(DEPLOYMENT_NAME )
100+ @if [[ ! -s $( ARTIFACT_DIR) /syncer.log ]]; then ( $( KIND_KUBECTL) --namespace $( DEPLOYMENT_NAMESPACE) logs deployment/$( DEPLOYMENT_NAME) -f > $( ARTIFACT_DIR) /syncer.log 2>&1 & ); fi
101+ $(KCP_KUBECTL ) wait --for=condition=Ready synctarget/catalog
102+
103+ $(ARTIFACT_DIR ) /syncer.yaml : # # Generate the manifests necessary to register the kind cluster with kcp.
104+ $(KCP_KUBECTL ) kcp workload sync catalog --resources services --syncer-image ghcr.io/kcp-dev/kcp/syncer:v$(KCP_VERSION ) --output-file $(ARTIFACT_DIR ) /syncer.yaml
105+
106+ .PHONY : kcp-workspace
107+ kcp-workspace : $(KUBECTL_KCP ) kcp-server # # Create a workspace in kcp for the controller-manager.
108+ $(KCP_KUBECTL ) kcp workspace use ' ~'
109+ @if ! $(KCP_KUBECTL ) kcp workspace use catalog; then $(KCP_KUBECTL ) kcp workspace create catalog --type universal --enter; fi
110+
111+ .PHONY : kcp-server
112+ kcp-server : $(KCP ) $(ARTIFACT_DIR ) /kcp # # Run the kcp server.
113+ @if [[ ! -s $( ARTIFACT_DIR) /kcp.log ]]; then ( $( KCP) start -v 5 --root-directory $( ARTIFACT_DIR) /kcp --kubeconfig-path $( ARTIFACT_DIR) /kcp.kubeconfig --audit-log-maxsize 1024 --audit-log-mode=batch --audit-log-batch-max-wait=1s --audit-log-batch-max-size=1000 --audit-log-batch-buffer-size=10000 --audit-log-batch-throttle-burst=15 --audit-log-batch-throttle-enable=true --audit-log-batch-throttle-qps=10 --audit-policy-file ./test/e2e/audit-policy.yaml --audit-log-path $( ARTIFACT_DIR) /audit.log > $( ARTIFACT_DIR) /kcp.log 2>&1 & ); fi
114+ @while true ; do if [[ ! -s $( ARTIFACT_DIR) /kcp.kubeconfig ]]; then sleep 0.2; else break ; fi ; done
115+ @while true ; do if ! kubectl --kubeconfig $( ARTIFACT_DIR) /kcp.kubeconfig get --raw /readyz > $( ARTIFACT_DIR) /kcp.probe.log 2>&1 ; then sleep 0.2; else break ; fi ; done
116+
117+ $(ARTIFACT_DIR ) /kcp : # # Create a directory for the kcp server data.
118+ mkdir -p $(ARTIFACT_DIR ) /kcp
119+
120+ .PHONY : test-e2e-cleanup
121+ test-e2e-cleanup : # # Clean up processes and directories from an end-to-end test run.
122+ kind delete cluster --name catalog || true
123+ rm -rf $(ARTIFACT_DIR ) || true
124+ pkill -sigterm kcp || true
125+ pkill -sigterm kubectl || true
61126
62127# #@ Build
63128
64129.PHONY : build
65- build : generate fmt vet # # Build manager binary.
130+ build : manifests generate fmt vet # # Build manager binary.
66131 go build -o bin/manager main.go
67132
68133.PHONY : run
69134run : manifests generate fmt vet # # Run a controller from your host.
70135 go run ./main.go
71136
137+ # If you wish built the manager image targeting other platforms you can use the --platform flag.
138+ # (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
139+ # More info: https://docs.docker.com/develop/develop-images/build_enhancements/
72140.PHONY : docker-build
73141docker-build : test # # Build docker image with the manager.
74142 docker build -t ${IMG} .
@@ -77,12 +145,31 @@ docker-build: test ## Build docker image with the manager.
77145docker-push : # # Push docker image with the manager.
78146 docker push ${IMG}
79147
148+ # PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
149+ # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
150+ # - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
151+ # - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
152+ # - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> than the export will fail)
153+ # To properly provided solutions that supports more than one platform you should use this option.
154+ PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
155+ .PHONY : docker-buildx
156+ docker-buildx : test # # Build and push docker image for the manager for cross-platform support
157+ # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
158+ sed -e ' 1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
159+ - docker buildx create --name project-v3-builder
160+ docker buildx use project-v3-builder
161+ - docker buildx build --push --platform=$(PLATFORMS ) --tag ${IMG} -f Dockerfile.cross .
162+ - docker buildx rm project-v3-builder
163+ rm Dockerfile.cross
164+
80165# #@ Deployment
81166
82167ifndef ignore-not-found
83168 ignore-not-found = false
84169endif
85170
171+ KUBECONFIG ?= $(abspath ~/.kube/config )
172+
86173.PHONY : install
87174install : manifests kustomize # # Install CRDs into the K8s cluster specified in ~/.kube/config.
88175 $(KUSTOMIZE ) build config/crd | kubectl apply -f -
@@ -91,6 +178,11 @@ install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~
91178uninstall : 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.
92179 $(KUSTOMIZE ) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found ) -f -
93180
181+ .PHONY : deploy-crd
182+ deploy-crd : manifests $(KUSTOMIZE ) # # Deploy controller
183+ cd config/manager && $(KUSTOMIZE ) edit set image controller=${REGISTRY} /${IMG}
184+ $(KUSTOMIZE ) build config/default-crd | kubectl --kubeconfig $(KUBECONFIG ) apply -f - || true
185+
94186.PHONY : deploy
95187deploy : manifests kustomize # # Deploy controller to the K8s cluster specified in ~/.kube/config.
96188 cd config/manager && $(KUSTOMIZE ) edit set image controller=${IMG}
@@ -111,23 +203,44 @@ $(LOCALBIN):
111203KUSTOMIZE ?= $(LOCALBIN ) /kustomize
112204CONTROLLER_GEN ?= $(LOCALBIN ) /controller-gen
113205ENVTEST ?= $(LOCALBIN ) /setup-envtest
206+ KCP ?= $(LOCALBIN ) /kcp
207+ KUBECTL_KCP ?= $(LOCALBIN ) /kubectl-kcp
208+ YQ ?= $(LOCALBIN ) /yq
114209
115210# # Tool Versions
116211KUSTOMIZE_VERSION ?= v3.8.7
117- CONTROLLER_TOOLS_VERSION ?= v0.8.0
212+ CONTROLLER_TOOLS_VERSION ?= v0.10.0
213+ KCP_VERSION ?= 0.9.1
214+ YQ_VERSION ?= v4.27.2
118215
119216KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
120217.PHONY : kustomize
121218kustomize : $(KUSTOMIZE ) # # Download kustomize locally if necessary.
122219$(KUSTOMIZE ) : $(LOCALBIN )
123- curl -s $(KUSTOMIZE_INSTALL_SCRIPT ) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION ) ) $(LOCALBIN )
220+ test -s $(LOCALBIN ) /kustomize || { curl -Ss $( KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $( subst v,,$( KUSTOMIZE_VERSION) ) $( LOCALBIN) ; }
124221
125222.PHONY : controller-gen
126223controller-gen : $(CONTROLLER_GEN ) # # Download controller-gen locally if necessary.
127224$(CONTROLLER_GEN ) : $(LOCALBIN )
128- GOBIN=$(LOCALBIN ) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION )
225+ test -s $( LOCALBIN ) /controller-gen || GOBIN=$(LOCALBIN ) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION )
129226
130227.PHONY : envtest
131228envtest : $(ENVTEST ) # # Download envtest-setup locally if necessary.
132229$(ENVTEST ) : $(LOCALBIN )
133- GOBIN=$(LOCALBIN ) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
230+ test -s $(LOCALBIN ) /setup-envtest || GOBIN=$(LOCALBIN ) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
231+
232+ $(YQ ) : # # Download yq locally if necessary.
233+ mkdir -p $(LOCALBIN )
234+ GOBIN=$(LOCALBIN ) go install github.com/mikefarah/yq/v4@$(YQ_VERSION )
235+
236+ .PHONY : kcp
237+ $(KCP ) : # # Download kcp locally if necessary.
238+ mkdir -p $(LOCALBIN )
239+ curl -L -s -o - https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION ) /kcp_$(KCP_VERSION ) _$(OS ) _$(ARCH ) .tar.gz | tar --directory $(LOCALBIN ) /../ -xvzf - bin/kcp
240+ touch $(KCP ) # we download an "old" file, so make will re-download to refresh it unless we make it newer than the owning dir
241+
242+ $(KUBECTL_KCP ) : # # Download kcp kubectl plugins locally if necessary.
243+ mkdir -p $(LOCALBIN )
244+ curl -L -s -o - https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION ) /kubectl-kcp-plugin_$(KCP_VERSION ) _$(OS ) _$(ARCH ) .tar.gz | tar --directory $(LOCALBIN ) /../ -xvzf - bin
245+ touch $(KUBECTL_KCP ) # we download an "old" file, so make will re-download to refresh it unless we make it newer than the owning dir
246+
0 commit comments