#!/usr/bin/env bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Allocate a Kind cluster with Knative, Kourier and a local container registry. # set -o errexit set -o nounset set -o pipefail source "$(dirname "$(realpath "$0")")/common.sh" set_versions() { # Note: Kubernetes Version node image per Kind releases (full hash is suggested): # https://github.com/kubernetes-sigs/kind/releases kind_node_version=v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245 knative_serving_version="v$(get_latest_release_version "knative" "serving")" knative_eventing_version="v$(get_latest_release_version "knative" "eventing")" contour_version="v$(get_latest_release_version "knative-extensions" "net-contour")" } main() { echo "${blue}Allocating${reset}" set_versions kubernetes loadbalancer echo "${blue}Beginning Cluster Configuration${reset}" echo "Tasks will be executed in parallel. Logs will be prefixed:" echo "svr: Serving, DNS and Networking" echo "evt: Eventing and Namespace" echo "reg: Local Registry" echo "dpr: Dapr Runtime" echo "" ( set -o pipefail; (serving && dns && networking) 2>&1 | sed -e 's/^/svr /')& ( set -o pipefail; (eventing && namespace) 2>&1 | sed -e 's/^/evt /')& ( set -o pipefail; registry 2>&1 | sed -e 's/^/reg /') & ( set -o pipefail; dapr_runtime 2>&1 | sed -e 's/^/dpr /')& local job for job in $(jobs -p); do wait "$job" done next_steps echo -e "\n${green}🎉 DONE${reset}\n" } # Retrieve latest version from given Knative repository tags # On 'main' branch the latest released version is returned # On 'release-x.y' branch the latest patch version for 'x.y.*' is returned # Similar to hack/library.sh get_latest_knative_yaml_source() function get_latest_release_version() { local org_name="$1" local repo_name="$2" local major_minor="" if is_release_branch; then local branch_name branch_name="$(current_branch)" major_minor="${branch_name##release-}" fi local version version="$(git ls-remote --tags --ref https://github.com/"${org_name}"/"${repo_name}".git \ | grep "${major_minor}" \ | cut -d '-' -f2 \ | cut -d 'v' -f2 \ | sort -Vr \ | head -n 1)" echo "${version}" } # Returns whether the current branch is a release branch. function is_release_branch() { [[ $(current_branch) =~ ^release-[0-9\.]+$ ]] } # Returns the current branch. # Taken from knative/hack. The function covers Knative CI use cases and local variant. function current_branch() { local branch_name="" # Get the branch name from Prow's env var, see https://github.com/kubernetes/test-infra/blob/master/prow/jobs.md. # Otherwise, try getting the current branch from git. (( ${IS_PROW:-} )) && branch_name="${PULL_BASE_REF:-}" [[ -z "${branch_name}" ]] && branch_name="${GITHUB_BASE_REF:-}" [[ -z "${branch_name}" ]] && branch_name="$(git rev-parse --abbrev-ref HEAD)" echo "${branch_name}" } kubernetes() { cat <=n )); then echo "Unable to set knative domain" exit 1 fi echo 'Retrying...' sleep 5 done echo "${green}✅ DNS${reset}" } loadbalancer() { echo "${blue}Installing Load Balancer (Metallb)${reset}" $KUBECTL apply -f "https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml" sleep 5 $KUBECTL wait --namespace metallb-system \ --for=condition=ready pod \ --selector=app=metallb \ --timeout=300s local kind_addr kind_addr="$($CONTAINER_ENGINE container inspect func-control-plane | jq '.[0].NetworkSettings.Networks.kind.IPAddress' -r)" echo "Setting up address pool." $KUBECTL apply -f - <Channel $KUBECTL apply -f - << EOF apiVersion: v1 kind: ConfigMap metadata: name: config-br-defaults namespace: knative-eventing data: default-br-config: | # This is the cluster-wide default broker channel. clusterDefault: brokerClass: MTChannelBasedBroker apiVersion: v1 kind: ConfigMap name: imc-channel namespace: knative-eventing EOF echo "${green}✅ Namespace${reset}" } dapr_runtime() { echo "${blue}Installing Dapr Runtime${reset}" echo "Version:\\n$($DAPR version)" local dapr_flags="" if [ "${GITHUB_ACTIONS:-false}" = "true" ]; then dapr_flags="--image-registry=ghcr.io/dapr --log-as-json" fi # Install Dapr Runtime # shellcheck disable=SC2086 $DAPR init ${dapr_flags} --kubernetes --wait # Enalble Redis Persistence and Pub/Sub # # 1) Redis # Creates a Redis leader with three replicas # TODO: helm and the bitnami charts are likely not necessary. The Bitnami # charts do tweak quite a few settings, but I am skeptical it is necessary # in a CI/CD environment, as it does add nontrivial support overhead. # TODO: If the bitnami redis chart seems worth the effort, munge this command # to only start a single instance rather than four. # helm repo add bitnami https://charts.bitnami.com/bitnami echo "${blue}- Redis ${reset}" $HELM repo add bitnami https://charts.bitnami.com/bitnami $HELM install redis bitnami/redis --set image.tag=6.2 $HELM repo update # 2) Expose a Redis-backed Dapr State Storage component echo "${blue}- State Storage Component${reset}" $KUBECTL apply -f - << EOF apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: statestore namespace: default spec: type: state.redis version: v1 metadata: - name: redisHost value: redis-master.default.svc.cluster.local:6379 - name: redisPassword secretKeyRef: name: redis key: redis-password EOF # 3) Expose A Redis-backed Dapr Pub/Sub Component echo "${blue}- Pub/Sub Component${reset}" $KUBECTL apply -f - << EOF apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: pubsub namespace: default spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: redis-master.default.svc.cluster.local:6379 - name: redisPassword secretKeyRef: name: redis key: redis-password EOF echo "${green}✅ Dapr Runtime${reset}" } next_steps() { echo -e "" echo -e "${blue}Next Steps${reset}" echo -e "${blue}----------${reset}" echo -e "" echo -e "${grey}REGISTRY" echo -e "Before using the cluster for integration and E2E tests, please run \"${reset}registry.sh${grey}\" (Linux systems) which will configure podman or docker to communicate with the standalone container registry without TLS." echo -e "" echo -e "For other operating systems, or to do this manually, edit the docker daemon config (/etc/docker/daemon.json on linux and ~/.docker/daemon.json on OSX), add:" echo -e "${reset}{ \"insecure-registries\": [ \"localhost:50000\" ] }" echo -e "" echo -e "${grey}For podman, edit /etc/container/registries.conf to include:" echo -e "${reset}[[registry-insecure-local]]\nlocation = \"localhost:50000\"\ninsecure = true\n" echo -e "${grey}The cluster and resources can be removed with \"${reset}delete.sh\"" echo -e "" echo -e "${grey}KUBECONFIG" echo -e "The kubeconfig for your test cluster has been saved to:${reset}" echo -e "${KUBECONFIG}" echo -e "" } main "$@"