From a4256c36da68a9e026d40cc10353ec7e804a50b2 Mon Sep 17 00:00:00 2001 From: Thibault Normand Date: Wed, 18 Feb 2026 10:34:14 +0100 Subject: [PATCH 1/2] feat(build): split makefile, ensure tools isolation. --- .gitignore | 1 + Makefile | 583 +++--------------- dogfood/chaosdogfood/chaosdogfood.pb.go | 185 ++---- .../disruptionlistener.pb.go | 167 ++--- mk/ci.mk | 93 +++ mk/docker.mk | 60 ++ mk/generate.mk | 57 ++ mk/lima.mk | 106 ++++ mk/lint.mk | 44 ++ mk/test.mk | 60 ++ mk/tools.mk | 254 ++++++++ 11 files changed, 853 insertions(+), 757 deletions(-) create mode 100644 mk/ci.mk create mode 100644 mk/docker.mk create mode 100644 mk/generate.mk create mode 100644 mk/lima.mk create mode 100644 mk/lint.mk create mode 100644 mk/test.mk create mode 100644 mk/tools.mk diff --git a/.gitignore b/.gitignore index 46d304079..45a915a70 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ cover.profile.* # other .venv +.tools/ # output of chaosli create disruption.yaml diff --git a/Makefile b/Makefile index 4b3b5db53..0053a0dc4 100644 --- a/Makefile +++ b/Makefile @@ -1,532 +1,103 @@ -.PHONY: * -.SILENT: release - -NOW_ISO8601 = $(shell date -u +"%Y-%m-%dT%H:%M:%S") - -GOOS = $(shell go env GOOS) -GOARCH = $(shell go env GOARCH) - -# change also github actions go build version "GO_VERSION:" if you change the version below -# https://github.com/DataDog/chaos-controller/blob/main/.github/workflows/ci.yml#L13 -BUILDGOVERSION = 1.25.6 - -# GOBIN can be provided (gitlab), defined (custom user setup), or empty/guessed (default go setup) -GOBIN ?= $(shell go env GOBIN) -ifeq (,$(GOBIN)) -GOBIN = $(shell go env GOPATH)/bin -endif - -INSTALL_DATADOG_AGENT = false -LIMA_INSTALL_SINK = noop -ifdef STAGING_DATADOG_API_KEY -ifdef STAGING_DATADOG_APP_KEY -INSTALL_DATADOG_AGENT = true -LIMA_INSTALL_SINK = datadog -endif -endif - -# Lima requires to have images built on a specific namespace to be shared to the Kubernetes cluster when using containerd runtime +# Makefile — Thin entry point. All logic lives in mk/*.mk modules. +# +# Usage: +# make help Show all available targets +# make test Run unit tests +# make lint Run linter +# make docker-build-all Build all container images +# +# Tools are automatically installed into .tools/bin/ on first use. +# Run `make clean-tools` to remove them. + +.DEFAULT_GOAL := help + +# ------------------------------------------------------------------------------ +# Go / build metadata +# ------------------------------------------------------------------------------ + +NOW_ISO8601 := $(shell date -u +"%Y-%m-%dT%H:%M:%S") + +# Change also github actions go build version if you change the version below +# https://github.com/DataDog/chaos-controller/blob/main/.github/workflows/ci.yml +BUILDGOVERSION := 1.25.6 + +# ------------------------------------------------------------------------------ +# Container images +# ------------------------------------------------------------------------------ + +# Lima requires images built on a specific namespace to be shared to the +# Kubernetes cluster when using containerd runtime. # https://github.com/abiosoft/colima#interacting-with-image-registry -CONTAINER_REGISTRY ?= k8s.io -CONTAINER_TAG ?= latest -CONTAINER_VERSION ?= $(shell git rev-parse HEAD)$(shell git diff --quiet || echo '-dirty') +CONTAINER_REGISTRY ?= k8s.io +CONTAINER_TAG ?= latest +CONTAINER_VERSION ?= $(shell git rev-parse HEAD)$(shell git diff --quiet || echo '-dirty') CONTAINER_BUILD_EXTRA_ARGS ?= -SIGN_IMAGE ?= false - +SIGN_IMAGE ?= false SKIP_GENERATE ?= false -# Image URL to use all building/pushing image targets -MANAGER_IMAGE ?= ${CONTAINER_REGISTRY}/chaos-controller -INJECTOR_IMAGE ?= ${CONTAINER_REGISTRY}/chaos-injector -HANDLER_IMAGE ?= ${CONTAINER_REGISTRY}/chaos-handler +MANAGER_IMAGE ?= $(CONTAINER_REGISTRY)/chaos-controller +INJECTOR_IMAGE ?= $(CONTAINER_REGISTRY)/chaos-injector +HANDLER_IMAGE ?= $(CONTAINER_REGISTRY)/chaos-handler + +# ------------------------------------------------------------------------------ +# Lima / Kubernetes +# ------------------------------------------------------------------------------ -LIMA_PROFILE ?= lima -LIMA_CONFIG ?= lima -# default instance name will be connected user name +LIMA_PROFILE ?= lima +LIMA_CONFIG ?= lima LIMA_INSTANCE ?= $(shell whoami | tr "." "-") -# cluster name is used by e2e-test to target the node with a disruption -# CI need to be able to override this value -E2E_TEST_CLUSTER_NAME ?= lima-$(LIMA_INSTANCE) +E2E_TEST_CLUSTER_NAME ?= lima-$(LIMA_INSTANCE) E2E_TEST_KUBECTL_CONTEXT ?= lima KUBECTL ?= limactl shell $(LIMA_INSTANCE) sudo kubectl -PROTOC_VERSION = 3.17.3 -PROTOC_OS ?= osx -PROTOC_ZIP = protoc-${PROTOC_VERSION}-${PROTOC_OS}-x86_64.zip -# you might also want to change ~/lima.yaml k3s version + KUBERNETES_MAJOR_VERSION ?= 1.28 -KUBERNETES_VERSION ?= v$(KUBERNETES_MAJOR_VERSION).0 -USE_VOLUMES ?= false +KUBERNETES_VERSION ?= v$(KUBERNETES_MAJOR_VERSION).0 +USE_VOLUMES ?= false HELM_VALUES ?= dev.yaml -HELM_VERSION = v3.19.0 -HELM_INSTALLED_VERSION = $(shell (helm version --template="{{ .Version }}" || echo "") | awk '{ print $$1 }') -# TODO: reenable depguard in .golangci.yml after upgrading golangci-lint again -GOLANGCI_LINT_VERSION = 2.8.0 -GOLANGCI_LINT_INSTALLED_VERSION = $(shell (golangci-lint --version || echo "") | sed -E 's/.*version ([^ ]+).*/\1/') - -CONTROLLER_GEN_VERSION = v0.19.0 -CONTROLLER_GEN_INSTALLED_VERSION = $(shell (controller-gen --version || echo "") | awk '{ print $$2 }') - -MOCKERY_VERSION = 2.53.5 -MOCKERY_ARCH = $(GOARCH) -ifeq (amd64,$(GOARCH)) -MOCKERY_ARCH = x86_64 +INSTALL_DATADOG_AGENT := false +LIMA_INSTALL_SINK := noop +ifdef STAGING_DATADOG_API_KEY +ifdef STAGING_DATADOG_APP_KEY +INSTALL_DATADOG_AGENT := true +LIMA_INSTALL_SINK := datadog endif -MOCKERY_INSTALLED_VERSION = $(shell mockery --version --quiet --config="" 2>/dev/null || echo "") - -# Additional args to provide to test runner (ginkgo) -# examples: -# `make test TEST_ARGS=--until-it-fails` to run tests randomly and repeatedly until a failure might occur (help to detect flaky tests or wrong tests setup) -# `make test TEST_ARGS=injector` will focus on package injector to run tests -TEST_ARGS ?= - -DD_ENV = local -# https://circleci.com/docs/variables/ -# we rely on standard CI env var to adapt test upload configuration automatically -ifeq (true,$(CI)) -DD_ENV = ci endif -LIMA_CGROUPS=v1 +LIMA_CGROUPS := v1 ifeq (v2,$(CGROUPS)) -LIMA_CGROUPS=v2 -endif - -# Docker builds now happen entirely within Docker using multi-stage builds -# All binaries (Go + EBPF) are built inside Docker - no local build steps required - -# Set container names for each component -docker-build-injector docker-build-only-injector: CONTAINER_NAME=$(INJECTOR_IMAGE) -docker-build-handler docker-build-only-handler: CONTAINER_NAME=$(HANDLER_IMAGE) -docker-build-manager docker-build-only-manager: CONTAINER_NAME=$(MANAGER_IMAGE) - -lima-push-injector lima-push-handler lima-push-manager: FAKE_FOR=COMPLETION - -# Generate manifests before building manager -# Skip generate if SKIP_GENERATE=true (useful in CI when manifests are already committed) -ifneq ($(SKIP_GENERATE),true) -docker-build-manager docker-build-only-manager: generate -endif - -# Define template for docker build targets -# $(1) is the target name: injector|handler|manager -define TARGET_template - -docker-build-$(1): docker-build-only-$(1) - docker save $$(CONTAINER_NAME):$(CONTAINER_TAG) -o ./bin/$(1)/$(1).tar.gz - -docker-build-only-$(1): - docker buildx build \ - --build-arg BUILDGOVERSION=$(BUILDGOVERSION) \ - --build-arg BUILDSTAMP=$(NOW_ISO8601) \ - -t $$(CONTAINER_NAME):$(CONTAINER_TAG) \ - --metadata-file ./bin/$(1)/docker-metadata.json \ - $(CONTAINER_BUILD_EXTRA_ARGS) \ - -f bin/$(1)/Dockerfile . - - if [ "$${SIGN_IMAGE}" = "true" ]; then \ - ddsign sign $$(CONTAINER_NAME):$(CONTAINER_VERSION) --docker-metadata-file ./bin/$(1)/docker-metadata.json; \ - fi - -lima-push-$(1): docker-build-$(1) - limactl copy ./bin/$(1)/$(1).tar.gz $(LIMA_INSTANCE):/tmp/ - limactl shell $(LIMA_INSTANCE) -- sudo k3s ctr i import /tmp/$(1).tar.gz - -minikube-load-$(1): - ls -la ./bin/$(1)/$(1).tar.gz - minikube image load --daemon=false --overwrite=true ./bin/$(1)/$(1).tar.gz -endef - -# Define targets we want to generate make targets for -TARGETS = injector handler manager - -# Generate docker build rules for each target -$(foreach tgt,$(TARGETS),$(eval $(call TARGET_template,$(tgt)))) - -# Build actions -docker-build-all: $(addprefix docker-build-,$(TARGETS)) - -docker-build-only-all: $(addprefix docker-build-only-,$(TARGETS)) - -lima-push-all: $(addprefix lima-push-,$(TARGETS)) -minikube-load-all: $(addprefix minikube-load-,$(TARGETS)) - -# Build chaosli -chaosli: - GOOS=darwin GOARCH=$(GOARCH) CGO_ENABLED=0 go build -ldflags="-X github.com/DataDog/chaos-controller/cli/chaosli/cmd.Version=$(VERSION)" -o bin/chaosli/chaosli_darwin_$(GOARCH) ./cli/chaosli/ - -# https://onsi.github.io/ginkgo/#recommended-continuous-integration-configuration -GINKGO_PROCS ?= 4 - -_ginkgo_test: -# Run the test and write a file if succeed -# Do not stop on any error - -go run github.com/onsi/ginkgo/v2/ginkgo --fail-on-pending --keep-going --vv \ - --cover --coverprofile=cover.profile --randomize-all \ - --race --trace --json-report=report-$(GO_TEST_REPORT_NAME).json --junit-report=report-$(GO_TEST_REPORT_NAME).xml \ - --compilers=$(GINKGO_PROCS) --procs=$(GINKGO_PROCS) \ - --poll-progress-after=10s --poll-progress-interval=10s \ - $(GINKGO_TEST_ARGS) \ - && touch report-$(GO_TEST_REPORT_NAME)-succeed -# Try upload test reports if allowed and necessary prerequisites exists -ifneq (true,$(GO_TEST_SKIP_UPLOAD)) # you can bypass test upload -ifdef DATADOG_API_KEY # if no API key bypass is guaranteed -ifneq (,$(shell which datadog-ci)) # same if no test binary - -DD_ENV=$(DD_ENV) datadog-ci junit upload --service chaos-controller --tags="team:chaos-engineering,type:$(GO_TEST_REPORT_NAME)" report-$(GO_TEST_REPORT_NAME).xml -else - @echo "datadog-ci binary is not installed, run 'make install-datadog-ci' to upload tests results to datadog" -endif -else - @echo "DATADOG_API_KEY env var is not defined, create a local API key https://app.datadoghq.com/personal-settings/application-keys if you want to upload your local tests results to datadog" -endif -else - @echo "datadog-ci junit upload SKIPPED" -endif -# Fail if succeed file does not exists - [ -f report-$(GO_TEST_REPORT_NAME)-succeed ] && rm -f report-$(GO_TEST_REPORT_NAME)-succeed || exit 1 - -# Tests & CI -## Run unit tests -test: generate manifests - $(if $(GOPATH),,$(error GOPATH is not set. Please set GOPATH before running make test)) - $(MAKE) _ginkgo_test GO_TEST_REPORT_NAME=$@ \ - GINKGO_TEST_ARGS="-r --skip-package=controllers --randomize-suites --timeout=10m $(TEST_ARGS)" - -spellcheck-deps: -ifeq (, $(shell which npm)) - @{\ - echo "please install npm or run 'make spellcheck-docker' for a slow but platform-agnistic run" ;\ - exit 1 ;\ - } -endif -ifeq (, $(shell which mdspell)) - @{\ - echo "installing mdspell through npm -g... (might require sudo run)" ;\ - npm -g i markdown-spellcheck ;\ - } -endif - -spellcheck: spellcheck-deps - mdspell --en-us --ignore-acronyms --ignore-numbers \ - $(shell find . -name vendor -prune -o -name '*.md' -print); - -spellcheck-report: spellcheck-deps - mdspell --en-us --ignore-acronyms --ignore-numbers --report \ - $(shell find . -name vendor -prune -o -name '*.md' -print); - -spellcheck-docker: - docker run --rm -ti -v $(shell pwd):/workdir tmaier/markdown-spellcheck:latest --ignore-numbers --ignore-acronyms --en-us \ - $(shell find . -name vendor -prune -o -name '*.md' -print); - -spellcheck-format-spelling: - sort < .spelling | sort | uniq | grep -v '^-' | tee .spelling.tmp > /dev/null && mv .spelling.tmp .spelling - -## This target is dedicated for CI and aims to reuse the Kubernetes version defined here as the source of truth -MINIKUBE_CPUS ?= 6 -MINIKUBE_MEMORY ?= 28672 - -ci-install-minikube: - curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb - sudo dpkg -i minikube_latest_amd64.deb - minikube start --cpus='$(MINIKUBE_CPUS)' --memory='$(MINIKUBE_MEMORY)' --vm-driver=docker --container-runtime=containerd --kubernetes-version=${KUBERNETES_VERSION} - minikube status - -SKIP_DEPLOY ?= - -## Run e2e tests (against a real cluster) -## to run them locally you first need to run `make install-kubebuilder` -e2e-test: generate manifests -ifneq (true,$(SKIP_DEPLOY)) # we can only wait for a controller if it exists, local.yaml does not deploy the controller - $(MAKE) lima-install HELM_VALUES=ci.yaml -endif - E2E_TEST_CLUSTER_NAME=$(E2E_TEST_CLUSTER_NAME) E2E_TEST_KUBECTL_CONTEXT=$(E2E_TEST_KUBECTL_CONTEXT) $(MAKE) _ginkgo_test GO_TEST_REPORT_NAME=$@ \ - GINKGO_TEST_ARGS="--flake-attempts=3 --timeout=25m controllers" - -# Test chaosli API portability -chaosli-test: - docker buildx build -f ./cli/chaosli/chaosli.DOCKERFILE -t test-chaosli-image . - -# Go actions -## Generate manifests e.g. CRD, RBAC etc. -manifests: install-controller-gen install-yamlfmt - controller-gen rbac:roleName=chaos-controller crd:crdVersions=v1 paths="./..." output:crd:dir=./chart/templates/generated/ output:rbac:dir=./chart/templates/generated/ -# ensure generated files stays formatted as expected - yamlfmt chart/templates/generated - -## Run go fmt against code -fmt: - go fmt ./... - -## Run go vet against code -vet: - go vet ./... - -## Run golangci-lint against code -lint: install-golangci-lint -# By using GOOS=linux we aim to validate files as if we were on linux -# you can use a similar trick with gopls to have vs-code linting your linux platform files instead of darwin - GOOS=linux golangci-lint run -E ginkgolinter ./... - GOOS=linux golangci-lint run - -## Generate code -generate: install-controller-gen - controller-gen object:headerFile=./hack/boilerplate.go.txt paths="./..." - -# Lima actions -## Create a new lima cluster and deploy the chaos-controller into it -lima-all: lima-start lima-install-datadog-agent lima-install-cert-manager lima-push-all lima-install - kubens chaos-engineering - -## Rebuild the chaos-controller images, re-install the chart and restart the chaos-controller pods -lima-redeploy: lima-push-all lima-install lima-restart - -## Install cert-manager chart -lima-install-cert-manager: - $(KUBECTL) apply -f https://github.com/jetstack/cert-manager/releases/download/v1.9.1/cert-manager.yaml - $(KUBECTL) -n cert-manager rollout status deployment/cert-manager-webhook --timeout=180s - -lima-install-demo: - $(KUBECTL) apply -f - < ./examples/namespace.yaml - $(KUBECTL) apply -f - < ./examples/demo.yaml - $(KUBECTL) -n chaos-demo rollout status deployment/demo-curl --timeout=60s - $(KUBECTL) -n chaos-demo rollout status deployment/demo-nginx --timeout=60s - -## Install CRDs and controller into a lima k3s cluster -## In order to use already built images inside the containerd runtime -## we override images for all of our components to the expected namespace -lima-install: manifests - helm template \ - --set=controller.version=$(CONTAINER_VERSION) \ - --set=controller.metricsSink=$(LIMA_INSTALL_SINK) \ - --set=controller.profilerSink=$(LIMA_INSTALL_SINK) \ - --set=controller.tracerSink=$(LIMA_INSTALL_SINK) \ - --values ./chart/values/$(HELM_VALUES) \ - ./chart | $(KUBECTL) apply -f - -ifneq (local.yaml,$(HELM_VALUES)) # we can only wait for a controller if it exists, local.yaml does not deploy the controller - $(KUBECTL) -n chaos-engineering rollout status deployment/chaos-controller --timeout=60s -endif - -## Uninstall CRDs and controller from a lima k3s cluster -lima-uninstall: - helm template --set=skipNamespace=true --values ./chart/values/$(HELM_VALUES) ./chart | $(KUBECTL) delete -f - - -## Restart the chaos-controller pod -lima-restart: -ifneq (local.yaml,$(HELM_VALUES)) # we can only wait for a controller if it exists, local.yaml does not deploy the controller - $(KUBECTL) -n chaos-engineering rollout restart deployment/chaos-controller - $(KUBECTL) -n chaos-engineering rollout status deployment/chaos-controller --timeout=60s -endif - -## Remove lima references from kubectl config -lima-kubectx-clean: - -kubectl config delete-cluster ${LIMA_PROFILE} - -kubectl config delete-context ${LIMA_PROFILE} - -kubectl config delete-user ${LIMA_PROFILE} - kubectl config unset current-context - -lima-kubectx: - limactl shell $(LIMA_INSTANCE) sudo sed 's/default/lima/g' /etc/rancher/k3s/k3s.yaml > ~/.kube/config_lima - KUBECONFIG=${KUBECONFIG}:~/.kube/config:~/.kube/config_lima kubectl config view --flatten > /tmp/config - rm ~/.kube/config_lima - mv /tmp/config ~/.kube/config - chmod 600 ~/.kube/config - kubectx ${LIMA_PROFILE} - -## Stop and delete the lima cluster -lima-stop: - limactl stop -f $(LIMA_INSTANCE) - limactl delete $(LIMA_INSTANCE) - $(MAKE) lima-kubectx-clean - -## Start the lima cluster, pre-cleaning kubectl config -lima-start: lima-kubectx-clean - LIMA_CGROUPS=${LIMA_CGROUPS} LIMA_CONFIG=${LIMA_CONFIG} LIMA_INSTANCE=${LIMA_INSTANCE} ./scripts/lima_start.sh - $(MAKE) lima-kubectx - -# Longhorn is used as an alternative StorageClass in order to enable "reliable" disk throttling accross various local setup -# It aims to bypass some issues encountered with default StorageClass (local-path --> tmpfs) that led to virtual unnamed devices -# unnamed devices are linked to 0 as a major device identifier, that blkio does not support -# https://super-unix.com/unixlinux/can-you-throttle-the-bandwidth-to-a-tmpfs-based-ramdisk/ -lima-install-longhorn: - $(KUBECTL) apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.0/deploy/longhorn.yaml - -# CI-specific actions - -venv: - test -d .venv || python3 -m venv .venv - . .venv/bin/activate; pip install -qr tasks/requirements.txt - -header: venv - . .venv/bin/activate; inv header-check - -header-fix: -# First re-generate header, it should complain as just (re)generated mocks does not contains them - -$(MAKE) header -# Then, re-generate header, it should succeed as now all files contains headers as expected, and command return with an happy exit code - $(MAKE) header - -license: venv - . .venv/bin/activate; inv license-check - -godeps: - go mod tidy; go mod vendor - -update-deps: - @echo "Updating Python dependencies..." - @pip install -q uv - @uv pip compile --python-platform linux tasks/requirements.in -o tasks/requirements.txt - @echo "Updated tasks/requirements.txt" - @echo "Please commit both tasks/requirements.in and tasks/requirements.txt" - -deps: godeps license - -generate-disruptionlistener-protobuf: - cd grpc/disruptionlistener && \ - go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1 && \ - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0 && \ - protoc --proto_path=. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative disruptionlistener.proto - -generate-chaosdogfood-protobuf: - cd dogfood/chaosdogfood && \ - go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1 && \ - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0 && \ - protoc --proto_path=. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative chaosdogfood.proto - -clean-mocks: - find . -type f -name "*mock*.go" -not -path "./vendor/*" -exec rm {} \; - rm -rf mocks/ - -generate-mocks: clean-mocks install-mockery - go generate ./... - $(MAKE) header-fix - -release: - VERSION=$(VERSION) ./tasks/release.sh - -_pre_local: generate manifests - @$(shell $(KUBECTL) get deploy chaos-controller 2> /dev/null) -ifeq (0,$(.SHELLSTATUS)) -# uninstall using a non local value to ensure deployment is deleted - -$(MAKE) lima-uninstall HELM_VALUES=dev.yaml - $(MAKE) lima-install HELM_VALUES=local.yaml - $(KUBECTL) -n chaos-engineering get cm chaos-controller -oyaml | yq '.data["config.yaml"]' > .local.yaml - yq -i '.controller.webhook.certDir = "chart/certs"' .local.yaml -else - @echo "Chaos controller is not installed, skipped!" -endif - -debug: _pre_local - @echo "now you can launch through vs-code or your favorite IDE a controller in debug with appropriate configuration (--config=chart/values/local.yaml + CONTROLLER_NODE_NAME=local)" - -run: - CONTROLLER_NODE_NAME=local go run . --config=.local.yaml - -watch: _pre_local install-watchexec - watchexec make SKIP_EBPF=true lima-push-injector run - -install-protobuf: - curl -sSLo /tmp/${PROTOC_ZIP} https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP} - unzip -o /tmp/${PROTOC_ZIP} -d ${GOPATH} bin/protoc - unzip -o /tmp/${PROTOC_ZIP} -d ${GOPATH} 'include/*' - rm -f /tmp/${PROTOC_ZIP} - -install-golangci-lint: -ifneq ($(GOLANGCI_LINT_VERSION),$(GOLANGCI_LINT_INSTALLED_VERSION)) - $(info golangci-lint version $(GOLANGCI_LINT_VERSION) is not installed or version differ ($(GOLANGCI_LINT_VERSION) != $(GOLANGCI_LINT_INSTALLED_VERSION))) - $(info installing golangci-lint v$(GOLANGCI_LINT_VERSION)...) - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) v$(GOLANGCI_LINT_VERSION) -endif - -install-kubebuilder: -# download kubebuilder and install locally. - curl -sSLo $(GOBIN)/kubebuilder https://go.kubebuilder.io/dl/latest/$(GOOS)/$(GOARCH) - chmod u+x $(GOBIN)/kubebuilder -# download setup-envtest and install related binaries locally - go install -v sigs.k8s.io/controller-runtime/tools/setup-envtest@latest -# setup-envtest use -p path $(KUBERNETES_MAJOR_VERSION).x - -install-helm: -ifneq ($(HELM_INSTALLED_VERSION),$(HELM_VERSION)) - $(info helm version $(HELM_VERSION) is not installed or version differ ($(HELM_VERSION) != $(HELM_INSTALLED_VERSION))) - $(info installing helm $(HELM_VERSION)...) - curl -sSLo /tmp/helm.tar.gz "https://get.helm.sh/helm-$(HELM_VERSION)-$(GOOS)-$(GOARCH).tar.gz" - tar -xvzf /tmp/helm.tar.gz --directory=$(GOBIN) --strip-components=1 $(GOOS)-$(GOARCH)/helm - rm /tmp/helm.tar.gz -endif - -# install controller-gen expected version -install-controller-gen: -ifneq ($(CONTROLLER_GEN_INSTALLED_VERSION),$(CONTROLLER_GEN_VERSION)) - $(info controller-gen version $(CONTROLLER_GEN_VERSION) is not installed or version differ ($(CONTROLLER_GEN_VERSION) != $(CONTROLLER_GEN_INSTALLED_VERSION))) - $(info installing controller-gen $(CONTROLLER_GEN_VERSION)...) - @{ \ - set -e ;\ - CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ - cd $$CONTROLLER_GEN_TMP_DIR ;\ - go mod init tmp ;\ - CGO_ENABLED=0 go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION) ;\ - rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ - } -endif - -install-datadog-ci: - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_$(GOOS)-x64" --output "$(GOBIN)/datadog-ci" && chmod u+x $(GOBIN)/datadog-ci - -install-mockery: -# recommended way to install mockery is through their released binaries, NOT go install... -# https://vektra.github.io/mockery/installation/#github-release -ifneq ($(MOCKERY_INSTALLED_VERSION),v$(MOCKERY_VERSION)) - $(info mockery version $(MOCKERY_VERSION) is not installed or version differ (v$(MOCKERY_VERSION) != $(MOCKERY_INSTALLED_VERSION))) - $(info installing mockery v$(MOCKERY_VERSION)...) - curl -sSLo /tmp/mockery.tar.gz https://github.com/vektra/mockery/releases/download/v$(MOCKERY_VERSION)/mockery_$(MOCKERY_VERSION)_$(GOOS)_$(MOCKERY_ARCH).tar.gz - tar -xvzf /tmp/mockery.tar.gz --directory=$(GOBIN) mockery - rm /tmp/mockery.tar.gz -endif - -YAMLFMT_ARCH = $(GOARCH) -ifeq (amd64,$(GOARCH)) -YAMLFMT_ARCH = x86_64 +LIMA_CGROUPS := v2 endif -install-yamlfmt: -ifeq (,$(wildcard $(GOBIN)/yamlfmt)) - $(info installing yamlfmt...) - curl -sSLo /tmp/yamlfmt.tar.gz https://github.com/google/yamlfmt/releases/download/v0.9.0/yamlfmt_0.9.0_$(GOOS)_$(YAMLFMT_ARCH).tar.gz - tar -xvzf /tmp/yamlfmt.tar.gz --directory=$(GOBIN) yamlfmt - rm /tmp/yamlfmt.tar.gz -endif +# ------------------------------------------------------------------------------ +# Local tool bin (isolated from system) +# ------------------------------------------------------------------------------ -install-watchexec: -ifeq (,$(wildcard $(GOBIN)/watchexec)) - $(info installing watchexec...) - brew install watchexec -endif +LOCALBIN := $(CURDIR)/.tools/bin +LOCALSTAMP := $(CURDIR)/.tools/stamps +export PATH := $(LOCALBIN):$(PATH) -install-go: - BUILDGOVERSION=$(BUILDGOVERSION) ./scripts/install-go +# ------------------------------------------------------------------------------ +# Include modules +# ------------------------------------------------------------------------------ -EXISTING_NAMESPACE = $(shell $(KUBECTL) get ns datadog-agent -oname || echo "") +include mk/tools.mk +include mk/docker.mk +include mk/test.mk +include mk/generate.mk +include mk/lint.mk +include mk/lima.mk +include mk/ci.mk -lima-install-datadog-agent: -ifeq (true,$(INSTALL_DATADOG_AGENT)) -ifeq (,$(EXISTING_NAMESPACE)) - $(KUBECTL) create ns datadog-agent - helm repo add --force-update datadoghq https://helm.datadoghq.com - helm install -n datadog-agent my-datadog-operator datadoghq/datadog-operator - $(KUBECTL) create secret -n datadog-agent generic datadog-secret --from-literal api-key=${STAGING_DATADOG_API_KEY} --from-literal app-key=${STAGING_DATADOG_APP_KEY} -endif - $(KUBECTL) apply -f - < examples/datadog-agent.yaml -endif +# ------------------------------------------------------------------------------ +# Help +# ------------------------------------------------------------------------------ -open-dd: -ifeq (true,$(INSTALL_DATADOG_AGENT)) -ifdef STAGING_DD_SITE - open "${STAGING_DD_SITE}/infrastructure?host=lima-$(LIMA_INSTANCE)&tab=details" -else - @echo "You need to define STAGING_DD_SITE in your .zshrc or similar to use this feature" -endif -endif +.PHONY: help +help: ## Show this help + @grep -hE '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \ + awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/dogfood/chaosdogfood/chaosdogfood.pb.go b/dogfood/chaosdogfood/chaosdogfood.pb.go index 9d71d7b1b..cdc33da42 100644 --- a/dogfood/chaosdogfood/chaosdogfood.pb.go +++ b/dogfood/chaosdogfood/chaosdogfood.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 +// protoc-gen-go v1.36.11 // protoc v3.17.3 // source: chaosdogfood.proto @@ -17,6 +17,7 @@ import ( emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -27,20 +28,17 @@ const ( ) type FoodRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Animal string `protobuf:"bytes,1,opt,name=animal,proto3" json:"animal,omitempty"` unknownFields protoimpl.UnknownFields - - Animal string `protobuf:"bytes,1,opt,name=animal,proto3" json:"animal,omitempty"` + sizeCache protoimpl.SizeCache } func (x *FoodRequest) Reset() { *x = FoodRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_chaosdogfood_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_chaosdogfood_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FoodRequest) String() string { @@ -51,7 +49,7 @@ func (*FoodRequest) ProtoMessage() {} func (x *FoodRequest) ProtoReflect() protoreflect.Message { mi := &file_chaosdogfood_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -74,21 +72,18 @@ func (x *FoodRequest) GetAnimal() string { } type FoodReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - ConfirmationId int32 `protobuf:"varint,2,opt,name=confirmation_id,json=confirmationId,proto3" json:"confirmation_id,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + ConfirmationId int32 `protobuf:"varint,2,opt,name=confirmation_id,json=confirmationId,proto3" json:"confirmation_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FoodReply) Reset() { *x = FoodReply{} - if protoimpl.UnsafeEnabled { - mi := &file_chaosdogfood_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_chaosdogfood_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FoodReply) String() string { @@ -99,7 +94,7 @@ func (*FoodReply) ProtoMessage() {} func (x *FoodReply) ProtoReflect() protoreflect.Message { mi := &file_chaosdogfood_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -129,20 +124,17 @@ func (x *FoodReply) GetConfirmationId() int32 { } type CatalogReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Items []*CatalogItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields - - Items []*CatalogItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CatalogReply) Reset() { *x = CatalogReply{} - if protoimpl.UnsafeEnabled { - mi := &file_chaosdogfood_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_chaosdogfood_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CatalogReply) String() string { @@ -153,7 +145,7 @@ func (*CatalogReply) ProtoMessage() {} func (x *CatalogReply) ProtoReflect() protoreflect.Message { mi := &file_chaosdogfood_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -176,21 +168,18 @@ func (x *CatalogReply) GetItems() []*CatalogItem { } type CatalogItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Animal string `protobuf:"bytes,1,opt,name=animal,proto3" json:"animal,omitempty"` + Food string `protobuf:"bytes,2,opt,name=food,proto3" json:"food,omitempty"` unknownFields protoimpl.UnknownFields - - Animal string `protobuf:"bytes,1,opt,name=animal,proto3" json:"animal,omitempty"` - Food string `protobuf:"bytes,2,opt,name=food,proto3" json:"food,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CatalogItem) Reset() { *x = CatalogItem{} - if protoimpl.UnsafeEnabled { - mi := &file_chaosdogfood_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_chaosdogfood_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CatalogItem) String() string { @@ -201,7 +190,7 @@ func (*CatalogItem) ProtoMessage() {} func (x *CatalogItem) ProtoReflect() protoreflect.Message { mi := &file_chaosdogfood_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -232,53 +221,38 @@ func (x *CatalogItem) GetFood() string { var File_chaosdogfood_proto protoreflect.FileDescriptor -var file_chaosdogfood_proto_rawDesc = []byte{ - 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x64, 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x64, 0x6f, 0x67, 0x66, 0x6f, - 0x6f, 0x64, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x25, 0x0a, 0x0b, 0x46, 0x6f, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x22, 0x4e, 0x0a, 0x09, 0x46, 0x6f, 0x6f, 0x64, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, - 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x3f, 0x0a, 0x0c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x64, 0x6f, 0x67, - 0x66, 0x6f, 0x6f, 0x64, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x74, 0x65, 0x6d, - 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x39, 0x0a, 0x0b, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x12, 0x12, - 0x0a, 0x04, 0x66, 0x6f, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x6f, - 0x6f, 0x64, 0x32, 0x91, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x6f, 0x73, 0x44, 0x6f, 0x67, 0x66, - 0x6f, 0x6f, 0x64, 0x12, 0x3d, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, - 0x68, 0x61, 0x6f, 0x73, 0x64, 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x2e, 0x46, 0x6f, 0x6f, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x64, - 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x2e, 0x46, 0x6f, 0x6f, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0a, 0x67, 0x65, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x63, 0x68, 0x61, 0x6f, 0x73, - 0x64, 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x63, 0x68, 0x61, 0x6f, - 0x73, 0x64, 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +const file_chaosdogfood_proto_rawDesc = "" + + "\n" + + "\x12chaosdogfood.proto\x12\fchaosdogfood\x1a\x1bgoogle/protobuf/empty.proto\"%\n" + + "\vFoodRequest\x12\x16\n" + + "\x06animal\x18\x01 \x01(\tR\x06animal\"N\n" + + "\tFoodReply\x12\x18\n" + + "\amessage\x18\x01 \x01(\tR\amessage\x12'\n" + + "\x0fconfirmation_id\x18\x02 \x01(\x05R\x0econfirmationId\"?\n" + + "\fCatalogReply\x12/\n" + + "\x05items\x18\x01 \x03(\v2\x19.chaosdogfood.CatalogItemR\x05items\"9\n" + + "\vCatalogItem\x12\x16\n" + + "\x06animal\x18\x01 \x01(\tR\x06animal\x12\x12\n" + + "\x04food\x18\x02 \x01(\tR\x04food2\x91\x01\n" + + "\fChaosDogfood\x12=\n" + + "\x05order\x12\x19.chaosdogfood.FoodRequest\x1a\x17.chaosdogfood.FoodReply\"\x00\x12B\n" + + "\n" + + "getCatalog\x12\x16.google.protobuf.Empty\x1a\x1a.chaosdogfood.CatalogReply\"\x00B\x10Z\x0e./chaosdogfoodb\x06proto3" var ( file_chaosdogfood_proto_rawDescOnce sync.Once - file_chaosdogfood_proto_rawDescData = file_chaosdogfood_proto_rawDesc + file_chaosdogfood_proto_rawDescData []byte ) func file_chaosdogfood_proto_rawDescGZIP() []byte { file_chaosdogfood_proto_rawDescOnce.Do(func() { - file_chaosdogfood_proto_rawDescData = protoimpl.X.CompressGZIP(file_chaosdogfood_proto_rawDescData) + file_chaosdogfood_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_chaosdogfood_proto_rawDesc), len(file_chaosdogfood_proto_rawDesc))) }) return file_chaosdogfood_proto_rawDescData } var file_chaosdogfood_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_chaosdogfood_proto_goTypes = []interface{}{ +var file_chaosdogfood_proto_goTypes = []any{ (*FoodRequest)(nil), // 0: chaosdogfood.FoodRequest (*FoodReply)(nil), // 1: chaosdogfood.FoodReply (*CatalogReply)(nil), // 2: chaosdogfood.CatalogReply @@ -303,61 +277,11 @@ func file_chaosdogfood_proto_init() { if File_chaosdogfood_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_chaosdogfood_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FoodRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_chaosdogfood_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FoodReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_chaosdogfood_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CatalogReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_chaosdogfood_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CatalogItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_chaosdogfood_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_chaosdogfood_proto_rawDesc), len(file_chaosdogfood_proto_rawDesc)), NumEnums: 0, NumMessages: 4, NumExtensions: 0, @@ -368,7 +292,6 @@ func file_chaosdogfood_proto_init() { MessageInfos: file_chaosdogfood_proto_msgTypes, }.Build() File_chaosdogfood_proto = out.File - file_chaosdogfood_proto_rawDesc = nil file_chaosdogfood_proto_goTypes = nil file_chaosdogfood_proto_depIdxs = nil } diff --git a/grpc/disruptionlistener/disruptionlistener.pb.go b/grpc/disruptionlistener/disruptionlistener.pb.go index 0f2bcac9b..4e5ddde9b 100644 --- a/grpc/disruptionlistener/disruptionlistener.pb.go +++ b/grpc/disruptionlistener/disruptionlistener.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 +// protoc-gen-go v1.36.11 // protoc v3.17.3 // source: disruptionlistener.proto @@ -17,6 +17,7 @@ import ( emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -27,20 +28,17 @@ const ( ) type DisruptionSpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Endpoints []*EndpointSpec `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` unknownFields protoimpl.UnknownFields - - Endpoints []*EndpointSpec `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DisruptionSpec) Reset() { *x = DisruptionSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_disruptionlistener_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_disruptionlistener_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DisruptionSpec) String() string { @@ -51,7 +49,7 @@ func (*DisruptionSpec) ProtoMessage() {} func (x *DisruptionSpec) ProtoReflect() protoreflect.Message { mi := &file_disruptionlistener_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -74,21 +72,18 @@ func (x *DisruptionSpec) GetEndpoints() []*EndpointSpec { } type EndpointSpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TargetEndpoint string `protobuf:"bytes,1,opt,name=targetEndpoint,proto3" json:"targetEndpoint,omitempty"` - Alterations []*AlterationSpec `protobuf:"bytes,2,rep,name=alterations,proto3" json:"alterations,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + TargetEndpoint string `protobuf:"bytes,1,opt,name=targetEndpoint,proto3" json:"targetEndpoint,omitempty"` + Alterations []*AlterationSpec `protobuf:"bytes,2,rep,name=alterations,proto3" json:"alterations,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *EndpointSpec) Reset() { *x = EndpointSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_disruptionlistener_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_disruptionlistener_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EndpointSpec) String() string { @@ -99,7 +94,7 @@ func (*EndpointSpec) ProtoMessage() {} func (x *EndpointSpec) ProtoReflect() protoreflect.Message { mi := &file_disruptionlistener_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -129,22 +124,19 @@ func (x *EndpointSpec) GetAlterations() []*AlterationSpec { } type AlterationSpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ErrorToReturn string `protobuf:"bytes,1,opt,name=errorToReturn,proto3" json:"errorToReturn,omitempty"` - OverrideToReturn string `protobuf:"bytes,2,opt,name=overrideToReturn,proto3" json:"overrideToReturn,omitempty"` - QueryPercent int32 `protobuf:"varint,3,opt,name=queryPercent,proto3" json:"queryPercent,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ErrorToReturn string `protobuf:"bytes,1,opt,name=errorToReturn,proto3" json:"errorToReturn,omitempty"` + OverrideToReturn string `protobuf:"bytes,2,opt,name=overrideToReturn,proto3" json:"overrideToReturn,omitempty"` + QueryPercent int32 `protobuf:"varint,3,opt,name=queryPercent,proto3" json:"queryPercent,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AlterationSpec) Reset() { *x = AlterationSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_disruptionlistener_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_disruptionlistener_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AlterationSpec) String() string { @@ -155,7 +147,7 @@ func (*AlterationSpec) ProtoMessage() {} func (x *AlterationSpec) ProtoReflect() protoreflect.Message { mi := &file_disruptionlistener_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -193,62 +185,36 @@ func (x *AlterationSpec) GetQueryPercent() int32 { var File_disruptionlistener_proto protoreflect.FileDescriptor -var file_disruptionlistener_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x64, 0x69, 0x73, 0x72, - 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x1a, 0x1b, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x0e, 0x44, - 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3e, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x7c, 0x0a, - 0x0c, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x26, 0x0a, - 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x0b, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x73, - 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x2e, - 0x41, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0b, - 0x61, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x0e, - 0x41, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x24, - 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x6f, 0x52, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x54, 0x6f, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x12, 0x22, 0x0a, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72, - 0x63, 0x65, 0x6e, 0x74, 0x32, 0xa3, 0x01, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x07, 0x44, - 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x12, 0x22, 0x2e, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x2e, 0x44, 0x69, 0x73, 0x72, - 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x69, 0x73, - 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x2f, - 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +const file_disruptionlistener_proto_rawDesc = "" + + "\n" + + "\x18disruptionlistener.proto\x12\x12disruptionlistener\x1a\x1bgoogle/protobuf/empty.proto\"P\n" + + "\x0eDisruptionSpec\x12>\n" + + "\tendpoints\x18\x01 \x03(\v2 .disruptionlistener.EndpointSpecR\tendpoints\"|\n" + + "\fEndpointSpec\x12&\n" + + "\x0etargetEndpoint\x18\x01 \x01(\tR\x0etargetEndpoint\x12D\n" + + "\valterations\x18\x02 \x03(\v2\".disruptionlistener.AlterationSpecR\valterations\"\x86\x01\n" + + "\x0eAlterationSpec\x12$\n" + + "\rerrorToReturn\x18\x01 \x01(\tR\rerrorToReturn\x12*\n" + + "\x10overrideToReturn\x18\x02 \x01(\tR\x10overrideToReturn\x12\"\n" + + "\fqueryPercent\x18\x03 \x01(\x05R\fqueryPercent2\xa3\x01\n" + + "\x12DisruptionListener\x12G\n" + + "\aDisrupt\x12\".disruptionlistener.DisruptionSpec\x1a\x16.google.protobuf.Empty\"\x00\x12D\n" + + "\x10ResetDisruptions\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00B\x16Z\x14./disruptionlistenerb\x06proto3" var ( file_disruptionlistener_proto_rawDescOnce sync.Once - file_disruptionlistener_proto_rawDescData = file_disruptionlistener_proto_rawDesc + file_disruptionlistener_proto_rawDescData []byte ) func file_disruptionlistener_proto_rawDescGZIP() []byte { file_disruptionlistener_proto_rawDescOnce.Do(func() { - file_disruptionlistener_proto_rawDescData = protoimpl.X.CompressGZIP(file_disruptionlistener_proto_rawDescData) + file_disruptionlistener_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_disruptionlistener_proto_rawDesc), len(file_disruptionlistener_proto_rawDesc))) }) return file_disruptionlistener_proto_rawDescData } var file_disruptionlistener_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_disruptionlistener_proto_goTypes = []interface{}{ +var file_disruptionlistener_proto_goTypes = []any{ (*DisruptionSpec)(nil), // 0: disruptionlistener.DisruptionSpec (*EndpointSpec)(nil), // 1: disruptionlistener.EndpointSpec (*AlterationSpec)(nil), // 2: disruptionlistener.AlterationSpec @@ -273,49 +239,11 @@ func file_disruptionlistener_proto_init() { if File_disruptionlistener_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_disruptionlistener_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DisruptionSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_disruptionlistener_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EndpointSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_disruptionlistener_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AlterationSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_disruptionlistener_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_disruptionlistener_proto_rawDesc), len(file_disruptionlistener_proto_rawDesc)), NumEnums: 0, NumMessages: 3, NumExtensions: 0, @@ -326,7 +254,6 @@ func file_disruptionlistener_proto_init() { MessageInfos: file_disruptionlistener_proto_msgTypes, }.Build() File_disruptionlistener_proto = out.File - file_disruptionlistener_proto_rawDesc = nil file_disruptionlistener_proto_goTypes = nil file_disruptionlistener_proto_depIdxs = nil } diff --git a/mk/ci.mk b/mk/ci.mk new file mode 100644 index 000000000..38e74ca3a --- /dev/null +++ b/mk/ci.mk @@ -0,0 +1,93 @@ +# mk/ci.mk — CI-specific targets, Python tasks, dependency management, and Datadog agent. + +# ------------------------------------------------------------------------------ +# Minikube (CI) +# ------------------------------------------------------------------------------ + +MINIKUBE_CPUS ?= 6 +MINIKUBE_MEMORY ?= 28672 + +.PHONY: ci-install-minikube +ci-install-minikube: ## Install and start Minikube (CI only) + curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb + sudo dpkg -i minikube_latest_amd64.deb + minikube start --cpus='$(MINIKUBE_CPUS)' --memory='$(MINIKUBE_MEMORY)' --vm-driver=docker --container-runtime=containerd --kubernetes-version=${KUBERNETES_VERSION} + minikube status + +# ------------------------------------------------------------------------------ +# Python venv and invoke tasks +# ------------------------------------------------------------------------------ + +.PHONY: venv +venv: + test -d .venv || python3 -m venv .venv + . .venv/bin/activate; pip install -qr tasks/requirements.txt + +.PHONY: header +header: venv ## Check license headers + . .venv/bin/activate; inv header-check + +.PHONY: header-fix +header-fix: ## Fix license headers (run twice to converge) + -$(MAKE) header + $(MAKE) header + +.PHONY: license +license: venv ## Check third-party licenses + . .venv/bin/activate; inv license-check + +# ------------------------------------------------------------------------------ +# Dependency management +# ------------------------------------------------------------------------------ + +.PHONY: godeps +godeps: ## Tidy and vendor Go dependencies + go mod tidy; go mod vendor + +.PHONY: update-deps +update-deps: ## Update pinned Python dependencies + @echo "Updating Python dependencies..." + @pip install -q uv + @uv pip compile --python-platform linux tasks/requirements.in -o tasks/requirements.txt + @echo "Updated tasks/requirements.txt" + @echo "Please commit both tasks/requirements.in and tasks/requirements.txt" + +.PHONY: deps +deps: godeps license ## Tidy Go deps and check licenses + +# ------------------------------------------------------------------------------ +# Release +# ------------------------------------------------------------------------------ + +.SILENT: release +.PHONY: release +release: ## Create a release + VERSION=$(VERSION) ./tasks/release.sh + +# ------------------------------------------------------------------------------ +# Datadog agent (Lima) +# ------------------------------------------------------------------------------ + +EXISTING_NAMESPACE = $(shell $(KUBECTL) get ns datadog-agent -oname 2>/dev/null || echo "") + +.PHONY: lima-install-datadog-agent +lima-install-datadog-agent: ## Install Datadog agent into Lima cluster +ifeq (true,$(INSTALL_DATADOG_AGENT)) +ifeq (,$(EXISTING_NAMESPACE)) + $(KUBECTL) create ns datadog-agent + helm repo add --force-update datadoghq https://helm.datadoghq.com + helm install -n datadog-agent my-datadog-operator datadoghq/datadog-operator + $(KUBECTL) create secret -n datadog-agent generic datadog-secret --from-literal api-key=${STAGING_DATADOG_API_KEY} --from-literal app-key=${STAGING_DATADOG_APP_KEY} +endif + $(KUBECTL) apply -f - < examples/datadog-agent.yaml +endif + +.PHONY: open-dd +open-dd: ## Open Datadog infrastructure page for Lima host +ifeq (true,$(INSTALL_DATADOG_AGENT)) +ifdef STAGING_DD_SITE + open "${STAGING_DD_SITE}/infrastructure?host=lima-$(LIMA_INSTANCE)&tab=details" +else + @echo "You need to define STAGING_DD_SITE in your .zshrc or similar to use this feature" +endif +endif diff --git a/mk/docker.mk b/mk/docker.mk new file mode 100644 index 000000000..16e9151fb --- /dev/null +++ b/mk/docker.mk @@ -0,0 +1,60 @@ +# mk/docker.mk — Docker build, save, and push targets for all components. + +# Set container names for each component +docker-build-injector docker-build-only-injector: CONTAINER_NAME=$(INJECTOR_IMAGE) +docker-build-handler docker-build-only-handler: CONTAINER_NAME=$(HANDLER_IMAGE) +docker-build-manager docker-build-only-manager: CONTAINER_NAME=$(MANAGER_IMAGE) + +lima-push-injector lima-push-handler lima-push-manager: FAKE_FOR=COMPLETION + +# Generate manifests before building manager unless skipped (useful in CI) +ifneq ($(SKIP_GENERATE),true) +docker-build-manager docker-build-only-manager: generate +endif + +# Template for per-component docker targets. +# $(1) is the target name: injector|handler|manager +define TARGET_template + +docker-build-$(1): docker-build-only-$(1) + docker save $$(CONTAINER_NAME):$(CONTAINER_TAG) -o ./bin/$(1)/$(1).tar.gz + +docker-build-only-$(1): + docker buildx build \ + --build-arg BUILDGOVERSION=$(BUILDGOVERSION) \ + --build-arg BUILDSTAMP=$(NOW_ISO8601) \ + -t $$(CONTAINER_NAME):$(CONTAINER_TAG) \ + --metadata-file ./bin/$(1)/docker-metadata.json \ + $(CONTAINER_BUILD_EXTRA_ARGS) \ + -f bin/$(1)/Dockerfile . + if [ "$${SIGN_IMAGE}" = "true" ]; then \ + ddsign sign $$(CONTAINER_NAME):$(CONTAINER_VERSION) --docker-metadata-file ./bin/$(1)/docker-metadata.json; \ + fi + +lima-push-$(1): docker-build-$(1) + limactl copy ./bin/$(1)/$(1).tar.gz $(LIMA_INSTANCE):/tmp/ + limactl shell $(LIMA_INSTANCE) -- sudo k3s ctr i import /tmp/$(1).tar.gz + +minikube-load-$(1): + ls -la ./bin/$(1)/$(1).tar.gz + minikube image load --daemon=false --overwrite=true ./bin/$(1)/$(1).tar.gz + +endef + +TARGETS := injector handler manager + +$(foreach tgt,$(TARGETS),$(eval $(call TARGET_template,$(tgt)))) + +# Aggregate targets +.PHONY: docker-build-all docker-build-only-all lima-push-all minikube-load-all +docker-build-all: $(addprefix docker-build-,$(TARGETS)) ## Build and save all Docker images +docker-build-only-all: $(addprefix docker-build-only-,$(TARGETS)) ## Build all Docker images (no save) +lima-push-all: $(addprefix lima-push-,$(TARGETS)) ## Push all images to Lima +minikube-load-all: $(addprefix minikube-load-,$(TARGETS)) ## Load all images into Minikube + +# Build chaosli CLI +.PHONY: chaosli +chaosli: ## Build chaosli CLI binary + GOOS=darwin GOARCH=$(GOARCH) CGO_ENABLED=0 go build \ + -ldflags="-X github.com/DataDog/chaos-controller/cli/chaosli/cmd.Version=$(VERSION)" \ + -o bin/chaosli/chaosli_darwin_$(GOARCH) ./cli/chaosli/ diff --git a/mk/generate.mk b/mk/generate.mk new file mode 100644 index 000000000..0cf53ebe9 --- /dev/null +++ b/mk/generate.mk @@ -0,0 +1,57 @@ +# mk/generate.mk — Code generation: CRDs, deepcopy, protobuf, mocks. + +# ------------------------------------------------------------------------------ +# Manifests (CRD, RBAC) +# ------------------------------------------------------------------------------ + +.PHONY: manifests +manifests: $(CONTROLLER_GEN) $(YAMLFMT) ## Generate CRD and RBAC manifests + $(CONTROLLER_GEN) rbac:roleName=chaos-controller crd:crdVersions=v1 \ + paths="./..." \ + output:crd:dir=./chart/templates/generated/ \ + output:rbac:dir=./chart/templates/generated/ + $(YAMLFMT) chart/templates/generated + +# ------------------------------------------------------------------------------ +# controller-gen object generation (deepcopy) +# ------------------------------------------------------------------------------ + +.PHONY: generate +generate: $(CONTROLLER_GEN) ## Generate deepcopy helpers + $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths="./..." + +# ------------------------------------------------------------------------------ +# Protobuf generation (DRY template for all proto packages) +# ------------------------------------------------------------------------------ + +PROTOBUF_PACKAGES := grpc/disruptionlistener dogfood/chaosdogfood + +define protobuf_target +.PHONY: generate-$(notdir $(1))-protobuf +generate-$(notdir $(1))-protobuf: $(PROTOC) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC) + cd $(1) && \ + PATH="$(LOCALBIN):$(PATH)" $(PROTOC) \ + --proto_path=. \ + --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + $(notdir $(wildcard $(1)/*.proto)) +endef + +$(foreach pkg,$(PROTOBUF_PACKAGES),$(eval $(call protobuf_target,$(pkg)))) + +.PHONY: generate-protobuf +generate-protobuf: $(foreach p,$(PROTOBUF_PACKAGES),generate-$(notdir $(p))-protobuf) ## Generate all protobuf stubs + +# ------------------------------------------------------------------------------ +# Mocks +# ------------------------------------------------------------------------------ + +.PHONY: clean-mocks +clean-mocks: ## Remove generated mocks + find . -type f -name "*mock*.go" -not -path "./vendor/*" -exec rm {} \; + rm -rf mocks/ + +.PHONY: generate-mocks +generate-mocks: clean-mocks $(MOCKERY) ## Regenerate all mocks + go generate ./... + $(MAKE) header-fix diff --git a/mk/lima.mk b/mk/lima.mk new file mode 100644 index 000000000..ba39ca4d2 --- /dev/null +++ b/mk/lima.mk @@ -0,0 +1,106 @@ +# mk/lima.mk — Lima cluster management targets. + +.PHONY: lima-all +lima-all: lima-start lima-install-datadog-agent lima-install-cert-manager lima-push-all lima-install ## Create Lima cluster and deploy chaos-controller + kubens chaos-engineering + +.PHONY: lima-redeploy +lima-redeploy: lima-push-all lima-install lima-restart ## Rebuild images, re-install chart, restart pods + +.PHONY: lima-install-cert-manager +lima-install-cert-manager: ## Install cert-manager chart + $(KUBECTL) apply -f https://github.com/jetstack/cert-manager/releases/download/v1.9.1/cert-manager.yaml + $(KUBECTL) -n cert-manager rollout status deployment/cert-manager-webhook --timeout=180s + +.PHONY: lima-install-demo +lima-install-demo: ## Deploy demo workloads + $(KUBECTL) apply -f - < ./examples/namespace.yaml + $(KUBECTL) apply -f - < ./examples/demo.yaml + $(KUBECTL) -n chaos-demo rollout status deployment/demo-curl --timeout=60s + $(KUBECTL) -n chaos-demo rollout status deployment/demo-nginx --timeout=60s + +.PHONY: lima-install +lima-install: manifests ## Install CRDs and controller into Lima k3s cluster + helm template \ + --set=controller.version=$(CONTAINER_VERSION) \ + --set=controller.metricsSink=$(LIMA_INSTALL_SINK) \ + --set=controller.profilerSink=$(LIMA_INSTALL_SINK) \ + --set=controller.tracerSink=$(LIMA_INSTALL_SINK) \ + --values ./chart/values/$(HELM_VALUES) \ + ./chart | $(KUBECTL) apply -f - +ifneq (local.yaml,$(HELM_VALUES)) + $(KUBECTL) -n chaos-engineering rollout status deployment/chaos-controller --timeout=60s +endif + +.PHONY: lima-uninstall +lima-uninstall: ## Uninstall CRDs and controller from Lima k3s cluster + helm template --set=skipNamespace=true --values ./chart/values/$(HELM_VALUES) ./chart | $(KUBECTL) delete -f - + +.PHONY: lima-restart +lima-restart: ## Restart the chaos-controller pod +ifneq (local.yaml,$(HELM_VALUES)) + $(KUBECTL) -n chaos-engineering rollout restart deployment/chaos-controller + $(KUBECTL) -n chaos-engineering rollout status deployment/chaos-controller --timeout=60s +endif + +.PHONY: lima-kubectx-clean +lima-kubectx-clean: ## Remove Lima references from kubectl config + -kubectl config delete-cluster ${LIMA_PROFILE} + -kubectl config delete-context ${LIMA_PROFILE} + -kubectl config delete-user ${LIMA_PROFILE} + kubectl config unset current-context + +.PHONY: lima-kubectx +lima-kubectx: + limactl shell $(LIMA_INSTANCE) sudo sed 's/default/lima/g' /etc/rancher/k3s/k3s.yaml > ~/.kube/config_lima + KUBECONFIG=${KUBECONFIG}:~/.kube/config:~/.kube/config_lima kubectl config view --flatten > /tmp/config + rm ~/.kube/config_lima + mv /tmp/config ~/.kube/config + chmod 600 ~/.kube/config + kubectx ${LIMA_PROFILE} + +.PHONY: lima-stop +lima-stop: ## Stop and delete the Lima cluster + limactl stop -f $(LIMA_INSTANCE) + limactl delete $(LIMA_INSTANCE) + $(MAKE) lima-kubectx-clean + +.PHONY: lima-start +lima-start: lima-kubectx-clean ## Start the Lima cluster + LIMA_CGROUPS=${LIMA_CGROUPS} LIMA_CONFIG=${LIMA_CONFIG} LIMA_INSTANCE=${LIMA_INSTANCE} ./scripts/lima_start.sh + $(MAKE) lima-kubectx + +# Longhorn provides an alternative StorageClass for reliable disk throttling. +# Default local-path uses tmpfs which leads to virtual unnamed devices (major 0) +# that blkio does not support. +.PHONY: lima-install-longhorn +lima-install-longhorn: ## Install Longhorn storage driver + $(KUBECTL) apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.0/deploy/longhorn.yaml + +# ------------------------------------------------------------------------------ +# Local development helpers +# ------------------------------------------------------------------------------ + +.PHONY: _pre_local +_pre_local: generate manifests + @$(shell $(KUBECTL) get deploy chaos-controller 2> /dev/null) +ifeq (0,$(.SHELLSTATUS)) + -$(MAKE) lima-uninstall HELM_VALUES=dev.yaml + $(MAKE) lima-install HELM_VALUES=local.yaml + $(KUBECTL) -n chaos-engineering get cm chaos-controller -oyaml | yq '.data["config.yaml"]' > .local.yaml + yq -i '.controller.webhook.certDir = "chart/certs"' .local.yaml +else + @echo "Chaos controller is not installed, skipped!" +endif + +.PHONY: debug +debug: _pre_local ## Prepare environment for IDE debugging + @echo "now you can launch through vs-code or your favorite IDE a controller in debug with appropriate configuration (--config=chart/values/local.yaml + CONTROLLER_NODE_NAME=local)" + +.PHONY: run +run: ## Run the controller locally + CONTROLLER_NODE_NAME=local go run . --config=.local.yaml + +.PHONY: watch +watch: _pre_local install-watchexec ## Watch for changes and auto-rebuild + watchexec make SKIP_EBPF=true lima-push-injector run diff --git a/mk/lint.mk b/mk/lint.mk new file mode 100644 index 000000000..2e6e39937 --- /dev/null +++ b/mk/lint.mk @@ -0,0 +1,44 @@ +# mk/lint.mk — Formatting, vetting, and linting targets. + +.PHONY: fmt +fmt: ## Run go fmt + go fmt ./... + +.PHONY: vet +vet: ## Run go vet + go vet ./... + +.PHONY: lint +lint: $(GOLANGCI_LINT) ## Run golangci-lint + GOOS=linux $(GOLANGCI_LINT) run -E ginkgolinter ./... + GOOS=linux $(GOLANGCI_LINT) run + +# ------------------------------------------------------------------------------ +# Spellcheck +# ------------------------------------------------------------------------------ + +.PHONY: spellcheck-deps +spellcheck-deps: +ifeq (, $(shell which npm)) + @{ \ + echo "please install npm or run 'make spellcheck-docker' for a slow but platform-agnostic run"; \ + exit 1; \ + } +endif +ifeq (, $(shell which mdspell)) + @{ \ + echo "installing mdspell through npm -g... (might require sudo run)"; \ + npm -g i markdown-spellcheck; \ + } +endif + +.PHONY: spellcheck +spellcheck: spellcheck-deps ## Spellcheck markdown files + mdspell --en-us --ignore-acronyms --ignore-numbers \ + $(shell find . -name vendor -prune -o -name '*.md' -print); + +.PHONY: spellcheck-docker +spellcheck-docker: ## Spellcheck via Docker (no local npm needed) + docker run --rm -ti -v $(shell pwd):/workdir tmaier/markdown-spellcheck:latest \ + --ignore-numbers --ignore-acronyms --en-us \ + $(shell find . -name vendor -prune -o -name '*.md' -print); diff --git a/mk/test.mk b/mk/test.mk new file mode 100644 index 000000000..64bc0f3d8 --- /dev/null +++ b/mk/test.mk @@ -0,0 +1,60 @@ +# mk/test.mk — Test targets (unit, e2e, chaosli). + +# https://onsi.github.io/ginkgo/#recommended-continuous-integration-configuration +GINKGO_PROCS ?= 4 + +# Additional args to provide to test runner (ginkgo). +# Examples: +# make test TEST_ARGS=--until-it-fails +# make test TEST_ARGS=injector +TEST_ARGS ?= + +DD_ENV := local +ifeq (true,$(CI)) +DD_ENV := ci +endif + +SKIP_DEPLOY ?= + +# Internal ginkgo runner — not meant to be called directly. +.PHONY: _ginkgo_test +_ginkgo_test: + -go run github.com/onsi/ginkgo/v2/ginkgo --fail-on-pending --keep-going --vv \ + --cover --coverprofile=cover.profile --randomize-all \ + --race --trace --json-report=report-$(GO_TEST_REPORT_NAME).json --junit-report=report-$(GO_TEST_REPORT_NAME).xml \ + --compilers=$(GINKGO_PROCS) --procs=$(GINKGO_PROCS) \ + --poll-progress-after=10s --poll-progress-interval=10s \ + $(GINKGO_TEST_ARGS) \ + && touch report-$(GO_TEST_REPORT_NAME)-succeed +ifneq (true,$(GO_TEST_SKIP_UPLOAD)) +ifdef DATADOG_API_KEY +ifneq (,$(shell which datadog-ci)) + -DD_ENV=$(DD_ENV) datadog-ci junit upload --service chaos-controller --tags="team:chaos-engineering,type:$(GO_TEST_REPORT_NAME)" report-$(GO_TEST_REPORT_NAME).xml +else + @echo "datadog-ci binary is not installed, run 'make install-datadog-ci' to upload tests results to datadog" +endif +else + @echo "DATADOG_API_KEY env var is not defined, create a local API key https://app.datadoghq.com/personal-settings/application-keys if you want to upload your local tests results to datadog" +endif +else + @echo "datadog-ci junit upload SKIPPED" +endif + [ -f report-$(GO_TEST_REPORT_NAME)-succeed ] && rm -f report-$(GO_TEST_REPORT_NAME)-succeed || exit 1 + +.PHONY: test +test: generate manifests ## Run unit tests + $(if $(GOPATH),,$(error GOPATH is not set. Please set GOPATH before running make test)) + $(MAKE) _ginkgo_test GO_TEST_REPORT_NAME=$@ \ + GINKGO_TEST_ARGS="-r --skip-package=controllers --randomize-suites --timeout=10m $(TEST_ARGS)" + +.PHONY: e2e-test +e2e-test: generate manifests ## Run e2e tests (against a real cluster) +ifneq (true,$(SKIP_DEPLOY)) + $(MAKE) lima-install HELM_VALUES=ci.yaml +endif + E2E_TEST_CLUSTER_NAME=$(E2E_TEST_CLUSTER_NAME) E2E_TEST_KUBECTL_CONTEXT=$(E2E_TEST_KUBECTL_CONTEXT) $(MAKE) _ginkgo_test GO_TEST_REPORT_NAME=$@ \ + GINKGO_TEST_ARGS="--flake-attempts=3 --timeout=25m controllers" + +.PHONY: chaosli-test +chaosli-test: ## Test chaosli API portability + docker buildx build -f ./cli/chaosli/chaosli.DOCKERFILE -t test-chaosli-image . diff --git a/mk/tools.mk b/mk/tools.mk new file mode 100644 index 000000000..a47e30070 --- /dev/null +++ b/mk/tools.mk @@ -0,0 +1,254 @@ +# mk/tools.mk — Isolated tool management with stamp-based version tracking. +# All tools install into $(LOCALBIN). Stamp files in $(LOCALSTAMP) track +# installed versions so Make skips re-installs when the version hasn't changed. + +$(LOCALBIN) $(LOCALSTAMP): + mkdir -p $@ + +# ------------------------------------------------------------------------------ +# Tool versions (single source of truth) +# ------------------------------------------------------------------------------ + +GOLANGCI_LINT_VERSION := 2.8.0 +CONTROLLER_GEN_VERSION := v0.19.0 +MOCKERY_VERSION := 2.53.5 +YAMLFMT_VERSION := 0.9.0 +HELM_VERSION := v3.19.0 +PROTOC_VERSION := 3.17.3 +PROTOC_GEN_GO_VERSION := v1.36.11 # Must be aligned with the protobuf version in go.mod. +PROTOC_GEN_GO_GRPC_VERSION := v1.1.0 + +# ------------------------------------------------------------------------------ +# Platform detection +# ------------------------------------------------------------------------------ + +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) + +MOCKERY_ARCH := $(GOARCH) +ifeq (amd64,$(GOARCH)) +MOCKERY_ARCH := x86_64 +endif + +YAMLFMT_ARCH := $(GOARCH) +ifeq (amd64,$(GOARCH)) +YAMLFMT_ARCH := x86_64 +endif + +PROTOC_OS ?= osx + +# ------------------------------------------------------------------------------ +# Tool binary paths +# ------------------------------------------------------------------------------ + +GOLANGCI_LINT := $(LOCALBIN)/golangci-lint +CONTROLLER_GEN := $(LOCALBIN)/controller-gen +MOCKERY := $(LOCALBIN)/mockery +YAMLFMT := $(LOCALBIN)/yamlfmt +HELM := $(LOCALBIN)/helm +PROTOC := $(LOCALBIN)/protoc +PROTOC_GEN_GO := $(LOCALBIN)/protoc-gen-go +PROTOC_GEN_GO_GRPC := $(LOCALBIN)/protoc-gen-go-grpc +KUBEBUILDER := $(LOCALBIN)/kubebuilder +DATADOG_CI := $(LOCALBIN)/datadog-ci +WATCHEXEC := $(LOCALBIN)/watchexec + +PROTOC_INCLUDE := $(CURDIR)/.tools/include + +# ------------------------------------------------------------------------------ +# Stamp file paths (keyed by version) +# ------------------------------------------------------------------------------ + +GOLANGCI_LINT_STAMP := $(LOCALSTAMP)/golangci-lint-$(GOLANGCI_LINT_VERSION) +CONTROLLER_GEN_STAMP := $(LOCALSTAMP)/controller-gen-$(CONTROLLER_GEN_VERSION) +MOCKERY_STAMP := $(LOCALSTAMP)/mockery-$(MOCKERY_VERSION) +YAMLFMT_STAMP := $(LOCALSTAMP)/yamlfmt-$(YAMLFMT_VERSION) +HELM_STAMP := $(LOCALSTAMP)/helm-$(HELM_VERSION) +PROTOC_STAMP := $(LOCALSTAMP)/protoc-$(PROTOC_VERSION) +PROTOC_GEN_GO_STAMP := $(LOCALSTAMP)/protoc-gen-go-$(PROTOC_GEN_GO_VERSION) +PROTOC_GEN_GO_GRPC_STAMP := $(LOCALSTAMP)/protoc-gen-go-grpc-$(PROTOC_GEN_GO_GRPC_VERSION) +KUBEBUILDER_STAMP := $(LOCALSTAMP)/kubebuilder +DATADOG_CI_STAMP := $(LOCALSTAMP)/datadog-ci +WATCHEXEC_STAMP := $(LOCALSTAMP)/watchexec + +# ------------------------------------------------------------------------------ +# golangci-lint +# ------------------------------------------------------------------------------ + +$(GOLANGCI_LINT_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/golangci-lint-* + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_LINT_VERSION) + @touch $@ + +$(GOLANGCI_LINT): $(GOLANGCI_LINT_STAMP) + +.PHONY: install-golangci-lint +install-golangci-lint: $(GOLANGCI_LINT) ## Install golangci-lint + +# ------------------------------------------------------------------------------ +# controller-gen +# ------------------------------------------------------------------------------ + +$(CONTROLLER_GEN_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/controller-gen-* + GOBIN=$(LOCALBIN) CGO_ENABLED=0 go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION) + @touch $@ + +$(CONTROLLER_GEN): $(CONTROLLER_GEN_STAMP) + +.PHONY: install-controller-gen +install-controller-gen: $(CONTROLLER_GEN) ## Install controller-gen + +# ------------------------------------------------------------------------------ +# mockery +# ------------------------------------------------------------------------------ + +$(MOCKERY_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/mockery-* + curl -sSLo /tmp/mockery.tar.gz https://github.com/vektra/mockery/releases/download/v$(MOCKERY_VERSION)/mockery_$(MOCKERY_VERSION)_$(GOOS)_$(MOCKERY_ARCH).tar.gz + tar -xzf /tmp/mockery.tar.gz --directory=$(LOCALBIN) mockery + rm -f /tmp/mockery.tar.gz + @touch $@ + +$(MOCKERY): $(MOCKERY_STAMP) + +.PHONY: install-mockery +install-mockery: $(MOCKERY) ## Install mockery + +# ------------------------------------------------------------------------------ +# yamlfmt +# ------------------------------------------------------------------------------ + +$(YAMLFMT_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/yamlfmt-* + curl -sSLo /tmp/yamlfmt.tar.gz https://github.com/google/yamlfmt/releases/download/v$(YAMLFMT_VERSION)/yamlfmt_$(YAMLFMT_VERSION)_$(GOOS)_$(YAMLFMT_ARCH).tar.gz + tar -xzf /tmp/yamlfmt.tar.gz --directory=$(LOCALBIN) yamlfmt + rm -f /tmp/yamlfmt.tar.gz + @touch $@ + +$(YAMLFMT): $(YAMLFMT_STAMP) + +.PHONY: install-yamlfmt +install-yamlfmt: $(YAMLFMT) ## Install yamlfmt + +# ------------------------------------------------------------------------------ +# helm +# ------------------------------------------------------------------------------ + +$(HELM_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/helm-* + curl -sSLo /tmp/helm.tar.gz "https://get.helm.sh/helm-$(HELM_VERSION)-$(GOOS)-$(GOARCH).tar.gz" + tar -xzf /tmp/helm.tar.gz --directory=$(LOCALBIN) --strip-components=1 $(GOOS)-$(GOARCH)/helm + rm -f /tmp/helm.tar.gz + @touch $@ + +$(HELM): $(HELM_STAMP) + +.PHONY: install-helm +install-helm: $(HELM) ## Install helm + +# ------------------------------------------------------------------------------ +# protoc +# ------------------------------------------------------------------------------ + +PROTOC_ZIP := protoc-$(PROTOC_VERSION)-$(PROTOC_OS)-x86_64.zip + +$(PROTOC_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/protoc-* + curl -sSLo /tmp/$(PROTOC_ZIP) https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/$(PROTOC_ZIP) + unzip -o /tmp/$(PROTOC_ZIP) -d $(CURDIR)/.tools bin/protoc + unzip -o /tmp/$(PROTOC_ZIP) -d $(CURDIR)/.tools 'include/*' + rm -f /tmp/$(PROTOC_ZIP) + @touch $@ + +$(PROTOC): $(PROTOC_STAMP) + +.PHONY: install-protobuf +install-protobuf: $(PROTOC) ## Install protoc compiler + +# ------------------------------------------------------------------------------ +# protoc-gen-go +# ------------------------------------------------------------------------------ + +$(PROTOC_GEN_GO_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/protoc-gen-go-* + GOBIN=$(LOCALBIN) go install google.golang.org/protobuf/cmd/protoc-gen-go@$(PROTOC_GEN_GO_VERSION) + @touch $@ + +$(PROTOC_GEN_GO): $(PROTOC_GEN_GO_STAMP) + +# ------------------------------------------------------------------------------ +# protoc-gen-go-grpc +# ------------------------------------------------------------------------------ + +$(PROTOC_GEN_GO_GRPC_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/protoc-gen-go-grpc-* + GOBIN=$(LOCALBIN) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$(PROTOC_GEN_GO_GRPC_VERSION) + @touch $@ + +$(PROTOC_GEN_GO_GRPC): $(PROTOC_GEN_GO_GRPC_STAMP) + +# ------------------------------------------------------------------------------ +# kubebuilder + setup-envtest +# ------------------------------------------------------------------------------ + +$(KUBEBUILDER_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/kubebuilder + curl -sSLo $(LOCALBIN)/kubebuilder https://go.kubebuilder.io/dl/latest/$(GOOS)/$(GOARCH) + chmod u+x $(LOCALBIN)/kubebuilder + GOBIN=$(LOCALBIN) go install -v sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + @touch $@ + +$(KUBEBUILDER): $(KUBEBUILDER_STAMP) + +.PHONY: install-kubebuilder +install-kubebuilder: $(KUBEBUILDER) ## Install kubebuilder and setup-envtest + +# ------------------------------------------------------------------------------ +# datadog-ci +# ------------------------------------------------------------------------------ + +$(DATADOG_CI_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/datadog-ci + curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_$(GOOS)-x64" --output "$(LOCALBIN)/datadog-ci" + chmod u+x $(LOCALBIN)/datadog-ci + @touch $@ + +$(DATADOG_CI): $(DATADOG_CI_STAMP) + +.PHONY: install-datadog-ci +install-datadog-ci: $(DATADOG_CI) ## Install datadog-ci + +# ------------------------------------------------------------------------------ +# watchexec (macOS only via brew; falls back to checking PATH) +# ------------------------------------------------------------------------------ + +$(WATCHEXEC_STAMP): | $(LOCALBIN) $(LOCALSTAMP) + @rm -f $(LOCALSTAMP)/watchexec + @if ! command -v watchexec >/dev/null 2>&1; then \ + echo "installing watchexec via brew..."; \ + brew install watchexec; \ + fi + @touch $@ + +.PHONY: install-watchexec +install-watchexec: $(WATCHEXEC_STAMP) ## Install watchexec + +# ------------------------------------------------------------------------------ +# install-go (delegates to scripts/install-go) +# ------------------------------------------------------------------------------ + +.PHONY: install-go +install-go: ## Install Go (for Docker/CI builds) + BUILDGOVERSION=$(BUILDGOVERSION) ./scripts/install-go + +# ------------------------------------------------------------------------------ +# install-tools / clean-tools +# ------------------------------------------------------------------------------ + +.PHONY: install-tools +install-tools: $(GOLANGCI_LINT) $(CONTROLLER_GEN) $(MOCKERY) $(YAMLFMT) $(HELM) $(PROTOC) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC) $(KUBEBUILDER) $(DATADOG_CI) ## Install all tools + +.PHONY: clean-tools +clean-tools: ## Remove all locally installed tools + rm -rf $(CURDIR)/.tools From c27cc6cb2d3ebf39b8fbdbc54916976a57300ce2 Mon Sep 17 00:00:00 2001 From: Thibault Normand Date: Wed, 18 Feb 2026 11:07:04 +0100 Subject: [PATCH 2/2] chore(ci): ensure CI workflows are all using makefile targets. --- .github/workflows/ci.yml | 2 +- mk/ci.mk | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5136a38ec..da2eff12b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: DATADOG_API_KEY: ${{ steps.dd-sts.outputs.api_key }} - name: Upload code coverage if: success() - run: datadog-ci coverage upload --format go-coverprofile --flags "type:unit-tests" cover.profile + run: make coverage-upload env: DATADOG_API_KEY: ${{ steps.dd-sts.outputs.api_key }} - name: Upload test report diff --git a/mk/ci.mk b/mk/ci.mk index 38e74ca3a..5140eae19 100644 --- a/mk/ci.mk +++ b/mk/ci.mk @@ -64,6 +64,14 @@ deps: godeps license ## Tidy Go deps and check licenses release: ## Create a release VERSION=$(VERSION) ./tasks/release.sh +# ------------------------------------------------------------------------------ +# Datadog coverage upload +# ------------------------------------------------------------------------------ + +.PHONY: coverage-upload +coverage-upload: $(DATADOG_CI) ## Upload Go coverage report to Datadog + $(DATADOG_CI) coverage upload --format go-coverprofile --flags "type:unit-tests" cover.profile + # ------------------------------------------------------------------------------ # Datadog agent (Lima) # ------------------------------------------------------------------------------