forked from vmware-tanzu/vm-operator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
757 lines (629 loc) · 26.6 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
# Ensure Make is run with bash shell as some syntax below is bash-specific
SHELL := /usr/bin/env bash
.DEFAULT_GOAL := help
# The list of goals that do not require Golang.
NON_GO_GOALS := lint-markdown lint-shell
# If one of the goals that require golang is present and the
# Go binary is not in the path, then print an error message
# and exit.
ifneq (,$(filter-out $(NON_GO_GOALS),$(MAKECMDGOALS)))
ifeq (,$(strip $(shell command -v go 2>/dev/null || true)))
$(error Golang binary not detected in path)
else # (,$(strip $(shell command -v go 2>/dev/null || true)))
# Active module mode, as we use go modules to manage dependencies.
export GO111MODULE := on
# Get the information about the platform on which the tools are built/run.
GOHOSTOS := $(shell go env GOHOSTOS)
GOHOSTARCH := $(shell go env GOHOSTARCH)
GOHOSTOSARCH := $(GOHOSTOS)_$(GOHOSTARCH)
# Default the GOOS and GOARCH values to be the same as the platform on which
# this Makefile is being executed.
export GOOS ?= $(GOHOSTOS)
export GOARCH ?= $(GOHOSTARCH)
# Default GOTOOLCHAIN to the one on the system instead of downloading whatever
# the go.mod file(s) specify. This fixes an issue of when the build happens
# behind a firewall or when GOSUMDB=off and the toolchain cannot be verified,
# and thus a potential download fails.
export GOTOOLCHAIN ?= local
# The directory in which this Makefile is located. Please note this will not
# behave correctly if the path to any Makefile in the list contains any spaces.
ROOT_DIR ?= $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
# Get the GOPATH, but do not export it. This is used to determine if the project
# is in the GOPATH and if not, to use the container runtime for the
# generate-go-conversions target.
GOPATH ?= $(shell go env GOPATH)
PROJECT_SLUG := github.com/vmware-tanzu/vm-operator
# ROOT_DIR_IN_GOPATH is non-empty if ROOT_DIR is in the GOPATH.
ROOT_DIR_IN_GOPATH := $(findstring $(GOPATH)/src/$(PROJECT_SLUG),$(ROOT_DIR))
# CONVERSION_GEN_FALLBACK_MODE determines how to run the conversion-gen tool if
# this project is not in the GOPATH at the expected location. Possible values
# include "symlink" and "docker|podman".
CONVERSION_GEN_FALLBACK_MODE ?= symlink
endif # ifneq (,$(filter-out $(NON_GO_GOALS),$(MAKECMDGOALS)))
endif # ifeq (,$(strip $(shell command -v go 2>/dev/null || true)))
# Directories
BIN_DIR := bin
TOOLS_DIR := hack/tools
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin/$(GOHOSTOSARCH)
UPGRADE_DIR := upgrade
export PATH := $(abspath $(BIN_DIR)):$(abspath $(TOOLS_BIN_DIR)):$(PATH)
export KUBEBUILDER_ASSETS := $(abspath $(TOOLS_BIN_DIR))
# Binaries
MANAGER := $(BIN_DIR)/manager
WEB_CONSOLE_VALIDATOR := $(BIN_DIR)/web-console-validator
# Tooling binaries
CRD_REF_DOCS := $(TOOLS_BIN_DIR)/crd-ref-docs
CONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen
CONVERSION_GEN := $(TOOLS_BIN_DIR)/conversion-gen
GOLANGCI_LINT := $(TOOLS_BIN_DIR)/golangci-lint
KUSTOMIZE := $(TOOLS_BIN_DIR)/kustomize
GOCOV := $(TOOLS_BIN_DIR)/gocov
GOCOV_XML := $(TOOLS_BIN_DIR)/gocov-xml
GINKGO := $(TOOLS_BIN_DIR)/ginkgo
KUBE_APISERVER := $(TOOLS_BIN_DIR)/kube-apiserver
KUBEBUILDER := $(TOOLS_BIN_DIR)/kubebuilder
KUBECTL := $(TOOLS_BIN_DIR)/kubectl
ETCD := $(TOOLS_BIN_DIR)/etcd
GOVULNCHECK := $(TOOLS_BIN_DIR)/govulncheck
KIND := $(TOOLS_BIN_DIR)/kind
# Allow overriding manifest generation destination directory
MANIFEST_ROOT ?= config
CRD_ROOT ?= $(MANIFEST_ROOT)/crd/bases
EXTERNAL_CRD_ROOT ?= $(MANIFEST_ROOT)/crd/external-crds
WEBHOOK_ROOT ?= $(MANIFEST_ROOT)/webhook
RBAC_ROOT ?= $(MANIFEST_ROOT)/rbac
# Image URL to use all building/pushing image targets
IMAGE ?= vmoperator-controller
IMAGE_TAG ?= latest
IMG ?= ${IMAGE}:${IMAGE_TAG}
# Code coverage files
COVERAGE_FILE := cover.out
# Gather a set of root packages that have at least one file that matches
# the pattern *_test.go as a child or descendent in that directory.
# However, given this is not a cheap operation, only gather these packages if
# the test-nocover target is one of the currenty active goals.
ifeq (,$(filter-out test-nocover,$(MAKECMDGOALS)))
COVERED_PKGS := $(shell find . -name '*_test.go' -not -path './api/*' -print | awk -F'/' '{print "./"$$2}' | sort -u)
endif
# CRI_BIN is the path to the container runtime binary.
ifeq (,$(strip $(GITHUB_RUN_ID)))
# Prefer podman locally.
CRI_BIN := $(shell command -v podman 2>/dev/null || command -v docker 2>/dev/null)
else
# Prefer docker in GitHub actions.
CRI_BIN := $(shell command -v docker 2>/dev/null || command -v podman 2>/dev/null)
endif
export CRI_BIN
KIND_CMD := $(KIND)
ifeq (podman,$(notdir $(CRI_BIN)))
KIND_CMD := KIND_EXPERIMENTAL_PROVIDER=podman $(KIND)
endif
# KIND_IMAGE may be overridden to use an upstream image.
KIND_IMAGE ?= dockerhub.packages.vcfd.broadcom.net/kindest/node:v1.31.0
ifneq (,$(strip $(KIND_IMAGE)))
KIND_IMAGE_FLAG := --image $(KIND_IMAGE)
endif
# Kind cluster name used in integration tests. Please note this name must
# match the value in the Groovy CI script or else the CI process won't
# discover the KubeConfig file for the cluster name.
KIND_CLUSTER_NAME ?= kind-it
# The path to the kubeconfig file used to access the bootstrap cluster.
KUBECONFIG ?= $(HOME)/.kube/config
# The directory to which information about the kind cluster is dumped.
KIND_CLUSTER_INFO_DUMP_DIR ?= kind-cluster-info-dump
ARTIFACTS_DIR := artifacts
LOCAL_YAML = $(ARTIFACTS_DIR)/local-deployment.yaml
DEFAULT_VMCLASSES_YAML = $(ARTIFACTS_DIR)/default-vmclasses.yaml
IMG_REGISTRY_OP_API_SLUG := github.com/vmware-tanzu/image-registry-operator-api
NET_OP_API_SLUG := github.com/vmware-tanzu/net-operator-api
BUILD_TYPE ?= dev
BUILD_NUMBER ?= 00000000
BUILD_COMMIT ?= $(shell git rev-parse --short HEAD)
export BUILD_VERSION ?= $(shell git describe --always --match "v*" | sed 's/v//')
BUILDINFO_LDFLAGS = "\
-X $(PROJECT_SLUG)/pkg.BuildVersion=$(BUILD_VERSION) \
-X $(PROJECT_SLUG)/pkg.BuildNumber=$(BUILD_NUMBER) \
-X $(PROJECT_SLUG)/pkg.BuildCommit=$(BUILD_COMMIT) \
-X $(PROJECT_SLUG)/pkg.BuildType=$(BUILD_TYPE) \
-extldflags -static -w -s "
.PHONY: all
all: prereqs test manager web-console-validator ## Tests and builds the manager and web-console-validator binaries.
prereqs:
@mkdir -p bin $(ARTIFACTS_DIR)
## --------------------------------------
## Help
## --------------------------------------
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
## --------------------------------------
## Testing
## --------------------------------------
.PHONY: test-api
test-api: | $(GINKGO)
test-api: ## Run API tests
COVERAGE_FILE="" hack/test.sh ./api
.PHONY: test-nocover
test-nocover: | $(GINKGO)
test-nocover: | test-api
test-nocover: ## Run tests sans coverage
hack/test.sh $(COVERED_PKGS)
.PHONY: test
test: | $(GINKGO) $(ETCD) $(KUBE_APISERVER)
test: ## Run tests
@rm -f "$(COVERAGE_FILE)"
COVERAGE_FILE="$(COVERAGE_FILE)" $(MAKE) test-nocover
.PHONY: coverage-xml
coverage-xml: $(GOCOV) $(GOCOV_XML)
coverage-xml:
gocov convert "$(COVERAGE_FILE)" | gocov-xml >"$(COVERAGE_FILE:.out=.xml)"
.PHONY: coverage
coverage: ## Show test coverage in browser
go tool cover -html="$(COVERAGE_FILE)"
## --------------------------------------
## Binaries
## --------------------------------------
.PHONY: $(MANAGER) manager-only
manager-only: $(MANAGER) ## Build manager binary only
$(MANAGER):
CGO_ENABLED=0 go build -o $@ -ldflags $(BUILDINFO_LDFLAGS) .
.PHONY: manager
manager: prereqs generate lint-go manager-only ## Build manager binary
.PHONY: $(WEB_CONSOLE_VALIDATOR) web-console-validator-only
web-console-validator-only: $(WEB_CONSOLE_VALIDATOR) ## Build web-console-validator binary only
$(WEB_CONSOLE_VALIDATOR):
CGO_ENABLED=0 go build -o $@ -ldflags $(BUILDINFO_LDFLAGS) cmd/web-console-validator/main.go
.PHONY: web-console-validator
web-console-validator: prereqs generate lint-go web-console-validator-only ## Build web-console-validator binary
## --------------------------------------
## Tooling Binaries
## --------------------------------------
TOOLING_BINARIES := $(CRD_REF_DOCS) $(CONTROLLER_GEN) $(CONVERSION_GEN) \
$(GOLANGCI_LINT) $(KUSTOMIZE) \
$(KUBE_APISERVER) $(KUBEBUILDER) $(KUBECTL) $(ETCD) \
$(GINKGO) $(GOCOV) $(GOCOV_XML) $(GOVULNCHECK) $(KIND)
tools: $(TOOLING_BINARIES) ## Build tooling binaries
$(TOOLING_BINARIES):
make -C $(TOOLS_DIR) $(@F)
## --------------------------------------
## Linting and fixing linter errors
## --------------------------------------
.PHONY: lint
lint: ## Run all the lint targets
$(MAKE) lint-go-full
$(MAKE) lint-markdown
$(MAKE) lint-shell
GOLANGCI_LINT_FLAGS ?= --fast=true
.PHONY: lint-go
lint-go: $(GOLANGCI_LINT)
lint-go: ## Lint codebase
$(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_FLAGS)
.PHONY: lint-go-full
lint-go-full: GOLANGCI_LINT_FLAGS = --fast=false
lint-go-full: lint-go ## Run slower linters to detect possible issues
.PHONY: lint-markdown
lint-markdown: ## Lint the project's markdown
$(CRI_BIN) run --rm -v "$$(pwd)":/build gcr.io/cluster-api-provider-vsphere/extra/mdlint:0.17.0
.PHONY: lint-shell
lint-shell: ## Lint the project's shell scripts
$(CRI_BIN) run --rm -t -v "$$(pwd)":/build:ro gcr.io/cluster-api-provider-vsphere/extra/shellcheck
.PHONY: fix
fix: GOLANGCI_LINT_FLAGS = --fast=false --fix
fix: lint-go ## Tries to fix errors reported by lint-go-full target
## --------------------------------------
## Generate
## --------------------------------------
.PHONY: modules
modules: ## Validates the modules
go mod tidy
cd hack/tools && go mod tidy
cd api && go mod tidy
cd pkg/backup/api && go mod tidy
cd pkg/constants/testlabels && go mod tidy
.PHONY: modules-vendor
modules-vendor: ## Vendors the modules
go mod vendor
cd hack/tools && go mod vendor
cd api && go mod vendor
cd pkg/constants/testlabels && go mod vendor
.PHONY: modules-download
modules-download: ## Downloads and caches the modules
go mod download
cd hack/tools && go mod download
cd api && go mod download
cd pkg/constants/testlabels && go mod download
.PHONY: generate
generate: ## Generate code
$(MAKE) generate-go
$(MAKE) generate-manifests
$(MAKE) generate-external-manifests
# Disable for now until we figure out why the check fails on GH actions
# $(MAKE) generate-api-docs
.PHONY: generate-go
generate-go: $(CONTROLLER_GEN)
generate-go: ## Generate golang sources
go -C ./api generate ./...
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/api/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/storage-policy-quota/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/tanzu-topology/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/byok/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/capabilities/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(MAKE) -C ./pkg/util/cloudinit/schema $@
.PHONY: generate-manifests
generate-manifests: $(CONTROLLER_GEN)
generate-manifests: ## Generate manifests e.g. CRD, RBAC etc.
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/api/... \
crd:crdVersions=v1 \
output:crd:dir=$(CRD_ROOT) \
output:none
$(CONTROLLER_GEN) \
paths=./webhooks/... \
output:webhook:dir=$(WEBHOOK_ROOT) \
webhook
$(CONTROLLER_GEN) \
paths=./controllers/... \
paths=./pkg/topology/... \
paths=./webhooks/... \
output:rbac:dir=$(RBAC_ROOT) \
rbac:roleName=manager-role
.PHONY: generate-external-manifests
generate-external-manifests: $(CONTROLLER_GEN)
generate-external-manifests: ## Generate manifests for the external types for testing
API_MOD_DIR=$(shell go mod download -json $(IMG_REGISTRY_OP_API_SLUG) | grep '"Dir":' | awk '{print $$2}' | tr -d '",') && \
$(CONTROLLER_GEN) \
paths=$${API_MOD_DIR}/api/v1alpha1/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
API_MOD_DIR=$(shell go mod download -json $(NET_OP_API_SLUG) | grep '"Dir":' | awk '{print $$2}' | tr -d '",') && \
$(CONTROLLER_GEN) \
paths=$${API_MOD_DIR}/api/v1alpha1/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/tanzu-topology/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/storage-policy-quota/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/byok/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/capabilities/... \
crd:crdVersions=v1 \
output:crd:dir=$(EXTERNAL_CRD_ROOT) \
output:none
.PHONY: generate-go-conversions
generate-go-conversions: ## Generate conversions go code
ifneq (,$(ROOT_DIR_IN_GOPATH))
# If the project is not cloned in the correct location in the GOPATH then the
# conversion-gen tool does not work. If ROOT_DIR_IN_GOPATH is non-empty, then
# the project is in the correct location for conversion-gen to work. Otherwise,
# there are two fallback modes controlled by CONVERSION_GEN_FALLBACK_MODE.
# When the CONVERSION_GEN_FALLBACK_MODE is symlink, the conversion-gen binary
# is rebuilt every time due to GNU Make, MTIME values, and symlinks. This ifeq
# statement ensures that there is not an order-only dependency on CONVERSION_GEN
# if it already exists.
ifeq (,$(strip $(wildcard $(CONVERSION_GEN))))
generate-go-conversions: $(CONVERSION_GEN)
endif
generate-go-conversions:
cd api && \
$(abspath $(CONVERSION_GEN)) \
-v 10 \
--output-file=zz_generated.conversion.go \
--go-header-file=$(abspath hack/boilerplate/boilerplate.generatego.txt) \
--extra-peer-dirs='./v1alpha2/sysprep/conversion/v1alpha2,./v1alpha2/sysprep/conversion/v1alpha3' \
./v1alpha1 ./v1alpha2
else ifeq (symlink,$(CONVERSION_GEN_FALLBACK_MODE))
# The generate-go-conversions target uses a symlink. Step-by-step, the target:
#
# 1. Creates a temporary directory to act as a GOPATH location and stores it
# in NEW_GOPATH.
#
# 2. Determines the path to this project under the NEW_GOPATH and stores it in
# NEW_ROOT_DIR.
#
# 3. Creates all of the path components for NEW_ROOT_DIR.
#
# 4. Removes the last path component in NEW_ROOT_DIR so it can be recreated as
# a symlink in the next step.
#
# 5. Creates a symlink from this project to its new location under NEW_GOPATH.
#
# 6. Changes directories into NEW_ROOT_DIR.
#
# 7. Invokes "make generate-go-conversions" from NEW_ROOT_DIR while sending in
# the values of GOPATH and ROOT_DIR to make this Makefile think it is in the
# NEW_GOPATH.
#
# Because make runs targets in a separate shell, it is not necessary to change
# back to the original directory.
generate-go-conversions:
NEW_GOPATH="$$(mktemp -d)" && \
NEW_ROOT_DIR="$${NEW_GOPATH}/src/$(PROJECT_SLUG)" && \
mkdir -p "$${NEW_ROOT_DIR}" && \
rm -fr "$${NEW_ROOT_DIR}" && \
ln -s "$(ROOT_DIR)" "$${NEW_ROOT_DIR}" && \
cd "$${NEW_ROOT_DIR}" && \
GOPATH="$${NEW_GOPATH}" ROOT_DIR="$${NEW_ROOT_DIR}" make $@
else ifeq ($(notdir $(CRI_BIN)),$(CONVERSION_GEN_FALLBACK_MODE))
ifeq (,$(CRI_BIN))
$(error Container runtime is required for generate-go-conversions and not detected in path!)
endif
# The generate-go-conversions target will use a container runtime. Step-by-step,
# the target:
#
# 1. GOLANG_IMAGE is set to golang:YOUR_LOCAL_GO_VERSION and is the image used
# to run make generate-go-conversions.
#
# 2. If using an arm host, the GOLANG_IMAGE is prefixed with arm64v8, which is
# the prefix for Golang's container images for arm systems.
#
# 3. A new, temporary directory is created and its path is stored in
# TOOLS_BIN_DIR. More on this later.
#
# 4. The flag --rm ensures that the container will be removed upon success or
# failure, preventing orphaned containers from hanging around.
#
# 5. The first -v flag is used to bind mount the project's root directory to
# the path /go/src/github.com/vmware-tanzu/vm-operator inside of the
# container. This is required for the conversion-gen tool to work correctly.
#
# 6. The second -v flag is used to bind mount the temporary directory stored
# TOOLS_BIN_DIR to /go/src/github.com/vmware-tanzu/vm-operator/hack/tools/bin
# inside the container. This ensures the local host's binaries are not
# overwritten case the local host is not Linux. Otherwise the container would
# fail to run the binaries because they are the wrong architecture or replace
# the binaries with Linux's elf architecture when the localhost uses
# something else (ex. macOS is Darwin and uses mach).
#
# 7. The -w flag sets the container's working directory to where the project's
# sources are bind mounted, /go/src/github.com/vmware-tanzu/vm-operator.
#
# 8. The image calculated earlier, GOLANG_IMAGE, is specified.
#
# 9. Finally, the command "make generate-go-conversions" is specified as what
# the container will run.
#
# Once this target completes, it will be as if the generate-go-conversions
# target was executed locally. Any necessary updates to the generated conversion
# sources will be found on the local filesystem. Use "git status" to verify the
# changes.
generate-go-conversions:
GOLANG_IMAGE="golang:$$(go env GOVERSION | cut -c3-)"; \
[ "$$(go env GOHOSTARCH)" = "arm64" ] && GOLANG_IMAGE="arm64v8/$${GOLANG_IMAGE}"; \
TOOLS_BIN_DIR="$$(mktemp -d)"; \
$(CRI_BIN) run -it --rm \
-v "$(ROOT_DIR)":/go/src/$(PROJECT_SLUG) \
-v "$${TOOLS_BIN_DIR}":/go/src/$(PROJECT_SLUG)/hack/tools/bin \
-w /go/src/$(PROJECT_SLUG) \
"$${GOLANG_IMAGE}" \
make generate-go-conversions
endif
.PHONY: generate-api-docs
generate-api-docs: $(CRD_REF_DOCS)
generate-api-docs: ## Generate API documentation
$(CRD_REF_DOCS) \
--renderer=markdown \
--source-path=./api/v1alpha1 \
--config=./.crd-ref-docs/config.yaml \
--templates-dir=./.crd-ref-docs/template \
--output-path=./docs/ref/api/
mv ./docs/ref/api/out.md ./docs/ref/api/v1alpha1.md
$(CRD_REF_DOCS) \
--renderer=markdown \
--source-path=./api/v1alpha2 \
--config=./.crd-ref-docs/config.yaml \
--templates-dir=./.crd-ref-docs/template \
--output-path=./docs/ref/api/
mv ./docs/ref/api/out.md ./docs/ref/api/v1alpha2.md
$(CRD_REF_DOCS) \
--renderer=markdown \
--source-path=./api/v1alpha3 \
--config=./.crd-ref-docs/config.yaml \
--templates-dir=./.crd-ref-docs/template \
--output-path=./docs/ref/api/
mv ./docs/ref/api/out.md ./docs/ref/api/v1alpha3.md
## --------------------------------------
## Kustomize
## --------------------------------------
.PHONY: kustomize-x
kustomize-x:
$(MAKE) -C config/$(CONFIG_TYPE) infrastructure-components
@cp -f config/$(CONFIG_TYPE)/infrastructure-components.yaml $(YAML_OUT)
$(MAKE) -C config/virtualmachineclasses default-vmclasses
@cp -f config/virtualmachineclasses/default-vmclasses.yaml $(DEFAULT_VMCLASSES_YAML)
.PHONY: kustomize-local
kustomize-local: CONFIG_TYPE=local
kustomize-local: YAML_OUT=$(LOCAL_YAML)
kustomize-local: prereqs generate-manifests $(KUSTOMIZE)
kustomize-local: kustomize-x ## Kustomize for local cluster
.PHONY: kustomize-local-vcsim
kustomize-local-vcsim: CONFIG_TYPE=local-vcsim
kustomize-local-vcsim: YAML_OUT=$(LOCAL_YAML)
kustomize-local-vcsim: prereqs generate-manifests $(KUSTOMIZE)
kustomize-local-vcsim: kustomize-x ## Kustomize for local-vcsim cluster
.PHONY: kustomize-wcp
kustomize-wcp: CONFIG_TYPE=wcp
kustomize-wcp: YAML_OUT=$(LOCAL_YAML)
kustomize-wcp: prereqs generate-manifests $(KUSTOMIZE)
kustomize-wcp: kustomize-x ## Kustomize for wcp cluster
.PHONY: kustomize-wcp-no-configmap
kustomize-wcp-no-configmap: CONFIG_TYPE=wcp-no-configmap
kustomize-wcp-no-configmap: YAML_OUT=$(LOCAL_YAML)
kustomize-wcp-no-configmap: prereqs generate-manifests $(KUSTOMIZE)
kustomize-wcp-no-configmap: kustomize-x ## Kustomize for wcp cluster sans configmap
## --------------------------------------
## Development - kind
## --------------------------------------
.PHONY: kind-cluster-info
kind-cluster-info: | $(KIND)
kind-cluster-info:
@$(KIND_CMD) get kubeconfig --name "$(KIND_CLUSTER_NAME)" >/dev/null 2>&1
@printf "kind cluster name: %s\nkind cluster config: %s\n" "$(KIND_CLUSTER_NAME)" "$(KUBECONFIG)"
@printf "KUBECONFIG=%s\n" "$(KUBECONFIG)" >local.envvars
.PHONY: kind-info
kind-info: kind-cluster-info
kind-info: ## Print kind cluster info
.PHONY: kind-cluster-info-dump
kind-cluster-info-dump: | $(KUBECTL)
@KUBECONFIG=$(KUBECONFIG) $(KUBECTL) cluster-info dump --all-namespaces --output-directory $(KIND_CLUSTER_INFO_DUMP_DIR) 1>/dev/null
# Collect any logs from previously failed container invocations
@KUBECONFIG=$(KUBECONFIG) $(KUBECTL) -n vmop-system logs --previous vmoperator-controller-manager-0 >$(KIND_CLUSTER_INFO_DUMP_DIR)/manager-0-prev-logs.txt 2>&1 || true
@KUBECONFIG=$(KUBECONFIG) $(KUBECTL) -n vmop-system logs --previous vmoperator-controller-manager-1 >$(KIND_CLUSTER_INFO_DUMP_DIR)/manager-1-prev-logs.txt 2>&1 || true
@KUBECONFIG=$(KUBECONFIG) $(KUBECTL) -n vmop-system logs --previous vmoperator-controller-manager-2 >$(KIND_CLUSTER_INFO_DUMP_DIR)/manager-2-prev-logs.txt 2>&1 || true
@printf "kind cluster dump: %s\n" "./$(KIND_CLUSTER_INFO_DUMP_DIR)"
.PHONY: kind-info-dump
kind-info-dump: kind-cluster-info-dump
kind-info-dump: ## Collect diagnostic info from kind cluster
.PHONY: kind-cluster
kind-cluster: | $(KIND)
kind-cluster:
@$(MAKE) --no-print-directory kind-cluster-info 2>/dev/null || \
$(KIND_CMD) create cluster --name "$(KIND_CLUSTER_NAME)" $(KIND_IMAGE_FLAG)
.PHONY: kind-up
kind-up: kind-cluster
kind-up: ## Create kind cluster
.PHONY: delete-kind-cluster
delete-kind-cluster: | $(KIND)
delete-kind-cluster:
@{ $(MAKE) --no-print-directory kind-cluster-info >/dev/null 2>&1 && \
$(KIND_CMD) delete cluster --name "$(KIND_CLUSTER_NAME)"; } || true
.PHONY: kind-down
kind-down: delete-kind-cluster
kind-down: ## Delete kind cluster
.PHONY: deploy-local-kind
deploy-local-kind: docker-build load-kind
.PHONY: kind-deploy
kind-deploy: deploy-local-kind
kind-deploy: ## Deploy controller into kind cluster
.PHONY: load-kind
load-kind: | $(KIND)
load-kind:
$(KIND_CMD) load docker-image $(IMG) --name $(KIND_CLUSTER_NAME) -v 10
.PHONY: kind-load
kind-load: load-kind
kind-load: ## Load image into kind cluster
## --------------------------------------
## Development - run
## --------------------------------------
.PHONY: run
run: prereqs generate lint-go
run: ## Run against the configured Kubernetes cluster in $(HOME)/.kube/config
go run main.go
## --------------------------------------
## Development - local
## --------------------------------------
.PHONY: deploy-local
deploy-local: prereqs kustomize-local | $(KUBECTL)
deploy-local: ## Deploy local YAML into kind cluster
KUBECONFIG=$(KUBECONFIG) hack/deploy-local.sh $(LOCAL_YAML) $(DEFAULT_VMCLASSES_YAML)
.PHONY: undeploy-local
undeploy-local: | $(KUBECTL)
undeploy-local: ## Undeploy local YAML from kind cluster
KUBECONFIG=$(KUBECONFIG) kubectl delete -f $(DEFAULT_VMCLASSES_YAML)
KUBECONFIG=$(KUBECONFIG) kubectl delete -f $(LOCAL_YAML)
## --------------------------------------
## Development - gce2e
## --------------------------------------
.PHONY: deploy-local-vcsim
deploy-local-vcsim: prereqs kustomize-local-vcsim | $(KUBECTL)
deploy-local-vcsim: ## Deploy local-vcsim YAML into kind cluster
KUBECONFIG=$(KUBECONFIG) hack/deploy-local.sh $(LOCAL_YAML)
## --------------------------------------
## Development - wcp
## --------------------------------------
.PHONY: deploy-wcp
deploy-wcp: prereqs kustomize-wcp | $(KUBECTL)
deploy-wcp: prereqs kustomize-wcp ## Deploy wcp YAML into local kind cluster
KUBECONFIG=$(KUBECONFIG) hack/deploy-local.sh $(LOCAL_YAML) $(DEFAULT_VMCLASSES_YAML)
## --------------------------------------
## Documentation
## --------------------------------------
MKDOCS_VENV := .venv/mkdocs
ifeq (,$(strip $(GITHUB_RUN_ID)))
MKDOCS := $(MKDOCS_VENV)/bin/mkdocs
else
MKDOCS := mkdocs
endif
.PHONY: docs-build-python
docs-build-python: ## Build docs w python
ifeq (,$(strip $(GITHUB_RUN_ID)))
@[ -d "$(MKDOCS_VENV)" ] || python3 -m venv $(MKDOCS_VENV)
$(MKDOCS_VENV)/bin/pip3 install -r ./docs/requirements.txt
endif
$(MKDOCS) build --clean --config-file mkdocs.yml
.PHONY: docs-build-docker
docs-build-docker: ## Build docs w container
$(CRI_BIN) build -f Dockerfile.docs -t $(IMAGE)-docs:$(IMAGE_TAG) .
$(CRI_BIN) run -it --rm -v "$$(pwd)":/docs --entrypoint /usr/bin/mkdocs \
$(IMAGE)-docs:$(IMAGE_TAG) build --clean --config-file mkdocs.yml
.PHONY: docs-serve-python
docs-serve-python: ## Serve docs w python
ifeq (,$(strip $(GITHUB_RUN_ID)))
@[ -d "$(MKDOCS_VENV)" ] || python3 -m venv $(MKDOCS_VENV)
$(MKDOCS_VENV)/bin/pip3 install -r ./docs/requirements.txt
endif
$(MKDOCS) serve
.PHONY: docs-serve-docker
docs-serve-docker: ## Serve docs w container
$(CRI_BIN) build -f Dockerfile.docs -t $(IMAGE)-docs:$(IMAGE_TAG) .
$(CRI_BIN) run -it --rm -p 8000:8000 -v "$$(pwd)":/docs $(IMAGE)-docs:$(IMAGE_TAG)
## --------------------------------------
## Docker
## --------------------------------------
.PHONY: docker-build
docker-build: ## Build the container image
hack/build-container.sh -i $(IMAGE) -t $(IMAGE_TAG) -v $(BUILD_VERSION) -n $(BUILD_NUMBER)
.PHONY: docker-push
docker-push: prereqs ## Push the container image
$(CRI_BIN) push ${IMG}
.PHONY: docker-remove
docker-remove: ## Remove the container image
@if [[ "`$(CRI_BIN) images -q ${IMG} 2>/dev/null`" != "" ]]; then \
echo "Remove container ${IMG}"; \
$(CRI_BIN) rmi ${IMG}; \
fi
## --------------------------------------
## Vulnerability Checks
## --------------------------------------
.PHONY: vulncheck-go
vulncheck-go: $(GOVULNCHECK)
$(GOVULNCHECK) ./...
## --------------------------------------
## Clean and verify
## --------------------------------------
.PHONY: clean
clean: docker-remove ## Remove all generated files
rm -rf bin *.out $(ARTIFACTS_DIR)
.PHONY: verify
verify: prereqs ## Run static code analysis
hack/lint.sh
.PHONY: verify-codegen
verify-codegen: ## Verify generated code
hack/verify-codegen.sh
.PHONY: verify-local-manifests
verify-local-manifests: ## Verify the local manifests
VERIFY_MANIFESTS=true $(MAKE) deploy-local
.PHONY: verify-wcp-manifests
verify-wcp-manifests: ## Verify the WCP manifests
VERIFY_MANIFESTS=true $(MAKE) deploy-wcp