spark-server/deploy/docker/lib.sh
2026-09-22 17:07:26 +08:00

161 lines
4.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Shared SSH paths and remote deploy/rollback helpers for ECS.
set -euo pipefail
deploy_lib_root() {
local here
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$here/../.." && pwd
}
deploy_lib_init() {
ROOT="$(deploy_lib_root)"
HOST="${SPARK_SSH_HOST:-root@47.236.66.9}"
KEY="${SPARK_SSH_KEY:-$HOME/.ssh/spark-ecs}"
DATA="${SPARK_DATA_DIR:-/data/spark-server}"
IMAGE_BASE="${SPARK_IMAGE_BASE:-spark-server}"
IMAGE_LATEST="${IMAGE_BASE}:latest"
ROLLBACK_TAG="${IMAGE_BASE}:rollback"
SSH=(ssh -i "$KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$HOST")
SCP=(scp -i "$KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new)
}
deploy_lib_release() {
local root="${1:?}"
if [[ -n "${SPARK_RELEASE:-}" ]]; then
printf '%s' "$SPARK_RELEASE"
return
fi
local sha
sha="$(git -C "$root" rev-parse --short HEAD 2>/dev/null || echo manual)"
printf '%s-%s' "$sha" "$(date +%Y%m%d%H%M%S)"
}
deploy_lib_need_tools() {
local t
for t in go docker rsync ssh scp curl; do
command -v "$t" >/dev/null || {
echo "need $t on this machine" >&2
exit 1
}
done
}
# Tag spark-server:latest as :rollback on the host before overwriting latest.
deploy_lib_remote_stamp_rollback() {
local data="${1:?}"
"${SSH[@]}" bash -s "$data" "$ROLLBACK_TAG" "$IMAGE_LATEST" <<'EOS'
set -euo pipefail
DATA="$1"
ROLLBACK_TAG="$2"
LATEST="$3"
mkdir -p "$DATA/releases" "$DATA/configs/backup"
if docker image inspect "$LATEST" >/dev/null 2>&1; then
docker tag "$LATEST" "$ROLLBACK_TAG"
docker image inspect "$LATEST" --format '{{.Id}}' >"$DATA/releases/previous_image_id"
date -Iseconds >"$DATA/releases/previous_stamped_at"
fi
if [[ -f "$DATA/configs/config.yaml" ]]; then
cp -a "$DATA/configs/config.yaml" "$DATA/configs/backup/config.yaml.$(date +%Y%m%d%H%M%S)"
fi
EOS
}
deploy_lib_remote_load_and_up() {
local data="${1:?}" tar_path="${2:?}" run_migrate="${3:-1}" release_tag="${4:-}"
"${SSH[@]}" bash -s "$data" "$tar_path" "$IMAGE_LATEST" "$run_migrate" "$release_tag" "$IMAGE_BASE" <<'EOS'
set -euo pipefail
DATA="$1"
TAR="$2"
LATEST="$3"
RUN_MIGRATE="$4"
RELEASE_TAG="$5"
IMAGE_BASE="$6"
chown -R 10001:10001 "$DATA/logs"
docker load -i "$TAR"
if [[ -n "$RELEASE_TAG" ]]; then
docker tag "${IMAGE_BASE}:${RELEASE_TAG}" "$LATEST"
else
loaded="$(docker image ls --format '{{.Repository}}:{{.Tag}}' | grep "^${IMAGE_BASE}:" | grep -v rollback | grep -v latest | head -1)"
if [[ -n "$loaded" ]]; then
docker tag "$loaded" "$LATEST"
fi
fi
docker rm -f spark-server 2>/dev/null || true
cd "$DATA/compose"
docker compose -f docker-compose.yaml up -d --force-recreate spark-server
for i in $(seq 1 30); do
if docker exec spark-server wget -qO- http://127.0.0.1:8080/healthz >/dev/null 2>&1; then
break
fi
sleep 2
done
if [[ "$RUN_MIGRATE" == "1" ]]; then
docker exec spark-server /usr/local/bin/spark-migrate -config /app/configs/config.yaml -dir /app/migrations
fi
EOS
}
deploy_lib_remote_health() {
local attempts="${1:-12}" sleep_s="${2:-5}"
local i
for ((i = 1; i <= attempts; i++)); do
if "${SSH[@]}" "curl -fsS http://127.0.0.1:18080/healthz >/dev/null && curl -fsS http://127.0.0.1:18080/readyz >/dev/null"; then
return 0
fi
sleep "$sleep_s"
done
return 1
}
deploy_lib_remote_rollback() {
local data="${1:?}"
"${SSH[@]}" bash -s "$data" "$ROLLBACK_TAG" "$IMAGE_LATEST" <<'EOS'
set -euo pipefail
DATA="$1"
ROLLBACK_TAG="$2"
LATEST="$3"
if ! docker image inspect "$ROLLBACK_TAG" >/dev/null 2>&1; then
echo "no rollback image ($ROLLBACK_TAG); load a previous tar from $DATA/images/ manually" >&2
exit 1
fi
docker tag "$ROLLBACK_TAG" "$LATEST"
docker rm -f spark-server 2>/dev/null || true
cd "$DATA/compose"
docker compose -f docker-compose.yaml up -d --force-recreate spark-server
EOS
}
deploy_lib_remote_write_manifest() {
local data="${1:?}" release="${2:?}" tar_name="${3:?}" status="${4:?}"
"${SSH[@]}" bash -s "$data" "$release" "$tar_name" "$status" "$IMAGE_LATEST" <<'EOS'
set -euo pipefail
DATA="$1"
RELEASE="$2"
TAR_NAME="$3"
STATUS="$4"
LATEST="$5"
ID="$(docker image inspect "$LATEST" --format '{{.Id}}' 2>/dev/null || echo unknown)"
PREV_ID=""
[[ -f "$DATA/releases/previous_image_id" ]] && PREV_ID="$(cat "$DATA/releases/previous_image_id")"
cat >"$DATA/releases/manifest.json" <<JSON
{
"status": "$STATUS",
"release": "$RELEASE",
"image_id": "$ID",
"previous_image_id": "$PREV_ID",
"image_tar": "$DATA/images/$TAR_NAME",
"deployed_at": "$(date -Iseconds)"
}
JSON
EOS
}
deploy_lib_remote_nginx_reload() {
"${SSH[@]}" "cp /tmp/spark-nginx-host/spark-sni.conf /etc/nginx/stream.d/spark-sni.conf && if [ -f /etc/letsencrypt/live/sparkr.wyrs365.com/fullchain.pem ]; then cp /tmp/spark-nginx-host/sparkr.conf /etc/nginx/conf.d/sparkr.conf; fi && nginx -t && systemctl reload nginx"
}
deploy_lib_remote_ps() {
"${SSH[@]}" "docker ps --filter name=spark-server --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
}