diff --git a/Makefile b/Makefile index 705168fc..842a32cc 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,10 @@ NAMESPACE := streamspace HELM_RELEASE := streamspace KUBE_CONTEXT := $(shell kubectl config current-context) +# Paths +PROJECT_ROOT := $(shell pwd) +CHART_PATH := $(PROJECT_ROOT)/chart + # Build configuration GO_VERSION := 1.21 NODE_VERSION := 18 @@ -197,19 +201,22 @@ docker-build-multiarch: ## Build multi-architecture images (amd64, arm64) helm-lint: ## Lint Helm chart @echo "$(COLOR_GREEN)Linting Helm chart...$(COLOR_RESET)" - @helm lint chart/ + @echo "$(COLOR_YELLOW)Chart: $(CHART_PATH)$(COLOR_RESET)" + @helm lint $(CHART_PATH) @echo "$(COLOR_GREEN)✓ Helm chart is valid$(COLOR_RESET)" helm-template: ## Render Helm templates (dry-run) @echo "$(COLOR_GREEN)Rendering Helm templates...$(COLOR_RESET)" - @helm template $(HELM_RELEASE) chart/ --namespace $(NAMESPACE) + @echo "$(COLOR_YELLOW)Chart: $(CHART_PATH)$(COLOR_RESET)" + @helm template $(HELM_RELEASE) $(CHART_PATH) --namespace $(NAMESPACE) helm-install: ## Install StreamSpace using Helm @echo "$(COLOR_GREEN)Installing StreamSpace...$(COLOR_RESET)" @echo "$(COLOR_YELLOW)Context: $(KUBE_CONTEXT)$(COLOR_RESET)" @echo "$(COLOR_YELLOW)Namespace: $(NAMESPACE)$(COLOR_RESET)" + @echo "$(COLOR_YELLOW)Chart: $(CHART_PATH)$(COLOR_RESET)" @kubectl create namespace $(NAMESPACE) --dry-run=client -o yaml | kubectl apply -f - - @helm install $(HELM_RELEASE) chart/ \ + @helm install $(HELM_RELEASE) $(CHART_PATH) \ --namespace $(NAMESPACE) \ --set controller.image.tag=$(VERSION) \ --set api.image.tag=$(VERSION) \ @@ -221,7 +228,8 @@ helm-install: ## Install StreamSpace using Helm helm-upgrade: ## Upgrade StreamSpace Helm release @echo "$(COLOR_GREEN)Upgrading StreamSpace...$(COLOR_RESET)" - @helm upgrade $(HELM_RELEASE) chart/ \ + @echo "$(COLOR_YELLOW)Chart: $(CHART_PATH)$(COLOR_RESET)" + @helm upgrade $(HELM_RELEASE) $(CHART_PATH) \ --namespace $(NAMESPACE) \ --set controller.image.tag=$(VERSION) \ --set api.image.tag=$(VERSION) \ diff --git a/chart/.helmignore b/chart/.helmignore index 399b0840..6b0c1aea 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -39,7 +39,6 @@ Thumbs.db # Test and docs *.md !README.md -!Chart.yaml test/ tests/ *.test diff --git a/scripts/DEPLOYMENT_TROUBLESHOOTING.md b/scripts/DEPLOYMENT_TROUBLESHOOTING.md new file mode 100644 index 00000000..44e105d9 --- /dev/null +++ b/scripts/DEPLOYMENT_TROUBLESHOOTING.md @@ -0,0 +1,229 @@ +# Helm Deployment Troubleshooting Guide + +## Issue: "Chart.yaml file is missing" Error + +If you're encountering the error `Error: INSTALLATION FAILED: Chart.yaml file is missing` when running `./local-deploy.sh`, this guide provides solutions. + +## Quick Solution: Use Alternative Deployment Script + +We've created an alternative deployment script that packages the chart first, which avoids path resolution issues: + +```bash +./scripts/local-deploy-alt.sh +``` + +This script: +- Packages the Helm chart into a `.tgz` file before installation +- Eliminates path resolution issues +- Follows Helm best practices +- Works consistently across all environments + +## Diagnostic Approach: Enhanced Debugging + +The main `local-deploy.sh` script now includes comprehensive debugging output: + +```bash +./scripts/local-deploy.sh +``` + +This will show: +1. **Helm version** - Identifies version-specific issues +2. **Chart path** - Fully resolved absolute path +3. **Chart.yaml existence** - Verifies file is accessible +4. **Directory contents** - Lists all chart files +5. **Helm lint results** - Validates chart structure +6. **Chart packaging test** - Tests if Helm can package the chart +7. **Debug output** - Full Helm operation details with `--debug` flag + +## Common Causes and Solutions + +### 1. Path Resolution Issues + +**Symptom:** Chart.yaml exists but Helm can't find it + +**Solution:** Use absolute paths (already fixed in latest version) + +```bash +# Now uses fully resolved path +CHART_PATH="$(cd "${PROJECT_ROOT}/chart" && pwd)" +``` + +### 2. Helm Version Compatibility + +**Symptom:** Error varies by Helm version + +**Solution:** Check your Helm version: + +```bash +helm version +``` + +Recommended: Helm 3.8+ for best compatibility + +### 3. Chart Structure Issues + +**Symptom:** Helm lint fails + +**Solution:** Verify chart structure: + +```bash +chart/ +├── Chart.yaml # Chart metadata +├── values.yaml # Default values +├── templates/ # Kubernetes templates +│ ├── _helpers.tpl # Template helpers +│ └── *.yaml # Resource templates +└── crds/ # Custom Resource Definitions + └── *.yaml +``` + +### 4. Permission Issues + +**Symptom:** Can't read chart files + +**Solution:** Check file permissions: + +```bash +ls -la chart/ +ls -la chart/Chart.yaml +``` + +All files should be readable (r-- permission). + +### 5. Working Directory Issues + +**Symptom:** Error when running from different directories + +**Solution:** Both scripts now handle this correctly. Run from any directory: + +```bash +# From project root +./scripts/local-deploy.sh + +# From scripts directory +./local-deploy.sh +``` + +## Makefile Fixes + +If using `make helm-install`, the Makefile now uses absolute paths: + +```bash +make helm-install +``` + +The Makefile will display the resolved chart path for debugging. + +## Manual Installation Steps + +If both scripts fail, try manual installation: + +```bash +# 1. Navigate to project root +cd /path/to/streamspace + +# 2. Create namespace +kubectl create namespace streamspace + +# 3. Apply CRDs manually +kubectl apply -f chart/crds/ + +# 4. Package chart +helm package chart/ -d /tmp + +# 5. Install from package +helm install streamspace /tmp/streamspace-*.tgz \ + --namespace streamspace \ + --set controller.image.tag=local \ + --set controller.image.pullPolicy=Never \ + --set api.image.tag=local \ + --set api.image.pullPolicy=Never \ + --set ui.image.tag=local \ + --set ui.image.pullPolicy=Never \ + --wait +``` + +## Verification Steps + +After deployment, verify the installation: + +```bash +# Check Helm release status +helm status streamspace -n streamspace + +# Check pods +kubectl get pods -n streamspace + +# Check CRDs +kubectl get crds | grep streamspace + +# View Helm release values +helm get values streamspace -n streamspace +``` + +## Debugging Commands + +### Check Helm can access the chart + +```bash +helm lint chart/ +helm template streamspace chart/ > /tmp/rendered-templates.yaml +helm package chart/ -d /tmp +``` + +### Check kubectl connectivity + +```bash +kubectl cluster-info +kubectl get nodes +kubectl get namespaces +``` + +### View Helm debug output + +```bash +helm install streamspace chart/ \ + --namespace streamspace \ + --dry-run \ + --debug +``` + +## Getting Help + +If you're still experiencing issues: + +1. **Capture full output:** + ```bash + ./scripts/local-deploy.sh 2>&1 | tee deployment-debug.log + ``` + +2. **Check the logs** in `deployment-debug.log` for: + - Helm version + - Chart path resolution + - Lint results + - Error messages + +3. **Try alternative script:** + ```bash + ./scripts/local-deploy-alt.sh + ``` + +4. **Report issue** with: + - Helm version (`helm version`) + - Kubernetes version (`kubectl version`) + - OS and architecture + - Full debug output + - Contents of chart/ directory (`ls -laR chart/`) + +## Related Changes + +- ✅ Fixed `.helmignore` to remove confusing `!Chart.yaml` line +- ✅ Updated Makefile to use `CHART_PATH` variable with absolute paths +- ✅ Enhanced `local-deploy.sh` with comprehensive debugging +- ✅ Created `local-deploy-alt.sh` as alternative package-based approach + +## References + +- [Helm Charts Documentation](https://helm.sh/docs/topics/charts/) +- [Helm Install Command](https://helm.sh/docs/helm/helm_install/) +- [Debugging Helm Charts](https://helm.sh/docs/chart_template_guide/debugging/) diff --git a/scripts/local-deploy-alt.sh b/scripts/local-deploy-alt.sh new file mode 100755 index 00000000..725a7c48 --- /dev/null +++ b/scripts/local-deploy-alt.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash +# +# local-deploy-alt.sh - Alternative Helm deployment approach +# +# This script packages the chart first, then installs from the package. +# This avoids potential path resolution issues with chart directories. +# + +set -euo pipefail + +# Colors for output +COLOR_RESET='\033[0m' +COLOR_BOLD='\033[1m' +COLOR_GREEN='\033[32m' +COLOR_YELLOW='\033[33m' +COLOR_BLUE='\033[34m' +COLOR_RED='\033[31m' + +# Project configuration +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +NAMESPACE="${NAMESPACE:-streamspace}" +RELEASE_NAME="${RELEASE_NAME:-streamspace}" +VERSION="${VERSION:-local}" + +# Helm chart location +CHART_DIR="${PROJECT_ROOT}/chart" +PACKAGE_DIR="${PROJECT_ROOT}/.helm-packages" + +# Helper functions +log() { + echo -e "${COLOR_BOLD}==>${COLOR_RESET} $*" +} + +log_success() { + echo -e "${COLOR_GREEN}✓${COLOR_RESET} $*" +} + +log_error() { + echo -e "${COLOR_RED}✗${COLOR_RESET} $*" >&2 +} + +log_info() { + echo -e "${COLOR_BLUE}→${COLOR_RESET} $*" +} + +log_warning() { + echo -e "${COLOR_YELLOW}⚠${COLOR_RESET} $*" +} + +# Main execution +main() { + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" + echo -e "${COLOR_BOLD} StreamSpace Alternative Deployment${COLOR_RESET}" + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" + echo "" + echo -e "${COLOR_BLUE}Strategy:${COLOR_RESET} Package-first installation" + echo -e "${COLOR_BLUE}Namespace:${COLOR_RESET} ${NAMESPACE}" + echo -e "${COLOR_BLUE}Release:${COLOR_RESET} ${RELEASE_NAME}" + echo -e "${COLOR_BLUE}Version:${COLOR_RESET} ${VERSION}" + echo "" + + # Create package directory + log "Creating package directory..." + mkdir -p "${PACKAGE_DIR}" + log_success "Package directory ready: ${PACKAGE_DIR}" + + # Package the chart + log "Packaging Helm chart..." + log_info "Chart directory: ${CHART_DIR}" + + cd "${PROJECT_ROOT}" + local package_file=$(helm package "${CHART_DIR}" -d "${PACKAGE_DIR}" --version "${VERSION}" | grep -oE '[^ ]+\.tgz$') + + if [ -z "${package_file}" ] || [ ! -f "${package_file}" ]; then + log_error "Failed to package chart" + exit 1 + fi + + log_success "Chart packaged: ${package_file}" + + # Create namespace + log "Creating namespace: ${NAMESPACE}" + kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f - + log_success "Namespace ready" + + # Apply CRDs manually (Helm doesn't upgrade CRDs automatically) + log "Applying CRDs..." + kubectl apply -f "${CHART_DIR}/crds/" + log_success "CRDs applied" + + # Install or upgrade from package + log "Deploying StreamSpace from package..." + + if helm status "${RELEASE_NAME}" -n "${NAMESPACE}" &> /dev/null; then + log_info "Release exists, upgrading..." + helm upgrade "${RELEASE_NAME}" "${package_file}" \ + --namespace "${NAMESPACE}" \ + --set controller.image.tag="${VERSION}" \ + --set controller.image.pullPolicy=Never \ + --set api.image.tag="${VERSION}" \ + --set api.image.pullPolicy=Never \ + --set ui.image.tag="${VERSION}" \ + --set ui.image.pullPolicy=Never \ + --set postgresql.enabled=true \ + --set postgresql.auth.password=streamspace \ + --wait \ + --timeout 5m + else + log_info "Installing fresh release..." + helm install "${RELEASE_NAME}" "${package_file}" \ + --namespace "${NAMESPACE}" \ + --create-namespace \ + --set controller.image.tag="${VERSION}" \ + --set controller.image.pullPolicy=Never \ + --set api.image.tag="${VERSION}" \ + --set api.image.pullPolicy=Never \ + --set ui.image.tag="${VERSION}" \ + --set ui.image.pullPolicy=Never \ + --set postgresql.enabled=true \ + --set postgresql.auth.password=streamspace \ + --wait \ + --timeout 5m + fi + + log_success "Helm deployment complete" + + # Wait for pods + log "Waiting for pods to be ready..." + sleep 5 + kubectl wait --for=condition=ready pod \ + -l app.kubernetes.io/name=streamspace \ + -n "${NAMESPACE}" \ + --timeout=300s 2>/dev/null || log_warning "Some pods may still be starting" + + # Show status + echo "" + log "Deployment Status:" + echo "" + log_info "Pods:" + kubectl get pods -n "${NAMESPACE}" + echo "" + log_info "Services:" + kubectl get svc -n "${NAMESPACE}" + echo "" + + # Access instructions + echo "" + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" + echo -e "${COLOR_BOLD} Access Instructions${COLOR_RESET}" + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" + echo "" + log_info "Port-forward UI:" + echo " kubectl port-forward -n ${NAMESPACE} svc/${RELEASE_NAME}-ui 3000:80" + echo " Then access: http://localhost:3000" + echo "" + log_info "Port-forward API:" + echo " kubectl port-forward -n ${NAMESPACE} svc/${RELEASE_NAME}-api 8000:8000" + echo "" + log_info "View logs:" + echo " kubectl logs -n ${NAMESPACE} -l app.kubernetes.io/component=controller -f" + echo "" + log_info "Cleanup:" + echo " ./scripts/local-teardown.sh" + echo "" + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" + log_success "Deployment complete!" + echo -e "${COLOR_BOLD}═══════════════════════════════════════════════════${COLOR_RESET}" +} + +# Run main function +main "$@" diff --git a/scripts/local-deploy.sh b/scripts/local-deploy.sh index 833e3ef9..975d442f 100755 --- a/scripts/local-deploy.sh +++ b/scripts/local-deploy.sh @@ -22,8 +22,8 @@ NAMESPACE="${NAMESPACE:-streamspace}" RELEASE_NAME="${RELEASE_NAME:-streamspace}" VERSION="${VERSION:-local}" -# Helm chart location -CHART_PATH="${PROJECT_ROOT}/chart" +# Helm chart location - use absolute path +CHART_PATH="$(cd "${PROJECT_ROOT}/chart" && pwd)" # Helper functions log() { @@ -60,6 +60,10 @@ check_prerequisites() { exit 1 fi + # Check Helm version + local helm_version=$(helm version --short 2>/dev/null || echo "unknown") + log_info "Helm version: ${helm_version}" + if ! kubectl cluster-info &> /dev/null; then log_error "Cannot connect to Kubernetes cluster" log_info "Make sure your kubeconfig is properly configured" @@ -119,6 +123,31 @@ apply_crds() { deploy_helm() { log "Deploying StreamSpace with Helm..." + # Debug output + log_info "Chart path: ${CHART_PATH}" + log_info "Chart.yaml exists: $(test -f "${CHART_PATH}/Chart.yaml" && echo "YES" || echo "NO")" + log_info "Chart directory contents:" + ls -la "${CHART_PATH}/" 2>&1 | head -10 + + # Validate chart with helm lint + log_info "Validating chart with helm lint..." + if ! helm lint "${CHART_PATH}"; then + log_error "Helm chart validation failed!" + exit 1 + fi + log_success "Chart validation passed" + + # Test if Helm can package the chart + log_info "Testing chart packaging..." + local temp_dir=$(mktemp -d) + if helm package "${CHART_PATH}" -d "${temp_dir}" &> /dev/null; then + log_success "Chart packaging test passed" + rm -rf "${temp_dir}" + else + log_warning "Chart packaging test failed (may not be critical)" + rm -rf "${temp_dir}" + fi + # Check if release exists if helm status "${RELEASE_NAME}" -n "${NAMESPACE}" &> /dev/null; then log_info "Release exists, upgrading..." @@ -136,6 +165,7 @@ deploy_helm() { --timeout 5m else log_info "Installing fresh release..." + log_info "Running: helm install ${RELEASE_NAME} ${CHART_PATH}" helm install "${RELEASE_NAME}" "${CHART_PATH}" \ --namespace "${NAMESPACE}" \ --create-namespace \ @@ -147,6 +177,7 @@ deploy_helm() { --set ui.image.pullPolicy=Never \ --set postgresql.enabled=true \ --set postgresql.auth.password=streamspace \ + --debug \ --wait \ --timeout 5m fi