2026-03-02 05:16:58 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
# dd0c Watch Loop (replaces the old git pull + docker compose up loop)
|
|
|
|
|
# Run this on the NAS: watch -n300 './watch-loop.sh'
|
|
|
|
|
# Or as a cron: */5 * * * * cd ~/services/dd0c/products && ./watch-loop.sh >> /tmp/dd0c-watch.log 2>&1
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
cd "$SCRIPT_DIR"
|
|
|
|
|
|
2026-03-02 13:31:11 +00:00
|
|
|
REGISTRY="${REGISTRY:-reg.dd0c.net}"
|
2026-03-02 05:16:58 +00:00
|
|
|
LOCK="/tmp/dd0c-watch.lock"
|
|
|
|
|
|
|
|
|
|
# Prevent concurrent runs
|
|
|
|
|
if [ -f "$LOCK" ]; then
|
|
|
|
|
PID=$(cat "$LOCK")
|
|
|
|
|
if kill -0 "$PID" 2>/dev/null; then
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') Already running (pid $PID), skipping"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
echo $$ > "$LOCK"
|
|
|
|
|
trap 'rm -f "$LOCK"' EXIT
|
|
|
|
|
|
|
|
|
|
# Pull latest code
|
|
|
|
|
BEFORE=$(git rev-parse HEAD 2>/dev/null || echo "none")
|
|
|
|
|
git pull --ff-only 2>/dev/null || { echo "$(date -u '+%H:%M:%S') git pull failed"; exit 1; }
|
|
|
|
|
AFTER=$(git rev-parse HEAD 2>/dev/null || echo "none")
|
|
|
|
|
|
|
|
|
|
if [ "$BEFORE" = "$AFTER" ]; then
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') No changes"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') New commits: $BEFORE → $AFTER"
|
|
|
|
|
|
|
|
|
|
# Detect which products changed
|
|
|
|
|
CHANGED=$(git diff --name-only "$BEFORE" "$AFTER" 2>/dev/null || echo "")
|
|
|
|
|
|
|
|
|
|
declare -A SERVICES=(
|
|
|
|
|
["02-iac-drift-detection"]="dd0c-drift:02-iac-drift-detection/saas"
|
|
|
|
|
["03-alert-intelligence"]="dd0c-alert:03-alert-intelligence"
|
|
|
|
|
["04-lightweight-idp"]="dd0c-portal:04-lightweight-idp"
|
|
|
|
|
["05-aws-cost-anomaly"]="dd0c-cost:05-aws-cost-anomaly"
|
|
|
|
|
["06-runbook-automation"]="dd0c-run:06-runbook-automation/saas"
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-02 05:40:02 +00:00
|
|
|
echo "secret" | docker login "$REGISTRY" --username dd0c --password-stdin 2>/dev/null || true
|
2026-03-02 05:16:58 +00:00
|
|
|
REBUILT=0
|
|
|
|
|
for prefix in "${!SERVICES[@]}"; do
|
|
|
|
|
if echo "$CHANGED" | grep -q "products/$prefix/"; then
|
|
|
|
|
IFS=: read -r img ctx <<< "${SERVICES[$prefix]}"
|
|
|
|
|
TAG="${REGISTRY}/${img}:latest"
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') Building $img..."
|
2026-03-02 13:53:15 +00:00
|
|
|
if docker build -t "$TAG" --build-arg BUILD_SHA=$(git rev-parse --short HEAD) --build-arg BUILD_TIME=$(date -u +%Y%m%dT%H%M%S) "./$ctx" --no-cache && docker push "$TAG"; then
|
2026-03-02 05:16:58 +00:00
|
|
|
echo "$(date -u '+%H:%M:%S') ✓ $img pushed"
|
|
|
|
|
((REBUILT++)) || true
|
|
|
|
|
else
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') ✗ $img build failed"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [ "$REBUILT" -gt 0 ]; then
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') Deploying $REBUILT service(s)..."
|
|
|
|
|
docker compose pull
|
|
|
|
|
docker compose up -d
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') Done"
|
|
|
|
|
else
|
|
|
|
|
# Still might need compose changes (new infra services, env vars, etc.)
|
|
|
|
|
if echo "$CHANGED" | grep -q "docker-compose.yml"; then
|
|
|
|
|
echo "$(date -u '+%H:%M:%S') Compose file changed, redeploying..."
|
|
|
|
|
docker compose up -d
|
|
|
|
|
fi
|
|
|
|
|
fi
|