#!/bin/bash # Full deployment: mcpd image → k8s rollout → RPM build/publish/install # # Production runtime is Kubernetes (context: worker0-k8s0, namespace: mcpctl). # The docker-compose stack under stack/ + deploy/ is kept for local/VM testing # only and is no longer invoked from here. # # Infra (Deployment shape, env, RBAC, NetworkPolicies) is managed by Pulumi # in ../kubernetes-deployment. This script runs `pulumi preview` before the # rollout; if there is infra drift it halts so you can `pulumi up` first. set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # Load .env if [ -f .env ]; then set -a; source .env; set +a fi KUBE_CONTEXT="${KUBE_CONTEXT:-worker0-k8s0}" KUBE_NAMESPACE="${KUBE_NAMESPACE:-mcpctl}" KUBE_DEPLOYMENT="${KUBE_DEPLOYMENT:-mcpd}" PULUMI_DIR="${PULUMI_DIR:-$SCRIPT_DIR/../kubernetes-deployment}" PULUMI_STACK="${PULUMI_STACK:-homelab}" echo "========================================" echo " mcpctl Full Deploy" echo "========================================" # --- Pre-flight: Pulumi drift check --- # Uses the kubernetes-deployment/scripts/pulumi.sh wrapper which pulls # PULUMI_CONFIG_PASSPHRASE from OpenBao at runtime, so the passphrase # never needs to live in .env or shell history. Falls back to a warning # if the wrapper isn't present (older clone of kubernetes-deployment). echo "" echo ">>> Pre-flight: checking for Pulumi infra drift" echo "" if [ -d "$PULUMI_DIR" ] && [ -x "$PULUMI_DIR/scripts/pulumi.sh" ]; then preview_output=$("$PULUMI_DIR/scripts/pulumi.sh" preview --stack "$PULUMI_STACK" --non-interactive --diff 2>&1) || true if echo "$preview_output" | grep -qE '^\s+[-+~]'; then echo "$preview_output" echo "" echo "ERROR: Pulumi detected infra changes that have not been applied." echo " Run: $PULUMI_DIR/scripts/pulumi.sh up -s $PULUMI_STACK" echo " Then re-run this script." exit 1 fi echo " No drift — infra is in sync." elif [ -d "$PULUMI_DIR" ]; then echo " WARNING: $PULUMI_DIR/scripts/pulumi.sh not found or not executable —" echo " skipping drift check. Pull latest kubernetes-deployment." else echo " WARNING: Pulumi repo not found at $PULUMI_DIR — skipping drift check." fi echo "" echo ">>> Step 1/4: Build & push mcpd Docker image" echo "" bash scripts/build-mcpd.sh "$@" echo "" echo ">>> Step 2/4: Build & push mcplocal (HTTP-mode) Docker image" echo "" bash scripts/build-mcplocal.sh "$@" echo "" echo ">>> Step 3/4: Roll out mcpd + mcplocal on k8s ($KUBE_CONTEXT / $KUBE_NAMESPACE)" echo "" kubectl --context "$KUBE_CONTEXT" -n "$KUBE_NAMESPACE" rollout restart "deployment/$KUBE_DEPLOYMENT" kubectl --context "$KUBE_CONTEXT" -n "$KUBE_NAMESPACE" rollout status "deployment/$KUBE_DEPLOYMENT" --timeout=3m if kubectl --context "$KUBE_CONTEXT" -n "$KUBE_NAMESPACE" get deployment/mcplocal >/dev/null 2>&1; then kubectl --context "$KUBE_CONTEXT" -n "$KUBE_NAMESPACE" rollout restart deployment/mcplocal kubectl --context "$KUBE_CONTEXT" -n "$KUBE_NAMESPACE" rollout status deployment/mcplocal --timeout=3m else echo " NOTE: deployment/mcplocal does not exist in the cluster yet — skipping rollout." echo " Apply the Pulumi stack in ../kubernetes-deployment to create it." fi echo "" echo ">>> Step 4/4: Build, publish & install RPM" echo "" bash scripts/release.sh echo "" echo ">>> Post-deploy: Restart mcplocal" echo "" systemctl --user restart mcplocal sleep 2 echo "" echo ">>> Post-deploy: Smoke tests" echo "" export PATH="$HOME/.npm-global/bin:$PATH" if pnpm test:smoke; then echo " Smoke tests passed!" else echo " WARNING: Smoke tests failed! Verify mcplocal + mcpd are healthy." fi echo "" echo "========================================" echo " Full deploy complete!" echo "========================================"