Loading deploy/all.sh +42 −2 Viewed Changes for deploy/all.sh: 42 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -69,6 +69,9 @@ export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device pathcomp service slice n # Uncomment to activate E2E Orchestrator #export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" # Uncomment to activate Pluggables Component #export TFS_COMPONENTS="${TFS_COMPONENTS} pluggables" # If not already set, set the tag you want to use for your images. export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"} Loading Loading @@ -151,6 +154,26 @@ export NATS_DEPLOY_MODE=${NATS_DEPLOY_MODE:-"single"} export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # ----- Apache Kafka ----------------------------------------------------------- # If not already set, set the namespace where Kafka will be deployed. export KFK_NAMESPACE=${KFK_NAMESPACE:-"kafka"} # If not already set, set the external port Kafka Client interface will be exposed to. export KFK_EXT_PORT_CLIENT=${KFK_EXT_PORT_CLIENT:-"9092"} # If not already set, set Kafka installation mode. Accepted values are: 'single'. # - If KFK_DEPLOY_MODE is "single", Kafka is deployed in single node mode. It is convenient for # development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # NOTE: Production mode is still not supported. Will be provided in the future. export KFK_DEPLOY_MODE=${KFK_DEPLOY_MODE:-"single"} # If not already set, disable flag for re-deploying Kafka from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If KFK_REDEPLOY is "YES", the message broker will be dropped while checking/deploying Kafka. export KFK_REDEPLOY=${KFK_REDEPLOY:-""} # ----- QuestDB ---------------------------------------------------------------- # If not already set, set the namespace where QuestDB will be deployed. Loading Loading @@ -190,6 +213,23 @@ export QDB_DROP_TABLES_IF_EXIST=${QDB_DROP_TABLES_IF_EXIST:-""} export QDB_REDEPLOY=${QDB_REDEPLOY:-""} # ----- Time Series Storage - Prometheus / Grafana Mimir ----------------------- # If not already set, set Time Series Storage installation mode. Accepted values are: # 'single' and 'cluster'. # - If TSDB_DEPLOY_MODE is "single", Time Series Storage is deployed in single node # mode and features a basic Prometheus instance. It is convenient for development and # testing purposes and should fit in a VM. # IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # - If TSDB_DEPLOY_MODE is "cluster", Time Series Storage is deployed in cluster mode # and a Grafana Mimir database in cluster mode will be deployed. It is convenient for # production and provides scalability features. If you are deploying for production, # also read the following link providing details on deploying Grafana Mimir for # production environments: # Ref: https://grafana.com/docs/mimir/latest/manage/run-production-environment/ export TSDB_DEPLOY_MODE=${TSDB_DEPLOY_MODE:-"single"} # ----- K8s Observability ------------------------------------------------------ # If not already set, set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. Loading @@ -215,8 +255,8 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} # Deploy Apache Kafka ./deploy/kafka.sh #Deploy Monitoring (Prometheus, Mimir, Grafana) ./deploy/monitoring.sh #Deploy Monitoring (Prometheus Gateway, Prometheus) # ./deploy/monitoring.sh # Expose Dashboard ./deploy/expose_dashboard.sh Loading deploy/build-only.sh 0 → 100755 +143 −0 Viewed Changes for deploy/build-only.sh: 143 added lines, 0 removed lines. Original line number Diff line number Diff line #!/bin/bash # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # # 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 # # http://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. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # ----- TeraFlowSDN ------------------------------------------------------------ # If not already set, set the URL of the Docker registry where the images will be uploaded to. # By default, assume internal MicroK8s registry is used. export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} # If not already set, set the list of components, separated by spaces, you want to build images for, and deploy. # By default, only basic components are deployed export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device pathcomp service slice nbi webui load_generator"} # If not already set, set the tag you want to use for your images. export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"} ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Create a tmp folder for files modified during the deployment TMP_LOGS_FOLDER="./tmp/build" mkdir -p $TMP_LOGS_FOLDER DOCKER_BUILD="docker build" DOCKER_MAJOR_VERSION=$(docker --version | grep -o -E "Docker version [0-9]+\." | grep -o -E "[0-9]+" | cut -c 1-3) if [[ $DOCKER_MAJOR_VERSION -ge 23 ]]; then # If Docker version >= 23, build command was migrated to docker-buildx # In Ubuntu, in practice, means to install package docker-buildx together with docker.io # Check if docker-buildx plugin is installed docker buildx version 1>/dev/null 2>/dev/null if [[ $? -ne 0 ]]; then echo "Docker buildx command is not installed. Check: https://docs.docker.com/build/architecture/#install-buildx" echo "If you installed docker through APT package docker.io, consider installing also package docker-buildx" exit 1; fi DOCKER_BUILD="docker buildx build" fi for COMPONENT in $TFS_COMPONENTS; do echo "Processing '$COMPONENT' component..." echo " Building Docker image..." BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log" if [ "$COMPONENT" == "ztp" ] || [ "$COMPONENT" == "policy" ]; then $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG" elif [ "$COMPONENT" == "pathcomp" ] || [ "$COMPONENT" == "telemetry" ] || [ "$COMPONENT" == "analytics" ]; then BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log" $DOCKER_BUILD -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . > "$BUILD_LOG" BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log" $DOCKER_BUILD -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . > "$BUILD_LOG" if [ "$COMPONENT" == "pathcomp" ]; then # next command is redundant, but helpful to keep cache updated between rebuilds IMAGE_NAME="$COMPONENT-backend:$TFS_IMAGE_TAG-builder" $DOCKER_BUILD -t "$IMAGE_NAME" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG" fi elif [ "$COMPONENT" == "dlt" ]; then BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-connector.log" $DOCKER_BUILD -t "$COMPONENT-connector:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/connector/Dockerfile . > "$BUILD_LOG" BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-gateway.log" $DOCKER_BUILD -t "$COMPONENT-gateway:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/gateway/Dockerfile . > "$BUILD_LOG" else $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG" fi echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..." if [ "$COMPONENT" == "pathcomp" ] || [ "$COMPONENT" == "telemetry" ] || [ "$COMPONENT" == "analytics" ] ; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log" docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log" docker push "$IMAGE_URL" > "$PUSH_LOG" IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log" docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log" docker push "$IMAGE_URL" > "$PUSH_LOG" elif [ "$COMPONENT" == "dlt" ]; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-connector.log" docker tag "$COMPONENT-connector:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-connector.log" docker push "$IMAGE_URL" > "$PUSH_LOG" IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-gateway.log" docker tag "$COMPONENT-gateway:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-gateway.log" docker push "$IMAGE_URL" > "$PUSH_LOG" else IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log" docker tag "$COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log" docker push "$IMAGE_URL" > "$PUSH_LOG" fi printf "\n" done echo "Pruning Docker Images..." docker image prune --force printf "\n\n" if [ "$DOCKER_BUILD" == "docker buildx build" ]; then echo "Pruning Docker Buildx Cache..." docker buildx prune --force printf "\n\n" fi deploy/crdb.sh +8 −1 Viewed Changes for deploy/crdb.sh: 8 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ CRDB_MANIFESTS_PATH="manifests/cockroachdb" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${CRDB_NAMESPACE}/manifests" mkdir -p $TMP_MANIFESTS_FOLDER mkdir -p ${TMP_MANIFESTS_FOLDER} function crdb_deploy_single() { echo "CockroachDB Namespace" Loading Loading @@ -105,6 +105,13 @@ function crdb_deploy_single() { sleep 1 done kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 # Wait for CockroachDB to notify "start_node_query" echo ">>> CockroachDB pods created. Waiting CockroachDB server to be started..." while ! kubectl --namespace ${CRDB_NAMESPACE} logs pod/cockroachdb-0 -c cockroachdb 2>&1 | grep -q 'start_node_query'; do printf "%c" "." sleep 1 done fi echo Loading deploy/kafka.sh +78 −44 Viewed Changes for deploy/kafka.sh: 78 added lines, 44 removed lines. Original line number Diff line number Diff line Loading @@ -13,17 +13,26 @@ # See the License for the specific language governing permissions and # limitations under the License. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # If not already set, set the namespace where Apache Kafka will be deployed. # If not already set, set the namespace where Kafka will be deployed. export KFK_NAMESPACE=${KFK_NAMESPACE:-"kafka"} # If not already set, set the port Apache Kafka server will be exposed to. export KFK_SERVER_PORT=${KFK_SERVER_PORT:-"9092"} # If not already set, set the external port Kafka client interface will be exposed to. export KFK_EXT_PORT_CLIENT=${KFK_EXT_PORT_CLIENT:-"9092"} # If not already set, set Kafka installation mode. Accepted values are: 'single'. # - If KFK_DEPLOY_MODE is "single", Kafka is deployed in single node mode. It is convenient for # development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # NOTE: Production mode is still not supported. Will be provided in the future. export KFK_DEPLOY_MODE=${KFK_DEPLOY_MODE:-"single"} # If not already set, if flag is YES, Apache Kafka will be redeployed and all topics will be lost. # If not already set, disable flag for re-deploying Kafka from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If KFK_REDEPLOY is "YES", the message broker will be dropped while checking/deploying Kafka. export KFK_REDEPLOY=${KFK_REDEPLOY:-""} Loading @@ -34,58 +43,83 @@ export KFK_REDEPLOY=${KFK_REDEPLOY:-""} # Constants TMP_FOLDER="./tmp" KFK_MANIFESTS_PATH="manifests/kafka" KFK_ZOOKEEPER_MANIFEST="01-zookeeper.yaml" KFK_MANIFEST="02-kafka.yaml" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${KFK_NAMESPACE}/manifests" mkdir -p ${TMP_MANIFESTS_FOLDER} function kafka_deploy() { # copy zookeeper and kafka manifest files to temporary manifest location cp "${KFK_MANIFESTS_PATH}/${KFK_ZOOKEEPER_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}" cp "${KFK_MANIFESTS_PATH}/${KFK_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_MANIFEST}" # echo "Apache Kafka Namespace" echo "Delete Apache Kafka Namespace" kubectl delete namespace ${KFK_NAMESPACE} --ignore-not-found echo "Create Apache Kafka Namespace" function kfk_deploy_single() { echo "Kafka Namespace" echo ">>> Create Kafka Namespace (if missing)" kubectl create namespace ${KFK_NAMESPACE} echo # echo ">>> Deplying Apache Kafka Zookeeper" # Kafka zookeeper service should be deployed before the kafka service kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}" #KFK_ZOOKEEPER_SERVICE="zookeeper-service" # this command may be replaced with command to extract service name automatically #KFK_ZOOKEEPER_IP=$(kubectl --namespace ${KFK_NAMESPACE} get service ${KFK_ZOOKEEPER_SERVICE} -o 'jsonpath={.spec.clusterIP}') echo "Kafka (single-mode)" echo ">>> Checking if Kafka is deployed..." if kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; then echo ">>> Kafka is present; skipping step." else echo ">>> Deploy Kafka" cp "${KFK_MANIFESTS_PATH}/single-node.yaml" "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" #sed -i "s/<KFK_NAMESPACE>/${KFK_NAMESPACE}/" "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" echo ">>> Waiting Kafka statefulset to be created..." while ! kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; do printf "%c" "." sleep 1 done # Wait for statefulset condition "Available=True" does not work # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: # "error: readyReplicas is not found" # Workaround: Check the pods are ready #echo ">>> Kafka statefulset created. Waiting for readiness condition..." #kubectl wait --namespace ${KFK_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/kafka #kubectl wait --namespace ${KGK_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/kafka echo ">>> Kafka statefulset created. Waiting Kafka pods to be created..." while ! kubectl get --namespace ${KFK_NAMESPACE} pod/kafka-0 &> /dev/null; do printf "%c" "." sleep 1 done kubectl wait --namespace ${KFK_NAMESPACE} --for=condition=Ready --timeout=300s pod/kafka-0 # Wait for Kafka to notify "Kafka Server started" echo ">>> Kafka pods created. Waiting Kafka Server to be started..." while ! kubectl --namespace ${KFK_NAMESPACE} logs pod/kafka-0 -c kafka 2>&1 | grep -q 'Kafka Server started'; do printf "%c" "." sleep 1 done fi echo } # Kafka service should be deployed after the zookeeper service #sed -i "s/<ZOOKEEPER_INTERNAL_IP>/${KFK_ZOOKEEPER_IP}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" sed -i "s/<KAFKA_NAMESPACE>/${KFK_NAMESPACE}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" # echo ">>> Deploying Apache Kafka Broker" kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" function kfk_undeploy_single() { echo "Kafka (single-mode)" echo ">>> Checking if Kafka is deployed..." if kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; then echo ">>> Undeploy Kafka" kubectl delete --namespace ${KFK_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" --ignore-not-found else echo ">>> Kafka is not present; skipping step." fi echo # echo ">>> Verifing Apache Kafka deployment" sleep 5 # KFK_PODS_STATUS=$(kubectl --namespace ${KFK_NAMESPACE} get pods) # if echo "$KFK_PODS_STATUS" | grep -qEv 'STATUS|Running'; then # echo "Deployment Error: \n $KFK_PODS_STATUS" # else # echo "$KFK_PODS_STATUS" # fi echo "Kafka Namespace" echo ">>> Delete Kafka Namespace (if exists)" echo "NOTE: this step might take few minutes to complete!" kubectl delete namespace ${KFK_NAMESPACE} --ignore-not-found echo } echo ">>> Apache Kafka" echo "Checking if Apache Kafka is deployed ... " if [ "$KFK_DEPLOY_MODE" == "single" ]; then if [ "$KFK_REDEPLOY" == "YES" ]; then echo "Redeploying kafka namespace" kafka_deploy elif kubectl get namespace "${KFK_NAMESPACE}" &> /dev/null; then echo "Apache Kafka already present; skipping step." kfk_undeploy_single fi kfk_deploy_single else echo "Kafka namespace doesn't exists. Deploying kafka namespace" kafka_deploy echo "Unsupported value: KFK_DEPLOY_MODE=$KFK_DEPLOY_MODE" fi echo deploy/monitoring.sh +35 −14 Viewed Changes for deploy/monitoring.sh: 35 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -15,6 +15,24 @@ set -euo pipefail # ----- Time Series Storage - Prometheus / Grafana Mimir ----------------------- # If not already set, set Time Series Storage installation mode. Accepted values are: # 'single' and 'cluster'. # - If TSDB_DEPLOY_MODE is "single", Time Series Storage is deployed in single node # mode and features a basic Prometheus instance. It is convenient for development and # testing purposes and should fit in a VM. # IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # - If TSDB_DEPLOY_MODE is "cluster", Time Series Storage is deployed in cluster mode # and a Grafana Mimir database in cluster mode will be deployed. It is convenient for # production and provides scalability features. If you are deploying for production, # also read the following link providing details on deploying Grafana Mimir for # production environments: # Ref: https://grafana.com/docs/mimir/latest/manage/run-production-environment/ export TSDB_DEPLOY_MODE=${TSDB_DEPLOY_MODE:-"single"} # ----------------------------------------------------------- # Global namespace for all deployments # ----------------------------------------------------------- Loading @@ -33,11 +51,11 @@ VALUES_FILE_PROM="$VALUES_FILE_PATH/prometheus_values.yaml" # ----------------------------------------------------------- # Mimir Configuration # ----------------------------------------------------------- # RELEASE_NAME_MIMIR="mon-mimir" # CHART_REPO_NAME_MIMIR="grafana" # CHART_REPO_URL_MIMIR="https://grafana.github.io/helm-charts" # CHART_NAME_MIMIR="mimir-distributed" # VALUES_FILE_MIMIR="$VALUES_FILE_PATH/mimir_values.yaml" RELEASE_NAME_MIMIR="mon-mimir" CHART_REPO_NAME_MIMIR="grafana" CHART_REPO_URL_MIMIR="https://grafana.github.io/helm-charts" CHART_NAME_MIMIR="mimir-distributed" VALUES_FILE_MIMIR="$VALUES_FILE_PATH/mimir_values.yaml" # ----------------------------------------------------------- # Grafana Configuration Loading Loading @@ -105,16 +123,19 @@ kubectl rollout status deployment/"$RELEASE_NAME_PROM-server" -n "$NAMESPACE" || # 2) Deploy Mimir # deploy_chart "$RELEASE_NAME_MIMIR" \ # "$CHART_REPO_NAME_MIMIR" \ # "$CHART_REPO_URL_MIMIR" \ # "$CHART_NAME_MIMIR" \ # "$VALUES_FILE_MIMIR" \ # "$NAMESPACE" if [ "$TSDB_DEPLOY_MODE" == "cluster" ]; then echo "Deploying Mimir in production mode." # You can add any production-specific configurations here if needed deploy_chart "$RELEASE_NAME_MIMIR" \ "$CHART_REPO_NAME_MIMIR" \ "$CHART_REPO_URL_MIMIR" \ "$CHART_NAME_MIMIR" \ "$VALUES_FILE_MIMIR" \ "$NAMESPACE" # Depending on how Mimir runs (StatefulSets, Deployments), you can wait for # the correct resource to be ready. For example: # kubectl rollout status statefulset/"$RELEASE_NAME_MIMIR-distributor" -n "$NAMESPACE" || true # you can wait for the resource to be ready. kubectl rollout status statefulset/"$RELEASE_NAME_MIMIR-distributor" -n "$NAMESPACE" || true fi # 3) Deploy Grafana Loading Loading
deploy/all.sh +42 −2 Viewed Changes for deploy/all.sh: 42 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -69,6 +69,9 @@ export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device pathcomp service slice n # Uncomment to activate E2E Orchestrator #export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" # Uncomment to activate Pluggables Component #export TFS_COMPONENTS="${TFS_COMPONENTS} pluggables" # If not already set, set the tag you want to use for your images. export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"} Loading Loading @@ -151,6 +154,26 @@ export NATS_DEPLOY_MODE=${NATS_DEPLOY_MODE:-"single"} export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # ----- Apache Kafka ----------------------------------------------------------- # If not already set, set the namespace where Kafka will be deployed. export KFK_NAMESPACE=${KFK_NAMESPACE:-"kafka"} # If not already set, set the external port Kafka Client interface will be exposed to. export KFK_EXT_PORT_CLIENT=${KFK_EXT_PORT_CLIENT:-"9092"} # If not already set, set Kafka installation mode. Accepted values are: 'single'. # - If KFK_DEPLOY_MODE is "single", Kafka is deployed in single node mode. It is convenient for # development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # NOTE: Production mode is still not supported. Will be provided in the future. export KFK_DEPLOY_MODE=${KFK_DEPLOY_MODE:-"single"} # If not already set, disable flag for re-deploying Kafka from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If KFK_REDEPLOY is "YES", the message broker will be dropped while checking/deploying Kafka. export KFK_REDEPLOY=${KFK_REDEPLOY:-""} # ----- QuestDB ---------------------------------------------------------------- # If not already set, set the namespace where QuestDB will be deployed. Loading Loading @@ -190,6 +213,23 @@ export QDB_DROP_TABLES_IF_EXIST=${QDB_DROP_TABLES_IF_EXIST:-""} export QDB_REDEPLOY=${QDB_REDEPLOY:-""} # ----- Time Series Storage - Prometheus / Grafana Mimir ----------------------- # If not already set, set Time Series Storage installation mode. Accepted values are: # 'single' and 'cluster'. # - If TSDB_DEPLOY_MODE is "single", Time Series Storage is deployed in single node # mode and features a basic Prometheus instance. It is convenient for development and # testing purposes and should fit in a VM. # IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # - If TSDB_DEPLOY_MODE is "cluster", Time Series Storage is deployed in cluster mode # and a Grafana Mimir database in cluster mode will be deployed. It is convenient for # production and provides scalability features. If you are deploying for production, # also read the following link providing details on deploying Grafana Mimir for # production environments: # Ref: https://grafana.com/docs/mimir/latest/manage/run-production-environment/ export TSDB_DEPLOY_MODE=${TSDB_DEPLOY_MODE:-"single"} # ----- K8s Observability ------------------------------------------------------ # If not already set, set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. Loading @@ -215,8 +255,8 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} # Deploy Apache Kafka ./deploy/kafka.sh #Deploy Monitoring (Prometheus, Mimir, Grafana) ./deploy/monitoring.sh #Deploy Monitoring (Prometheus Gateway, Prometheus) # ./deploy/monitoring.sh # Expose Dashboard ./deploy/expose_dashboard.sh Loading
deploy/build-only.sh 0 → 100755 +143 −0 Viewed Changes for deploy/build-only.sh: 143 added lines, 0 removed lines. Original line number Diff line number Diff line #!/bin/bash # Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # # 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 # # http://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. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # ----- TeraFlowSDN ------------------------------------------------------------ # If not already set, set the URL of the Docker registry where the images will be uploaded to. # By default, assume internal MicroK8s registry is used. export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} # If not already set, set the list of components, separated by spaces, you want to build images for, and deploy. # By default, only basic components are deployed export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device pathcomp service slice nbi webui load_generator"} # If not already set, set the tag you want to use for your images. export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"} ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Create a tmp folder for files modified during the deployment TMP_LOGS_FOLDER="./tmp/build" mkdir -p $TMP_LOGS_FOLDER DOCKER_BUILD="docker build" DOCKER_MAJOR_VERSION=$(docker --version | grep -o -E "Docker version [0-9]+\." | grep -o -E "[0-9]+" | cut -c 1-3) if [[ $DOCKER_MAJOR_VERSION -ge 23 ]]; then # If Docker version >= 23, build command was migrated to docker-buildx # In Ubuntu, in practice, means to install package docker-buildx together with docker.io # Check if docker-buildx plugin is installed docker buildx version 1>/dev/null 2>/dev/null if [[ $? -ne 0 ]]; then echo "Docker buildx command is not installed. Check: https://docs.docker.com/build/architecture/#install-buildx" echo "If you installed docker through APT package docker.io, consider installing also package docker-buildx" exit 1; fi DOCKER_BUILD="docker buildx build" fi for COMPONENT in $TFS_COMPONENTS; do echo "Processing '$COMPONENT' component..." echo " Building Docker image..." BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log" if [ "$COMPONENT" == "ztp" ] || [ "$COMPONENT" == "policy" ]; then $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG" elif [ "$COMPONENT" == "pathcomp" ] || [ "$COMPONENT" == "telemetry" ] || [ "$COMPONENT" == "analytics" ]; then BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log" $DOCKER_BUILD -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . > "$BUILD_LOG" BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log" $DOCKER_BUILD -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . > "$BUILD_LOG" if [ "$COMPONENT" == "pathcomp" ]; then # next command is redundant, but helpful to keep cache updated between rebuilds IMAGE_NAME="$COMPONENT-backend:$TFS_IMAGE_TAG-builder" $DOCKER_BUILD -t "$IMAGE_NAME" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG" fi elif [ "$COMPONENT" == "dlt" ]; then BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-connector.log" $DOCKER_BUILD -t "$COMPONENT-connector:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/connector/Dockerfile . > "$BUILD_LOG" BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-gateway.log" $DOCKER_BUILD -t "$COMPONENT-gateway:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/gateway/Dockerfile . > "$BUILD_LOG" else $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG" fi echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..." if [ "$COMPONENT" == "pathcomp" ] || [ "$COMPONENT" == "telemetry" ] || [ "$COMPONENT" == "analytics" ] ; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log" docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log" docker push "$IMAGE_URL" > "$PUSH_LOG" IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log" docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log" docker push "$IMAGE_URL" > "$PUSH_LOG" elif [ "$COMPONENT" == "dlt" ]; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-connector.log" docker tag "$COMPONENT-connector:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-connector.log" docker push "$IMAGE_URL" > "$PUSH_LOG" IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-gateway.log" docker tag "$COMPONENT-gateway:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-gateway.log" docker push "$IMAGE_URL" > "$PUSH_LOG" else IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log" docker tag "$COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log" docker push "$IMAGE_URL" > "$PUSH_LOG" fi printf "\n" done echo "Pruning Docker Images..." docker image prune --force printf "\n\n" if [ "$DOCKER_BUILD" == "docker buildx build" ]; then echo "Pruning Docker Buildx Cache..." docker buildx prune --force printf "\n\n" fi
deploy/crdb.sh +8 −1 Viewed Changes for deploy/crdb.sh: 8 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ CRDB_MANIFESTS_PATH="manifests/cockroachdb" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${CRDB_NAMESPACE}/manifests" mkdir -p $TMP_MANIFESTS_FOLDER mkdir -p ${TMP_MANIFESTS_FOLDER} function crdb_deploy_single() { echo "CockroachDB Namespace" Loading Loading @@ -105,6 +105,13 @@ function crdb_deploy_single() { sleep 1 done kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 # Wait for CockroachDB to notify "start_node_query" echo ">>> CockroachDB pods created. Waiting CockroachDB server to be started..." while ! kubectl --namespace ${CRDB_NAMESPACE} logs pod/cockroachdb-0 -c cockroachdb 2>&1 | grep -q 'start_node_query'; do printf "%c" "." sleep 1 done fi echo Loading
deploy/kafka.sh +78 −44 Viewed Changes for deploy/kafka.sh: 78 added lines, 44 removed lines. Original line number Diff line number Diff line Loading @@ -13,17 +13,26 @@ # See the License for the specific language governing permissions and # limitations under the License. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # If not already set, set the namespace where Apache Kafka will be deployed. # If not already set, set the namespace where Kafka will be deployed. export KFK_NAMESPACE=${KFK_NAMESPACE:-"kafka"} # If not already set, set the port Apache Kafka server will be exposed to. export KFK_SERVER_PORT=${KFK_SERVER_PORT:-"9092"} # If not already set, set the external port Kafka client interface will be exposed to. export KFK_EXT_PORT_CLIENT=${KFK_EXT_PORT_CLIENT:-"9092"} # If not already set, set Kafka installation mode. Accepted values are: 'single'. # - If KFK_DEPLOY_MODE is "single", Kafka is deployed in single node mode. It is convenient for # development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # NOTE: Production mode is still not supported. Will be provided in the future. export KFK_DEPLOY_MODE=${KFK_DEPLOY_MODE:-"single"} # If not already set, if flag is YES, Apache Kafka will be redeployed and all topics will be lost. # If not already set, disable flag for re-deploying Kafka from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If KFK_REDEPLOY is "YES", the message broker will be dropped while checking/deploying Kafka. export KFK_REDEPLOY=${KFK_REDEPLOY:-""} Loading @@ -34,58 +43,83 @@ export KFK_REDEPLOY=${KFK_REDEPLOY:-""} # Constants TMP_FOLDER="./tmp" KFK_MANIFESTS_PATH="manifests/kafka" KFK_ZOOKEEPER_MANIFEST="01-zookeeper.yaml" KFK_MANIFEST="02-kafka.yaml" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${KFK_NAMESPACE}/manifests" mkdir -p ${TMP_MANIFESTS_FOLDER} function kafka_deploy() { # copy zookeeper and kafka manifest files to temporary manifest location cp "${KFK_MANIFESTS_PATH}/${KFK_ZOOKEEPER_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}" cp "${KFK_MANIFESTS_PATH}/${KFK_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_MANIFEST}" # echo "Apache Kafka Namespace" echo "Delete Apache Kafka Namespace" kubectl delete namespace ${KFK_NAMESPACE} --ignore-not-found echo "Create Apache Kafka Namespace" function kfk_deploy_single() { echo "Kafka Namespace" echo ">>> Create Kafka Namespace (if missing)" kubectl create namespace ${KFK_NAMESPACE} echo # echo ">>> Deplying Apache Kafka Zookeeper" # Kafka zookeeper service should be deployed before the kafka service kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}" #KFK_ZOOKEEPER_SERVICE="zookeeper-service" # this command may be replaced with command to extract service name automatically #KFK_ZOOKEEPER_IP=$(kubectl --namespace ${KFK_NAMESPACE} get service ${KFK_ZOOKEEPER_SERVICE} -o 'jsonpath={.spec.clusterIP}') echo "Kafka (single-mode)" echo ">>> Checking if Kafka is deployed..." if kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; then echo ">>> Kafka is present; skipping step." else echo ">>> Deploy Kafka" cp "${KFK_MANIFESTS_PATH}/single-node.yaml" "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" #sed -i "s/<KFK_NAMESPACE>/${KFK_NAMESPACE}/" "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" echo ">>> Waiting Kafka statefulset to be created..." while ! kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; do printf "%c" "." sleep 1 done # Wait for statefulset condition "Available=True" does not work # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: # "error: readyReplicas is not found" # Workaround: Check the pods are ready #echo ">>> Kafka statefulset created. Waiting for readiness condition..." #kubectl wait --namespace ${KFK_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/kafka #kubectl wait --namespace ${KGK_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/kafka echo ">>> Kafka statefulset created. Waiting Kafka pods to be created..." while ! kubectl get --namespace ${KFK_NAMESPACE} pod/kafka-0 &> /dev/null; do printf "%c" "." sleep 1 done kubectl wait --namespace ${KFK_NAMESPACE} --for=condition=Ready --timeout=300s pod/kafka-0 # Wait for Kafka to notify "Kafka Server started" echo ">>> Kafka pods created. Waiting Kafka Server to be started..." while ! kubectl --namespace ${KFK_NAMESPACE} logs pod/kafka-0 -c kafka 2>&1 | grep -q 'Kafka Server started'; do printf "%c" "." sleep 1 done fi echo } # Kafka service should be deployed after the zookeeper service #sed -i "s/<ZOOKEEPER_INTERNAL_IP>/${KFK_ZOOKEEPER_IP}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" sed -i "s/<KAFKA_NAMESPACE>/${KFK_NAMESPACE}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" # echo ">>> Deploying Apache Kafka Broker" kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST" function kfk_undeploy_single() { echo "Kafka (single-mode)" echo ">>> Checking if Kafka is deployed..." if kubectl get --namespace ${KFK_NAMESPACE} statefulset/kafka &> /dev/null; then echo ">>> Undeploy Kafka" kubectl delete --namespace ${KFK_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/kfk_single_node.yaml" --ignore-not-found else echo ">>> Kafka is not present; skipping step." fi echo # echo ">>> Verifing Apache Kafka deployment" sleep 5 # KFK_PODS_STATUS=$(kubectl --namespace ${KFK_NAMESPACE} get pods) # if echo "$KFK_PODS_STATUS" | grep -qEv 'STATUS|Running'; then # echo "Deployment Error: \n $KFK_PODS_STATUS" # else # echo "$KFK_PODS_STATUS" # fi echo "Kafka Namespace" echo ">>> Delete Kafka Namespace (if exists)" echo "NOTE: this step might take few minutes to complete!" kubectl delete namespace ${KFK_NAMESPACE} --ignore-not-found echo } echo ">>> Apache Kafka" echo "Checking if Apache Kafka is deployed ... " if [ "$KFK_DEPLOY_MODE" == "single" ]; then if [ "$KFK_REDEPLOY" == "YES" ]; then echo "Redeploying kafka namespace" kafka_deploy elif kubectl get namespace "${KFK_NAMESPACE}" &> /dev/null; then echo "Apache Kafka already present; skipping step." kfk_undeploy_single fi kfk_deploy_single else echo "Kafka namespace doesn't exists. Deploying kafka namespace" kafka_deploy echo "Unsupported value: KFK_DEPLOY_MODE=$KFK_DEPLOY_MODE" fi echo
deploy/monitoring.sh +35 −14 Viewed Changes for deploy/monitoring.sh: 35 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -15,6 +15,24 @@ set -euo pipefail # ----- Time Series Storage - Prometheus / Grafana Mimir ----------------------- # If not already set, set Time Series Storage installation mode. Accepted values are: # 'single' and 'cluster'. # - If TSDB_DEPLOY_MODE is "single", Time Series Storage is deployed in single node # mode and features a basic Prometheus instance. It is convenient for development and # testing purposes and should fit in a VM. # IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. # - If TSDB_DEPLOY_MODE is "cluster", Time Series Storage is deployed in cluster mode # and a Grafana Mimir database in cluster mode will be deployed. It is convenient for # production and provides scalability features. If you are deploying for production, # also read the following link providing details on deploying Grafana Mimir for # production environments: # Ref: https://grafana.com/docs/mimir/latest/manage/run-production-environment/ export TSDB_DEPLOY_MODE=${TSDB_DEPLOY_MODE:-"single"} # ----------------------------------------------------------- # Global namespace for all deployments # ----------------------------------------------------------- Loading @@ -33,11 +51,11 @@ VALUES_FILE_PROM="$VALUES_FILE_PATH/prometheus_values.yaml" # ----------------------------------------------------------- # Mimir Configuration # ----------------------------------------------------------- # RELEASE_NAME_MIMIR="mon-mimir" # CHART_REPO_NAME_MIMIR="grafana" # CHART_REPO_URL_MIMIR="https://grafana.github.io/helm-charts" # CHART_NAME_MIMIR="mimir-distributed" # VALUES_FILE_MIMIR="$VALUES_FILE_PATH/mimir_values.yaml" RELEASE_NAME_MIMIR="mon-mimir" CHART_REPO_NAME_MIMIR="grafana" CHART_REPO_URL_MIMIR="https://grafana.github.io/helm-charts" CHART_NAME_MIMIR="mimir-distributed" VALUES_FILE_MIMIR="$VALUES_FILE_PATH/mimir_values.yaml" # ----------------------------------------------------------- # Grafana Configuration Loading Loading @@ -105,16 +123,19 @@ kubectl rollout status deployment/"$RELEASE_NAME_PROM-server" -n "$NAMESPACE" || # 2) Deploy Mimir # deploy_chart "$RELEASE_NAME_MIMIR" \ # "$CHART_REPO_NAME_MIMIR" \ # "$CHART_REPO_URL_MIMIR" \ # "$CHART_NAME_MIMIR" \ # "$VALUES_FILE_MIMIR" \ # "$NAMESPACE" if [ "$TSDB_DEPLOY_MODE" == "cluster" ]; then echo "Deploying Mimir in production mode." # You can add any production-specific configurations here if needed deploy_chart "$RELEASE_NAME_MIMIR" \ "$CHART_REPO_NAME_MIMIR" \ "$CHART_REPO_URL_MIMIR" \ "$CHART_NAME_MIMIR" \ "$VALUES_FILE_MIMIR" \ "$NAMESPACE" # Depending on how Mimir runs (StatefulSets, Deployments), you can wait for # the correct resource to be ready. For example: # kubectl rollout status statefulset/"$RELEASE_NAME_MIMIR-distributor" -n "$NAMESPACE" || true # you can wait for the resource to be ready. kubectl rollout status statefulset/"$RELEASE_NAME_MIMIR-distributor" -n "$NAMESPACE" || true fi # 3) Deploy Grafana Loading