diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 393062908..3b9085ff3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -158,6 +158,17 @@ jobs: docker tag quay.io/ambient_code/vteam_claude_runner:latest quay.io/ambient_code/vteam_claude_runner:e2e-test fi + # Build state-sync image (if changed or use latest) + if [ "${{ needs.detect-changes.outputs.claude-runner }}" == "true" ]; then + echo "Building state-sync (changed)..." + docker build -t quay.io/ambient_code/vteam_state_sync:e2e-test \ + components/runners/state-sync + else + echo "State-sync unchanged, pulling latest..." + docker pull quay.io/ambient_code/vteam_state_sync:latest + docker tag quay.io/ambient_code/vteam_state_sync:latest quay.io/ambient_code/vteam_state_sync:e2e-test + fi + echo "" echo "✅ All images ready" docker images | grep e2e-test @@ -184,6 +195,7 @@ jobs: kind load docker-image quay.io/ambient_code/vteam_backend:e2e-test --name ambient-local kind load docker-image quay.io/ambient_code/vteam_operator:e2e-test --name ambient-local kind load docker-image quay.io/ambient_code/vteam_claude_runner:e2e-test --name ambient-local + kind load docker-image quay.io/ambient_code/vteam_state_sync:e2e-test --name ambient-local echo "✅ All images loaded into kind cluster" - name: Update kustomization to use e2e-test images diff --git a/Makefile b/Makefile index fa3289aad..dbab512e2 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ .PHONY: local-dev-token .PHONY: local-logs local-logs-backend local-logs-frontend local-logs-operator local-shell local-shell-frontend .PHONY: local-test local-test-dev local-test-quick test-all local-url local-troubleshoot local-port-forward local-stop-port-forward -.PHONY: push-all registry-login setup-hooks remove-hooks check-minikube check-kind check-kubectl +.PHONY: push-all registry-login setup-hooks remove-hooks check-minikube check-kind check-kubectl check-image-arch .PHONY: e2e-test e2e-setup e2e-clean deploy-langfuse-openshift .PHONY: setup-minio minio-console minio-logs minio-status .PHONY: validate-makefile lint-makefile check-shell makefile-health @@ -560,7 +560,7 @@ clean: ## Clean up Kubernetes resources ##@ Kind Local Development -kind-up: check-kind check-kubectl ## Start kind cluster with Quay.io images (production-like) +kind-up: check-kind check-kubectl check-image-arch ## Start kind cluster with Quay.io images (production-like) @echo "$(COLOR_BLUE)▶$(COLOR_RESET) Starting kind cluster..." @cd e2e && CONTAINER_ENGINE=$(CONTAINER_ENGINE) ./scripts/setup-kind.sh @echo "$(COLOR_BLUE)▶$(COLOR_RESET) Waiting for API server to be accessible..." @@ -674,6 +674,23 @@ check-kubectl: ## Check if kubectl is installed @command -v kubectl >/dev/null 2>&1 || \ (echo "$(COLOR_RED)✗$(COLOR_RESET) kubectl not found. Install: https://kubernetes.io/docs/tasks/tools/" && exit 1) +check-image-arch: ## Verify overlay images are multi-arch compatible with host + @if [ "$(HOST_ARCH)" = "arm64" ] || [ "$(HOST_ARCH)" = "aarch64" ]; then \ + OVERLAY="components/manifests/overlays/kind/operator-env-patch.yaml"; \ + BAD=$$(grep -E 'value:.*quay\.io/' "$$OVERLAY" 2>/dev/null | grep -v 'quay\.io/ambient_code/' || true); \ + if [ -n "$$BAD" ]; then \ + echo "$(COLOR_RED)✗$(COLOR_RESET) arm64 host detected but kind overlay references non-multi-arch images:"; \ + echo "$$BAD" | sed 's/^/ /'; \ + echo ""; \ + echo " Images must come from quay.io/ambient_code/ (multi-arch)."; \ + echo " Fix: $(COLOR_BOLD)$$OVERLAY$(COLOR_RESET)"; \ + exit 1; \ + fi; \ + echo "$(COLOR_GREEN)✓$(COLOR_RESET) Image arch check passed (arm64 host, multi-arch images)"; \ + else \ + echo "$(COLOR_GREEN)✓$(COLOR_RESET) Image arch check passed (amd64 host)"; \ + fi + check-architecture: ## Validate build architecture matches host @echo "$(COLOR_BOLD)Architecture Check$(COLOR_RESET)" @echo " Host: $(HOST_OS) / $(HOST_ARCH)" @@ -700,21 +717,26 @@ _build-and-load: ## Internal: Build and load images @$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) -t $(OPERATOR_IMAGE) components/operator $(QUIET_REDIRECT) @echo " Building runner ($(PLATFORM))..." @$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) -t $(RUNNER_IMAGE) -f components/runners/claude-code-runner/Dockerfile components/runners $(QUIET_REDIRECT) + @echo " Building state-sync ($(PLATFORM))..." + @$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) -t $(STATE_SYNC_IMAGE) components/runners/state-sync $(QUIET_REDIRECT) @echo " Tagging images with localhost prefix..." @$(CONTAINER_ENGINE) tag $(BACKEND_IMAGE) localhost/$(BACKEND_IMAGE) 2>/dev/null || true @$(CONTAINER_ENGINE) tag $(FRONTEND_IMAGE) localhost/$(FRONTEND_IMAGE) 2>/dev/null || true @$(CONTAINER_ENGINE) tag $(OPERATOR_IMAGE) localhost/$(OPERATOR_IMAGE) 2>/dev/null || true @$(CONTAINER_ENGINE) tag $(RUNNER_IMAGE) localhost/$(RUNNER_IMAGE) 2>/dev/null || true + @$(CONTAINER_ENGINE) tag $(STATE_SYNC_IMAGE) localhost/$(STATE_SYNC_IMAGE) 2>/dev/null || true @echo " Loading images into minikube..." @mkdir -p /tmp/minikube-images @$(CONTAINER_ENGINE) save -o /tmp/minikube-images/backend.tar localhost/$(BACKEND_IMAGE) @$(CONTAINER_ENGINE) save -o /tmp/minikube-images/frontend.tar localhost/$(FRONTEND_IMAGE) @$(CONTAINER_ENGINE) save -o /tmp/minikube-images/operator.tar localhost/$(OPERATOR_IMAGE) @$(CONTAINER_ENGINE) save -o /tmp/minikube-images/runner.tar localhost/$(RUNNER_IMAGE) + @$(CONTAINER_ENGINE) save -o /tmp/minikube-images/state-sync.tar localhost/$(STATE_SYNC_IMAGE) @minikube image load /tmp/minikube-images/backend.tar $(QUIET_REDIRECT) @minikube image load /tmp/minikube-images/frontend.tar $(QUIET_REDIRECT) @minikube image load /tmp/minikube-images/operator.tar $(QUIET_REDIRECT) @minikube image load /tmp/minikube-images/runner.tar $(QUIET_REDIRECT) + @minikube image load /tmp/minikube-images/state-sync.tar $(QUIET_REDIRECT) @rm -rf /tmp/minikube-images @echo "$(COLOR_GREEN)✓$(COLOR_RESET) Images built and loaded" diff --git a/components/manifests/overlays/kind/operator-env-patch.yaml b/components/manifests/overlays/kind/operator-env-patch.yaml index b40d12735..77b8a0487 100644 --- a/components/manifests/overlays/kind/operator-env-patch.yaml +++ b/components/manifests/overlays/kind/operator-env-patch.yaml @@ -14,9 +14,9 @@ spec: # - operator: fsGroup:0 for volume permissions # - runner: minimal MCP config (webfetch only, faster startup) - name: AMBIENT_CODE_RUNNER_IMAGE - value: "quay.io/gkrumbach07/vteam_claude_runner:latest" + value: "quay.io/ambient_code/vteam_claude_runner:latest" - name: STATE_SYNC_IMAGE - value: "quay.io/gkrumbach07/vteam_state_sync:latest" + value: "quay.io/ambient_code/vteam_state_sync:latest" - name: IMAGE_PULL_POLICY value: "Always" - name: POD_FSGROUP diff --git a/docs/developer/local-development/README.md b/docs/developer/local-development/README.md index 0708363b8..0288bf499 100644 --- a/docs/developer/local-development/README.md +++ b/docs/developer/local-development/README.md @@ -1,248 +1,65 @@ # Local Development Environments -The Ambient Code Platform supports four local development approaches. **Kind is recommended** for most development and testing. +**Bottom line:** Use Kind. Run `make kind-up` and access at `http://localhost:8080`. Everything else on this page is for edge cases. -## Choose Your Approach +## Approaches -### 🐳 Kind (Kubernetes in Docker) - **RECOMMENDED** +| Approach | When to Use | Startup | Guide | +|----------|-------------|---------|-------| +| **Kind** | All development and testing (default) | ~30 sec | [kind.md](kind.md) | +| Hybrid | Rapid single-component iteration with IDE debugging | ~30 sec + manual | [hybrid.md](hybrid.md) | +| CRC | OpenShift-specific features (Routes, OAuth, BuildConfigs) | ~5-10 min | [crc.md](crc.md) | +| Minikube | Legacy fallback (deprecated) | ~2-3 min | [minikube.md](minikube.md) | -**Best for:** All development, E2E testing, CI/CD +### Kind (Recommended) -**Why Kind?** -- ⚡ **Fastest startup** (~30 seconds) -- 🎯 **Same as CI** - Tests run in Kind, develop in Kind -- 💨 **Lightweight** - Lower memory usage -- 🔄 **Quick iteration** - Fast to create/destroy clusters -- ✅ **Battle-tested** - Used by Kubernetes project itself +Matches CI exactly. Fastest startup. Lowest resource usage. -**Pros:** -- ⚡ Fast startup (~30 seconds) -- 🎯 Matches CI/CD environment exactly -- 💨 Lightweight and quick to reset -- 🔄 Multiple clusters easy -- ✅ Official Kubernetes project - -**Cons:** -- 📚 Requires basic Docker knowledge -- 🐳 Docker must be installed - -**Quick Start:** ```bash -make kind-up -# Access at http://localhost:8080 +make kind-up # Deploy with Quay.io images +make kind-port-forward # In another terminal +make test-e2e # Run tests +make kind-down # Cleanup ``` -**Full Guide:** [kind.md](kind.md) - ---- - -### 🚀 Minikube (Older Alternative) - -**Status:** ⚠️ Still supported but Kind is recommended for new development - -**Best for:** Beginners uncomfortable with Docker, Windows users - -**Best for:** First-time setup, general development, stable environment - -**Pros:** -- ✅ Mature and well-documented -- ✅ Works on all platforms (macOS, Linux, Windows) -- ✅ Simpler troubleshooting -- ✅ Stable driver support +### Hybrid -**Cons:** -- ⏱️ Slower startup (~2-3 minutes) -- 💾 Higher memory usage +Run one component locally (with IDE breakpoints) while Kind provides the cluster. -**Quick Start:** -```bash -make local-up -# Access at http://$(minikube ip):30030 -``` - -**Full Guide:** [minikube.md](minikube.md) - ---- - -### 🐳 Kind (Kubernetes in Docker) - -**Best for:** E2E testing, CI/CD, experienced Kubernetes developers - -**Pros:** -- ⚡ Fast startup (~30 seconds) -- 🎯 Same environment as CI/CD -- 💨 Lightweight and quick to reset -- 🔄 Multiple clusters easy - -**Cons:** -- 📚 Steeper learning curve -- 🐛 Less forgiving of configuration mistakes -- 🐳 Requires Docker knowledge - -**Quick Start:** ```bash make kind-up -make test-e2e -make kind-down +cd components/backend && go run . ``` -**Full Guide:** [kind.md](kind.md) - ---- - -### 🔴 OpenShift Local (CRC) (Specialized Use) +See [hybrid.md](hybrid.md). -**Status:** ⚠️ Use only when you need OpenShift-specific features +### CRC (OpenShift Local) -**Best for:** Testing OpenShift Routes, BuildConfigs, OAuth integration +Only needed for OpenShift Routes, BuildConfigs, or OAuth integration testing. -**Pros:** -- ✅ Full OpenShift features (Routes, BuildConfigs, OAuth) -- ✅ Production-like environment -- ✅ OpenShift console access -- ✅ Hot-reloading development mode - -**Cons:** -- ⏱️ Slower startup (~5-10 minutes first time) -- 💾 Higher resource requirements -- 🖥️ macOS and Linux only - -**Quick Start:** ```bash make dev-start # Access at https://vteam-frontend-vteam-dev.apps-crc.testing ``` -**Full Guide:** [crc.md](crc.md) - ---- - -### ⚡ Hybrid Local Development - -**Best for:** Rapid iteration on specific components - -**What it is:** Run components (frontend, backend, operator) locally on your machine while using Kind for dependencies (CRDs, MinIO). - -**Pros:** -- 🚀 Instant code reloads (no container rebuilds) -- 🐛 Direct debugging with IDE breakpoints -- ⚡ Fastest iteration cycle (seconds) - -**Cons:** -- 🔧 More manual setup -- 🧩 Need to manage multiple terminals -- 💻 Not suitable for integration testing - -**Quick Start:** -```bash -make kind-up -# Then run components locally (see guide) -``` - -**Full Guide:** [hybrid.md](hybrid.md) - ---- - -## Quick Comparison - -| Feature | **Kind (Recommended)** | Minikube | CRC | Hybrid | -|---------|------------------------|----------|-----|--------| -| **Status** | ✅ **Recommended** | ⚠️ Older | ⚠️ Specialized | Advanced | -| **Startup Time** | ⚡ ~30 sec | ~2-3 min | ~5-10 min | ~30 sec + manual | -| **Memory Usage** | Lower | Higher | Highest | Lowest | -| **CI/CD Match** | ✅ **Yes (exact!)** | No | No | No | -| **Learning Curve** | Moderate | Easier | Moderate | Advanced | -| **Code Iteration** | Moderate | Slow (rebuild) | Fast (hot-reload) | ⚡ Instant | -| **Debugging** | Logs only | Logs only | Logs only | ✅ IDE debugging | -| **OpenShift Features** | No | No | ✅ Yes | No | -| **Production-Like** | Good | Basic | ✅ Best | No | -| **Integration Testing** | ✅ **Best** | Yes | Yes | Limited | -| **E2E Testing** | ✅ **Required** | Yes | Yes | No | -| **Platform Support** | Linux/macOS | All | macOS/Linux | All | -| **Our CI Uses** | ✅ **Kind** | No | No | No | - -## Which Should I Use? - -### ⭐ Choose **Kind** (Recommended for 95% of use cases) -- 👋 You're new to the project → **Start with Kind** -- 🧪 You're writing or running E2E tests → **Use Kind** -- 🔄 You're working on any development → **Use Kind** -- ⚡ You value fast iteration → **Use Kind** -- 🎯 You want to match CI/CD environment → **Use Kind** - -**TL;DR:** Just use Kind. It's faster, lighter, and matches our CI environment. - ---- - -### Choose **Minikube** only if: -- 💻 You're on Windows (Kind doesn't work well on Windows) -- 🆘 Kind doesn't work on your machine for some reason -- 📚 You already have Minikube experience +See [crc.md](crc.md). -**Note:** Minikube is the older approach. We recommend migrating to Kind. +### Minikube (Deprecated) ---- +Still supported but Kind is recommended. See [minikube.md](minikube.md) for migration instructions. -### Choose **CRC** only if: -- 🔴 You **specifically** need OpenShift Routes (not Ingress) -- 🏗️ You're testing OpenShift BuildConfigs -- 🔐 You're developing OpenShift OAuth integration -- 🎛️ You need the OpenShift console +## Comparison -**Note:** CRC is for OpenShift-specific features only. If you don't need OpenShift features, use Kind. - ---- - -### Choose **Hybrid** if: -- 🚀 You're rapidly iterating on ONE component -- 🐛 You need to debug with IDE breakpoints -- ⚡ Container rebuild time is slowing you down -- 💪 You're very comfortable with Kubernetes - -## Getting Started - -### 👉 First Time Here? Use Kind! - -**Our recommendation for everyone:** - -```bash -# 1. Install Docker (if not already installed) -# 2. Start Kind cluster -make kind-up - -# 3. Verify -make test-e2e - -# Access at http://localhost:8080 -``` - -**Full guide:** [kind.md](kind.md) - -### Working on E2E Tests? -Use **Kind** - it's what CI uses: -```bash -make kind-up -make test-e2e -``` - -### Need OpenShift-Specific Features? -Use **CRC** only if you need Routes, BuildConfigs, etc: -```bash -make dev-start # CRC-based -``` - -### Need to Debug with Breakpoints? -Use **Hybrid** to run components locally: -```bash -make kind-up -cd components/backend && go run . -``` +| Feature | Kind | Hybrid | CRC | Minikube | +|---------|------|--------|-----|----------| +| Matches CI | Yes | No | No | No | +| Code iteration | Moderate | Instant | Fast (hot-reload) | Slow | +| IDE debugging | No | Yes | No | No | +| OpenShift features | No | No | Yes | No | +| Memory usage | Low | Lowest | High | Medium | +| Platform | Linux/macOS | All | macOS/Linux | All | -## Additional Resources +## See Also -- [Kind Quick Start](../../../QUICK_START.md) - 2-minute setup -- [Minikube Setup](minikube.md) - Older approach (deprecated) -- [Kind Development Guide](kind.md) - Using Kind for development and testing -- [CRC Development Guide](crc.md) - OpenShift Local development -- [Hybrid Development Guide](hybrid.md) - Running components locally -- [E2E Testing](../../testing/e2e-guide.md) - End-to-end test suite +- [Kind Development Guide](kind.md) - Full reference +- [E2E Testing](../../testing/e2e-guide.md) - Test suite documentation diff --git a/docs/developer/local-development/kind.md b/docs/developer/local-development/kind.md index 9496af018..3b5042160 100644 --- a/docs/developer/local-development/kind.md +++ b/docs/developer/local-development/kind.md @@ -1,8 +1,8 @@ # Local Development with Kind -Run the Ambient Code Platform locally using kind (Kubernetes in Podman/Docker) for development and testing. +**Bottom line:** `make kind-up` creates a local cluster with production images from Quay.io. Access at `http://localhost:8080` after running `make kind-port-forward`. Works natively on both Apple Silicon (arm64) and Intel (amd64). -> **Cluster Name**: `ambient-local` +> **Cluster Name**: `ambient-local` > **Default Engine**: Podman (use `CONTAINER_ENGINE=docker` for more stable networking on macOS) ## Quick Start @@ -260,6 +260,22 @@ lsof -i:8080 # Find what's using the port # Kill it or edit e2e/scripts/setup-kind.sh to use different ports ``` +### init-hydrate crashes on Apple Silicon + +**Symptom:** `init-hydrate` init container crashes with `lfstack.push invalid packing` or rclone segfaults. The runner pod stays in `Init:CrashLoopBackOff`. + +**Cause:** The `STATE_SYNC_IMAGE` is pointing to an amd64-only image that runs under QEMU emulation, hitting a known Go runtime bug. + +**Fix:** Ensure the kind overlay uses multi-arch images from `quay.io/ambient_code/`: +```bash +# Verify the operator is using the correct registry +kubectl get deployment agentic-operator -n ambient-code \ + -o jsonpath='{.spec.template.spec.containers[0].env}' | python3 -m json.tool | grep -A1 STATE_SYNC + +# Should show: quay.io/ambient_code/vteam_state_sync:latest +# If it shows gkrumbach07 or another registry, update the kind overlay and redeploy +``` + ### Build crashes with segmentation fault **Symptom:** `qemu: uncaught target signal 11 (Segmentation fault)` during Next.js build