diff --git a/.github/workflows/bake_targets.yml b/.github/workflows/bake_targets.yml index bf0c7a0..9bba905 100644 --- a/.github/workflows/bake_targets.yml +++ b/.github/workflows/bake_targets.yml @@ -130,24 +130,20 @@ jobs: with: persist-credentials: false - - name: Create kind cluster - uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0 - with: - version: ${{ env.KIND_VERSION }} - kubectl_version: ${{ env.KIND_NODE_VERSION }} - node_image: kindest/node:${{ env.KIND_NODE_VERSION }} - config: kind-config.yaml + - name: Install Task + uses: go-task/setup-task@0ab1b2a65bc55236a3bc64cde78f80e20e8885c2 # v1.0.0 - - name: Install CNPG (${{ matrix.cnpg }}) + - name: Install Dagger env: - CNPG_RELEASE: ${{ matrix.cnpg }} + # renovate: datasource=github-tags depName=dagger/dagger versioning=semver + DAGGER_VERSION: 0.19.8 run: | - operator_manifest="https://raw.githubusercontent.com/cloudnative-pg/artifacts/release-$CNPG_RELEASE/manifests/operator-manifest.yaml" - if [[ "$CNPG_RELEASE" == "main" ]]; then - operator_manifest="https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml" - fi - curl -sSfL "$operator_manifest" | kubectl apply --server-side -f - - kubectl wait --for=condition=Available --timeout=2m -n cnpg-system deployments cnpg-controller-manager + curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh + + - name: Set up environment + run: | + task e2e:setup-env + task e2e:export-kubeconfig - name: Generate Chainsaw testing values uses: dagger/dagger-for-github@d913e70051faf3b907d4dd96ef1161083c88c644 # v8.2.0 diff --git a/BUILD.md b/BUILD.md index 0a1ae67..7301b62 100644 --- a/BUILD.md +++ b/BUILD.md @@ -83,3 +83,33 @@ task DRY_RUN=true # or task bake TARGET=pgvector DRY_RUN=true ``` + +## Testing locally + +Local testing can be performed by using a local Docker container registry and a Kind cluster with CNPG installed. +The Taskfile includes utilities to set up and tear down such an environment. + +### Create a local test environment + +The `e2e:setup-env` task takes care of setting up a Kind cluster with a local Docker container registry connected to the same +Docker network and installs CloudNativePG by default. + +```bash +task e2e:setup-env +``` + +The container registry will be exposed locally at `localhost:5000`. + +The Kubeconfig to connect to the Kind cluster can be retrieved with: + +```bash +task e2e:export-kubeconfig KUBECONFIG_PATH= +``` + +### Tear down the local test environment + +To clean up all the resources created by the `e2e:setup-env` task, run: + +```bash +task e2e:cleanup +``` diff --git a/Taskfile.yml b/Taskfile.yml index c82155f..9ca8247 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -8,6 +8,16 @@ vars: RED: \033[0;31m NC: \033[0m + E2E_NETWORK: pg-extensions-e2e + DAGGER_ENGINE_NAME: dagger-engine-pg-extensions + REGISTRY_NAME: registry.pg-extensions + REGISTRY_HOST_PORT: 5000 + # TODO: renovate + K8S_VERSION: 1.34.2 + # TODO: renovate ? + CNPG_RELEASE: 1.28 + KIND_CLUSTER_NAME: pg-extensions-{{ .K8S_VERSION }} + tasks: default: desc: Build all targets (default) @@ -15,7 +25,7 @@ tasks: - task: bake:all prereqs: - description: Ensure prerequisites are met + desc: Ensure prerequisites are met run: once silent: true cmds: @@ -28,7 +38,7 @@ tasks: - echo -e "{{.GREEN}}All prerequisites satisfied!{{.NC}}" checks: - description: Run checks for the specified target + desc: Run checks for the specified target deps: - prereqs prefix: 'checks-{{.TARGET}}' @@ -44,7 +54,7 @@ tasks: - name: TARGET checks:all: - description: Run checks for all the available targets + desc: Run checks for all the available targets vars: TARGETS: sh: dagger call -sm ./dagger/maintenance/ get-targets | tr -d '[]"' | tr ',' '\n' @@ -56,7 +66,7 @@ tasks: task: checks bake: - description: Bake the specified target + desc: Bake the specified target deps: - prereqs prefix: 'bake-{{.TARGET}}' @@ -81,7 +91,7 @@ tasks: - name: TARGET bake:all: - description: Bake all the available targets + desc: Bake all the available targets vars: TARGETS: sh: dagger call -sm ./dagger/maintenance/ get-targets | tr -d '[]"' | tr ',' '\n' @@ -93,7 +103,7 @@ tasks: task: bake update-os-libs: - description: Update OS libs on the specified target + desc: Update OS libs on the specified target deps: - prereqs prefix: 'update-os-libs-{{.TARGET}}' @@ -106,7 +116,7 @@ tasks: - name: TARGET update-os-libs:all: - description: Update OS libs for all the available targets + desc: Update OS libs for all the available targets vars: TARGETS: sh: dagger call -sm ./dagger/maintenance/ get-oslibs-targets | tr -d '[]"' | tr ',' '\n' @@ -116,3 +126,164 @@ tasks: vars: TARGET: "{{.ITEM}}" task: update-os-libs + + e2e:create-docker-network: + desc: Create Docker network to connect all the services, such as the Registry, Kind nodes, Chainsaw, etc. + run: once + internal: true + cmds: + - docker network create {{ .E2E_NETWORK }} + status: + - docker network inspect {{ .E2E_NETWORK }} + + e2e:start-container-registry: + desc: Start a local Docker registry to push the built images for E2E tests + deps: + - e2e:create-docker-network + internal: true + run: once + vars: + REGISTRY_VERSION: 2 + cmds: + - > + docker run -d --name {{ .REGISTRY_NAME }} --rm -p {{ .REGISTRY_HOST_PORT }}:5000 + --network {{ .E2E_NETWORK }} registry:{{ .REGISTRY_VERSION }} + status: + - test "$(docker inspect -f {{`'{{json .State.Running}}'`}} {{ .REGISTRY_NAME }})" == "true" + + e2e:start-dagger-engine: + desc: Start a custom Dagger engine so we can connect it to the E2E Docker network + deps: + - e2e:create-docker-network + internal: true + run: once + vars: + # TODO: renovate + DAGGER_ENGINE_VERSION: v0.19.8 + cmds: + - > + docker run -d -v /var/lib/dagger --name {{ .DAGGER_ENGINE_NAME }} --rm --network {{ .E2E_NETWORK }} + --privileged registry.dagger.io/engine:{{ .DAGGER_ENGINE_VERSION }} + status: + - test "$(docker inspect -f {{`'{{json .State.Running}}'`}} {{ .DAGGER_ENGINE_NAME }})" == "true" + + e2e:setup-kind: + desc: Setup Kind cluster for E2E tests + deps: + - e2e:start-container-registry + - e2e:start-dagger-engine + internal: true + run: once + vars: + #TODO: renovate + DAGGER_KIND_SHA: dadbc09a1e0790ccbf1d88f796308b26a12f0488 + REGISTRY_DIR: /etc/containerd/certs.d/localhost:{{ .REGISTRY_HOST_PORT }} + DOCKER_SOCKET: + sh: docker context inspect -f {{`'{{json .Endpoints.docker.Host}}'`}} $(docker context show) + env: + _EXPERIMENTAL_DAGGER_RUNNER_HOST: container://{{ .DAGGER_ENGINE_NAME }} + cmds: + - > + dagger call -m github.com/aweris/daggerverse/kind@{{ .DAGGER_KIND_SHA }} --socket {{ .DOCKER_SOCKET }} + container with-env-variable --name=KIND_EXPERIMENTAL_DOCKER_NETWORK --value={{ .E2E_NETWORK }} with-env-variable --name=CACHE_BUSTER --value="$(date)" + with-file --source=kind-config.yaml --path=/root/kind-config.yaml + with-exec --args="kind","create","cluster","--name","{{ .KIND_CLUSTER_NAME }}","--image","kindest/node:v{{ .K8S_VERSION }}","--config","/root/kind-config.yaml" sync + - docker exec "{{ .KIND_CLUSTER_NAME }}-control-plane" mkdir -p "{{ .REGISTRY_DIR }}" + - | + cat < + test "$(dagger call -m github.com/aweris/daggerverse/kind@{{ .DAGGER_KIND_SHA }} + --socket {{ .DOCKER_SOCKET }} cluster --name {{ .KIND_CLUSTER_NAME }} exist)" == "true" + + e2e:install-cnpg: + desc: Install CloudNativePG operator in the Kind cluster + deps: + - e2e:start-dagger-engine + - e2e:setup-kind + internal: true + vars: + # TODO: renovate + DAGGER_KIND_SHA: dadbc09a1e0790ccbf1d88f796308b26a12f0488 + DOCKER_SOCKET: + sh: docker context inspect -f {{`'{{json .Endpoints.docker.Host}}'`}} $(docker context show) + CNPG_MANIFEST: + sh: | + if [ "{{ .CNPG_RELEASE }}" = "main" ]; then + echo "https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml" + else + echo "https://raw.githubusercontent.com/cloudnative-pg/artifacts/release-{{ .CNPG_RELEASE }}/manifests/operator-manifest.yaml" + fi + env: + _EXPERIMENTAL_DAGGER_RUNNER_HOST: container://{{ .DAGGER_ENGINE_NAME }} + cmds: + - | + kubeconfig=$(dagger call -m github.com/aweris/daggerverse/kind@{{ .DAGGER_KIND_SHA }} \ + --socket {{ .DOCKER_SOCKET }} container \ + with-exec --args "kind","get","kubeconfig","--internal","--name","{{ .KIND_CLUSTER_NAME }}" stdout) + + dagger core container from --address=alpine/kubectl:{{ .K8S_VERSION }} \ + with-new-file --contents "${kubeconfig}" --path /root/.kube/config --expand \ + with-env-variable --name=CACHEBUSTER --value="$(date)" \ + with-exec --args="apply","--server-side","-f","{{ .CNPG_MANIFEST }}" --use-entrypoint sync + + dagger core container from --address=alpine/kubectl:{{ .K8S_VERSION }} \ + with-new-file --contents "${kubeconfig}" --path /root/.kube/config --expand \ + with-env-variable --name=CACHEBUSTER --value="$(date)" \ + with-exec \ + --args="wait","--for=condition=Available","--timeout=2m","-n","cnpg-system","deployments","cnpg-controller-manager" \ + --use-entrypoint sync + + e2e:export-kubeconfig: + desc: Export Kind cluster kubeconfig at path defined by KUBECONFIG_PATH var (default ~/.kube/config) + deps: + - e2e:start-dagger-engine + - e2e:setup-kind + vars: + # TODO: renovate + DAGGER_KIND_SHA: dadbc09a1e0790ccbf1d88f796308b26a12f0488 + KUBECONFIG_PATH: '{{.KUBECONFIG_PATH| default "~/.kube/config"}}' + DOCKER_SOCKET: + sh: docker context inspect -f {{`'{{json .Endpoints.docker.Host}}'`}} $(docker context show) + env: + _EXPERIMENTAL_DAGGER_RUNNER_HOST: container://{{ .DAGGER_ENGINE_NAME }} + cmds: + - | + CONFIG=$(dagger call -m github.com/aweris/daggerverse/kind@{{ .DAGGER_KIND_SHA }} \ + --socket {{ .DOCKER_SOCKET }} container \ + with-exec --args "kind","get","kubeconfig","--name","{{ .KIND_CLUSTER_NAME }}" stdout) + mkdir -p $(dirname {{ .KUBECONFIG_PATH }}) + echo "${CONFIG}" > {{ .KUBECONFIG_PATH }} + + e2e:setup-env: + desc: Setup E2E environment + silent: true + deps: + - e2e:create-docker-network + - e2e:start-container-registry + - e2e:start-dagger-engine + - e2e:setup-kind + - e2e:install-cnpg + cmds: + - echo -e "{{.GREEN}}--- E2E environment setup complete ---{{.NC}}" + + e2e:cleanup: + desc: Cleanup E2E resources + deps: + - e2e:start-dagger-engine + vars: + # TODO: renovate + DAGGER_KIND_SHA: dadbc09a1e0790ccbf1d88f796308b26a12f0488 + DOCKER_SOCKET: + sh: docker context inspect -f {{`'{{json .Endpoints.docker.Host}}'`}} $(docker context show) + env: + _EXPERIMENTAL_DAGGER_RUNNER_HOST: container://{{ .DAGGER_ENGINE_NAME }} + cmds: + - > + dagger call -m github.com/aweris/daggerverse/kind@{{ .DAGGER_KIND_SHA }} + --socket {{ .DOCKER_SOCKET }} cluster --name {{ .KIND_CLUSTER_NAME }} delete || true + - docker rm -fv {{ .DAGGER_ENGINE_NAME }} || true + - docker rm -fv {{ .REGISTRY_NAME }} || true + - docker network rm {{ .E2E_NETWORK }} || true diff --git a/kind-config.yaml b/kind-config.yaml index 8b16432..04e6447 100644 --- a/kind-config.yaml +++ b/kind-config.yaml @@ -2,3 +2,7 @@ kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 featureGates: ImageVolume: true +containerdConfigPatches: + - |- + [plugins."io.containerd.grpc.v1.cri".registry] + config_path = "/etc/containerd/certs.d"