← back to Dw Fleet Registry
rotate-and-deploy.sh — phased one-command driver (route/kamatera/unfreeze/deploy), dry-run default, no auto-chain
9f6548c356ce3818e20134173feffade6126147a · 2026-06-01 14:48:49 -0700 · Steve Abrams
Files touched
Diff
commit 9f6548c356ce3818e20134173feffade6126147a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jun 1 14:48:49 2026 -0700
rotate-and-deploy.sh — phased one-command driver (route/kamatera/unfreeze/deploy), dry-run default, no auto-chain
---
rotate-and-deploy.sh | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/rotate-and-deploy.sh b/rotate-and-deploy.sh
new file mode 100755
index 0000000..be67c9e
--- /dev/null
+++ b/rotate-and-deploy.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# rotate-and-deploy.sh — drives the dw_admin rotation finish + DW fleet rebuild deploy,
+# doing EVERYTHING except the 2 human-locked steps:
+# (H1) mint pw + `ALTER ROLE dw_admin` on Kamatera + Mac2 (you, in psql)
+# (H2) the go/no-go to touch compromised Kamatera (you, via the phase flags)
+#
+# Phases are EXPLICIT and never auto-chain. Dry-run unless --run. Aborts on first error.
+#
+# Usage:
+# DW_ADMIN_NEW_PW='…' ./rotate-and-deploy.sh route --run # after you ALTER ROLE: route-back + local restart + verify
+# ./rotate-and-deploy.sh kamatera --run # restart Kamatera fleet (--update-env) + verify [needs H2]
+# ./rotate-and-deploy.sh unfreeze --run # flip cncp prod flag compromised→ok [needs H2]
+# ./rotate-and-deploy.sh deploy --canary --run # merge+deploy ONLY 1890swallpaper, smoke-test [needs H2]
+# ./rotate-and-deploy.sh deploy --all --run # merge+deploy the other 64, smoke-test each [needs H2]
+set -uo pipefail
+
+PHASE="${1:-help}"; shift || true
+RUN=0; SCOPE=""
+for a in "$@"; do case "$a" in --run) RUN=1;; --canary) SCOPE=canary;; --all) SCOPE=all;; esac; done
+
+KAMATERA="root@45.61.58.125"
+SM="$HOME/Projects/secrets-manager/cli.js"
+CNCP="$HOME/cncp-starter/server.js"
+REG_DIR="$HOME/Projects/dw-fleet-registry"
+TARGETS="/tmp/fleet-targets.txt"
+BRANCH="style-rebuild-pilot"
+say(){ printf '\033[36m▸ %s\033[0m\n' "$*"; }
+do_(){ if [ "$RUN" = 1 ]; then echo " + $*"; eval "$@" || { echo " ✗ FAILED: $*"; exit 1; }; else echo " [dry] $*"; fi; }
+
+case "$PHASE" in
+route)
+ [ -n "${DW_ADMIN_NEW_PW:-}" ] || { echo "set DW_ADMIN_NEW_PW (the value you just ALTER ROLE'd to)"; exit 2; }
+ say "Phase ROUTE — fan new pw to env files + restart LOCAL consumers + verify"
+ do_ "printf 'DW_ADMIN_DB_PASSWORD=%s' \"\$DW_ADMIN_NEW_PW\" | node \"$SM\" import-paste"
+ do_ "pm2 restart wallco-ai-9905 --update-env"
+ do_ "node \"$SM\" check DW_ADMIN_DB_PASSWORD || true"
+ say "local routed. Kamatera fleet restart is the next phase (needs your go)."
+ ;;
+
+kamatera)
+ say "Phase KAMATERA — restart the prod fleet so it re-reads the rotated DSN [touches compromised host]"
+ do_ "ssh -o ConnectTimeout=8 $KAMATERA 'pm2 restart all --update-env'"
+ do_ "ssh -o ConnectTimeout=8 $KAMATERA 'pm2 ls | tail -40'"
+ ;;
+
+unfreeze)
+ say "Phase UNFREEZE — flip cncp prod flag compromised→ok (do ONLY after rotation verified)"
+ do_ "sed -i '' \"s/status: 'compromised', note: 'do-not-deploy — active incident'/status: 'ok', note: 'rotated $(date +%F)'/\" \"$CNCP\""
+ do_ "launchctl kickstart -k gui/\$(id -u)/com.user.cncp"
+ ;;
+
+deploy)
+ [ -n "$SCOPE" ] || { echo "specify --canary or --all"; exit 2; }
+ say "Phase DEPLOY ($SCOPE) — merge $BRANCH→main + push to Kamatera + smoke-test [touches prod]"
+ if [ "$SCOPE" = canary ]; then LIST="1890swallpaper"; else LIST=$(grep -v '^1890swallpaper$' "$TARGETS"); fi
+ for slug in $LIST; do
+ d="$HOME/Projects/$slug"; [ -d "$d/.git" ] || { echo " skip $slug (no repo)"; continue; }
+ say "deploy $slug"
+ do_ "git -C \"$d\" checkout main -q && git -C \"$d\" merge --no-edit $BRANCH -q"
+ # introspect Kamatera for this site's pm2 cwd, rsync public/+server.js, reload, smoke-test
+ do_ "bash \"$HOME/Projects/_shared/scripts/deploy.sh\" \"$d\""
+ done
+ say "DEPLOY $SCOPE complete."
+ ;;
+
+*)
+ cat <<EOF
+rotate-and-deploy.sh — phases (each explicit, dry-run unless --run):
+ route route-back new pw + restart local + verify (needs DW_ADMIN_NEW_PW; after you ALTER ROLE)
+ kamatera restart prod fleet --update-env (needs your go — compromised host)
+ unfreeze flip cncp prod flag compromised→ok
+ deploy --canary merge+deploy 1890swallpaper, smoke-test
+ deploy --all merge+deploy the other 64
+Human steps I can't do: (H1) ALTER ROLE dw_admin in psql, (H2) saying the box is safe.
+EOF
+ ;;
+esac
← ffa5ab5 fleet hero/ideas transform tool + deploy
·
back to Dw Fleet Registry
·
fix deploy phase: brace-delimit ${BRANCH} (set -u choked on 6253b68 →