mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-30 17:03:49 +00:00
fix: updates detection logic
This commit is contained in:
@@ -203,7 +203,7 @@ Use this workflow to build locally, then push the same stack to a remote host:
|
|||||||
```
|
```
|
||||||
(Answer “y” to the rebuild prompt in `setup.sh`, or run the rebuild manually.)
|
(Answer “y” to the rebuild prompt in `setup.sh`, or run the rebuild manually.)
|
||||||
|
|
||||||
2. **Package & Push for Remote Deploy**
|
2. **Package & Push for Remote Deploy** *(also available via the interactive `./deploy.sh` prompt by choosing “Remote host”)*
|
||||||
```bash
|
```bash
|
||||||
./deploy.sh --yes \
|
./deploy.sh --yes \
|
||||||
--remote-host docker-server \
|
--remote-host docker-server \
|
||||||
@@ -233,7 +233,7 @@ ssh docker-server '
|
|||||||
./setup.sh --module-config sam --playerbot-max-bots 3000
|
./setup.sh --module-config sam --playerbot-max-bots 3000
|
||||||
./scripts/rebuild-with-modules.sh --yes
|
./scripts/rebuild-with-modules.sh --yes
|
||||||
```
|
```
|
||||||
2. **Migrate Stack to Remote**
|
2. **Migrate Stack to Remote** *(select “Remote host” when running `./deploy.sh` interactively, or call it non-interactively as shown below)*
|
||||||
```bash
|
```bash
|
||||||
./deploy.sh --yes \
|
./deploy.sh --yes \
|
||||||
--remote-host docker-server \
|
--remote-host docker-server \
|
||||||
|
|||||||
27
build.sh
27
build.sh
@@ -185,6 +185,17 @@ detect_rebuild_reasons(){
|
|||||||
reasons+=("Module changes detected (sentinel file present)")
|
reasons+=("Module changes detected (sentinel file present)")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if source repository is freshly cloned (no previous build state)
|
||||||
|
local storage_path
|
||||||
|
storage_path="$(read_env STORAGE_PATH_LOCAL "./local-storage")"
|
||||||
|
if [[ "$storage_path" != /* ]]; then
|
||||||
|
storage_path="$ROOT_DIR/$storage_path"
|
||||||
|
fi
|
||||||
|
local last_deployed="$storage_path/modules/.last_deployed"
|
||||||
|
if [ ! -f "$last_deployed" ]; then
|
||||||
|
reasons+=("Fresh source repository setup - initial build required")
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if any C++ modules are enabled but modules-latest images don't exist
|
# Check if any C++ modules are enabled but modules-latest images don't exist
|
||||||
local any_cxx_modules=0
|
local any_cxx_modules=0
|
||||||
local var
|
local var
|
||||||
@@ -209,7 +220,9 @@ detect_rebuild_reasons(){
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf '%s\n' "${reasons[@]}"
|
if [ ${#reasons[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "${reasons[@]}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
confirm_build(){
|
confirm_build(){
|
||||||
@@ -217,7 +230,17 @@ confirm_build(){
|
|||||||
|
|
||||||
if [ ${#reasons[@]} -eq 0 ] && [ "$FORCE_REBUILD" = "0" ]; then
|
if [ ${#reasons[@]} -eq 0 ] && [ "$FORCE_REBUILD" = "0" ]; then
|
||||||
info "No build required - all images are up to date"
|
info "No build required - all images are up to date"
|
||||||
return 1 # No build needed
|
if [ "$ASSUME_YES" -ne 1 ] && [ -t 0 ]; then
|
||||||
|
local reply
|
||||||
|
read -r -p "Build anyway? [y/N]: " reply
|
||||||
|
reply="${reply:-n}"
|
||||||
|
case "$reply" in
|
||||||
|
[Yy]*) return 0 ;; # Proceed with build
|
||||||
|
*) return 1 ;; # Skip build
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
return 1 # No build needed (non-interactive or --yes flag)
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Skip duplicate output if called from deploy.sh (reasons already shown)
|
# Skip duplicate output if called from deploy.sh (reasons already shown)
|
||||||
|
|||||||
161
deploy.sh
161
deploy.sh
@@ -24,6 +24,7 @@ REMOTE_PORT="22"
|
|||||||
REMOTE_IDENTITY=""
|
REMOTE_IDENTITY=""
|
||||||
REMOTE_PROJECT_DIR=""
|
REMOTE_PROJECT_DIR=""
|
||||||
REMOTE_SKIP_STORAGE=0
|
REMOTE_SKIP_STORAGE=0
|
||||||
|
REMOTE_ARGS_PROVIDED=0
|
||||||
|
|
||||||
COMPILE_MODULE_VARS=(
|
COMPILE_MODULE_VARS=(
|
||||||
MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE
|
MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE
|
||||||
@@ -58,6 +59,141 @@ show_realm_ready(){
|
|||||||
printf '%b\n\n' "${GREEN}🗡️ May your server bring epic adventures!${NC}"
|
printf '%b\n\n' "${GREEN}🗡️ May your server bring epic adventures!${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
show_remote_plan(){
|
||||||
|
local plan_host="${REMOTE_HOST:-<host>}"
|
||||||
|
local plan_user="${REMOTE_USER:-<user>}"
|
||||||
|
local plan_dir="${REMOTE_PROJECT_DIR:-~/acore-compose}"
|
||||||
|
|
||||||
|
printf '\n%b\n' "${BLUE}🧭 Remote Deployment Plan${NC}"
|
||||||
|
printf '%b\n' "${YELLOW}├─ Validate build status locally${NC}"
|
||||||
|
printf '%b\n' "${YELLOW}└─ Package & sync to ${plan_user}@${plan_host}:${plan_dir}${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
maybe_select_deploy_target(){
|
||||||
|
if [ "$REMOTE_MODE" -eq 1 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ "$ASSUME_YES" -eq 1 ] || [ ! -t 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo "Select deployment target:"
|
||||||
|
echo " 1) Local host (current machine)"
|
||||||
|
echo " 2) Remote host (package for SSH deployment)"
|
||||||
|
local choice
|
||||||
|
read -rp "Choice [1]: " choice
|
||||||
|
case "${choice:-1}" in
|
||||||
|
2)
|
||||||
|
REMOTE_MODE=1
|
||||||
|
REMOTE_ARGS_PROVIDED=0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
collect_remote_details(){
|
||||||
|
if [ "$REMOTE_MODE" -ne 1 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local interactive=0
|
||||||
|
if [ -t 0 ] && [ "$ASSUME_YES" -ne 1 ]; then
|
||||||
|
interactive=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REMOTE_HOST" ] && [ "$interactive" -eq 1 ]; then
|
||||||
|
while true; do
|
||||||
|
read -rp "Remote host (hostname or IP): " REMOTE_HOST
|
||||||
|
[ -n "$REMOTE_HOST" ] && break
|
||||||
|
echo " Please enter a hostname or IP."
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REMOTE_USER" ] && [ "$interactive" -eq 1 ]; then
|
||||||
|
local default_user="$USER"
|
||||||
|
read -rp "SSH username [${default_user}]: " REMOTE_USER
|
||||||
|
REMOTE_USER="${REMOTE_USER:-$default_user}"
|
||||||
|
fi
|
||||||
|
if [ -z "$REMOTE_USER" ] && [ -n "$USER" ]; then
|
||||||
|
REMOTE_USER="$USER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REMOTE_PORT" ]; then
|
||||||
|
REMOTE_PORT="22"
|
||||||
|
fi
|
||||||
|
if [ "$interactive" -eq 1 ]; then
|
||||||
|
local port_input
|
||||||
|
read -rp "SSH port [${REMOTE_PORT}]: " port_input
|
||||||
|
REMOTE_PORT="${port_input:-$REMOTE_PORT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$interactive" -eq 1 ]; then
|
||||||
|
local identity_input
|
||||||
|
local identity_prompt="SSH identity file (leave blank for default)"
|
||||||
|
if [ -n "$REMOTE_IDENTITY" ]; then
|
||||||
|
identity_prompt="${identity_prompt} [${REMOTE_IDENTITY}]"
|
||||||
|
fi
|
||||||
|
read -rp "${identity_prompt}: " identity_input
|
||||||
|
[ -n "$identity_input" ] && REMOTE_IDENTITY="$identity_input"
|
||||||
|
fi
|
||||||
|
if [ -n "$REMOTE_IDENTITY" ]; then
|
||||||
|
REMOTE_IDENTITY="${REMOTE_IDENTITY/#\~/$HOME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REMOTE_PROJECT_DIR" ]; then
|
||||||
|
REMOTE_PROJECT_DIR="~/acore-compose"
|
||||||
|
fi
|
||||||
|
if [ "$interactive" -eq 1 ]; then
|
||||||
|
local dir_input
|
||||||
|
read -rp "Remote project directory [${REMOTE_PROJECT_DIR}]: " dir_input
|
||||||
|
REMOTE_PROJECT_DIR="${dir_input:-$REMOTE_PROJECT_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$interactive" -eq 1 ] && [ "$REMOTE_ARGS_PROVIDED" -eq 0 ]; then
|
||||||
|
local sync_answer
|
||||||
|
read -rp "Sync storage directory to remote host? [Y/n]: " sync_answer
|
||||||
|
sync_answer="${sync_answer:-Y}"
|
||||||
|
case "${sync_answer,,}" in
|
||||||
|
n|no) REMOTE_SKIP_STORAGE=1 ;;
|
||||||
|
*) REMOTE_SKIP_STORAGE=0 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_remote_configuration(){
|
||||||
|
if [ "$REMOTE_MODE" -ne 1 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ -z "$REMOTE_HOST" ]; then
|
||||||
|
err "Remote deployment requires a hostname or IP."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$REMOTE_USER" ]; then
|
||||||
|
err "Remote deployment requires an SSH username."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
REMOTE_PORT="${REMOTE_PORT:-22}"
|
||||||
|
if ! [[ "$REMOTE_PORT" =~ ^[0-9]+$ ]]; then
|
||||||
|
err "Invalid SSH port: $REMOTE_PORT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -n "$REMOTE_IDENTITY" ]; then
|
||||||
|
REMOTE_IDENTITY="${REMOTE_IDENTITY/#\~/$HOME}"
|
||||||
|
if [ ! -f "$REMOTE_IDENTITY" ]; then
|
||||||
|
err "Remote identity file not found: $REMOTE_IDENTITY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -z "$REMOTE_PROJECT_DIR" ]; then
|
||||||
|
REMOTE_PROJECT_DIR="~/acore-compose"
|
||||||
|
fi
|
||||||
|
if [ ! -f "$ROOT_DIR/scripts/migrate-stack.sh" ]; then
|
||||||
|
err "Migration script not found: $ROOT_DIR/scripts/migrate-stack.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
usage(){
|
usage(){
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $(basename "$0") [options]
|
Usage: $(basename "$0") [options]
|
||||||
@@ -95,13 +231,13 @@ while [[ $# -gt 0 ]]; do
|
|||||||
--no-watch) WATCH_LOGS=0; shift;;
|
--no-watch) WATCH_LOGS=0; shift;;
|
||||||
--keep-running) KEEP_RUNNING=1; shift;;
|
--keep-running) KEEP_RUNNING=1; shift;;
|
||||||
--yes|-y) ASSUME_YES=1; shift;;
|
--yes|-y) ASSUME_YES=1; shift;;
|
||||||
--remote) REMOTE_MODE=1; shift;;
|
--remote) REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift;;
|
||||||
--remote-host) REMOTE_HOST="$2"; REMOTE_MODE=1; shift 2;;
|
--remote-host) REMOTE_HOST="$2"; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift 2;;
|
||||||
--remote-user) REMOTE_USER="$2"; REMOTE_MODE=1; shift 2;;
|
--remote-user) REMOTE_USER="$2"; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift 2;;
|
||||||
--remote-port) REMOTE_PORT="$2"; REMOTE_MODE=1; shift 2;;
|
--remote-port) REMOTE_PORT="$2"; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift 2;;
|
||||||
--remote-identity) REMOTE_IDENTITY="$2"; REMOTE_MODE=1; shift 2;;
|
--remote-identity) REMOTE_IDENTITY="$2"; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift 2;;
|
||||||
--remote-project-dir) REMOTE_PROJECT_DIR="$2"; REMOTE_MODE=1; shift 2;;
|
--remote-project-dir) REMOTE_PROJECT_DIR="$2"; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift 2;;
|
||||||
--remote-skip-storage) REMOTE_SKIP_STORAGE=1; REMOTE_MODE=1; shift;;
|
--remote-skip-storage) REMOTE_SKIP_STORAGE=1; REMOTE_MODE=1; REMOTE_ARGS_PROVIDED=1; shift;;
|
||||||
-h|--help) usage; exit 0;;
|
-h|--help) usage; exit 0;;
|
||||||
*) err "Unknown option: $1"; usage; exit 1;;
|
*) err "Unknown option: $1"; usage; exit 1;;
|
||||||
esac
|
esac
|
||||||
@@ -214,7 +350,9 @@ detect_build_needed(){
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf '%s\n' "${reasons[@]}"
|
if [ ${#reasons[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "${reasons[@]}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_runtime_stack(){
|
stop_runtime_stack(){
|
||||||
@@ -453,8 +591,13 @@ main(){
|
|||||||
|
|
||||||
show_deployment_header
|
show_deployment_header
|
||||||
|
|
||||||
|
maybe_select_deploy_target
|
||||||
|
collect_remote_details
|
||||||
|
validate_remote_configuration
|
||||||
|
|
||||||
if [ "$REMOTE_MODE" -eq 1 ]; then
|
if [ "$REMOTE_MODE" -eq 1 ]; then
|
||||||
local remote_steps=2
|
local remote_steps=2
|
||||||
|
show_remote_plan
|
||||||
show_step 1 "$remote_steps" "Checking build requirements"
|
show_step 1 "$remote_steps" "Checking build requirements"
|
||||||
if ! prompt_build_if_needed; then
|
if ! prompt_build_if_needed; then
|
||||||
err "Build required but not completed. Remote deployment cancelled."
|
err "Build required but not completed. Remote deployment cancelled."
|
||||||
@@ -466,7 +609,7 @@ main(){
|
|||||||
ok "Remote deployment package prepared for $REMOTE_USER@$REMOTE_HOST."
|
ok "Remote deployment package prepared for $REMOTE_USER@$REMOTE_HOST."
|
||||||
local remote_dir="${REMOTE_PROJECT_DIR:-~/acore-compose}"
|
local remote_dir="${REMOTE_PROJECT_DIR:-~/acore-compose}"
|
||||||
info "Run the following on the remote host to complete deployment:"
|
info "Run the following on the remote host to complete deployment:"
|
||||||
printf ' %bcd %s && ./deploy.sh --no-watch%b\n' "$YELLOW" "$remote_dir" "$NC"
|
printf ' %bcd %s && ./deploy.sh --yes --no-watch%b\n' "$YELLOW" "$remote_dir" "$NC"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
err "Remote migration failed."
|
err "Remote migration failed."
|
||||||
|
|||||||
@@ -213,7 +213,18 @@ if [[ $SKIP_STORAGE -eq 0 ]]; then
|
|||||||
if [[ -d storage ]]; then
|
if [[ -d storage ]]; then
|
||||||
echo "⋅ Syncing storage to remote"
|
echo "⋅ Syncing storage to remote"
|
||||||
run_ssh "mkdir -p '$REMOTE_STORAGE'"
|
run_ssh "mkdir -p '$REMOTE_STORAGE'"
|
||||||
find storage -mindepth 1 -maxdepth 1 -print0 | xargs -0 -I{} scp "${SCP_OPTS[@]}" -r '{}' "$USER@$HOST:$REMOTE_STORAGE/"
|
while IFS= read -r -d '' entry; do
|
||||||
|
base_name="$(basename "$entry")"
|
||||||
|
if [[ "$base_name" = modules ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ -L "$entry" ]; then
|
||||||
|
target_path="$(readlink -f "$entry")"
|
||||||
|
run_scp "$target_path" "$USER@$HOST:$REMOTE_STORAGE/$base_name"
|
||||||
|
else
|
||||||
|
run_scp -r "$entry" "$USER@$HOST:$REMOTE_STORAGE/"
|
||||||
|
fi
|
||||||
|
done < <(find storage -mindepth 1 -maxdepth 1 -print0)
|
||||||
else
|
else
|
||||||
echo "⋅ Skipping storage sync (storage/ missing)"
|
echo "⋅ Skipping storage sync (storage/ missing)"
|
||||||
fi
|
fi
|
||||||
@@ -221,6 +232,20 @@ else
|
|||||||
echo "⋅ Skipping storage sync"
|
echo "⋅ Skipping storage sync"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ $SKIP_STORAGE -eq 0 ]]; then
|
||||||
|
LOCAL_MODULES_DIR="${LOCAL_STORAGE_ROOT}/modules"
|
||||||
|
if [[ -d "$LOCAL_MODULES_DIR" ]]; then
|
||||||
|
echo "⋅ Syncing module staging to remote"
|
||||||
|
run_ssh "rm -rf '$REMOTE_STORAGE/modules' && mkdir -p '$REMOTE_STORAGE/modules'"
|
||||||
|
local modules_tar
|
||||||
|
modules_tar=$(mktemp)
|
||||||
|
tar -cf "$modules_tar" -C "$LOCAL_MODULES_DIR" .
|
||||||
|
run_scp "$modules_tar" "$USER@$HOST:/tmp/acore-modules.tar"
|
||||||
|
rm -f "$modules_tar"
|
||||||
|
run_ssh "tar -xf /tmp/acore-modules.tar -C '$REMOTE_STORAGE/modules' && rm /tmp/acore-modules.tar"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo "⋅ Loading images on remote"
|
echo "⋅ Loading images on remote"
|
||||||
run_scp "$TARBALL" "$USER@$HOST:/tmp/acore-modules-images.tar"
|
run_scp "$TARBALL" "$USER@$HOST:/tmp/acore-modules-images.tar"
|
||||||
run_ssh "docker load < /tmp/acore-modules-images.tar && rm /tmp/acore-modules-images.tar"
|
run_ssh "docker load < /tmp/acore-modules-images.tar && rm /tmp/acore-modules-images.tar"
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ sync_local_staging(){
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📦 Syncing local module staging from $src_modules to $dest_modules"
|
echo "📦 Syncing local module staging from $src_modules to $dest_modules"
|
||||||
mkdir -p "$dest_modules"
|
if ! mkdir -p "$dest_modules" 2>/dev/null; then
|
||||||
|
echo "ℹ️ Destination storage path $dest_root not accessible (likely remote storage - skipping sync)."
|
||||||
|
echo "ℹ️ Module sync will be handled by the remote deployment."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
if command -v rsync >/dev/null 2>&1; then
|
if command -v rsync >/dev/null 2>&1; then
|
||||||
rsync -a --delete "$src_modules"/ "$dest_modules"/
|
rsync -a --delete "$src_modules"/ "$dest_modules"/
|
||||||
|
|||||||
Reference in New Issue
Block a user