diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 9aa8c670a..4d6dced83 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -52,11 +52,19 @@ jobs: with: asdf_branch: v0.11.0 + - name: Build and install on KinD + run: make dev.run-on-kind + - name: Run e2e tests run: make e2e-test env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Cleanup KinD cluster + if: always() + run: make kind.delete + + lint: runs-on: ubuntu-22.04 steps: diff --git a/.go-tools b/.go-tools index ae6855872..7abfaaa35 100644 --- a/.go-tools +++ b/.go-tools @@ -3,3 +3,4 @@ github.com/segmentio/golines@v0.11.0 gotest.tools/gotestsum@v1.9.0 sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20230131195449-5db173878d6d github.com/google/go-containerregistry/cmd/crane@v0.12.1 +github.com/drone/envsubst/cmd/envsubst@v1.0.3 # FREEZE diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index abe310e89..b05ccb518 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -100,6 +100,7 @@ repos: rev: v1.2.0 hooks: - id: helm-docs + stages: [commit] args: # Make the tool search for charts only under the `example-charts` directory - --chart-search-root=charts diff --git a/.tool-versions b/.tool-versions index 1afcae88d..0a5f39480 100644 --- a/.tool-versions +++ b/.tool-versions @@ -8,6 +8,7 @@ golangci-lint 1.50.1 goreleaser 1.15.0 helm 3.11.0 helm-docs 1.11.0 +kind 0.17.0 kube-controller-tools 0.11.2 kubectl 1.26.1 kustomize 4.5.7 diff --git a/README.md b/README.md index 608bad5ff..0c75cc52c 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,17 @@ # CAPI Runtime Extensions Server See [upstream documentation](https://cluster-api.sigs.k8s.io/tasks/experimental-features/runtime-sdk/index.html). + +## Development + +To deploy a local build, either initial install to update an existing deployment, run: + +```shell +make dev.run-on-kind +``` + +To delete the dev KinD cluster, run: + +```shell +make kind.delete +``` diff --git a/hack/common.sh b/hack/common.sh index 51f614193..da6a2f130 100644 --- a/hack/common.sh +++ b/hack/common.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + GIT_REPO_ROOT="$(git rev-parse --show-toplevel)" export GIT_REPO_ROOT diff --git a/hack/kind/create-cluster.sh b/hack/kind/create-cluster.sh new file mode 100755 index 000000000..97c012cd4 --- /dev/null +++ b/hack/kind/create-cluster.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail +IFS=$'\n\t' + +SCRIPT_NAME="$(basename "$0")" +readonly SCRIPT_NAME + +function print_usage { + cat >&2 <"$cluster_config" + + kind create cluster --name "$cluster_name" --config "$cluster_config" +} + +run_cmd "$@" diff --git a/hack/kind/kind-base-config.yaml b/hack/kind/kind-base-config.yaml new file mode 100644 index 000000000..ba9fd4885 --- /dev/null +++ b/hack/kind/kind-base-config.yaml @@ -0,0 +1,24 @@ +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +containerdConfigPatches: + - |- + [plugins."io.containerd.grpc.v1.cri".registry.configs."registry-1.docker.io".auth] + username = "${DOCKER_USERNAME}" + password = "${DOCKER_PASSWORD}" + - |- + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] + endpoint = ["${DOCKER_MIRROR:-https://registry-1.docker.io}"] +kubeadmConfigPatches: + - | + apiVersion: kubelet.config.k8s.io/v1beta1 + kind: KubeletConfiguration + nodeStatusMaxImages: -1 +nodes: + - role: control-plane + image: "${KINDEST_IMAGE}" + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" diff --git a/make/all.mk b/make/all.mk index 16c3caa32..3fc71e05b 100644 --- a/make/all.mk +++ b/make/all.mk @@ -17,3 +17,6 @@ include $(INCLUDE_DIR)ci.mk include $(INCLUDE_DIR)tag.mk include $(INCLUDE_DIR)upx.mk include $(INCLUDE_DIR)addons.mk +include $(INCLUDE_DIR)kind.mk +include $(INCLUDE_DIR)clusterctl.mk +include $(INCLUDE_DIR)dev.mk diff --git a/make/clusterctl.mk b/make/clusterctl.mk new file mode 100644 index 000000000..1d982313a --- /dev/null +++ b/make/clusterctl.mk @@ -0,0 +1,13 @@ +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +.PHONY: clusterctl.init +clusterctl.init: install-tool.clusterctl + env CLUSTER_TOPOLOGY=true EXP_RUNTIME_SDK=true clusterctl init \ + --kubeconfig=$(KIND_KUBECONFIG) \ + --infrastructure docker \ + --wait-providers + +.PHONY: clusterctl.delete +clusterctl.delete: install-tool.clusterctl + clusterctl delete --kubeconfig=$(KIND_KUBECONFIG) --all diff --git a/make/dev.mk b/make/dev.mk new file mode 100644 index 000000000..140bf79cb --- /dev/null +++ b/make/dev.mk @@ -0,0 +1,15 @@ +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +.PHONY: dev.run-on-kind +dev.run-on-kind: kind.create clusterctl.init install-tool.helm install-tool.gojq +ifndef SKIP_BUILD + $(MAKE) release-snapshot +endif + kind load docker-image --name $(KIND_CLUSTER_NAME) \ + $$(gojq -r '.[] | select(.type=="Docker Image") | select(.goarch=="$(GOARCH)") | .name' dist/artifacts.json) + helm upgrade --install --kubeconfig $(KIND_KUBECONFIG) capi-runtime-extensions ./charts/capi-runtime-extensions \ + --set-string image.tag=$$(gojq -r .version dist/metadata.json) \ + --wait --wait-for-jobs + kubectl --kubeconfig $(KIND_KUBECONFIG) rollout restart deployment capi-runtime-extensions + kubectl --kubeconfig $(KIND_KUBECONFIG) rollout status deployment capi-runtime-extensions diff --git a/make/go.mk b/make/go.mk index 09b7e54eb..793de9028 100644 --- a/make/go.mk +++ b/make/go.mk @@ -78,9 +78,9 @@ E2E_FLAKE_ATTEMPTS ?= 1 .PHONY: e2e-test e2e-test: ## Runs e2e tests +ifneq ($(wildcard test/e2e/*),) e2e-test: install-tool.golang install-tool.ginkgo install-tool.gojq $(info $(M) running e2e tests$(if $(E2E_LABEL), labelled "$(E2E_LABEL)")$(if $(E2E_FOCUS), matching "$(E2E_FOCUS)")) -ifneq ($(wildcard test/e2e/*),) ifneq ($(SKIP_BUILD),true) $(MAKE) GORELEASER_FLAGS=$$'--config=<(env GOOS=$(shell go env GOOS) GOARCH=$(shell go env GOARCH) gojq --yaml-input --yaml-output \'del(.builds[0].goarch) | del(.builds[0].goos) | .builds[0].targets|=(["linux_amd64","linux_arm64",env.GOOS+"_"+env.GOARCH] | unique | map(. | sub("_amd64";"_amd64_v1")))\' .goreleaser.yml) --clean --skip-validate --skip-publish' release endif diff --git a/make/kind.mk b/make/kind.mk new file mode 100644 index 000000000..b519f0a23 --- /dev/null +++ b/make/kind.mk @@ -0,0 +1,44 @@ +# Copyright 2023 D2iQ, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +KIND_DIR := $(REPO_ROOT)/.local/kind + +KIND_CLUSTER_NAME ?= $(GITHUB_REPOSITORY)-dev +KIND_KUBECONFIG ?= $(KIND_DIR)/$(KIND_CLUSTER_NAME)/kubeconfig + +KINDEST_NODE_IMAGE ?= kindest/node +KINDEST_NODE_VERSION_v1.24 ?= v1.24.7@sha256:577c630ce8e509131eab1aea12c022190978dd2f745aac5eb1fe65c0807eb315 +KINDEST_NODE_VERSION_v1.25 ?= v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 +KINDEST_NODE_VERSION_v1.26 ?= v1.26.0@sha256:691e24bd2417609db7e589e1a479b902d2e209892a10ce375fab60a8407c7352 +# Allow easy override of Kubernetes version to use via `make KIND_KUBERNETES_VERSION=v1.23` to use in CI +KIND_KUBERNETES_VERSION ?= v1.26 +ifndef KINDEST_NODE_VERSION_$(KIND_KUBERNETES_VERSION) + $(error Unsupported Kind Kubernetes version: $(KIND_KUBERNETES_VERSION) (use on of: [$(patsubst KINDEST_NODE_VERSION_%,%,$(filter KINDEST_NODE_VERSION_%,$(.VARIABLES)))])) +endif + +KINDEST_IMAGE = $(KINDEST_NODE_IMAGE):$(KINDEST_NODE_VERSION_$(KIND_KUBERNETES_VERSION)) + +.PHONY: kind.recreate +kind.recreate: ## Re-creates new KinD cluster if necessary +kind.recreate: kind.delete kind.create + +.PHONY: kind.create +kind.create: ## Creates new KinD cluster +kind.create: install-tool.kubectl install-tool.kind install-tool.go.envsubst ; $(info $(M) creating kind cluster - $(KIND_CLUSTER_NAME)) + (kind get clusters | grep -Eq '^$(KIND_CLUSTER_NAME)$$' && echo '$(KIND_CLUSTER_NAME) already exists') || \ + env KUBECONFIG=$(KIND_KUBECONFIG) $(REPO_ROOT)/hack/kind/create-cluster.sh \ + --cluster-name $(KIND_CLUSTER_NAME) \ + --kindest-image $(KINDEST_IMAGE) \ + --output-dir $(KIND_DIR)/$(KIND_CLUSTER_NAME) \ + --base-config $(REPO_ROOT)/hack/kind/kind-base-config.yaml + +.PHONY: kind.delete +kind.delete: ## Deletes KinD cluster +kind.delete: install-tool.kind ; $(info $(M) deleting kind cluster - $(KIND_CLUSTER_NAME)) + (kind get clusters | grep -Eq '^$(KIND_CLUSTER_NAME)$$' && kind delete cluster --name $(KIND_CLUSTER_NAME)) || \ + echo '$(KIND_CLUSTER_NAME) does not exist' + rm -rf $(KIND_DIR)/$(KIND_CLUSTER_NAME) + +.PHONY: kind.kubeconfig +kind.kubeconfig: ## Prints export definition for kubeconfig + echo "export KUBECONFIG=$(KIND_KUBECONFIG)" diff --git a/make/repo.mk b/make/repo.mk index bc6ef3337..c5004bd3f 100644 --- a/make/repo.mk +++ b/make/repo.mk @@ -9,8 +9,8 @@ GIT_COMMIT := $(shell git rev-parse "HEAD^{commit}") export GIT_TAG ?= $(shell git describe --tags "$(GIT_COMMIT)^{commit}" --match v* --abbrev=0 2>/dev/null) export GIT_CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) -export GITHUB_ORG ?= $(notdir $(realpath $(dir $(REPO_ROOT)))) -export GITHUB_REPOSITORY ?= $(notdir $(REPO_ROOT)) +export GITHUB_ORG := $(notdir $(realpath $(dir $(REPO_ROOT)))) +export GITHUB_REPOSITORY := $(notdir $(REPO_ROOT)) ifneq ($(shell git status --porcelain 2>/dev/null; echo $$?), 0) export GIT_TREE_STATE := dirty diff --git a/make/tools.mk b/make/tools.mk index 6381a95ee..eeb0dd719 100644 --- a/make/tools.mk +++ b/make/tools.mk @@ -13,7 +13,7 @@ export PATH := $(GOBIN):$(PATH) ifneq ($(wildcard $(GO_TOOLS_FILE)),) define install_go_tool mkdir -p $(GOBIN) - CGO_ENABLED=0 go install -v $$(grep $1 $(GO_TOOLS_FILE)) + CGO_ENABLED=0 go install -v $$(grep -Eo '^.+$1[^ ]+' $(GO_TOOLS_FILE)) endef .PHONY: