fix: correct Woodpecker CI v2 format (no pipeline wrapper, when blocks)
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy DCOS to Kubernetes (standalone pipeline, mirrors stonks-oracle pattern)
|
||||
# Usage: runmefirst.sh
|
||||
# Detects existing deploy and adds/updates; idempotent.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
NAMESPACE="dcos-service"
|
||||
REPO_DIR="$HOME/sources/sama/sama"
|
||||
KUBE_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
GHCR="ghcr.io/celesrenata/dcos"
|
||||
|
||||
# --- Secrets ---
|
||||
# All secrets are read from ~/sources/kube/dcos/ on the deploy host.
|
||||
# This directory is NOT a git repo — secrets stay local to the deploy host.
|
||||
#
|
||||
# Required files:
|
||||
# /run/secrets/github_token (for GHCR push/pull)
|
||||
# ~/sources/kube/dcos/postgres.password (PG password for dcos user)
|
||||
# ~/sources/kube/dcos/redis.password (Redis password)
|
||||
|
||||
_read_secret() {
|
||||
local file="$1"
|
||||
local default="${2:-}"
|
||||
if [ -f "$file" ]; then
|
||||
cat "$file" | tr -d '[:space:]'
|
||||
elif [ -n "$default" ]; then
|
||||
echo "$default"
|
||||
else
|
||||
echo "ERROR: Secret file not found: $file" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
GHCR_TOKEN=$(_read_secret /run/secrets/github_token)
|
||||
PG_PASSWORD=$(_read_secret "$KUBE_DIR/postgres.password")
|
||||
REDIS_PASSWORD=$(_read_secret "$KUBE_DIR/redis.password")
|
||||
|
||||
# Compute git SHA for image tagging (same pattern as stonks-oracle Makefile)
|
||||
SHA=$(git -C "$REPO_DIR" rev-parse --short HEAD 2>/dev/null || echo "dev")
|
||||
|
||||
echo "=== DCOS Deployment ==="
|
||||
echo "Namespace: $NAMESPACE"
|
||||
echo "Image: $GHCR:$SHA"
|
||||
echo "Repo: $REPO_DIR"
|
||||
echo "Secrets: $KUBE_DIR"
|
||||
|
||||
# --- 0. Pull latest code ---
|
||||
echo "[0/6] Pulling latest code..."
|
||||
git -C "$REPO_DIR" pull --ff-only || echo "WARNING: git pull failed — using existing code"
|
||||
|
||||
# Force-pull the image on all gremlin nodes to avoid stale cache (IfNotPresent uses local)
|
||||
echo "[0.5/6] Forcing fresh image pull on cluster nodes..."
|
||||
for node in $(kubectl get nodes -o name 2>/dev/null | sed 's/node\.//'); do
|
||||
echo " Pulling on $node..."
|
||||
kubectl debug node/$node --image=busybox:1.36 -- chroot /host sh -c "docker rmi ghcr.io/celesrenata/dcos:$SHA 2>/dev/null; docker pull ghcr.io/celesrenata/dcos:$SHA" || true
|
||||
done
|
||||
|
||||
# --- 1. Ensure namespace exists with correct labels ---
|
||||
echo "[1/6] Ensuring namespace $NAMESPACE exists..."
|
||||
if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then
|
||||
kubectl create namespace "$NAMESPACE"
|
||||
fi
|
||||
kubectl label namespace "$NAMESPACE" app.kubernetes.io/managed-by=Helm --overwrite
|
||||
kubectl annotate namespace "$NAMESPACE" meta.helm.sh/release-name=dcos meta.helm.sh/release-namespace=$NAMESPACE --overwrite
|
||||
|
||||
# --- 2. Build and push image ---
|
||||
echo "[2/6] Building DCOS image..."
|
||||
docker build \
|
||||
--build-arg "SERVICE_CMD=python -m dcos.core --init" \
|
||||
-t $GHCR:$SHA \
|
||||
-t $GHCR:latest \
|
||||
-f "$REPO_DIR/docker/Dockerfile.dcos" "$REPO_DIR" || {
|
||||
echo "ERROR: Docker build failed." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "Pushing image..."
|
||||
if ! echo "$GHCR_TOKEN" | docker login ghcr.io -u celesrenata --password-stdin >/dev/null 2>&1; then
|
||||
echo "WARNING: GHCR login failed — token may be expired or missing scopes." >&2
|
||||
echo " Ensure /run/secrets/github_token has 'read:packages' scope." >&2
|
||||
echo " Generate a new token at: https://github.com/settings/tokens" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker push $GHCR:$SHA
|
||||
docker push $GHCR:latest
|
||||
|
||||
# --- 3. Create/update GHCR pull secret and DB secrets ---
|
||||
echo "[3/6] Creating/updating GHCR credentials and database secrets..."
|
||||
|
||||
# Force-recreate the GHCR pull secret so pods can authenticate to pull images
|
||||
kubectl delete secret ghcr-credentials -n "$NAMESPACE" --ignore-not-found
|
||||
kubectl create secret docker-registry ghcr-credentials \
|
||||
--namespace="$NAMESPACE" \
|
||||
--docker-server=ghcr.io \
|
||||
--docker-username=celesrenata \
|
||||
--docker-password="$GHCR_TOKEN" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
# Read MinIO credentials (same as stonks-oracle)
|
||||
MINIO_ACCESS_KEY=$(_read_secret "$KUBE_DIR/minio.access_key" "AKIA6V7J3N9B5P0D2YQH")
|
||||
MINIO_SECRET_KEY=$(_read_secret "$KUBE_DIR/minio.secret_key" "8fG3!v2rJ7\$wN@9mLpQ6zXbC4tKdPqW1")
|
||||
|
||||
kubectl delete secret dcos-db-secret -n "$NAMESPACE" --ignore-not-found
|
||||
kubectl create secret generic dcos-db-secret \
|
||||
--namespace="$NAMESPACE" \
|
||||
--from-literal=POSTGRES_PASSWORD="$PG_PASSWORD" \
|
||||
--from-literal=REDIS_PASSWORD="$REDIS_PASSWORD" \
|
||||
--from-literal=MINIO_ACCESS_KEY="$MINIO_ACCESS_KEY" \
|
||||
--from-literal=MINIO_SECRET_KEY="$MINIO_SECRET_KEY" \
|
||||
--from-literal=MINIO_ENDPOINT="minio-crawler-console:9090"
|
||||
|
||||
# --- 3.5. Apply middleware (Traefik dependency, no version label to update) ---
|
||||
echo "[3.5/6] Applying Traefik middleware..."
|
||||
kubectl apply -f "$KUBE_DIR/middleware.yaml" -n "$NAMESPACE"
|
||||
|
||||
# --- 4. Apply PVCs (for SQLite fallback tiers: long_term, semantic, episodic) ---
|
||||
echo "[4/6] Applying PVCs..."
|
||||
kubectl apply -f "$KUBE_DIR/pvc.yaml" -n "$NAMESPACE"
|
||||
|
||||
# --- 5. Apply deployment manifests (inject SHA into image tag and version labels) ---
|
||||
echo "[5/6] Applying K8s manifests..."
|
||||
|
||||
# Temporarily inject the SHA-based image tag and version labels
|
||||
DEPLOY_TMP=$(mktemp)
|
||||
sed -e "s|ghcr.io/celesrenata/dcos:[0-9.]*|$GHCR:$SHA|" \
|
||||
-e 's|app.kubernetes.io/version: "[0-9.]*"|app.kubernetes.io/version: "'"$SHA"'"|' \
|
||||
"$KUBE_DIR/deployment.yaml" > "$DEPLOY_TMP"
|
||||
|
||||
kubectl apply -f "$DEPLOY_TMP" -n "$NAMESPACE"
|
||||
rm -f "$DEPLOY_TMP"
|
||||
|
||||
# Also update version labels in service.yaml and ingress.yaml
|
||||
SVC_TMP=$(mktemp)
|
||||
sed -e 's|app.kubernetes.io/version: "[0-9.]*"|app.kubernetes.io/version: "'"$SHA"'"|' \
|
||||
"$KUBE_DIR/service.yaml" > "$SVC_TMP"
|
||||
kubectl apply -f "$SVC_TMP" -n "$NAMESPACE"
|
||||
rm -f "$SVC_TMP"
|
||||
|
||||
INGRESS_TMP=$(mktemp)
|
||||
sed -e 's|app.kubernetes.io/version: "[0-9.]*"|app.kubernetes.io/version: "'"$SHA"'"|' \
|
||||
"$KUBE_DIR/ingress.yaml" > "$INGRESS_TMP"
|
||||
kubectl apply -f "$INGRESS_TMP" -n "$NAMESPACE"
|
||||
rm -f "$INGRESS_TMP"
|
||||
|
||||
kubectl apply -f "$KUBE_DIR/serviceaccount.yaml" -n "$NAMESPACE"
|
||||
|
||||
# --- 6. Rolling restart to pick up new image ---
|
||||
echo "[6/6] Rolling restart..."
|
||||
kubectl rollout restart deployment/dcos -n "$NAMESPACE"
|
||||
|
||||
echo ""
|
||||
echo "=== Deployment complete ==="
|
||||
echo "Waiting for pods..."
|
||||
sleep 10
|
||||
kubectl get pods -n "$NAMESPACE" -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[0].ready,STATUS:.status.phase,RESTARTS:.status.containerStatuses[0].restartCount'
|
||||
echo ""
|
||||
echo "Ingress endpoints:"
|
||||
kubectl get ingress -n "$NAMESPACE" -o custom-columns='HOST:.spec.rules[0].host,ADDRESS:.status.loadBalancer.ingress[0].ip' 2>/dev/null || echo " (no ingress found)"
|
||||
Reference in New Issue
Block a user