161 lines
4.8 KiB
Bash
Executable File
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}}'"
|
|
}
|