1
0
mirror of git://f0xx.org/ac/ac-scripts synced 2026-07-29 01:38:08 +03:00
Files
ac-scripts/full_deployment.sh
Anton Afanasyeu 8927c65f63 refactor(deploy): delegate SFU phase to cluster deploy-janus-sfu.sh
Replace inline Janus/rsync steps with the shared cluster script on cast01–03.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 22:12:02 +02:00

211 lines
7.1 KiB
Bash
Executable File

#!/bin/sh
# full_deployment.sh — Full backend cluster deployment for Android Cast
#
# Usage:
# ./ac-scripts/full_deployment.sh [OPTIONS]
#
# Options:
# --phase baseline|db|app|sfu|all (default: all)
# --host cast01|cast02|cast03|all (default: all)
# --dry-run Print commands without executing
# --no-color Disable color output
# -h|--help
#
# This script:
# 1. Pulls latest ac/* repos on each node (git pull + submodule update)
# 2. Runs populate_lab_setup.sh phases on each node via SSH
# 3. Runs Janus SFU deployment on cast02 (phase sfu)
# 4. Reloads nginx on cast01
# 5. Runs load-schemas.sh to apply any new SQL migrations
#
# Prerequisites:
# - SSH passwordless access to cast01, cast02, cast03
# - /mnt/repos/ac checkout on each node
#
set -eu
# ── Helpers ──────────────────────────────────────────────────────────
RED='\033[0;31m'; GRN='\033[0;32m'; YEL='\033[1;33m'; BLU='\033[0;34m'; RST='\033[0m'
if [ "${NO_COLOR:-}" = "1" ] || [ "${1:-}" = "--no-color" ]; then
RED=''; GRN=''; YEL=''; BLU=''; RST=''
fi
log() { printf "%b[%s]%b %s\n" "$BLU" "$(date '+%H:%M:%S')" "$RST" "$*"; }
ok() { printf "%b[OK]%b %s\n" "$GRN" "$RST" "$*"; }
warn() { printf "%b[WARN]%b %s\n" "$YEL" "$RST" "$*"; }
fail() { printf "%b[FAIL]%b %s\n" "$RED" "$RST" "$*" >&2; exit 1; }
DRY=0
PHASE="all"
TARGET_HOST="all"
while [ $# -gt 0 ]; do
case "$1" in
--dry-run) DRY=1 ;;
--no-color) : ;;
--phase) shift; PHASE="${1:?phase value required}" ;;
--host) shift; TARGET_HOST="${1:?host value required}" ;;
-h|--help)
sed -n '2,30p' "$0" | sed 's/^# //'
exit 0 ;;
*) warn "Unknown option: $1" ;;
esac
shift
done
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DEPLOY_DIR="$(cd "${SCRIPT_DIR}/../ac-deploy/sim/cluster0" && pwd)"
NODES="cast01 cast02 cast03"
rsh() {
local host="$1"; shift
if [ "$DRY" = "1" ]; then
log "[DRY] ssh $host $*"
return 0
fi
ssh "$host" "$@"
}
on_host() {
local host="$1"
[ "$TARGET_HOST" = "all" ] || [ "$TARGET_HOST" = "$host" ]
}
# ── Phase helpers ────────────────────────────────────────────────────
phase_sync() {
local host="$1"
log "$host: pulling latest ac/* repos..."
rsh "$host" "cd /mnt/repos/ac && git fetch origin && git checkout next && git pull && git submodule update --init --recursive 2>&1 | tail -5"
# Sync critical cluster files from git repo to NFS share (scripts + nginx templates only)
rsh "$host" "
SRC=/mnt/repos/ac/ac-deploy/sim/cluster0
DST=/shared/cluster
[ -d \"\$SRC\" ] || exit 0
for f in nginx/apps-port80.conf nginx/url-shortener-port80.conf \
scripts/load-schemas.sh scripts/configure-nginx.sh \
scripts/deploy-ac-workspace.sh; do
[ -f \"\$SRC/\$f\" ] && sudo cp \"\$SRC/\$f\" \"\$DST/\$f\" 2>/dev/null || true
done
sudo cp -r \"\$SRC/lab-seeds/backend/sql/migrations/\" \"\$DST/lab-seeds/backend/sql/migrations/\" 2>/dev/null || true
"
ok "$host: sync done"
}
phase_baseline() {
local host="$1"
log "$host: running baseline..."
rsh "$host" "cd /mnt/repos/ac/ac-deploy/sim/cluster0 && sudo sh populate_lab_setup.sh --phase baseline 2>&1 | tail -10"
ok "$host: baseline done"
}
phase_db() {
local host="$1"
log "$host: running DB setup..."
rsh "$host" "cd /mnt/repos/ac/ac-deploy/sim/cluster0 && sudo sh populate_lab_setup.sh --phase db 2>&1 | tail -10"
ok "$host: DB done"
}
phase_workspace_bump() {
# Bump ac-workspace submodule SHAs from the monorepo clone so the deployment
# workspace (/var/www/ac/workspace) gets the latest code on next pull.
local host="$1"
rsh "$host" "
WS=/var/www/ac/workspace
MONOREPO=/mnt/repos/ac
[ -d \"\$WS/.git\" ] || exit 0
changed=0
for sub in \$(sudo -u nginx git -C \"\$WS\" submodule status 2>/dev/null | awk '{print \$2}'); do
local_sha=\$(git -C \"\$MONOREPO/\$sub\" rev-parse HEAD 2>/dev/null) || continue
ws_sha=\$(sudo -u nginx git -C \"\$WS/\$sub\" rev-parse HEAD 2>/dev/null) || continue
[ \"\$local_sha\" = \"\$ws_sha\" ] && continue
sudo -u nginx git -C \"\$WS/\$sub\" fetch origin 2>/dev/null || true
sudo -u nginx git -C \"\$WS/\$sub\" checkout \"\$local_sha\" 2>/dev/null || true
sudo -u nginx git -C \"\$WS\" add \"\$sub\" 2>/dev/null || true
changed=1
done
[ \"\$changed\" = '1' ] && sudo -u nginx git -C \"\$WS\" commit -m 'auto-bump submodules from monorepo' 2>/dev/null || true
sudo -u nginx git -C \"\$WS\" push origin next 2>/dev/null || true
" 2>/dev/null || true
}
phase_app() {
local host="$1"
log "$host: running app deploy..."
phase_workspace_bump "$host"
rsh "$host" "cd /mnt/repos/ac/ac-deploy/sim/cluster0 && sudo sh populate_lab_setup.sh --phase app 2>&1 | tail -10"
ok "$host: app done"
}
phase_sfu() {
log "Deploying Janus SFU (cluster script)..."
rsh cast02 "sudo sh /shared/cluster/scripts/deploy-janus-sfu.sh" \
&& ok "cast02: Janus SFU deployed" \
|| warn "cast02: deploy-janus-sfu failed"
for h in cast01 cast03; do
rsh "$h" "sudo sh /shared/cluster/scripts/deploy-janus-sfu.sh" \
&& ok "$h: SFU signaling/nginx OK" \
|| warn "$h: deploy-janus-sfu failed"
done
}
phase_nginx_reload() {
log "cast01: reloading nginx..."
rsh cast01 "sudo /usr/sbin/nginx -t && sudo rc-service nginx reload 2>&1 | tail -2"
ok "cast01: nginx reloaded"
}
phase_verify() {
log "Running cluster verification..."
rsh cast01 "cd /mnt/repos/ac/ac-deploy/sim/cluster0 && sh scripts/verify-cluster.sh 2>&1 | tail -20" || warn "verify-cluster returned non-zero"
}
# ── Main ─────────────────────────────────────────────────────────────
log "=== Android Cast Full Deployment ==="
log "Phase: $PHASE | Hosts: $TARGET_HOST | Dry: $DRY"
echo ""
case "$PHASE" in
baseline)
for h in $NODES; do
on_host "$h" && { phase_sync "$h"; phase_baseline "$h"; }
done ;;
db)
for h in $NODES; do
on_host "$h" && { phase_sync "$h"; phase_db "$h"; }
done ;;
app)
for h in $NODES; do
on_host "$h" && { phase_sync "$h"; phase_app "$h"; }
done
on_host cast01 && phase_nginx_reload ;;
sfu)
phase_sync cast02
phase_sync cast01
phase_sfu ;;
all)
# 1. Sync all nodes
for h in $NODES; do
on_host "$h" && phase_sync "$h"
done
# 2. Baseline on all
for h in $NODES; do
on_host "$h" && phase_baseline "$h"
done
# 3. DB on cast01 (primary + replicas follow)
on_host cast01 && phase_db cast01
# 4. App on all nodes
for h in $NODES; do
on_host "$h" && phase_app "$h"
done
# 5. SFU
phase_sfu
# 6. Verify
on_host cast01 && phase_verify ;;
*)
fail "Unknown phase: $PHASE (use: baseline|db|app|sfu|all)" ;;
esac
echo ""
ok "=== Deployment complete (phase=$PHASE) ==="