Skip to content
This repository was archived by the owner on Apr 24, 2024. It is now read-only.

Commit 9b82887

Browse files
make: add an end-to-end test
Signed-off-by: Steve Kuznetsov <[email protected]>
1 parent b095739 commit 9b82887

File tree

3 files changed

+460
-71
lines changed

3 files changed

+460
-71
lines changed

Makefile

Lines changed: 147 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,73 @@
1+
##@ General
2+
3+
# The help target prints out all targets with their descriptions organized
4+
# beneath their categories. The categories are represented by '##@' and the
5+
# target descriptions by '##'. The awk commands is responsible for reading the
6+
# entire set of makefiles included in this invocation, looking for lines of the
7+
# file as xyz: ## something, and then pretty-format the target and help. Then,
8+
# if there's a line with ##@ something, that gets pretty-printed as a category.
9+
# More info on the usage of ANSI control characters for terminal formatting:
10+
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
11+
# More info on the awk command:
12+
# http://linuxcommand.org/lc3_adv_awk.php
13+
14+
.PHONY: help
15+
help: ## Display this help.
16+
@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)
17+
18+
##@ Build Dependencies
19+
20+
## Location to install dependencies to
21+
LOCALBIN ?= $(shell pwd)/bin
22+
23+
## Tool Binaries
24+
KUSTOMIZE ?= $(LOCALBIN)/kustomize
25+
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
26+
ENVTEST ?= $(LOCALBIN)/setup-envtest
27+
KCP ?= $(LOCALBIN)/kcp
28+
KUBECTL_KCP ?= $(LOCALBIN)/kubectl-kcp
29+
YQ ?= $(LOCALBIN)/yq
130

2-
# Image URL to use all building/pushing image targets
3-
IMG ?= controller:latest
31+
## Tool Versions
32+
KUSTOMIZE_VERSION ?= v3.8.7
33+
CONTROLLER_TOOLS_VERSION ?= v0.8.0
34+
KCP_VERSION ?= 0.7.5
35+
YQ_VERSION ?= v4.27.2
36+
37+
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
38+
$(KUSTOMIZE): ## Download kustomize locally if necessary.
39+
mkdir -p $(LOCALBIN)
40+
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
41+
touch $(KUSTOMIZE) # we download an "old" file, so make will re-download to refresh it unless we make it newer than the owning dir
42+
43+
$(CONTROLLER_GEN): ## Download controller-gen locally if necessary.
44+
mkdir -p $(LOCALBIN)
45+
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
46+
47+
$(YQ): ## Download yq locally if necessary.
48+
mkdir -p $(LOCALBIN)
49+
GOBIN=$(LOCALBIN) go install github.com/mikefarah/yq/v4@$(YQ_VERSION)
50+
51+
OS ?= $(shell go env GOOS )
52+
ARCH ?= $(shell go env GOARCH )
53+
54+
$(KCP): ## Download kcp locally if necessary.
55+
mkdir -p $(LOCALBIN)
56+
wget -qO- https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION)/kcp_$(KCP_VERSION)_$(OS)_$(ARCH).tar.gz | tar -xvzf - bin/kcp --directory $(LOCALBIN)/../
57+
touch $(KCP) # we download an "old" file, so make will re-download to refresh it unless we make it newer than the owning dir
58+
59+
$(KUBECTL_KCP): ## Download kcp kubectl plugins locally if necessary.
60+
mkdir -p $(LOCALBIN)
61+
wget -qO- https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION)/kubectl-kcp-plugin_$(KCP_VERSION)_$(OS)_$(ARCH).tar.gz | tar -xvzf - bin --directory $(LOCALBIN)/../
62+
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
63+
64+
$(ENVTEST): ## Download envtest locally if necessary.
65+
mkdir -p $(LOCALBIN)
66+
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
67+
68+
# Image registry and URL to use all building/pushing image targets
69+
REGISTRY ?= localhost
70+
IMG ?= controller:test
471
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
572
ENVTEST_K8S_VERSION = 1.23
673

