-
Notifications
You must be signed in to change notification settings - Fork 24
Add unified k3d local development with helm mode #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3f42e1f
d9e1cca
0aed56d
0c86445
6805af6
de54a7f
d2a36dc
1d85f10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # k3d cluster config for Helm dev mode (DEV_MODE=helm) | ||
| # Based on single-cluster-config.yaml with additional AMP service port mappings. | ||
| # This allows all services (OpenChoreo + AMP) to run in a single k3d cluster. | ||
| apiVersion: k3d.io/v1alpha5 | ||
| kind: Simple | ||
| metadata: | ||
| name: openchoreo-local-v0.14.0 | ||
| image: rancher/k3s:v1.32.9-k3s1 | ||
| servers: 1 | ||
| agents: 0 | ||
| kubeAPI: | ||
| hostPort: "6550" | ||
| ports: | ||
| # === OpenChoreo Ports (same as single-cluster-config.yaml) === | ||
| # Control Plane uses port range 8xxx | ||
| # HTTP traffic to OpenChoreo UI and API (Kgateway LoadBalancer on port 80) | ||
| - port: 8080:80 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # HTTPS traffic to OpenChoreo UI and API (Kgateway LoadBalancer on port 443) | ||
| - port: 8443:443 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Data Plane uses port range 19xxx | ||
| # HTTP traffic to workloads via Gateway | ||
| - port: 19080:19080 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # HTTPS traffic to workloads via Gateway | ||
| - port: 19443:19443 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Build Plane uses port range 10xxx | ||
| # Argo Workflows UI for development testing | ||
| - port: 10081:2746 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Container Registry for storing built images | ||
| - port: 10082:5000 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Observability Plane uses port range 11xxx | ||
| # Observer API | ||
| - port: 11080:8080 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # OpenSearch Dashboard | ||
| - port: 11081:5601 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # OpenSearch API for Fluent Bit data pushing | ||
| - port: 11082:9200 | ||
| nodeFilters: | ||
| - loadbalancer | ||
|
|
||
| # === AMP Service Ports === | ||
| # Console (React frontend) | ||
| - port: 3000:3000 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Agent Manager API | ||
| - port: 9000:9000 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Internal API / Gateway Management | ||
| - port: 9243:9243 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # Traces Observer Service | ||
| - port: 9098:9098 | ||
| nodeFilters: | ||
| - loadbalancer | ||
|
|
||
| # === OTel / Observability Ports === | ||
| # Data Prepper HTTP source | ||
| - port: 21893:21893 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # OTel gRPC | ||
| - port: 22893:22893 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| # OTel HTTP | ||
| - port: 22894:22894 | ||
| nodeFilters: | ||
| - loadbalancer | ||
| options: | ||
| k3s: | ||
| extraArgs: | ||
| # Add host.k3d.internal to API server TLS certificate SANs. | ||
| # This allows consistent DataPlane configuration across single and multi-cluster setups | ||
| # where Control Plane pods can access the API server via host.k3d.internal:6550 | ||
| - arg: "--tls-san=host.k3d.internal" | ||
| nodeFilters: | ||
| - server:* | ||
| # Configure kubelet eviction thresholds to prevent resource exhaustion | ||
| - arg: "--kubelet-arg=eviction-hard=imagefs.available<1%,nodefs.available<1%" | ||
| nodeFilters: | ||
| - server:* | ||
| - arg: "--kubelet-arg=eviction-minimum-reclaim=imagefs.available=1%,nodefs.available=1%" | ||
| nodeFilters: | ||
| - server:* | ||
| # Disable Traefik to avoid conflicts with OpenChoreo Gateway controller | ||
| - arg: "--disable=traefik" | ||
| nodeFilters: | ||
| - server:* | ||
| # Configure insecure registries for HTTP access | ||
| # Allows kubelet to pull images from Build Plane registry via HTTP | ||
| registries: | ||
| config: | | ||
| mirrors: | ||
| "host.k3d.internal:10082": | ||
| endpoint: | ||
| - http://host.k3d.internal:10082 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Build Docker images from production Dockerfiles and import them into k3d. | ||
| # Usage: | ||
| # ./build-and-import.sh # Build and import all components | ||
| # ./build-and-import.sh api # Build and import API only | ||
| # ./build-and-import.sh console api # Build and import Console and API | ||
| # | ||
| # Supported components: api, console, traces-observer, evaluation-job | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" | ||
|
|
||
| source "$SCRIPT_DIR/env.sh" | ||
|
|
||
| # Components and their build contexts (relative to ROOT_DIR) | ||
| declare -A COMPONENT_CONTEXT=( | ||
| [api]="agent-manager-service" | ||
| [console]="console" | ||
| [traces-observer]="traces-observer-service" | ||
| [evaluation-job]="evaluation-job" | ||
| ) | ||
|
|
||
| declare -A COMPONENT_IMAGE=( | ||
| [api]="amp-api" | ||
| [console]="amp-console" | ||
| [traces-observer]="amp-traces-observer" | ||
| [evaluation-job]="amp-evaluation-job" | ||
| ) | ||
|
|
||
| ALL_COMPONENTS="api console traces-observer evaluation-job" | ||
|
|
||
| # Determine which components to build | ||
| if [ $# -eq 0 ]; then | ||
| COMPONENTS="$ALL_COMPONENTS" | ||
| else | ||
| COMPONENTS="$*" | ||
| fi | ||
|
|
||
| # Validate component names | ||
| for comp in $COMPONENTS; do | ||
| if [ -z "${COMPONENT_CONTEXT[$comp]}" ]; then | ||
| echo "Unknown component: $comp" | ||
| echo "Valid components: $ALL_COMPONENTS" | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| echo "=== Building and importing images into k3d ===" | ||
| echo "" | ||
|
|
||
| # Verify k3d cluster exists | ||
| if ! k3d cluster list 2>/dev/null | grep -q "${CLUSTER_NAME}"; then | ||
| echo "k3d cluster '${CLUSTER_NAME}' not found. Run 'make setup-k3d' first." | ||
| exit 1 | ||
| fi | ||
|
|
||
| FAILED="" | ||
|
|
||
| for comp in $COMPONENTS; do | ||
| IMAGE="${COMPONENT_IMAGE[$comp]}:${AMP_IMAGE_TAG}" | ||
| CONTEXT="${ROOT_DIR}/${COMPONENT_CONTEXT[$comp]}" | ||
|
|
||
| echo "Building ${comp} -> ${IMAGE}..." | ||
| if docker build -t "$IMAGE" "$CONTEXT" --quiet; then | ||
| echo "Importing ${IMAGE} into k3d cluster..." | ||
| if k3d image import "$IMAGE" -c "${CLUSTER_NAME}"; then | ||
| echo "${comp} ready." | ||
| else | ||
| echo "Failed to import ${comp}." | ||
| FAILED="$FAILED $comp" | ||
| fi | ||
| else | ||
| echo "Failed to build ${comp}." | ||
| FAILED="$FAILED $comp" | ||
| fi | ||
| echo "" | ||
| done | ||
|
|
||
| if [ -n "$FAILED" ]; then | ||
| echo "Failed components:${FAILED}" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "All images built and imported successfully." | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,70 @@ | ||||||||||||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Deploy AMP to the k3d cluster using Helm. | ||||||||||||||||||||||||||||||
| # Usage: | ||||||||||||||||||||||||||||||
| # ./helm-deploy-amp.sh # Install or upgrade | ||||||||||||||||||||||||||||||
| # ./helm-deploy-amp.sh --uninstall # Uninstall (preserves cluster) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||||||||||||||||||||||||||
| ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" | ||||||||||||||||||||||||||||||
| CHART_DIR="$ROOT_DIR/deployments/helm-charts/wso2-agent-manager" | ||||||||||||||||||||||||||||||
| VALUES_FILE="$ROOT_DIR/deployments/values/values-local.yaml" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| source "$SCRIPT_DIR/env.sh" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if [ "$1" = "--uninstall" ]; then | ||||||||||||||||||||||||||||||
| echo "=== Uninstalling AMP from k3d ===" | ||||||||||||||||||||||||||||||
| if helm status "$AMP_RELEASE_NAME" -n "$AMP_NAMESPACE" --kube-context "${CLUSTER_CONTEXT}" &>/dev/null; then | ||||||||||||||||||||||||||||||
| helm uninstall "$AMP_RELEASE_NAME" -n "$AMP_NAMESPACE" --kube-context "${CLUSTER_CONTEXT}" | ||||||||||||||||||||||||||||||
| echo "AMP uninstalled. Cluster and namespace preserved." | ||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||
| echo "AMP release '${AMP_RELEASE_NAME}' not found in namespace '${AMP_NAMESPACE}'." | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| echo "=== Deploying AMP to k3d cluster ===" | ||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Verify cluster is accessible | ||||||||||||||||||||||||||||||
| if ! kubectl cluster-info --context "${CLUSTER_CONTEXT}" &>/dev/null; then | ||||||||||||||||||||||||||||||
| echo "k3d cluster '${CLUSTER_NAME}' is not accessible." | ||||||||||||||||||||||||||||||
| echo "Run 'make setup-k3d' or 'k3d cluster start ${CLUSTER_NAME}' first." | ||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Create namespace if it doesn't exist | ||||||||||||||||||||||||||||||
| kubectl create namespace "$AMP_NAMESPACE" --context "${CLUSTER_CONTEXT}" --dry-run=client -o yaml | \ | ||||||||||||||||||||||||||||||
| kubectl apply --context "${CLUSTER_CONTEXT}" -f - | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Update Helm dependencies | ||||||||||||||||||||||||||||||
| echo "Updating Helm chart dependencies..." | ||||||||||||||||||||||||||||||
| helm dependency update "$CHART_DIR" | ||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Install or upgrade | ||||||||||||||||||||||||||||||
| echo "Running helm upgrade --install..." | ||||||||||||||||||||||||||||||
| helm upgrade --install "$AMP_RELEASE_NAME" "$CHART_DIR" \ | ||||||||||||||||||||||||||||||
| --namespace "$AMP_NAMESPACE" \ | ||||||||||||||||||||||||||||||
| --kube-context "${CLUSTER_CONTEXT}" \ | ||||||||||||||||||||||||||||||
| --values "$VALUES_FILE" \ | ||||||||||||||||||||||||||||||
| --wait \ | ||||||||||||||||||||||||||||||
| --timeout 5m | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
| echo "Waiting for deployments to be ready..." | ||||||||||||||||||||||||||||||
| kubectl wait --for=condition=Available deployment --all \ | ||||||||||||||||||||||||||||||
| -n "$AMP_NAMESPACE" \ | ||||||||||||||||||||||||||||||
| --context "${CLUSTER_CONTEXT}" \ | ||||||||||||||||||||||||||||||
| --timeout=300s 2>/dev/null || true | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
| echo "AMP deployed successfully!" | ||||||||||||||||||||||||||||||
|
Comment on lines
+57
to
+63
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don’t suppress deployment readiness failures. Line 60 uses Suggested fix kubectl wait --for=condition=Available deployment --all \
-n "$AMP_NAMESPACE" \
--context "${CLUSTER_CONTEXT}" \
- --timeout=300s 2>/dev/null || true
+ --timeout=300s📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
| echo "Services:" | ||||||||||||||||||||||||||||||
| echo " Console: http://localhost:3000" | ||||||||||||||||||||||||||||||
| echo " API: http://localhost:9000" | ||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||
| echo "Status:" | ||||||||||||||||||||||||||||||
| kubectl get pods -n "$AMP_NAMESPACE" --context "${CLUSTER_CONTEXT}" | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,14 @@ cd "$SCRIPT_DIR" | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| source "$SCRIPT_DIR/env.sh" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| echo "=== Setting up k3d Cluster for OpenChoreo ===" | ||||||||||||||||||||||
| # Select k3d config based on DEV_MODE | ||||||||||||||||||||||
| if [ "${DEV_MODE}" = "helm" ]; then | ||||||||||||||||||||||
| K3D_CONFIG="../dev-cluster-config.yaml" | ||||||||||||||||||||||
| echo "=== Setting up k3d Cluster for OpenChoreo + AMP (Helm mode) ===" | ||||||||||||||||||||||
| else | ||||||||||||||||||||||
| K3D_CONFIG="../single-cluster-config.yaml" | ||||||||||||||||||||||
| echo "=== Setting up k3d Cluster for OpenChoreo ===" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Check prerequisites | ||||||||||||||||||||||
| if ! command -v k3d &> /dev/null; then | ||||||||||||||||||||||
|
|
@@ -52,6 +59,27 @@ if k3d cluster list 2>/dev/null | grep -q "${CLUSTER_NAME}"; then | |||||||||||||||||||||
| done | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # When using Helm mode, verify AMP ports are mapped | ||||||||||||||||||||||
| if [ "${DEV_MODE}" = "helm" ]; then | ||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||
| echo "🔍 Checking AMP port mappings..." | ||||||||||||||||||||||
| MISSING_PORTS="" | ||||||||||||||||||||||
| for PORT in 3000 9000; do | ||||||||||||||||||||||
| if ! docker port "k3d-${CLUSTER_NAME}-serverlb" "${PORT}/tcp" &>/dev/null; then | ||||||||||||||||||||||
| MISSING_PORTS="${MISSING_PORTS} ${PORT}" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
| done | ||||||||||||||||||||||
|
Comment on lines
+67
to
+71
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Helm port validation is incomplete. At Line 67, the check only verifies Suggested fix- for PORT in 3000 9000; do
+ for PORT in 3000 9000 9243 9098 21893 22893 22894; do
if ! docker port "k3d-${CLUSTER_NAME}-serverlb" "${PORT}/tcp" &>/dev/null; then
MISSING_PORTS="${MISSING_PORTS} ${PORT}"
fi
done📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| if [ -n "$MISSING_PORTS" ]; then | ||||||||||||||||||||||
| echo "⚠️ AMP ports not mapped:${MISSING_PORTS}" | ||||||||||||||||||||||
| echo " The cluster was created without AMP port mappings." | ||||||||||||||||||||||
| echo " To fix, delete and recreate the cluster:" | ||||||||||||||||||||||
| echo " k3d cluster delete ${CLUSTER_NAME}" | ||||||||||||||||||||||
| echo " DEV_MODE=helm make setup-k3d" | ||||||||||||||||||||||
| else | ||||||||||||||||||||||
| echo "✅ AMP ports are mapped correctly" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||
| echo "Cluster info:" | ||||||||||||||||||||||
| kubectl cluster-info --context ${CLUSTER_CONTEXT} | ||||||||||||||||||||||
|
|
@@ -62,9 +90,9 @@ else | |||||||||||||||||||||
| echo "📁 Creating shared directory for OpenChoreo..." | ||||||||||||||||||||||
| mkdir -p /tmp/k3d-shared | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Create k3d cluster with OpenChoreo configuration | ||||||||||||||||||||||
| echo "🚀 Creating k3d cluster with OpenChoreo configuration..." | ||||||||||||||||||||||
| k3d cluster create --config ../single-cluster-config.yaml | ||||||||||||||||||||||
| # Create k3d cluster with appropriate configuration | ||||||||||||||||||||||
| echo "🚀 Creating k3d cluster with config: ${K3D_CONFIG}..." | ||||||||||||||||||||||
| k3d cluster create --config "${K3D_CONFIG}" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||
| echo "✅ k3d cluster created successfully!" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n deployments/scripts/build-and-import.sh | head -n 35Repository: wso2/agent-manager
Length of output: 1357
🏁 Script executed:
Repository: wso2/agent-manager
Length of output: 164
🏁 Script executed:
Repository: wso2/agent-manager
Length of output: 355
Add Bash 4+ version guard to prevent script failure on macOS.
The script uses
declare -A(associative arrays) on lines 18 and 25, which requires Bash 4+. Default macOS/bin/bashis version 3.2 (due to Apple's GPL licensing constraints), causing the script to fail immediately on standard macOS systems before any build/import work runs.Add this check after sourcing env.sh
🤖 Prompt for AI Agents