Files
endorphin-aster-vm/scripts/deploy-ces-control.sh
T
codex-bot 9648b9e8dd
Verify databases and deploy Aster VM / verify-and-deploy (push) Waiting to run
Initialize Aster VM and deploy PostgreSQL host on ces-control
2026-10-17 23:42:39 +08:00

73 lines
2.6 KiB
Bash

#!/bin/sh
# Deploy only the image produced after the remote database checks succeed.
set -eu
cd "$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
test "$(id -u)" -eq 0 || { echo "Deployment requires root on ces-control" >&2; exit 1; }
release_sha=${ASTER_RELEASE_SHA:?ASTER_RELEASE_SHA is required}
case "$release_sha" in *[!0-9a-f]*|'') echo "Invalid release SHA" >&2; exit 1;; esac
test "${#release_sha}" -eq 40
image="endorphin-aster-vm:$release_sha"
docker image inspect "$image" >/dev/null
umask 077
root=/opt/endorphin-aster-vm
config=/etc/endorphin-aster-vm/production.env
release="$root/releases/$release_sha"
mkdir -p "$release" /etc/endorphin-aster-vm /var/lib/endorphin-aster-vm/postgres
exec 9>/var/lock/endorphin-aster-vm-deploy.lock
flock 9
if [ ! -f "$config" ]; then
password=$(openssl rand -hex 24)
printf 'POSTGRES_PASSWORD=%s\nASTER_PORT=18081\n' "$password" > "$config"
unset password
fi
chmod 600 "$config"
cp docker-compose.ces-control.yml "$release/compose.yml"
printf 'ASTER_IMAGE=%s\n' "$image" > "$release/release.env"
previous=$(readlink -f "$root/current" 2>/dev/null || true)
compose_at() {
location=$1
shift
docker compose -p endorphin-aster-vm --env-file "$config" \
--env-file "$location/release.env" -f "$location/compose.yml" "$@"
}
rollback() {
echo "Deployment failed; application data has been retained" >&2
if [ -n "$previous" ] && [ "$previous" != "$release" ] && [ -f "$previous/compose.yml" ]; then
echo "Restoring the previously healthy release" >&2
compose_at "$previous" up -d --no-build --wait --wait-timeout 180 || true
fi
}
if ! compose_at "$release" up -d --no-build --wait --wait-timeout 180; then
rollback
exit 1
fi
if ! compose_at "$release" exec -T aster aster metadata put deployment.release "$release_sha"; then
rollback
exit 1
fi
if ! actual=$(compose_at "$release" exec -T aster aster metadata get deployment.release); then
rollback
exit 1
fi
if [ "$actual" != "$release_sha" ]; then
rollback
exit 1
fi
if ! health=$(compose_at "$release" exec -T aster curl --fail --silent http://127.0.0.1:8080/health); then
rollback
exit 1
fi
printf '%s' "$health" | python3 -c 'import json,sys; d=json.load(sys.stdin); assert d == {"status":"ok", "storage":"postgresql"}' || {
rollback
exit 1
}
ln -sfn "$release" "$root/current.next"
mv -Tf "$root/current.next" "$root/current"
compose_at "$release" ps
echo "Deployed release=$release_sha backend=postgresql endpoint=127.0.0.1:18081"
echo "Persistent PostgreSQL data: /var/lib/endorphin-aster-vm/postgres"