@@ -15,43 +82,26 @@ endif
1582
# This is a requirement for 'setup-envtest.sh' in the test target.
1683
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
1784
SHELL = /usr/bin/env bash -o pipefail
18-
.SHELLFLAGS = -ec
85+
.SHELLFLAGS = -ecx
1986

2087
.PHONY: all
2188
all: build
2289

2390
# kcp specific
2491
APIEXPORT_PREFIX ?= today
2592

26-
##@ General
27-
28-
# The help target prints out all targets with their descriptions organized
29-
# beneath their categories. The categories are represented by '##@' and the
30-
# target descriptions by '##'. The awk commands is responsible for reading the
31-
# entire set of makefiles included in this invocation, looking for lines of the
32-
# file as xyz: ## something, and then pretty-format the target and help. Then,
33-
# if there's a line with ##@ something, that gets pretty-printed as a category.
34-
# More info on the usage of ANSI control characters for terminal formatting:
35-
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
36-
# More info on the awk command:
37-
# http://linuxcommand.org/lc3_adv_awk.php
38-
39-
.PHONY: help
40-
help: ## Display this help.
41-
@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)
42-
4393
##@ Development
4494

4595
.PHONY: manifests
46-
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
96+
manifests: $(CONTROLLER_GEN) ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
4797
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
4898

4999
.PHONY: apiresourceschemas
50-
apiresourceschemas: kustomize ## Convert CRDs from config/crds to APIResourceSchemas. Specify APIEXPORT_PREFIX as needed.
100+
apiresourceschemas: $(KUSTOMIZE) ## Convert CRDs from config/crds to APIResourceSchemas. Specify APIEXPORT_PREFIX as needed.
51101
$(KUSTOMIZE) build config/crd | kubectl kcp crd snapshot -f - --prefix $(APIEXPORT_PREFIX) > config/kcp/$(APIEXPORT_PREFIX).apiresourceschemas.yaml
52102

53103
.PHONY: generate
54-
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
104+
generate: $(CONTROLLER_GEN) ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
55105
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
56106

57107
.PHONY: fmt
@@ -63,9 +113,67 @@ vet: ## Run go vet against code.
63113
go vet ./...
64114

65115
.PHONY: test
66-
test: manifests generate fmt vet envtest ## Run tests.
116+
test: manifests generate fmt vet $(ENVTEST) ## Run tests.
67117
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out
68118

