257 lines
6.7 KiB
Bash
Executable File
257 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
BASE_DIR="${BASE_DIR:-/opt/aslan-test}"
|
|
SRC_DIR="${SRC_DIR:-$BASE_DIR/source/aslan-server}"
|
|
COMPOSE_FILE="${COMPOSE_FILE:-$BASE_DIR/docker-compose.yml}"
|
|
ENV_FILE="${ENV_FILE:-$BASE_DIR/config/.env}"
|
|
LOCK_FILE="${LOCK_FILE:-$BASE_DIR/deploy.lock}"
|
|
GIT_REMOTE_URL="${GIT_REMOTE_URL:-git@gitea.haiyihy.com:hy/aslan-server.git}"
|
|
GIT_REF="${GIT_REF:-aslan_test}"
|
|
ALLOWED_GIT_REFS="${ALLOWED_GIT_REFS:-aslan_test}"
|
|
MAVEN_GOALS="${MAVEN_GOALS:-clean package}"
|
|
MAVEN_PROFILE="${MAVEN_PROFILE:-prod}"
|
|
MAVEN_EXTRA_ARGS="${MAVEN_EXTRA_ARGS:-}"
|
|
SKIP_BUILD="${SKIP_BUILD:-0}"
|
|
MODE="${MODE:-compose}"
|
|
BUILD_TS="${BUILD_TS:-$(date +%Y%m%d%H%M%S)}"
|
|
|
|
ALL_SERVICES=(auth gateway external wallet order live other console)
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
deploy-likei-services.sh [--mode compose|build-only|status] [--skip-build] [--fast] [auth|gateway|external|wallet|order|live|other|console ...]
|
|
|
|
Examples:
|
|
/opt/aslan-test/deploy-likei-services.sh status
|
|
/opt/aslan-test/deploy-likei-services.sh other
|
|
/opt/aslan-test/deploy-likei-services.sh --fast other external console
|
|
GIT_REF=aslan_test /opt/aslan-test/deploy-likei-services.sh auth gateway external wallet order live other console
|
|
|
|
Notes:
|
|
- This is the single-machine test deployment flow.
|
|
- It pulls aslan_test, builds local aslan-test/* images, then replaces docker compose app containers.
|
|
- MySQL/Mongo/Redis/Nacos/RocketMQ are not rebuilt or restarted by this script.
|
|
EOF
|
|
}
|
|
|
|
log() {
|
|
printf '[%s] %s\n' "$(date '+%F %T')" "$*"
|
|
}
|
|
|
|
need_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
echo "missing command: $1" >&2
|
|
exit 2
|
|
}
|
|
}
|
|
|
|
acquire_deploy_lock() {
|
|
need_cmd flock
|
|
mkdir -p "$(dirname "$LOCK_FILE")"
|
|
exec 9>"$LOCK_FILE"
|
|
# The visual ops panel and manual SSH deploys share this lock so builds cannot interleave.
|
|
flock -n 9 || {
|
|
echo "another deploy is already running: $LOCK_FILE" >&2
|
|
exit 5
|
|
}
|
|
}
|
|
|
|
validate_git_ref() {
|
|
if [[ ! "$GIT_REF" =~ ^[A-Za-z0-9._/-]{1,80}$ || "$GIT_REF" == -* || "$GIT_REF" == *..* ]]; then
|
|
echo "invalid GIT_REF: $GIT_REF" >&2
|
|
exit 2
|
|
fi
|
|
local allowed
|
|
for allowed in $ALLOWED_GIT_REFS; do
|
|
[[ "$GIT_REF" == "$allowed" ]] && return 0
|
|
done
|
|
echo "GIT_REF is not allowed for test deploy: $GIT_REF (allowed: $ALLOWED_GIT_REFS)" >&2
|
|
exit 2
|
|
}
|
|
|
|
service_module() {
|
|
case "$1" in
|
|
auth) echo "rc-auth" ;;
|
|
gateway) echo "rc-gateway" ;;
|
|
external) echo "rc-service/rc-service-external/external-start" ;;
|
|
wallet) echo "rc-service/rc-service-wallet/wallet-start" ;;
|
|
order) echo "rc-service/rc-service-order/order-start" ;;
|
|
live) echo "rc-service/rc-service-live/live-start" ;;
|
|
other) echo "rc-service/rc-service-other/other-start" ;;
|
|
console) echo "rc-service/rc-service-console/console-start" ;;
|
|
*) echo "unsupported service: $1" >&2; exit 2 ;;
|
|
esac
|
|
}
|
|
|
|
service_dir() {
|
|
case "$1" in
|
|
auth) echo "rc-auth" ;;
|
|
gateway) echo "rc-gateway" ;;
|
|
external) echo "rc-service/rc-service-external" ;;
|
|
wallet) echo "rc-service/rc-service-wallet" ;;
|
|
order) echo "rc-service/rc-service-order" ;;
|
|
live) echo "rc-service/rc-service-live" ;;
|
|
other) echo "rc-service/rc-service-other" ;;
|
|
console) echo "rc-service/rc-service-console" ;;
|
|
*) echo "unsupported service: $1" >&2; exit 2 ;;
|
|
esac
|
|
}
|
|
|
|
service_image() {
|
|
case "$1" in
|
|
auth|gateway|external|wallet|order|live|other|console) echo "aslan-test/$1:latest" ;;
|
|
*) echo "unsupported service: $1" >&2; exit 2 ;;
|
|
esac
|
|
}
|
|
|
|
contains_service() {
|
|
local needle="$1"
|
|
local item
|
|
for item in "${ALL_SERVICES[@]}"; do
|
|
[[ "$item" == "$needle" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
update_source_from_git() {
|
|
need_cmd git
|
|
validate_git_ref
|
|
[[ -d "$SRC_DIR/.git" ]] || { echo "missing git source: $SRC_DIR" >&2; exit 2; }
|
|
|
|
log "reset source to origin/$GIT_REF from $GIT_REMOTE_URL"
|
|
git -C "$SRC_DIR" remote set-url origin "$GIT_REMOTE_URL"
|
|
git -C "$SRC_DIR" fetch origin "$GIT_REF"
|
|
git -C "$SRC_DIR" checkout -B "$GIT_REF" "origin/$GIT_REF"
|
|
git -C "$SRC_DIR" reset --hard "origin/$GIT_REF"
|
|
}
|
|
|
|
package_services() {
|
|
local services=("$@")
|
|
local modules=()
|
|
local svc
|
|
for svc in "${services[@]}"; do
|
|
modules+=("$(service_module "$svc")")
|
|
done
|
|
local module_csv
|
|
module_csv="$(IFS=,; echo "${modules[*]}")"
|
|
|
|
if [[ "$SKIP_BUILD" == "1" ]]; then
|
|
log "skip maven build"
|
|
return
|
|
fi
|
|
|
|
cd "$SRC_DIR"
|
|
log "maven $MAVEN_GOALS -pl $module_csv -P $MAVEN_PROFILE"
|
|
# The test compose stack still reads the prod-profile Nacos configs; use -P prod unless the caller overrides it.
|
|
# shellcheck disable=SC2086
|
|
mvn $MAVEN_GOALS -pl "$module_csv" -am -P "$MAVEN_PROFILE" -Dmaven.test.skip=true $MAVEN_EXTRA_ARGS
|
|
}
|
|
|
|
build_image() {
|
|
local svc="$1"
|
|
local dir image
|
|
dir="$(service_dir "$svc")"
|
|
image="$(service_image "$svc")"
|
|
cd "$SRC_DIR"
|
|
log "docker build $image"
|
|
docker build \
|
|
--build-arg "SERVICE_VERSION=aslan-test:${svc}-${BUILD_TS}" \
|
|
-f "$dir/Dockerfile" \
|
|
-t "$image" \
|
|
"$dir"
|
|
}
|
|
|
|
compose_up() {
|
|
local services=("$@")
|
|
cd "$BASE_DIR"
|
|
log "docker compose recreate: ${services[*]}"
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d --no-deps --force-recreate "${services[@]}"
|
|
}
|
|
|
|
status() {
|
|
log "source"
|
|
git -C "$SRC_DIR" status -sb || true
|
|
git -C "$SRC_DIR" log -1 --oneline --decorate || true
|
|
log "compose"
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps --format table
|
|
}
|
|
|
|
main() {
|
|
local services=()
|
|
while [[ "$#" -gt 0 ]]; do
|
|
case "$1" in
|
|
--mode)
|
|
[[ -n "${2:-}" ]] || { echo "--mode requires an argument" >&2; exit 2; }
|
|
MODE="$2"
|
|
shift 2
|
|
;;
|
|
--skip-build)
|
|
SKIP_BUILD=1
|
|
shift
|
|
;;
|
|
--fast)
|
|
MAVEN_GOALS=package
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
status)
|
|
MODE=status
|
|
shift
|
|
;;
|
|
*)
|
|
services+=("$1")
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
need_cmd git
|
|
need_cmd docker
|
|
[[ -f "$COMPOSE_FILE" ]] || { echo "missing compose file: $COMPOSE_FILE" >&2; exit 2; }
|
|
[[ -f "$ENV_FILE" ]] || { echo "missing env file: $ENV_FILE" >&2; exit 2; }
|
|
|
|
if [[ "$MODE" == "status" ]]; then
|
|
status
|
|
exit 0
|
|
fi
|
|
|
|
need_cmd java
|
|
need_cmd mvn
|
|
acquire_deploy_lock
|
|
update_source_from_git
|
|
|
|
if [[ "${#services[@]}" -eq 0 ]]; then
|
|
services=("${ALL_SERVICES[@]}")
|
|
fi
|
|
local svc
|
|
for svc in "${services[@]}"; do
|
|
contains_service "$svc" || { echo "unsupported service: $svc" >&2; exit 2; }
|
|
done
|
|
|
|
package_services "${services[@]}"
|
|
for svc in "${services[@]}"; do
|
|
build_image "$svc"
|
|
done
|
|
|
|
case "$MODE" in
|
|
compose)
|
|
compose_up "${services[@]}"
|
|
;;
|
|
build-only)
|
|
log "build-only completed: ${services[*]}"
|
|
;;
|
|
*)
|
|
echo "unsupported MODE: $MODE" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
status
|
|
}
|
|
|
|
main "$@"
|