diff --git a/e2e/k8s/scripts/install_helm_e2e.sh b/e2e/k8s/scripts/install_helm_e2e.sh index 07f4f34baf..5cdd785051 100755 --- a/e2e/k8s/scripts/install_helm_e2e.sh +++ b/e2e/k8s/scripts/install_helm_e2e.sh @@ -9,6 +9,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib.sh" REPO_ROOT="$(git -C "${SCRIPT_DIR}" rev-parse --show-toplevel)" NAMESPACE="${NAMESPACE:-${KUBE_NAMESPACE:-default}}" @@ -31,22 +32,6 @@ RUSTFS_SECRET_KEY="${RUSTFS_SECRET_KEY:-rustfsadmin}" MINIKUBE_PROFILE="${MINIKUBE_PROFILE:-minikube}" EXTRA_HELM_ARGS=() -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' - -log_info() { - echo -e "${GREEN}[INFO]${NC} $*" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $*" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $*" -} require_non_empty() { local name="$1" @@ -239,6 +224,18 @@ if [ -n "${NMP_E2E_PULL_POLICY}" ]; then ) fi +IMAGE_PULL_SECRET_INDEX=0 + +if [ -n "${NGC_API_KEY:-}" ]; then + HELM_ARGS+=(--set "imagePullSecrets[${IMAGE_PULL_SECRET_INDEX}].name=nvcrimagepullsecret") + IMAGE_PULL_SECRET_INDEX=$((IMAGE_PULL_SECRET_INDEX + 1)) +fi + +if [ -n "${GITHUB_TOKEN:-}" ]; then + HELM_ARGS+=(--set "imagePullSecrets[${IMAGE_PULL_SECRET_INDEX}].name=ghcr-pull") + IMAGE_PULL_SECRET_INDEX=$((IMAGE_PULL_SECRET_INDEX + 1)) +fi + log_info "Helm install inputs:" printf ' release: %s\n' "${HELM_RELEASE_NAME}" printf ' namespace: %s\n' "${NAMESPACE}" diff --git a/e2e/k8s/scripts/lib.sh b/e2e/k8s/scripts/lib.sh new file mode 100644 index 0000000000..6df829398c --- /dev/null +++ b/e2e/k8s/scripts/lib.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Shared utilities for e2e K8s setup scripts. + +# --------------------------------------------------------------------------- +# Logging +# --------------------------------------------------------------------------- + +log_info() { echo -e "\033[0;32m[INFO]\033[0m $*"; } +log_warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; } +log_error() { echo -e "\033[0;31m[ERROR]\033[0m $*"; } + +# --------------------------------------------------------------------------- +# Secrets +# --------------------------------------------------------------------------- + +# _dockerconfigjson SERVER USERNAME PASSWORD +# +# Prints a dockerconfigjson blob for a single registry. +_dockerconfigjson() { + printf '{"auths":{"%s":{"username":"%s","password":"%s","auth":"%s"}}}' \ + "$1" "$2" "$3" "$(printf '%s:%s' "$2" "$3" | base64 | tr -d '\n')" +} + +# create_platform_secrets NAMESPACE +# +# Creates the standard set of platform secrets in the given namespace. +# NGC secrets are always created (with a placeholder if NGC_API_KEY is unset) +# because the helm chart expects the ngc-api secret to exist. Other secrets +# are created only when their corresponding env var is set: +# - ghcr-pull: when GITHUB_TOKEN is set +# - huggingface-token: when HF_TOKEN is set +# +# Secret values are passed via process substitution to keep them out of +# process arguments visible in /proc. +create_platform_secrets() { + local namespace="${1:?namespace is required}" + local kubectl_ns=(kubectl -n "${namespace}") + local ngc_key="${NGC_API_KEY:-placeholder}" + + if [ -z "${NGC_API_KEY:-}" ]; then + log_warn "NGC_API_KEY not set, creating NGC secrets with placeholder" + fi + + log_info "Creating NGC API secret..." + "${kubectl_ns[@]}" create secret generic ngc-api \ + --from-file=NGC_API_KEY=<(printf '%s' "${ngc_key}") \ + --dry-run=client -o yaml | "${kubectl_ns[@]}" apply -f - + + log_info "Creating NGC image pull secret..." + "${kubectl_ns[@]}" create secret generic nvcrimagepullsecret \ + --type=kubernetes.io/dockerconfigjson \ + --from-file=.dockerconfigjson=<(_dockerconfigjson nvcr.io '$oauthtoken' "${ngc_key}") \ + --dry-run=client -o yaml | "${kubectl_ns[@]}" apply -f - + + if [ -n "${GITHUB_TOKEN:-}" ]; then + log_info "Creating GHCR image pull secret..." + "${kubectl_ns[@]}" create secret generic ghcr-pull \ + --type=kubernetes.io/dockerconfigjson \ + --from-file=.dockerconfigjson=<(_dockerconfigjson ghcr.io x-access-token "${GITHUB_TOKEN}") \ + --dry-run=client -o yaml | "${kubectl_ns[@]}" apply -f - + else + log_warn "GITHUB_TOKEN not set, skipping GHCR image pull secret" + fi + + if [ -n "${HF_TOKEN:-}" ]; then + log_info "Creating HuggingFace token secret..." + "${kubectl_ns[@]}" create secret generic huggingface-token \ + --from-file=HF_TOKEN=<(printf '%s' "${HF_TOKEN}") \ + --dry-run=client -o yaml | "${kubectl_ns[@]}" apply -f - + else + log_warn "HF_TOKEN not set, skipping HuggingFace token secret" + fi +} diff --git a/e2e/k8s/scripts/setup_local_kind_cpu.sh b/e2e/k8s/scripts/setup_local_kind_cpu.sh index e770431d7a..9300ec65ff 100755 --- a/e2e/k8s/scripts/setup_local_kind_cpu.sh +++ b/e2e/k8s/scripts/setup_local_kind_cpu.sh @@ -4,6 +4,9 @@ set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib.sh" + KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-nmp-e2e}" KIND_NODE_IMAGE="${KIND_NODE_IMAGE:-kindest/node:v1.33.7@sha256:d26ef333bdb2cbe9862a0f7c3803ecc7b4303d8cea8e814b481b09949d353040}" KUBE_NAMESPACE="${KUBE_NAMESPACE:-default}" @@ -12,23 +15,6 @@ CLOUD_PROVIDER_KIND_VERSION="${CLOUD_PROVIDER_KIND_VERSION:-v0.10.0}" GATEWAY_API_VERSION="${GATEWAY_API_VERSION:-v1.4.1}" CLOUD_PROVIDER_KIND_CONTAINER="cloud-provider-kind-${KIND_CLUSTER_NAME}" -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' - -log_info() { - echo -e "${GREEN}[INFO]${NC} $*" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $*" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $*" -} - for tool in kind docker kubectl helm; do if ! command -v "$tool" >/dev/null 2>&1; then log_error "$tool is not installed. Please install it first." @@ -93,24 +79,7 @@ fi KUBECTL_NS=(kubectl -n "${KUBE_NAMESPACE}") log_info "Creating Kubernetes secrets in namespace ${KUBE_NAMESPACE}..." -"${KUBECTL_NS[@]}" create secret generic ngc-api \ - --from-literal=NGC_API_KEY="${NGC_API_KEY}" \ - --dry-run=client -o yaml | "${KUBECTL_NS[@]}" apply -f - - -"${KUBECTL_NS[@]}" create secret docker-registry nvcrimagepullsecret \ - --docker-server=nvcr.io \ - --docker-username="\$oauthtoken" \ - --docker-password="${NGC_API_KEY}" \ - --dry-run=client -o yaml | "${KUBECTL_NS[@]}" apply -f - - -if [ -n "${HF_TOKEN:-}" ]; then - log_info "Creating HuggingFace token secret..." - "${KUBECTL_NS[@]}" create secret generic huggingface-token \ - --from-literal=HF_TOKEN="${HF_TOKEN}" \ - --dry-run=client -o yaml | "${KUBECTL_NS[@]}" apply -f - -else - log_warn "HF_TOKEN not set, skipping HuggingFace token secret" -fi +create_platform_secrets "${KUBE_NAMESPACE}" log_info "Creating Gateway ${KUBE_NAMESPACE}/${KUBE_GATEWAY_NAME}..." kubectl apply -f - </dev/null 2>&1; then log_error "$tool is not installed. Please install it first." @@ -90,23 +76,8 @@ fi KUBECTL_NS=(kubectl -n "${KUBE_NAMESPACE}") -log_info "Creating placeholder platform secrets in namespace ${KUBE_NAMESPACE}..." -${KUBECTL_NS[@]} create secret generic ngc-api \ - --from-literal=NGC_API_KEY="${NGC_API_KEY:-local-dev-placeholder}" \ - --dry-run=client -o yaml | ${KUBECTL_NS[@]} apply -f - - -${KUBECTL_NS[@]} create secret docker-registry nvcrimagepullsecret \ - --docker-server="${NVCI_DOCKER_SERVER:-docker.io}" \ - --docker-username="${NVCI_DOCKER_USERNAME:-local}" \ - --docker-password="${NVCI_DOCKER_PASSWORD:-local-dev-placeholder}" \ - --dry-run=client -o yaml | ${KUBECTL_NS[@]} apply -f - - -if [ -n "${HF_TOKEN:-}" ]; then - log_info "Creating HuggingFace token secret..." - ${KUBECTL_NS[@]} create secret generic huggingface-token \ - --from-literal=HF_TOKEN="${HF_TOKEN}" \ - --dry-run=client -o yaml | ${KUBECTL_NS[@]} apply -f - -fi +log_info "Creating platform secrets in namespace ${KUBE_NAMESPACE}..." +create_platform_secrets "${KUBE_NAMESPACE}" MINIKUBE_IP="$(minikube ip -p "${MINIKUBE_PROFILE}")" diff --git a/e2e/k8s/scripts/setup_local_minikube_gpu.sh b/e2e/k8s/scripts/setup_local_minikube_gpu.sh index 297c5df279..e0fbfa601c 100755 --- a/e2e/k8s/scripts/setup_local_minikube_gpu.sh +++ b/e2e/k8s/scripts/setup_local_minikube_gpu.sh @@ -10,24 +10,10 @@ set -euo pipefail -MINIKUBE_PROFILE="${MINIKUBE_PROFILE:-minikube}" - -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -log_info() { - echo -e "${GREEN}[INFO]${NC} $*" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $*" -} +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib.sh" -log_error() { - echo -e "${RED}[ERROR]${NC} $*" -} +MINIKUBE_PROFILE="${MINIKUBE_PROFILE:-minikube}" log_info "Validating environment..." @@ -131,27 +117,7 @@ if [ "${KUBE_NAMESPACE}" != "default" ]; then fi log_info "Creating Kubernetes secrets in namespace '${KUBE_NAMESPACE}'..." - -log_info "Creating NGC API secret..." -${KUBECTL_NS} create secret generic ngc-api \ - --from-literal=NGC_API_KEY="$NGC_API_KEY" \ - --dry-run=client -o yaml | ${KUBECTL_NS} apply -f - - -log_info "Creating NGC image pull secret..." -${KUBECTL_NS} create secret docker-registry nvcrimagepullsecret \ - --docker-server=nvcr.io \ - --docker-username='$oauthtoken' \ - --docker-password="$NGC_API_KEY" \ - --dry-run=client -o yaml | ${KUBECTL_NS} apply -f - - -if [ -n "${HF_TOKEN:-}" ]; then - log_info "Creating HuggingFace token secret..." - ${KUBECTL_NS} create secret generic huggingface-token \ - --from-literal=HF_TOKEN=$HF_TOKEN \ - --dry-run=client -o yaml | ${KUBECTL_NS} apply -f - -else - log_warn "HF_TOKEN not set, skipping HuggingFace token secret" -fi +create_platform_secrets "${KUBE_NAMESPACE}" MINIKUBE_IP=$(minikube ip -p "${MINIKUBE_PROFILE}") CLUSTER_URL="http://${MINIKUBE_IP}"