119+
ARTIFACT_DIR ?= .test
120+
121+
.PHONY: test-e2e
122+
test-e2e: $(ARTIFACT_DIR)/kind.kubeconfig kcp-synctarget ready-deployment ## Run end-to-end tests on a cluster.
123+
go test ./test/e2e/...
124+
125+
.PHONY: ready-deployment
126+
ready-deployment: KUBECONFIG = $(ARTIFACT_DIR)/kcp.kubeconfig
127+
ready-deployment: kind-image install deploy ## Deploy the controller-manager and wait for it to be ready.
128+
$(KCP_KUBECTL) --namespace "controller-runtime-example-system" rollout status deployment/controller-runtime-example-controller-manager
129+
130+
.PHONY: kind-image
131+
kind-image: docker-build ## Load the controller-manager image into the kind cluster.
132+
kind load docker-image $(REGISTRY)/$(IMG) --name controller-runtime-example
133+
134+
$(ARTIFACT_DIR)/kind.kubeconfig: $(ARTIFACT_DIR) ## Run a kind cluster and generate a $KUBECONFIG for it.
135+
@if ! kind get clusters --quiet | grep --quiet controller-runtime-example; then kind create cluster --name controller-runtime-example; fi
136+
kind get kubeconfig --name controller-runtime-example > $(ARTIFACT_DIR)/kind.kubeconfig
137+
138+
$(ARTIFACT_DIR): ## Create a directory for test artifacts.
139+
mkdir -p $(ARTIFACT_DIR)
140+
141+
KCP_KUBECTL ?= PATH=$(LOCALBIN):$(PATH) KUBECONFIG=$(ARTIFACT_DIR)/kcp.kubeconfig kubectl
142+
KIND_KUBECTL ?= kubectl --kubeconfig $(ARTIFACT_DIR)/kind.kubeconfig
143+
144+
.PHONY: kcp-synctarget
145+
kcp-synctarget: kcp-workspace $(ARTIFACT_DIR)/syncer.yaml $(YQ) ## Add the kind cluster to kcp as a target for workloads.
146+
$(KIND_KUBECTL) apply -f $(ARTIFACT_DIR)/syncer.yaml
147+
$(eval DEPLOYMENT_NAME = $(shell $(YQ) 'select(.kind=="Deployment") | .metadata.name' < $(ARTIFACT_DIR)/syncer.yaml ))
148+
$(eval DEPLOYMENT_NAMESPACE = $(shell $(YQ) 'select(.kind=="Deployment") | .metadata.namespace' < $(ARTIFACT_DIR)/syncer.yaml ))
149+
$(KIND_KUBECTL) --namespace $(DEPLOYMENT_NAMESPACE) rollout status deployment/$(DEPLOYMENT_NAME)
150+
@if [[ ! -s $(ARTIFACT_DIR)/syncer.log ]]; then ( $(KIND_KUBECTL) --namespace $(DEPLOYMENT_NAMESPACE) logs deployment/$(DEPLOYMENT_NAME) -f >$(ARTIFACT_DIR)/syncer.log 2>&1 & ); fi
151+
$(KCP_KUBECTL) wait --for=condition=Ready synctarget/controller-runtime
152+
153+
$(ARTIFACT_DIR)/syncer.yaml: ## Generate the manifests necessary to register the kind cluster with kcp.
154+
$(KCP_KUBECTL) kcp workload sync controller-runtime --resources services --syncer-image ghcr.io/kcp-dev/kcp/syncer:v$(KCP_VERSION) --output-file $(ARTIFACT_DIR)/syncer.yaml
155+
156+
.PHONY: kcp-workspace
157+
kcp-workspace: $(KUBECTL_KCP) kcp-server ## Create a workspace in kcp for the controller-manager.
158+
$(KCP_KUBECTL) kcp workspace use '~'
159+
@if ! $(KCP_KUBECTL) kcp workspace use controller-runtime-example; then $(KCP_KUBECTL) kcp workspace create controller-runtime-example --type universal --enter; fi
160+
161+
.PHONY: kcp-server
162+
kcp-server: $(KCP) $(ARTIFACT_DIR)/kcp ## Run the kcp server.
163+
@if [[ ! -s $(ARTIFACT_DIR)/kcp.log ]]; then ( $(KCP) start --root-directory $(ARTIFACT_DIR)/kcp --kubeconfig-path $(ARTIFACT_DIR)/kcp.kubeconfig >$(ARTIFACT_DIR)/kcp.log 2>&1 & ); fi
164+
@while true; do if [[ ! -s $(ARTIFACT_DIR)/kcp.kubeconfig ]]; then sleep 0.2; else break; fi; done
165+
@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
166+
167+
$(ARTIFACT_DIR)/kcp: ## Create a directory for the kcp server data.
168+
mkdir -p $(ARTIFACT_DIR)/kcp
169+
170+
.PHONY: test-e2e-cleanup
171+
test-e2e-cleanup: ## Clean up processes and directories from an end-to-end test run.
172+
kind delete cluster --name controller-runtime-example || true
173+
rm -rf $(ARTIFACT_DIR) || true
174+
pkill -sigterm kcp || true
175+
pkill -sigterm kubectl || true
176+
69177
##@ Build
70178

71179
.PHONY: build
@@ -81,68 +189,38 @@ run: manifests generate fmt vet ## Run a controller from your host.
81189

82190
.PHONY: docker-build
83191
docker-build: build ## Build docker image with the manager.
84-
docker build -t ${IMG} .
192+
docker build -t ${REGISTRY}/${IMG} .
85193

86194
.PHONY: docker-push
87195
docker-push: ## Push docker image with the manager.
88-
docker push ${IMG}
196+
docker push ${REGISTRY}/${IMG}
89197

90198
##@ Deployment
91199

