Makefile 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. export GO111MODULE=on
  2. .PHONY: push container clean container-name container-latest push-latest fmt lint test unit vendor header generate crd client deepcopy informer lister manifest manfest-latest manifest-annotate manifest manfest-latest manifest-annotate release gen-docs e2e
  3. OS ?= $(shell go env GOOS)
  4. ARCH ?= $(shell go env GOARCH)
  5. ALL_ARCH := amd64 arm arm64
  6. DOCKER_ARCH := "amd64" "arm v7" "arm64 v8"
  7. ifeq ($(OS),linux)
  8. BINS := bin/$(OS)/$(ARCH)/kg bin/$(OS)/$(ARCH)/kgctl
  9. else
  10. BINS := bin/$(OS)/$(ARCH)/kgctl
  11. endif
  12. RELEASE_BINS := $(addprefix bin/release/kgctl-, $(addprefix linux-, $(ALL_ARCH)) darwin-amd64 darwin-arm64 windows-amd64)
  13. PROJECT := kilo
  14. PKG := github.com/squat/$(PROJECT)
  15. REGISTRY ?= index.docker.io
  16. IMAGE ?= squat/$(PROJECT)
  17. FULLY_QUALIFIED_IMAGE := $(REGISTRY)/$(IMAGE)
  18. TAG := $(shell git describe --abbrev=0 --tags HEAD 2>/dev/null)
  19. COMMIT := $(shell git rev-parse HEAD)
  20. VERSION := $(COMMIT)
  21. ifneq ($(TAG),)
  22. ifeq ($(COMMIT), $(shell git rev-list -n1 $(TAG)))
  23. VERSION := $(TAG)
  24. endif
  25. endif
  26. DIRTY := $(shell test -z "$$(git diff --shortstat 2>/dev/null)" || echo -dirty)
  27. VERSION := $(VERSION)$(DIRTY)
  28. LD_FLAGS := -ldflags '-X $(PKG)/pkg/version.Version=$(VERSION)'
  29. SRC := $(shell find . -type f -name '*.go' -not -path "./vendor/*")
  30. GO_FILES ?= $$(find . -name '*.go' -not -path './vendor/*')
  31. GO_PKGS ?= $$(go list ./... | grep -v "$(PKG)/vendor")
  32. CONTROLLER_GEN_BINARY := bin/controller-gen
  33. CLIENT_GEN_BINARY := bin/client-gen
  34. DOCS_GEN_BINARY := bin/docs-gen
  35. DEEPCOPY_GEN_BINARY := bin/deepcopy-gen
  36. INFORMER_GEN_BINARY := bin/informer-gen
  37. LISTER_GEN_BINARY := bin/lister-gen
  38. GOLINT_BINARY := bin/golint
  39. EMBEDMD_BINARY := bin/embedmd
  40. KIND_BINARY := $(shell pwd)/bin/kind
  41. KUBECTL_BINARY := $(shell pwd)/bin/kubectl
  42. BASH_UNIT := $(shell pwd)/bin/bash_unit
  43. BASH_UNIT_FLAGS :=
  44. BUILD_IMAGE ?= golang:1.17.1-alpine3.14
  45. BASE_IMAGE ?= alpine:3.14
  46. build: $(BINS)
  47. build-%:
  48. @$(MAKE) --no-print-directory OS=$(word 1,$(subst -, ,$*)) ARCH=$(word 2,$(subst -, ,$*)) build
  49. container-latest-%:
  50. @$(MAKE) --no-print-directory ARCH=$* container-latest
  51. container-%:
  52. @$(MAKE) --no-print-directory ARCH=$* container
  53. push-latest-%:
  54. @$(MAKE) --no-print-directory ARCH=$* push-latest
  55. push-%:
  56. @$(MAKE) --no-print-directory ARCH=$* push
  57. all-build: $(addprefix build-$(OS)-, $(ALL_ARCH))
  58. all-container: $(addprefix container-, $(ALL_ARCH))
  59. all-push: $(addprefix push-, $(ALL_ARCH))
  60. all-container-latest: $(addprefix container-latest-, $(ALL_ARCH))
  61. all-push-latest: $(addprefix push-latest-, $(ALL_ARCH))
  62. generate: client deepcopy informer lister crd
  63. crd: manifests/crds.yaml
  64. manifests/crds.yaml: pkg/k8s/apis/kilo/v1alpha1/types.go $(CONTROLLER_GEN_BINARY)
  65. $(CONTROLLER_GEN_BINARY) crd \
  66. paths=./pkg/k8s/apis/kilo/... \
  67. output:crd:stdout | tail -n +3 > $@
  68. client: pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go
  69. pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go: .header pkg/k8s/apis/kilo/v1alpha1/types.go $(CLIENT_GEN_BINARY)
  70. $(CLIENT_GEN_BINARY) \
  71. --clientset-name versioned \
  72. --input-base "" \
  73. --input $(PKG)/pkg/k8s/apis/kilo/v1alpha1 \
  74. --output-base $(CURDIR) \
  75. --output-package $(PKG)/pkg/k8s/clientset \
  76. --go-header-file=.header \
  77. --logtostderr
  78. rm -r pkg/k8s/clientset || true
  79. mv $(PKG)/pkg/k8s/clientset pkg/k8s
  80. rm -r github.com || true
  81. go fmt ./pkg/k8s/clientset/...
  82. deepcopy: pkg/k8s/apis/kilo/v1alpha1/zz_generated.deepcopy.go
  83. pkg/k8s/apis/kilo/v1alpha1/zz_generated.deepcopy.go: .header pkg/k8s/apis/kilo/v1alpha1/types.go $(DEEPCOPY_GEN_BINARY)
  84. $(DEEPCOPY_GEN_BINARY) \
  85. --input-dirs ./$(@D) \
  86. --go-header-file=.header \
  87. --logtostderr \
  88. --output-base $(CURDIR) \
  89. --output-file-base zz_generated.deepcopy
  90. mv $(PKG)/$@ $@ || true
  91. rm -r github.com || true
  92. go fmt $@
  93. informer: pkg/k8s/informers/kilo/v1alpha1/peer.go
  94. pkg/k8s/informers/kilo/v1alpha1/peer.go: .header pkg/k8s/apis/kilo/v1alpha1/types.go $(INFORMER_GEN_BINARY)
  95. $(INFORMER_GEN_BINARY) \
  96. --input-dirs $(PKG)/pkg/k8s/apis/kilo/v1alpha1 \
  97. --go-header-file=.header \
  98. --logtostderr \
  99. --versioned-clientset-package $(PKG)/pkg/k8s/clientset/versioned \
  100. --listers-package $(PKG)/pkg/k8s/listers \
  101. --output-base $(CURDIR) \
  102. --output-package $(PKG)/pkg/k8s/informers \
  103. --single-directory
  104. rm -r pkg/k8s/informers || true
  105. mv $(PKG)/pkg/k8s/informers pkg/k8s
  106. rm -r github.com || true
  107. go fmt ./pkg/k8s/informers/...
  108. lister: pkg/k8s/listers/kilo/v1alpha1/peer.go
  109. pkg/k8s/listers/kilo/v1alpha1/peer.go: .header pkg/k8s/apis/kilo/v1alpha1/types.go $(LISTER_GEN_BINARY)
  110. $(LISTER_GEN_BINARY) \
  111. --input-dirs $(PKG)/pkg/k8s/apis/kilo/v1alpha1 \
  112. --go-header-file=.header \
  113. --logtostderr \
  114. --output-base $(CURDIR) \
  115. --output-package $(PKG)/pkg/k8s/listers
  116. rm -r pkg/k8s/listers || true
  117. mv $(PKG)/pkg/k8s/listers pkg/k8s
  118. rm -r github.com || true
  119. go fmt ./pkg/k8s/listers/...
  120. gen-docs: generate docs/api.md
  121. docs/api.md: pkg/k8s/apis/kilo/v1alpha1/types.go $(DOCS_GEN_BINARY)
  122. $(DOCS_GEN_BINARY) $< > $@
  123. $(BINS): $(SRC) go.mod
  124. @mkdir -p bin/$(word 2,$(subst /, ,$@))/$(word 3,$(subst /, ,$@))
  125. @echo "building: $@"
  126. @docker run --rm \
  127. -u $$(id -u):$$(id -g) \
  128. -v $$(pwd):/$(PROJECT) \
  129. -w /$(PROJECT) \
  130. $(BUILD_IMAGE) \
  131. /bin/sh -c " \
  132. GOARCH=$(word 3,$(subst /, ,$@)) \
  133. GOOS=$(word 2,$(subst /, ,$@)) \
  134. GOCACHE=/$(PROJECT)/.cache \
  135. CGO_ENABLED=0 \
  136. go build -mod=vendor -o $@ \
  137. $(LD_FLAGS) \
  138. ./cmd/$(@F)/... \
  139. "
  140. fmt:
  141. @echo $(GO_PKGS)
  142. gofmt -w -s $(GO_FILES)
  143. lint: header $(GOLINT_BINARY)
  144. @echo 'go vet $(GO_PKGS)'
  145. @vet_res=$$(GO111MODULE=on go vet -mod=vendor $(GO_PKGS) 2>&1); if [ -n "$$vet_res" ]; then \
  146. echo ""; \
  147. echo "Go vet found issues. Please check the reported issues"; \
  148. echo "and fix them if necessary before submitting the code for review:"; \
  149. echo "$$vet_res"; \
  150. exit 1; \
  151. fi
  152. @echo '$(GOLINT_BINARY) $(GO_PKGS)'
  153. @lint_res=$$($(GOLINT_BINARY) $(GO_PKGS)); if [ -n "$$lint_res" ]; then \
  154. echo ""; \
  155. echo "Golint found style issues. Please check the reported issues"; \
  156. echo "and fix them if necessary before submitting the code for review:"; \
  157. echo "$$lint_res"; \
  158. exit 1; \
  159. fi
  160. @echo 'gofmt -d -s $(GO_FILES)'
  161. @fmt_res=$$(gofmt -d -s $(GO_FILES)); if [ -n "$$fmt_res" ]; then \
  162. echo ""; \
  163. echo "Gofmt found style issues. Please check the reported issues"; \
  164. echo "and fix them if necessary before submitting the code for review:"; \
  165. echo "$$fmt_res"; \
  166. exit 1; \
  167. fi
  168. unit:
  169. go test -mod=vendor --race ./...
  170. test: lint unit e2e
  171. $(KIND_BINARY):
  172. curl -Lo $@ https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-$(ARCH)
  173. chmod +x $@
  174. $(KUBECTL_BINARY):
  175. curl -Lo $@ https://dl.k8s.io/release/v1.21.0/bin/linux/$(ARCH)/kubectl
  176. chmod +x $@
  177. $(BASH_UNIT):
  178. curl -Lo $@ https://raw.githubusercontent.com/pgrange/bash_unit/v1.7.2/bash_unit
  179. chmod +x $@
  180. e2e: container $(KIND_BINARY) $(KUBECTL_BINARY) $(BASH_UNIT) bin/$(OS)/$(ARCH)/kgctl
  181. KILO_IMAGE=$(IMAGE):$(ARCH)-$(VERSION) KIND_BINARY=$(KIND_BINARY) KUBECTL_BINARY=$(KUBECTL_BINARY) KGCTL_BINARY=$(shell pwd)/bin/$(OS)/$(ARCH)/kgctl $(BASH_UNIT) $(BASH_UNIT_FLAGS) ./e2e/setup.sh ./e2e/full-mesh.sh ./e2e/location-mesh.sh ./e2e/multi-cluster.sh ./e2e/handlers.sh ./e2e/kgctl.sh ./e2e/teardown.sh
  182. header: .header
  183. @HEADER=$$(cat .header); \
  184. HEADER_LEN=$$(wc -l .header | awk '{print $$1}'); \
  185. FILES=; \
  186. for f in $(GO_FILES); do \
  187. for i in 0 1 2 3 4 5; do \
  188. FILE=$$(t=$$(mktemp) && tail -n +$$i $$f > $$t && head -n $$HEADER_LEN $$t | sed "s/[0-9]\{4\}/YEAR/"); \
  189. [ "$$FILE" = "$$HEADER" ] && continue 2; \
  190. done; \
  191. FILES="$$FILES$$f "; \
  192. done; \
  193. if [ -n "$$FILES" ]; then \
  194. printf 'the following files are missing the license header: %s\n' "$$FILES"; \
  195. exit 1; \
  196. fi
  197. tmp/help.txt: bin/$(OS)/$(ARCH)/kg
  198. mkdir -p tmp
  199. bin//$(OS)/$(ARCH)/kg --help 2>&1 | head -n -1 > $@
  200. docs/kg.md: $(EMBEDMD_BINARY) tmp/help.txt
  201. $(EMBEDMD_BINARY) -w $@
  202. website/docs/README.md: README.md
  203. rm -rf website/static/img/graphs
  204. find docs -type f -name '*.md' | xargs -I{} sh -c 'cat $(@D)/$$(basename {} .md) > website/{}'
  205. find docs -type f -name '*.md' | xargs -I{} sh -c 'cat {} >> website/{}'
  206. cat $(@D)/$$(basename $@ .md) > $@
  207. cat README.md >> $@
  208. cp -r docs/graphs website/static/img/
  209. sed -i 's/\.\/docs\///g' $@
  210. find $(@D) -type f -name '*.md' | xargs -I{} sed -i 's/\.\/\(.\+\.\(svg\|png\)\)/\/img\/\1/g' {}
  211. sed -i 's/graphs\//\/img\/graphs\//g' $@
  212. # The next line is a workaround until mdx, docusaurus' markdown parser, can parse links with preceding brackets.
  213. sed -i 's/\[\]\(\[.*\](.*)\)/\&#91;\&#93;\1/g' website/docs/api.md
  214. website/build/index.html: website/docs/README.md docs/api.md
  215. yarn --cwd website install
  216. yarn --cwd website build
  217. container: .container-$(ARCH)-$(VERSION) container-name
  218. .container-$(ARCH)-$(VERSION): bin/linux/$(ARCH)/kg Dockerfile
  219. @i=0; for a in $(ALL_ARCH); do [ "$$a" = $(ARCH) ] && break; i=$$((i+1)); done; \
  220. ia=""; iv=""; \
  221. j=0; for a in $(DOCKER_ARCH); do \
  222. [ "$$i" -eq "$$j" ] && ia=$$(echo "$$a" | awk '{print $$1}') && iv=$$(echo "$$a" | awk '{print $$2}') && break; j=$$((j+1)); \
  223. done; \
  224. SHA=$$(docker manifest inspect $(BASE_IMAGE) | jq '.manifests[] | select(.platform.architecture == "'$$ia'") | if .platform | has("variant") then select(.platform.variant == "'$$iv'") else . end | .digest' -r); \
  225. docker build -t $(IMAGE):$(ARCH)-$(VERSION) --build-arg FROM=$(BASE_IMAGE)@$$SHA --build-arg GOARCH=$(ARCH) .
  226. @docker images -q $(IMAGE):$(ARCH)-$(VERSION) > $@
  227. container-latest: .container-$(ARCH)-$(VERSION)
  228. @docker tag $(IMAGE):$(ARCH)-$(VERSION) $(FULLY_QUALIFIED_IMAGE):$(ARCH)-latest
  229. @echo "container: $(IMAGE):$(ARCH)-latest"
  230. container-name:
  231. @echo "container: $(IMAGE):$(ARCH)-$(VERSION)"
  232. manifest: .manifest-$(VERSION) manifest-name
  233. .manifest-$(VERSION): Dockerfile $(addprefix push-, $(ALL_ARCH))
  234. @docker manifest create --amend $(FULLY_QUALIFIED_IMAGE):$(VERSION) $(addsuffix -$(VERSION), $(addprefix $(FULLY_QUALIFIED_IMAGE):, $(ALL_ARCH)))
  235. @$(MAKE) --no-print-directory manifest-annotate-$(VERSION)
  236. @docker manifest push $(FULLY_QUALIFIED_IMAGE):$(VERSION) > $@
  237. manifest-latest: Dockerfile $(addprefix push-latest-, $(ALL_ARCH))
  238. @docker manifest rm $(FULLY_QUALIFIED_IMAGE):latest || echo no old manifest
  239. @docker manifest create --amend $(FULLY_QUALIFIED_IMAGE):latest $(addsuffix -latest, $(addprefix $(FULLY_QUALIFIED_IMAGE):, $(ALL_ARCH)))
  240. @$(MAKE) --no-print-directory manifest-annotate-latest
  241. @docker manifest push $(FULLY_QUALIFIED_IMAGE):latest
  242. @echo "manifest: $(IMAGE):latest"
  243. manifest-annotate: manifest-annotate-$(VERSION)
  244. manifest-annotate-%:
  245. @i=0; \
  246. for a in $(ALL_ARCH); do \
  247. annotate=; \
  248. j=0; for da in $(DOCKER_ARCH); do \
  249. if [ "$$j" -eq "$$i" ] && [ -n "$$da" ]; then \
  250. annotate="docker manifest annotate $(FULLY_QUALIFIED_IMAGE):$* $(FULLY_QUALIFIED_IMAGE):$$a-$* --os linux --arch"; \
  251. k=0; for ea in $$da; do \
  252. [ "$$k" = 0 ] && annotate="$$annotate $$ea"; \
  253. [ "$$k" != 0 ] && annotate="$$annotate --variant $$ea"; \
  254. k=$$((k+1)); \
  255. done; \
  256. $$annotate; \
  257. fi; \
  258. j=$$((j+1)); \
  259. done; \
  260. i=$$((i+1)); \
  261. done
  262. manifest-name:
  263. @echo "manifest: $(IMAGE):$(VERSION)"
  264. push: .push-$(ARCH)-$(VERSION) push-name
  265. .push-$(ARCH)-$(VERSION): .container-$(ARCH)-$(VERSION)
  266. ifneq ($(REGISTRY),index.docker.io)
  267. @docker tag $(IMAGE):$(ARCH)-$(VERSION) $(FULLY_QUALIFIED_IMAGE):$(ARCH)-$(VERSION)
  268. endif
  269. @docker push $(FULLY_QUALIFIED_IMAGE):$(ARCH)-$(VERSION)
  270. @docker images -q $(IMAGE):$(ARCH)-$(VERSION) > $@
  271. push-latest: container-latest
  272. @docker push $(FULLY_QUALIFIED_IMAGE):$(ARCH)-latest
  273. @echo "pushed: $(IMAGE):$(ARCH)-latest"
  274. push-name:
  275. @echo "pushed: $(IMAGE):$(ARCH)-$(VERSION)"
  276. release: $(RELEASE_BINS)
  277. $(RELEASE_BINS):
  278. @make OS=$(word 2,$(subst -, ,$(@F))) ARCH=$(word 3,$(subst -, ,$(@F)))
  279. mkdir -p $(@D)
  280. cp bin/$(word 2,$(subst -, ,$(@F)))/$(word 3,$(subst -, ,$(@F)))/kgctl $@
  281. clean: container-clean bin-clean
  282. rm -rf .cache
  283. container-clean:
  284. rm -rf .container-* .manifest-* .push-*
  285. bin-clean:
  286. rm -rf bin
  287. vendor:
  288. go mod tidy
  289. go mod vendor
  290. $(CONTROLLER_GEN_BINARY):
  291. go build -mod=vendor -o $@ sigs.k8s.io/controller-tools/cmd/controller-gen
  292. $(CLIENT_GEN_BINARY):
  293. go build -mod=vendor -o $@ k8s.io/code-generator/cmd/client-gen
  294. $(DEEPCOPY_GEN_BINARY):
  295. go build -mod=vendor -o $@ k8s.io/code-generator/cmd/deepcopy-gen
  296. $(INFORMER_GEN_BINARY):
  297. go build -mod=vendor -o $@ k8s.io/code-generator/cmd/informer-gen
  298. $(LISTER_GEN_BINARY):
  299. go build -mod=vendor -o $@ k8s.io/code-generator/cmd/lister-gen
  300. $(DOCS_GEN_BINARY): cmd/docs-gen/main.go
  301. go build -mod=vendor -o $@ ./cmd/docs-gen
  302. $(GOLINT_BINARY):
  303. go build -mod=vendor -o $@ golang.org/x/lint/golint
  304. $(EMBEDMD_BINARY):
  305. go build -mod=vendor -o $@ github.com/campoy/embedmd