92200
ifndef ignore-not-found
93201
ignore-not-found = false
94202
endif
95203

204+
KUBECONFIG ?= $(shell realpath ~/.kube/config )
205+
96206
.PHONY: install
97-
install: manifests kustomize ## Install APIResourceSchemas and APIExport into kcp (using $KUBECONFIG or ~/.kube/config).
98-
$(KUSTOMIZE) build config/kcp | kubectl apply -f -
207+
install: manifests $(KUSTOMIZE) ## Install APIResourceSchemas and APIExport into kcp (using $KUBECONFIG or ~/.kube/config).
208+
$(KUSTOMIZE) build config/kcp | kubectl --kubeconfig $(KUBECONFIG) apply -f -
99209

100210
.PHONY: uninstall
101-
uninstall: manifests kustomize ## Uninstall APIResourceSchemas and APIExport from kcp (using $KUBECONFIG or ~/.kube/config). Call with ignore-not-found=true to ignore resource not found errors during deletion.
102-
$(KUSTOMIZE) build config/kcp | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
211+
uninstall: manifests $(KUSTOMIZE) ## Uninstall APIResourceSchemas and APIExport from kcp (using $KUBECONFIG or ~/.kube/config). Call with ignore-not-found=true to ignore resource not found errors during deletion.
212+
$(KUSTOMIZE) build config/kcp | kubectl --kubeconfig $(KUBECONFIG) delete --ignore-not-found=$(ignore-not-found) -f -
103213

104214
.PHONY: deploy-crd
105-
deploy-crd: manifests kustomize ## Deploy controller
106-
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
107-
$(KUSTOMIZE) build config/default-crd | kubectl apply -f - || true
215+
deploy-crd: manifests $(KUSTOMIZE) ## Deploy controller
216+
cd config/manager && $(KUSTOMIZE) edit set image controller=${REGISTRY}/${IMG}
217+
$(KUSTOMIZE) build config/default-crd | kubectl --kubeconfig $(KUBECONFIG) apply -f - || true
108218

109219
.PHONY: deploy
110-
deploy: manifests kustomize ## Deploy controller
111-
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
112-
$(KUSTOMIZE) build config/default | kubectl apply -f -
220+
deploy: manifests $(KUSTOMIZE) ## Deploy controller
221+
cd config/manager && $(KUSTOMIZE) edit set image controller=${REGISTRY}/${IMG}
222+
$(KUSTOMIZE) build config/default | kubectl --kubeconfig $(KUBECONFIG) apply -f -
113223

114224
.PHONY: undeploy
115225
undeploy: ## Undeploy controller. Call with ignore-not-found=true to ignore resource not found errors during deletion.
116-
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
117-
118-
##@ Build Dependencies
119-
120-
## Location to install dependencies to
121-
LOCALBIN ?= $(shell pwd)/bin
122-
$(LOCALBIN):
123-
mkdir -p $(LOCALBIN)
124-
125-
## Tool Binaries
126-
KUSTOMIZE ?= $(LOCALBIN)/kustomize
127-
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
128-
ENVTEST ?= $(LOCALBIN)/setup-envtest
129-
130-
## Tool Versions
131-
KUSTOMIZE_VERSION ?= v3.8.7
132-
CONTROLLER_TOOLS_VERSION ?= v0.8.0
133-
134-
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
135-
.PHONY: kustomize
136-
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
137-
$(KUSTOMIZE): $(LOCALBIN)
138-
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
139-
140-
.PHONY: controller-gen
141-
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
142-
$(CONTROLLER_GEN): $(LOCALBIN)
143-
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
144-
145-
.PHONY: envtest
146-
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
147-
$(ENVTEST): $(LOCALBIN)
148-
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
226+
$(KUSTOMIZE) build config/default | kubectl --kubeconfig $(KUBECONFIG) delete --ignore-not-found=$(ignore-not-found) -f -

config/manager/kustomization.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
1212
kind: Kustomization
1313
images:
1414
- name: controller
15-
newName: controller
16-
newTag: latest
15+
newName: localhost/controller
16+
newTag: test

0 commit comments

Comments
 (0)